From: Jean-Baptiste M. <jb...@kd...> - 2012-10-30 01:35:02
|
Git commit d385077e0eab07915166924ca41d9fa807072cf0 by Jean-Baptiste Mardelle. Committed on 30/10/2012 at 02:34. Pushed by mardelle into branch 'master'. Affine / composite transition path can now be edited on the monitor M +1 -1 src/effectstackedit.cpp M +1 -1 src/effectstackedit.h M +37 -2 src/geometrywidget.cpp M +4 -0 src/geometrywidget.h M +6 -1 src/monitoreditwidget.cpp M +1 -1 src/monitoreditwidget.h M +1 -0 src/onmonitoritems/CMakeLists.txt A +203 -0 src/onmonitoritems/onmonitorpathitem.cpp [License: GPL (v2+)] C +21 -14 src/onmonitoritems/onmonitorpathitem.h [from: src/onmonitoritems/onmonitorrectitem.h - 073% similarity] M +23 -11 src/onmonitoritems/onmonitorrectitem.cpp M +1 -0 src/onmonitoritems/onmonitorrectitem.h http://commits.kde.org/kdenlive/d385077e0eab07915166924ca41d9fa807072cf0 diff --git a/src/effectstackedit.cpp b/src/effectstackedit.cpp index cc4212f..1089911 100644 --- a/src/effectstackedit.cpp +++ b/src/effectstackedit.cpp @@ -152,7 +152,7 @@ void EffectStackEdit::transferParamDesc(const QDomElement &d, ItemInfo info, boo m_paramWidget = new ParameterContainer(d, info, &m_metaInfo, m_baseWidget); connect (m_paramWidget, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int))); - connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList)), this, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList))); + connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,const QMap<QString, QString>)), this, SIGNAL(startFilterJob(QString,QString,QString,QString,const QMap<QString, QString>))); connect (this, SIGNAL(syncEffectsPos(int)), m_paramWidget, SIGNAL(syncEffectsPos(int))); connect (m_paramWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int))); diff --git a/src/effectstackedit.h b/src/effectstackedit.h index 3ef8aaa..f760222 100644 --- a/src/effectstackedit.h +++ b/src/effectstackedit.h @@ -81,7 +81,7 @@ signals: void showComments(bool show); void effectStateChanged(bool enabled); /** @brief Start an MLT filter job on this clip. */ - void startFilterJob(const QString &filterName, const QString &filterParams, const QString &finalFilterName, const QString &consumer, const QString &consumerParams, const QStringList&extraParams); + void startFilterJob(const QString &filterName, const QString &filterParams, const QString &consumer, const QString &consumerParams, const QMap <QString, QString>); void importClipKeyframes(GRAPHICSRECTITEM = AVWIDGET); }; diff --git a/src/geometrywidget.cpp b/src/geometrywidget.cpp index 55a2340..fcbb90a 100644 --- a/src/geometrywidget.cpp +++ b/src/geometrywidget.cpp @@ -26,6 +26,7 @@ #include "monitorscene.h" #include "monitoreditwidget.h" #include "onmonitoritems/onmonitorrectitem.h" +#include "onmonitoritems/onmonitorpathitem.h" #include "kdenlivesettings.h" #include "dragvalue.h" @@ -46,6 +47,7 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos, m_outPoint(1), m_isEffect(isEffect), m_rect(NULL), + m_geomPath(NULL), m_previous(NULL), m_geometry(NULL), m_showScene(true), @@ -245,7 +247,9 @@ GeometryWidget::~GeometryWidget() delete m_spinHeight; delete m_opacity; m_scene->removeItem(m_rect); + m_scene->removeItem(m_geomPath); if (m_rect) delete m_rect; + if (m_geomPath) delete m_geomPath; if (m_previous) delete m_previous; delete m_geometry; m_extraGeometryNames.clear(); @@ -315,14 +319,25 @@ void GeometryWidget::setupParam(const QDomElement elem, int minframe, int maxfra } Mlt::GeometryItem item; - m_geometry->fetch(&item, 0); - delete m_rect; + if (m_rect) { + m_scene->removeItem(m_rect); + delete m_rect; + } + if (m_geomPath) { + m_scene->removeItem(m_geomPath); + delete m_geomPath; + } m_rect = new OnMonitorRectItem(QRectF(0, 0, item.w(), item.h()), m_monitor->render->dar()); m_rect->setPos(item.x(), item.y()); m_rect->setZValue(0); m_scene->addItem(m_rect); connect(m_rect, SIGNAL(changed()), this, SLOT(slotUpdateGeometry())); + m_geomPath = new OnMonitorPathItem(m_monitor->render->dar()); + connect(m_geomPath, SIGNAL(changed()), this, SLOT(slotUpdatePath())); + m_geomPath->setPen(QPen(Qt::red)); + m_scene->addItem(m_geomPath); + m_geomPath->setPoints(m_geometry); m_scene->centerView(); slotPositionChanged(0, false); } @@ -527,6 +542,25 @@ void GeometryWidget::slotAddDeleteKeyframe() slotDeleteKeyframe(); } +void GeometryWidget::slotUpdatePath() +{ + if (!m_geomPath) return; + QList <QPointF> points = m_geomPath->points(); + Mlt::GeometryItem item; + int pos = 0; + int ix = 0; + while (ix < points.count() && !m_geometry->next_key(&item, pos)) { + QPointF center = points.at(ix); + QSizeF size(item.w(), item.h()); + item.x(center.x() - size.width()/2); + item.y(center.y() - size.height()/2); + m_geometry->insert(item); + pos = item.frame() + 1; + ix++; + } + slotPositionChanged(-1, false); + emit parameterChanged(); +} void GeometryWidget::slotUpdateGeometry() @@ -556,6 +590,7 @@ void GeometryWidget::slotUpdateGeometry() geom->insert(item2); } } + if (m_geomPath) m_geomPath->setPoints(m_geometry); emit parameterChanged(); } diff --git a/src/geometrywidget.h b/src/geometrywidget.h index df26b9c..0ae57f7 100644 --- a/src/geometrywidget.h +++ b/src/geometrywidget.h @@ -33,6 +33,7 @@ class MonitorScene; class KeyframeHelper; class TimecodeDisplay; class OnMonitorRectItem; +class OnMonitorPathItem; class QGraphicsRectItem; class DragValue; @@ -81,6 +82,7 @@ private: bool m_isEffect; MonitorScene *m_scene; OnMonitorRectItem *m_rect; + OnMonitorPathItem *m_geomPath; QGraphicsRectItem *m_previous; KeyframeHelper *m_timeline; /** Stores the different settings in the MLT geometry format. */ @@ -128,6 +130,8 @@ private slots: /** @brief Adds or deletes a keyframe depending on whether there is already a keyframe at the current position. */ void slotAddDeleteKeyframe(); + /** @brief Updates the Mlt::Geometry path object. */ + void slotUpdatePath(); /** @brief Updates the Mlt::Geometry object. */ void slotUpdateGeometry(); /** @brief Updates the spinBoxes according to the rect. */ diff --git a/src/monitoreditwidget.cpp b/src/monitoreditwidget.cpp index d09a13c..c756cf9 100644 --- a/src/monitoreditwidget.cpp +++ b/src/monitoreditwidget.cpp @@ -22,13 +22,18 @@ #include "monitorscene.h" #include "kdenlivesettings.h" +#include "onmonitoritems/onmonitorrectitem.h" +#include "onmonitoritems/onmonitorpathitem.h" + #include <QGraphicsView> #include <QVBoxLayout> #include <QAction> #include <QToolButton> +#include <QMouseEvent> #include <KIcon> + MonitorEditWidget::MonitorEditWidget(Render* renderer, QWidget* parent) : QWidget(parent) { @@ -41,7 +46,7 @@ MonitorEditWidget::MonitorEditWidget(Render* renderer, QWidget* parent) : m_scene = new MonitorScene(renderer); m_view = new QGraphicsView(m_scene, m_ui.frameVideo); m_view->setFrameShape(QFrame::NoFrame); - m_view->setRenderHints(QFlags<QPainter::RenderHint>()); + //m_view->setRenderHints(QFlags<QPainter::RenderHint>()); m_view->scale(((double) renderer->renderWidth()) / renderer->frameRenderWidth(), 1.0); m_view->setMouseTracking(true); m_scene->setUp(); diff --git a/src/monitoreditwidget.h b/src/monitoreditwidget.h index 4df207a..34f3b07 100644 --- a/src/monitoreditwidget.h +++ b/src/monitoreditwidget.h @@ -22,6 +22,7 @@ #include "ui_monitoreditwidget_ui.h" #include <QWidget> +#include <QGraphicsView> class QIcon; class MonitorScene; @@ -31,7 +32,6 @@ class QToolButton; class QVBoxLayout; - class MonitorEditWidget : public QWidget { Q_OBJECT diff --git a/src/onmonitoritems/CMakeLists.txt b/src/onmonitoritems/CMakeLists.txt index 58ece7c..041a4d7 100644 --- a/src/onmonitoritems/CMakeLists.txt +++ b/src/onmonitoritems/CMakeLists.txt @@ -2,5 +2,6 @@ set(kdenlive_SRCS ${kdenlive_SRCS} onmonitoritems/onmonitorcornersitem.cpp onmonitoritems/onmonitorrectitem.cpp + onmonitoritems/onmonitorpathitem.cpp PARENT_SCOPE ) diff --git a/src/onmonitoritems/onmonitorpathitem.cpp b/src/onmonitoritems/onmonitorpathitem.cpp new file mode 100644 index 0000000..97e7ac9 --- /dev/null +++ b/src/onmonitoritems/onmonitorpathitem.cpp @@ -0,0 +1,203 @@ +/*************************************************************************** + * Copyright (C) 2010 by Till Theato (ro...@tt...) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "onmonitorpathitem.h" +#include "kdenlivesettings.h" + +#include <QGraphicsSceneMouseEvent> +#include <QPainter> +#include <QStyleOptionGraphicsItem> +#include <QCursor> +#include <QGraphicsView> +#include <QApplication> + +#include <mlt++/Mlt.h> + +OnMonitorPathItem::OnMonitorPathItem(double dar, QGraphicsItem* parent) : + QGraphicsPathItem(parent), + m_dar(dar), + m_modified(false), + m_view(NULL), + m_activePoint(-1) +{ + setFlags(QGraphicsItem::ItemIsMovable); + + QPen framepen(Qt::SolidLine); + framepen.setColor(Qt::red); + setPen(framepen); + setBrush(Qt::transparent); + setAcceptHoverEvents(true); +} + +void OnMonitorPathItem::setPoints(Mlt::Geometry *geometry) +{ + m_points.clear(); + QRectF r; + int pos = 0; + Mlt::GeometryItem item; + while (!geometry->next_key(&item, pos)) { + r = QRectF(item.x(), item.y(), item.w(), item.h()); + m_points << r.center(); + pos = item.frame() + 1; + } + rebuildShape(); +} + +void OnMonitorPathItem::rebuildShape() { + if (m_activePoint > m_points.count()) m_activePoint = -1; + QPainterPath p; + QPainterPath shape; + + if (!m_points.isEmpty()) { + QRectF r(0, 0, 20, 20); + r.moveCenter(m_points.at(0)); + shape.addRect(r); + + p.moveTo(m_points.at(0)); + for (int i = 1; i < m_points.count(); i++) { + p.lineTo(m_points.at(i)); + r.moveCenter(m_points.at(i)); + shape.addRect(r); + } + } + m_shape = shape; + setPath(p); +} + +void OnMonitorPathItem::getMode(QPointF pos) +{ + double dist = 8; + if (getView()) { + dist /= m_view->matrix().m11(); + } + // Item mapped coordinates + for (int i = 0; i < m_points.count(); i++) { + if ((pos - m_points.at(i)).manhattanLength() <= dist) { + m_activePoint = i; + return; + } + } + m_activePoint = -1; +} + +void OnMonitorPathItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event) +{ + /*if (event->buttons() != Qt::NoButton && (event->screenPos() - m_screenClickPoint).manhattanLength() < QApplication::startDragDistance()) { + * event->accept(); + * return; + }*/ + + if (m_activePoint >= 0 && event->buttons() & Qt::LeftButton) { + QPointF mousePos = event->pos(); + m_points[m_activePoint] = mousePos; + rebuildShape(); + m_modified = true; + update(); + } + + if (m_modified) { + event->accept(); + if (KdenliveSettings::monitorscene_directupdate()) { + emit changed(); + m_modified = false; + } + } else { + event->ignore(); + } +} + +QList <QPointF> OnMonitorPathItem::points() const +{ + return m_points; +} + +void OnMonitorPathItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) +{ + if (m_modified) { + m_modified = false; + emit changed(); + } + event->accept(); +} + +QRectF OnMonitorPathItem::boundingRect () const +{ + return shape().boundingRect(); +} + +QPainterPath OnMonitorPathItem::shape () const +{ + return m_shape; +} + +void OnMonitorPathItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) +{ + if (m_activePoint != -1) { + m_activePoint = -1; + update(); + } + unsetCursor(); +} + +void OnMonitorPathItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) +{ + setCursor(QCursor(Qt::PointingHandCursor)); +} + +void OnMonitorPathItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event) +{ + int currentPoint = m_activePoint; + getMode(event->pos()); + if (currentPoint != m_activePoint) update(); + setCursor(QCursor(Qt::PointingHandCursor)); +} + +void OnMonitorPathItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + //Q_UNUSED(widget) + QGraphicsPathItem::paint(painter, option, widget); + + double w = 6; + double h = 6; + if (getView()) { + w /= m_view->matrix().m11(); + h /= m_view->matrix().m22(); + } + + QRectF handle(0, 0, w, h); + for (int i = 0; i < m_points.count(); i++) { + handle.moveCenter(m_points.at(i)); + painter->fillRect(handle, m_activePoint == i ? Qt::blue : pen().color()); + } +} + +bool OnMonitorPathItem::getView() +{ + if (m_view) + return true; + + if (scene() && scene()->views().count()) { + m_view = scene()->views()[0]; + return true; + } else { + return false; + } +} + +#include "onmonitorpathitem.moc" diff --git a/src/onmonitoritems/onmonitorrectitem.h b/src/onmonitoritems/onmonitorpathitem.h similarity index 73% copy from src/onmonitoritems/onmonitorrectitem.h copy to src/onmonitoritems/onmonitorpathitem.h index ea7c2fe..7665852 100644 --- a/src/onmonitoritems/onmonitorrectitem.h +++ b/src/onmonitoritems/onmonitorpathitem.h @@ -18,44 +18,51 @@ ***************************************************************************/ -#ifndef ONMONITORRECTITEM_H -#define ONMONITORRECTITEM_H +#ifndef ONMONITORPATHITEM_H +#define ONMONITORPATHITEM_H #include <QtCore> -#include <QGraphicsRectItem> +#include <QGraphicsPathItem> class QGraphicsView; -enum rectActions { Move, ResizeTopLeft, ResizeBottomLeft, ResizeTopRight, ResizeBottomRight, ResizeLeft, ResizeRight, ResizeTop, ResizeBottom, NoAction }; +namespace Mlt { +class Geometry; +} -class OnMonitorRectItem : public QObject, public QGraphicsRectItem + +class OnMonitorPathItem : public QObject, public QGraphicsPathItem { Q_OBJECT public: - OnMonitorRectItem(const QRectF &rect, double dar, QGraphicsItem *parent = 0); - - /** @brief Gets The action mode for the area @param pos +- 4. - * e.g. pos(0,0) returns ResizeTopLeft */ - rectActions getMode(QPointF pos); + OnMonitorPathItem(double dar, QGraphicsItem *parent = 0); + void setPoints(Mlt::Geometry *geometry); + void getMode(QPointF pos); + void rebuildShape(); + QList <QPointF> points() const; + virtual QPainterPath shape () const; /** @brief Reimplemented to draw the handles. */ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0 ); + virtual QRectF boundingRect () const; protected: - virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + //virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); private: double m_dar; - rectActions m_mode; - QRectF m_oldRect; + QList <QPointF> m_points; QPointF m_lastPoint; bool m_modified; - QGraphicsView *m_view; + int m_activePoint; + QPainterPath m_shape; /** @brief Tries to get the view of the scene. */ bool getView(); diff --git a/src/onmonitoritems/onmonitorrectitem.cpp b/src/onmonitoritems/onmonitorrectitem.cpp index acf5c1f..37f918f 100644 --- a/src/onmonitoritems/onmonitorrectitem.cpp +++ b/src/onmonitoritems/onmonitorrectitem.cpp @@ -56,10 +56,13 @@ rectActions OnMonitorRectItem::getMode(QPointF pos) right.lineTo(pol.at(2)); QPainterPath mouseArea; - qreal size = 8; - if (getView()) - size /= m_view->matrix().m11(); - mouseArea.addRect(pos.x() - size / 2, pos.y() - size / 2, size, size); + qreal xsize = 10; + qreal ysize = 10; + if (getView()) { + xsize /= m_view->matrix().m11(); + ysize /= m_view->matrix().m22(); + } + mouseArea.addRect(pos.x() - xsize / 2, pos.y() - ysize / 2, xsize, ysize); // Check for collisions between the mouse and the borders if (mouseArea.contains(pol.at(0))) @@ -262,15 +265,24 @@ void OnMonitorRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* painter->setPen(pen()); painter->drawRect(option->rect); - + const QRectF r = painter->worldTransform().mapRect(option->rect); + painter->setWorldMatrixEnabled(false); if (isEnabled()) { - double handleSize = 6 / painter->worldTransform().m11(); - double halfHandleSize = handleSize / 2; - painter->fillRect(-halfHandleSize, -halfHandleSize, handleSize, handleSize, QColor(Qt::yellow)); - painter->fillRect(option->rect.width() - halfHandleSize, -halfHandleSize, handleSize, handleSize, QColor(Qt::yellow)); - painter->fillRect(option->rect.width() - halfHandleSize, option->rect.height() - halfHandleSize, handleSize, handleSize, QColor(Qt::yellow)); - painter->fillRect(-halfHandleSize, option->rect.height() - halfHandleSize, handleSize, handleSize, QColor(Qt::yellow)); + QRectF handle(0, 0, 6, 6); + handle.moveTopLeft(r.topLeft()); + painter->fillRect(handle, QColor(Qt::yellow)); + handle.moveTopRight(r.topRight()); + painter->fillRect(handle, QColor(Qt::yellow)); + handle.moveBottomLeft(r.bottomLeft()); + painter->fillRect(handle, QColor(Qt::yellow)); + handle.moveBottomRight(r.bottomRight()); + painter->fillRect(handle, QColor(Qt::yellow)); } + + // Draw cross at center + QPointF center = r.center(); + painter->drawLine(center + QPointF(-6, 0), center + QPointF(6, 0)); + painter->drawLine(center + QPointF(0, 6), center + QPointF(0, -6)); } bool OnMonitorRectItem::getView() diff --git a/src/onmonitoritems/onmonitorrectitem.h b/src/onmonitoritems/onmonitorrectitem.h index ea7c2fe..15e9394 100644 --- a/src/onmonitoritems/onmonitorrectitem.h +++ b/src/onmonitoritems/onmonitorrectitem.h @@ -29,6 +29,7 @@ class QGraphicsView; enum rectActions { Move, ResizeTopLeft, ResizeBottomLeft, ResizeTopRight, ResizeBottomRight, ResizeLeft, ResizeRight, ResizeTop, ResizeBottom, NoAction }; + class OnMonitorRectItem : public QObject, public QGraphicsRectItem { Q_OBJECT |