]> git.sesse.net Git - kdenlive/commitdiff
Affine / composite transition path can now be edited on the monitor
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 30 Oct 2012 01:34:24 +0000 (02:34 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 30 Oct 2012 01:34:24 +0000 (02:34 +0100)
src/effectstackedit.cpp
src/effectstackedit.h
src/geometrywidget.cpp
src/geometrywidget.h
src/monitoreditwidget.cpp
src/monitoreditwidget.h
src/onmonitoritems/CMakeLists.txt
src/onmonitoritems/onmonitorpathitem.cpp [new file with mode: 0644]
src/onmonitoritems/onmonitorpathitem.h [new file with mode: 0644]
src/onmonitoritems/onmonitorrectitem.cpp
src/onmonitoritems/onmonitorrectitem.h

index cc4212fdf511ab497549646ed1456ce28ede7506..10899110d1a13581a38596bc67b111006848b653 100644 (file)
@@ -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)));
index 3ef8aaa9b1bb3000e50cc9d786a3fc961b5b7bf7..f760222242c85ca8c2a185b5ed5651ac434632e8 100644 (file)
@@ -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);
 };
 
index 55a234046c1cfd309378345da8d743bd9380e21a..fcbb90a660ccf8f50e9b913182c17428601adfe5 100644 (file)
@@ -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();
 }
 
index df26b9c47259c4c653bb631a30de67a69735e1d0..0ae57f737468a22af3c024992cf899bdf60d0db3 100644 (file)
@@ -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. */
index d09a13c4c9cdb7da9559cad9312e96d5faf1821c..c756cf94f86584bcadcc9bcfc74af9dbcec787c1 100644 (file)
 #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();
index 4df207ab0567dc433617b55836c82ff3da55ea5b..34f3b07c8ae840a14a1851bc58101e001918a13b 100644 (file)
@@ -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
index 58ece7c0638524a9b29b3fec40882a0f609727d4..041a4d76a4549dcac32ac4fcaa442c9fb999a7c6 100644 (file)
@@ -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 (file)
index 0000000..97e7ac9
--- /dev/null
@@ -0,0 +1,203 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Till Theato (root@ttill.de)                     *
+ *                                                                         *
+ *   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/onmonitorpathitem.h b/src/onmonitoritems/onmonitorpathitem.h
new file mode 100644 (file)
index 0000000..7665852
--- /dev/null
@@ -0,0 +1,74 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Till Theato (root@ttill.de)                     *
+ *                                                                         *
+ *   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          *
+ ***************************************************************************/
+
+
+#ifndef ONMONITORPATHITEM_H
+#define ONMONITORPATHITEM_H
+
+
+#include <QtCore>
+#include <QGraphicsPathItem>
+
+class QGraphicsView;
+
+namespace Mlt {
+class Geometry;
+}
+
+
+class OnMonitorPathItem : public QObject, public QGraphicsPathItem
+{
+    Q_OBJECT
+public:
+    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 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;
+    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();
+
+signals:
+    void changed();
+};
+
+#endif
index acf5c1faf673aa219afdceb31ab1c9543e874676..37f918f356b978754b7cccb7615234d8b0487312 100644 (file)
@@ -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()
index ea7c2fe7206a7026ebb3ff44846d42c0c5e3f6b9..15e93941fc22c98eaa82f2186fc5c4ed7ec04f93 100644 (file)
@@ -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