]> git.sesse.net Git - kdenlive/commitdiff
First work on rotoscoping GUI
authorTill Theato <root@ttill.de>
Sun, 30 Jan 2011 14:24:57 +0000 (14:24 +0000)
committerTill Theato <root@ttill.de>
Sun, 30 Jan 2011 14:24:57 +0000 (14:24 +0000)
(MLT module: github.com/ttill/MLT-roto)

svn path=/trunk/kdenlive/; revision=5367

14 files changed:
data/blacklisted_effects.txt
effects/CMakeLists.txt
effects/rotoscoping.xml [new file with mode: 0644]
src/CMakeLists.txt
src/effectstackedit.cpp
src/onmonitoritems/CMakeLists.txt
src/onmonitoritems/rotoscoping/CMakeLists.txt [new file with mode: 0644]
src/onmonitoritems/rotoscoping/bpointitem.cpp [new file with mode: 0644]
src/onmonitoritems/rotoscoping/bpointitem.h [new file with mode: 0644]
src/onmonitoritems/rotoscoping/splineitem.cpp [new file with mode: 0644]
src/onmonitoritems/rotoscoping/splineitem.h [new file with mode: 0644]
src/rotoscoping/CMakeLists.txt [new file with mode: 0644]
src/rotoscoping/rotowidget.cpp [new file with mode: 0644]
src/rotoscoping/rotowidget.h [new file with mode: 0644]

index 9d35973ec11ce31471ed63f7a66b35c4a63aa76f..a4e28890ec8bcdfd8e41e469ad92c06286fddc19 100644 (file)
@@ -77,6 +77,7 @@ grain
 lines
 oldfilm
 tcolor
+rotoscoping
 
 #effects that have simplekeyframes
 vignette
index 0cb0f4909944aa99c30c5a885fa356ebd59048bd..c293b5145a71ba55b6c34f9c2ce5f71cdf74b640 100644 (file)
@@ -115,5 +115,6 @@ vignette.xml
 swapchannels.xml
 audiobalance.xml
 audiopan.xml
+rotoscoping.xml
 
 DESTINATION ${DATA_INSTALL_DIR}/kdenlive/effects)
diff --git a/effects/rotoscoping.xml b/effects/rotoscoping.xml
new file mode 100644 (file)
index 0000000..1e24d2d
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE kpartgui>
+<effect tag="rotoscoping" id="rotoscoping">
+        <name>Rotoscoping</name>
+        <description>Keyframable vector based rotoscoping</description>
+        <author>Till Theato</author>
+
+        <parameter type="list" name="mode" default="alpha" paramlist="alpha,matte,rgb">
+            <paramlistdisplay>Alpha,Matte,RGB</paramlistdisplay>
+            <name>Mode</name>
+        </parameter>
+
+        <parameter type="list" name="alpha_operation" default="clear" paramlist="clear,max,min,add,sub">
+            <paramlistdisplay>Write on clear,Maximum,Minimum,Add,Subtract</paramlistdisplay>
+            <name>Alpha Operation</name>
+        </parameter>
+
+        <parameter type="bool" name="invert" default="0">
+            <name>Invert</name>
+        </parameter>
+
+        <parameter type="constant" name="precision" max="500" min="1" default="1">
+            <name>Precision</name>
+        </parameter>
+
+        <parameter type="roto-spline" name="spline" default="[[[0,1],[0,0],[1,0]],[[1,0],[1,1],[0,1]]]"> <!-- TODO: set default to "" -->
+            <name>Rotoscopy Spline</name>
+        </parameter>
+</effect>
index 25dd4ed4fe689ee30a891ea146f3ef9581034e10..a2a7cd1affe412b347f31a51512d2ab4e7e6ccdf 100644 (file)
@@ -3,17 +3,21 @@ add_subdirectory(colorcorrection)
 add_subdirectory(kiss_fft)
 add_subdirectory(mimetypes)
 add_subdirectory(onmonitoritems)
+add_subdirectory(rotoscoping)
 add_subdirectory(widgets)
 
 macro_optional_find_package(Nepomuk)
 include(FindQImageBlitz)
 
+find_package(QJSON)
+
 include_directories(
   ${KDE4_INCLUDE_DIR}
   ${KDE4_INCLUDE_DIR}/KDE
   ${QT_INCLUDES}
   ${LIBMLT_INCLUDE_DIR}
   ${LIBMLTPLUS_INCLUDE_DIR}
+  ${QJSON_INCLUDE_DIR}
   ${QDBUS_INCLUDE_DIRS}
   ${CMAKE_SOURCE_DIR}
   ${CMAKE_BINARY_DIR}
@@ -22,6 +26,7 @@ include_directories(
   ${CMAKE_SOURCE_DIR}/src/colorcorrection
   ${CMAKE_SOURCE_DIR}/src/kiss_fft
   ${CMAKE_SOURCE_DIR}/src/onmonitoritems
+  ${CMAKE_SOURCE_DIR}/src/onmonitoritems/rotoscoping
   ${CMAKE_SOURCE_DIR}/src/widgets
 )
 
@@ -256,6 +261,8 @@ set(kdenlive_SRCS
   blackmagic/devices.cpp
   onmonitoritems/onmonitorrectitem.cpp
   onmonitoritems/onmonitorcornersitem.cpp
+  onmonitoritems/rotoscoping/splineitem.cpp
+  onmonitoritems/rotoscoping/bpointitem.cpp
   cornerswidget.cpp
   kiss_fft/_kiss_fft_guts.h
   kiss_fft/kiss_fft.c
@@ -266,6 +273,7 @@ set(kdenlive_SRCS
   beziercurve/cubicbezierspline.cpp
   dragvalue.cpp
   monitoreditwidget.cpp
+  rotoscoping/rotowidget.cpp
 )
 
 add_definitions(${KDE4_DEFINITIONS})
@@ -321,6 +329,7 @@ target_link_libraries(kdenlive
   ${KDE4_KROSSUI_LIBS}
   ${CMAKE_DL_LIBS}
   ${CMAKE_THREAD_LIBS_INIT}
+  ${QJSON_LIBRARIES}
 )
 
 if(Q_WS_X11)
index 1cb9d1d24df264e8e4e114965b31d8c2f4776d04..892dd8511a3c6fd7e8fba8e69879049839c801a4 100644 (file)
@@ -35,6 +35,7 @@
 #include "doubleparameterwidget.h"
 #include "cornerswidget.h"
 #include "beziercurve/beziersplinewidget.h"
+#include "rotoscoping/rotowidget.h"
 
 #include <KDebug>
 #include <KLocale>
@@ -407,6 +408,15 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
             QString depends = pa.attribute("depends");
             if (!depends.isEmpty())
                 meetDependency(paramName, type, EffectsList::parameter(e, depends));
+        } else if (type == "roto-spline") {
+            RotoWidget *roto = new RotoWidget(value, m_monitor, m_in, m_out, this);
+            roto->slotShowScene(!disable);
+            connect(roto, SIGNAL(valueChanged()), this, SLOT(collectAllParameters()));
+            connect(roto, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
+            connect(this, SIGNAL(syncEffectsPos(int)), roto, SLOT(slotSyncPosition(int)));
+            connect(this, SIGNAL(effectStateChanged(bool)), roto, SLOT(slotShowScene(bool)));
+            m_vbox->addWidget(roto);
+            m_valueItems[paramName] = roto;
         } else if (type == "wipe") {
             Wipeval *wpval = new Wipeval;
             wpval->setupUi(toFillin);
@@ -672,6 +682,9 @@ void EffectStackEdit::collectAllParameters()
             QString depends = pa.attributes().namedItem("depends").nodeValue();
             if (!depends.isEmpty())
                 meetDependency(paramName, type, EffectsList::parameter(newparam, depends));
+        } else if (type == "roto-spline") {
+            RotoWidget *widget = static_cast<RotoWidget *>(m_valueItems.value(paramName));
+            setValue = widget->getSpline();
         } else if (type == "wipe") {
             Wipeval *wp = (Wipeval*)m_valueItems.value(paramName);
             wipeInfo info;
index c7f782316586b410f4e5a01d13d8f6b722461e79..1afa18c3ebf87f566fbfe47607ccee1d3a9622d0 100644 (file)
@@ -1 +1 @@
-# Empty cmake file to satisfy CMake
\ No newline at end of file
+add_subdirectory(rotoscoping)
diff --git a/src/onmonitoritems/rotoscoping/CMakeLists.txt b/src/onmonitoritems/rotoscoping/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/onmonitoritems/rotoscoping/bpointitem.cpp b/src/onmonitoritems/rotoscoping/bpointitem.cpp
new file mode 100644 (file)
index 0000000..232255e
--- /dev/null
@@ -0,0 +1,154 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Till Theato (root@ttill.de)                     *
+ *   This file is part of Kdenlive (www.kdenlive.org).                     *
+ *                                                                         *
+ *   Kdenlive 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.                                   *
+ *                                                                         *
+ *   Kdenlive 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 Kdenlive.  If not, see <http://www.gnu.org/licenses/>.     *
+ ***************************************************************************/
+
+#include "bpointitem.h"
+#include "splineitem.h"
+
+#include <QPainter>
+#include <QGraphicsSceneMouseEvent>
+#include <QCursor>
+
+
+BPointItem::BPointItem(BPoint point, QGraphicsItem* parent) :
+        QAbstractGraphicsShapeItem(parent),
+        m_selection(-1)
+{
+    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+
+    QPen framepen(Qt::SolidLine);
+    framepen.setColor(Qt::yellow);
+    setPen(framepen);
+    setBrush(Qt::NoBrush);
+    setAcceptHoverEvents(true);
+
+    setPos(point.p);
+    m_point.h1 = mapFromScene(point.h1);
+    m_point.p = mapFromScene(point.p);
+    m_point.h2 = mapFromScene(point.h2);
+    m_point.handlesLinked = false;
+}
+
+BPoint BPointItem::getPoint()
+{
+    return BPoint(mapToScene(m_point.h1), mapToScene(m_point.p), mapToScene(m_point.h2));
+}
+
+int BPointItem::type() const
+{
+    return Type;
+}
+
+QRectF BPointItem::boundingRect() const
+{
+    QPolygonF p = QPolygonF() << m_point.h1 << m_point.p << m_point.h2;
+    return p.boundingRect().adjusted(-6, -6, 6, 6);
+}
+
+void BPointItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    painter->setPen(QPen(Qt::yellow, 1, Qt::SolidLine));
+    painter->setBrush(QBrush(isSelected() ? Qt::red : Qt::yellow));
+    painter->setRenderHint(QPainter::Antialiasing);
+
+    double handleSize = 6 / painter->matrix().m11();
+    double handleSizeHalf = handleSize / 2;
+
+    QPolygonF handle = QPolygonF() << QPointF(0, -handleSizeHalf) << QPointF(handleSizeHalf, 0) << QPointF(0, handleSizeHalf) << QPointF(-handleSizeHalf, 0);
+
+    painter->drawLine(m_point.h1, m_point.p);
+    painter->drawLine(m_point.p, m_point.h2);
+
+#if QT_VERSION >= 0x040600
+    painter->drawConvexPolygon(handle.translated(m_point.h1.x(), m_point.h1.y()));
+    painter->drawConvexPolygon(handle.translated(m_point.h2.x(), m_point.h2.y()));
+#else
+    tmp = handle;
+    tmp.translate(m_point.h1.x(), m_point.h1.y());
+    p.drawConvexPolygon(tmp);
+    tmp.translate(m_point.h2.x(), m_point.h2.y());
+    p.drawConvexPolygon(tmp);
+#endif
+
+    painter->drawEllipse(QRectF(m_point.p.x() - handleSizeHalf,
+                                m_point.p.y() - handleSizeHalf, handleSize, handleSize));
+}
+
+int BPointItem::getSelection(QPointF pos)
+{
+    QPainterPath mouseArea;
+    mouseArea.addRect(pos.x() - 6, pos.y() - 6, 12, 12);
+
+    if (mouseArea.contains(m_point.p))
+        return 1;
+    else if (mouseArea.contains(m_point.h1))
+        return 0;
+    else if (mouseArea.contains(m_point.h2))
+        return 2;
+
+    return -1;
+}
+
+void BPointItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
+{
+    m_selection = getSelection(event->pos());
+
+    if (m_selection < 0) {
+        event->ignore();
+        setSelected(false);
+    } else {
+        setSelected(true);
+    }
+}
+
+void BPointItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
+{
+    prepareGeometryChange();
+    switch (m_selection) {
+    case 0:
+        m_point.setH1(event->pos());
+        break;
+    case 1:
+        m_point.setP(event->pos());
+        break;
+    case 2:
+        m_point.setH2(event->pos());
+        break;
+    }
+
+    if (parentItem()) {
+        SplineItem *parent = qgraphicsitem_cast<SplineItem*>(parentItem());
+        if (parent)
+            parent->updateSpline();
+    }
+}
+
+void BPointItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
+{
+QGraphicsItem::mouseReleaseEvent(event);
+}
+
+void BPointItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
+{
+    if (getSelection(event->pos()) < 0)
+        unsetCursor();
+    else
+        setCursor(QCursor(Qt::PointingHandCursor));
+}
diff --git a/src/onmonitoritems/rotoscoping/bpointitem.h b/src/onmonitoritems/rotoscoping/bpointitem.h
new file mode 100644 (file)
index 0000000..7cb73db
--- /dev/null
@@ -0,0 +1,54 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Till Theato (root@ttill.de)                     *
+ *   This file is part of Kdenlive (www.kdenlive.org).                     *
+ *                                                                         *
+ *   Kdenlive 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.                                   *
+ *                                                                         *
+ *   Kdenlive 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 Kdenlive.  If not, see <http://www.gnu.org/licenses/>.     *
+ ***************************************************************************/
+
+#ifndef BPOINTITEM_H
+#define BPOINTITEM_H
+
+#include "bpoint.h"
+
+#include <QtCore>
+#include <QAbstractGraphicsShapeItem>
+
+class BPointItem : public QAbstractGraphicsShapeItem
+{
+public:
+    BPointItem(BPoint point, QGraphicsItem* parent = 0);
+
+    BPoint getPoint();
+
+    enum { Type = UserType + 11 };
+    virtual int type() const;
+
+    virtual QRectF boundingRect() const;
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+protected:
+    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+    virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+
+private:
+    BPoint m_point;
+    int m_selection;
+
+    /** @brief Gets The action mode for the area @param pos +- 4. */
+    int getSelection(QPointF pos);
+};
+
+#endif
diff --git a/src/onmonitoritems/rotoscoping/splineitem.cpp b/src/onmonitoritems/rotoscoping/splineitem.cpp
new file mode 100644 (file)
index 0000000..9260d4f
--- /dev/null
@@ -0,0 +1,75 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Till Theato (root@ttill.de)                     *
+ *   This file is part of Kdenlive (www.kdenlive.org).                     *
+ *                                                                         *
+ *   Kdenlive 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.                                   *
+ *                                                                         *
+ *   Kdenlive 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 Kdenlive.  If not, see <http://www.gnu.org/licenses/>.     *
+ ***************************************************************************/
+
+#include "splineitem.h"
+#include "bpointitem.h"
+
+#include <QGraphicsScene>
+
+SplineItem::SplineItem(const QList< BPoint >& points, QGraphicsItem* parent, QGraphicsScene *scene) :
+    QGraphicsPathItem(parent, scene)
+{
+    QPen framepen(Qt::SolidLine);
+    framepen.setColor(Qt::yellow);
+    setPen(framepen);
+    setBrush(Qt::NoBrush);
+
+    if (points.isEmpty())
+        return;
+
+    QPainterPath path(points.at(0).p);
+    int j;
+    for (int i = 0; i < points.count(); ++i) {
+        new BPointItem(points.at(i), this);
+        j = (i + 1) % points.count();
+        path.cubicTo(points.at(i).h2, points.at(j).h1, points.at(j).p);
+    }
+    setPath(path);
+}
+
+int SplineItem::type() const
+{
+    return Type;
+}
+
+void SplineItem::updateSpline()
+{
+    QPainterPath path(qgraphicsitem_cast<BPointItem *>(childItems().at(0))->getPoint().p);
+
+    BPoint p1, p2;
+    int j;
+    for (int i = 0; i < childItems().count(); ++i) {
+        j = (i + 1) % childItems().count();
+        p1 = qgraphicsitem_cast<BPointItem *>(childItems().at(i))->getPoint();
+        p2 = qgraphicsitem_cast<BPointItem *>(childItems().at(j))->getPoint();
+        path.cubicTo(p1.h2, p2.h1, p2.p);
+    }
+    setPath(path);
+
+    emit changed();
+}
+
+QList <BPoint> SplineItem::getPoints()
+{
+    QList <BPoint> points;
+    foreach (QGraphicsItem *child, childItems())
+        points << qgraphicsitem_cast<BPointItem *>(child)->getPoint();
+    return points;
+}
+
+#include "splineitem.moc"
diff --git a/src/onmonitoritems/rotoscoping/splineitem.h b/src/onmonitoritems/rotoscoping/splineitem.h
new file mode 100644 (file)
index 0000000..2fd8f0d
--- /dev/null
@@ -0,0 +1,45 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Till Theato (root@ttill.de)                     *
+ *   This file is part of Kdenlive (www.kdenlive.org).                     *
+ *                                                                         *
+ *   Kdenlive 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.                                   *
+ *                                                                         *
+ *   Kdenlive 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 Kdenlive.  If not, see <http://www.gnu.org/licenses/>.     *
+ ***************************************************************************/
+
+#ifndef SPLINEITEM_H
+#define SPLINEITEM_H
+
+#include <QtCore>
+#include <QGraphicsPathItem>
+
+class BPoint;
+
+class SplineItem : public QObject, public QGraphicsPathItem
+{
+    Q_OBJECT
+
+public:
+    SplineItem(const QList <BPoint> &points, QGraphicsItem* parent = 0, QGraphicsScene *scene = 0);
+
+    enum { Type = UserType + 10 };
+
+    virtual int type() const;
+
+    void updateSpline();
+    QList <BPoint> getPoints();
+
+signals:
+    void changed();
+};
+
+#endif
diff --git a/src/rotoscoping/CMakeLists.txt b/src/rotoscoping/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/src/rotoscoping/rotowidget.cpp b/src/rotoscoping/rotowidget.cpp
new file mode 100644 (file)
index 0000000..2d9e0ad
--- /dev/null
@@ -0,0 +1,126 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Till Theato (root@ttill.de)                     *
+ *   This file is part of Kdenlive (www.kdenlive.org).                     *
+ *                                                                         *
+ *   Kdenlive 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.                                   *
+ *                                                                         *
+ *   Kdenlive 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 Kdenlive.  If not, see <http://www.gnu.org/licenses/>.     *
+ ***************************************************************************/
+
+#include "rotowidget.h"
+#include "monitor.h"
+#include "renderer.h"
+#include "monitorscene.h"
+#include "monitoreditwidget.h"
+#include "onmonitoritems/rotoscoping/bpointitem.h"
+#include "onmonitoritems/rotoscoping/splineitem.h"
+
+#include <qjson/parser.h>
+#include <qjson/serializer.h>
+
+
+RotoWidget::RotoWidget(QString data, Monitor *monitor, int in, int out, QWidget* parent) :
+        QWidget(parent),
+        m_monitor(monitor),
+        m_showScene(true),
+        m_in(in),
+        m_out(out),
+        m_pos(0)
+{
+    MonitorEditWidget *edit = monitor->getEffectEdit();
+    edit->showVisibilityButton(true);
+    m_scene = edit->getScene();
+
+    QJson::Parser parser;
+    bool ok;
+    m_data = parser.parse(data.toUtf8(), &ok);
+    if (!ok) {
+        // :(
+    }
+
+    int width = m_monitor->render->frameRenderWidth();
+    int height = m_monitor->render->renderHeight();
+    QList <BPoint> points;
+    foreach (const QVariant &bpoint, m_data.toList()) {
+        QList <QVariant> l = bpoint.toList();
+        BPoint p;
+        p.h1 = QPointF(l.at(0).toList().at(0).toDouble() * width, l.at(0).toList().at(1).toDouble() * height);
+        p.p = QPointF(l.at(1).toList().at(0).toDouble() * width, l.at(2).toList().at(1).toDouble() * height);
+        p.h2 = QPointF(l.at(2).toList().at(0).toDouble() * width, l.at(2).toList().at(1).toDouble() * height);
+        points << p;
+    }
+
+    m_item = new SplineItem(points, NULL, m_scene);
+
+    connect(m_item, SIGNAL(changed()), this, SLOT(slotUpdateData()));
+    connect(edit, SIGNAL(showEdit(bool)), this, SLOT(slotShowScene(bool)));
+    connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
+}
+
+RotoWidget::~RotoWidget()
+{
+    m_scene->removeItem(m_item);
+    delete m_item;
+
+    if (m_monitor) {
+        MonitorEditWidget *edit = m_monitor->getEffectEdit();
+        edit->showVisibilityButton(false);
+        edit->removeCustomControls();
+        m_monitor->slotEffectScene(false);
+    }
+}
+
+void RotoWidget::slotCheckMonitorPosition(int renderPos)
+{
+    if (m_showScene)
+        emit checkMonitorPosition(renderPos);
+}
+
+void RotoWidget::slotSyncPosition(int relTimelinePos)
+{
+    Q_UNUSED(relTimelinePos);
+}
+
+void RotoWidget::slotShowScene(bool show)
+{
+    m_showScene = show;
+    if (!m_showScene)
+        m_monitor->slotEffectScene(false);
+    else
+        slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
+}
+
+void RotoWidget::slotUpdateData()
+{
+    int width = m_monitor->render->frameRenderWidth();
+    int height = m_monitor->render->renderHeight();
+
+    QList <BPoint> spline = m_item->getPoints();
+    QList <QVariant> vlist;
+    foreach (const BPoint &point, spline) {
+        QList <QVariant> pl;
+        for (int i = 0; i < 3; ++i)
+            pl << QVariant(QList <QVariant>() << QVariant(point[i].x() / width) << QVariant(point[i].y() / height));
+        vlist << QVariant(pl);
+    }
+    m_data = QVariant(vlist);
+
+    emit valueChanged();
+}
+
+QString RotoWidget::getSpline()
+{
+    QJson::Serializer serializer;
+    return QString(serializer.serialize(m_data));
+}
+
+#include "rotowidget.moc"
diff --git a/src/rotoscoping/rotowidget.h b/src/rotoscoping/rotowidget.h
new file mode 100644 (file)
index 0000000..3ac9fa0
--- /dev/null
@@ -0,0 +1,69 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Till Theato (root@ttill.de)                     *
+ *   This file is part of Kdenlive (www.kdenlive.org).                     *
+ *                                                                         *
+ *   Kdenlive 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.                                   *
+ *                                                                         *
+ *   Kdenlive 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 Kdenlive.  If not, see <http://www.gnu.org/licenses/>.     *
+ ***************************************************************************/
+
+#ifndef ROTOWIDGET_H
+#define ROTOWIDGET_H
+
+#include "bpoint.h"
+
+#include <QWidget>
+
+class Monitor;
+class MonitorScene;
+class SplineItem;
+
+class RotoWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    RotoWidget(QString data, Monitor *monitor, int in, int out, QWidget* parent = 0);
+    virtual ~RotoWidget();
+
+    QString getSpline();
+
+public slots:
+    /** @brief Switches from normal monitor to monitor scene according to @param show. */
+    void slotShowScene(bool show = true);
+    /** @brief Updates the on-monitor item.  */
+    void slotSyncPosition(int relTimelinePos);
+
+signals:
+    void valueChanged();
+    void checkMonitorPosition(int);
+
+
+private:
+    Monitor *m_monitor;
+    MonitorScene *m_scene;
+    bool m_showScene;
+    QVariant m_data;
+    SplineItem *m_item;
+    int m_in;
+    int m_out;
+    int m_pos;
+
+private slots:
+    /** @brief Makes sure the monitor effect scene is only visible if the clip this geometry belongs to is visible.
+    * @param renderPos Postion of the Monitor / Timeline cursor */
+    void slotCheckMonitorPosition(int renderPos);
+
+    void slotUpdateData();
+};
+
+#endif