]> git.sesse.net Git - kdenlive/blobdiff - src/onmonitoritems/rotoscoping/splineitem.cpp
coverity fix
[kdenlive] / src / onmonitoritems / rotoscoping / splineitem.cpp
index 64eedb03c347190cd293bef18b15b3f8abd87f5b..a7cdf5f293514dae339b6799ef955b417fe9edad 100644 (file)
 #include "splineitem.h"
 #include "bpointitem.h"
 #include "nearestpoint.h"
+#include "kdenlivesettings.h"
 
 #include <QGraphicsScene>
 #include <QCursor>
 #include <QGraphicsSceneMouseEvent>
+#include <QGraphicsView>
 
 
 inline QPointF closestPointInRect(QPointF point, QRectF rect)
@@ -52,7 +54,9 @@ void deCasteljau(BPoint *p1, BPoint *p2, BPoint *res, double t)
 
 
 SplineItem::SplineItem(const QList< BPoint >& points, QGraphicsItem* parent, QGraphicsScene *scene) :
-    QGraphicsPathItem(parent, scene)
+    QGraphicsPathItem(parent, scene),
+    m_closed(true),
+    m_editing(false)
 {
     QPen framepen(Qt::SolidLine);
     framepen.setColor(Qt::yellow);
@@ -60,21 +64,9 @@ SplineItem::SplineItem(const QList< BPoint >& points, QGraphicsItem* parent, QGr
     setBrush(Qt::NoBrush);
     setAcceptHoverEvents(true);
 
-    m_closed = true;
-    if (points.isEmpty()) {
-        m_closed = false;
-        grabMouse();
-        return;
-    }
+    m_view = scene->views().first();
 
-    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);
+    setPoints(points);
 }
 
 int SplineItem::type() const
@@ -82,7 +74,12 @@ int SplineItem::type() const
     return Type;
 }
 
-void SplineItem::updateSpline()
+bool SplineItem::editing() const
+{
+    return m_editing;
+}
+
+void SplineItem::updateSpline(bool editing)
 {
     QPainterPath path(qgraphicsitem_cast<BPointItem *>(childItems().at(0))->getPoint().p);
 
@@ -96,11 +93,13 @@ void SplineItem::updateSpline()
     }
     setPath(path);
 
-    if (m_closed)
-        emit changed();
+    m_editing = editing;
+
+    if (m_closed && (!editing || KdenliveSettings::monitorscene_directupdate()))
+        emit changed(editing);
 }
 
-QList <BPoint> SplineItem::getPoints()
+QList <BPoint> SplineItem::getPoints() const
 {
     QList <BPoint> points;
     foreach (QGraphicsItem *child, childItems())
@@ -108,6 +107,30 @@ QList <BPoint> SplineItem::getPoints()
     return points;
 }
 
+void SplineItem::setPoints(const QList< BPoint >& points)
+{
+    if (points.count() < 2) {
+        m_closed = false;
+        grabMouse();
+        return;
+    } else if (!m_closed) {
+        ungrabMouse();
+        m_closed = true;
+    }
+
+    qDeleteAll(childItems());
+    childItems().clear();
+
+    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);
+}
+
 void SplineItem::removeChild(QGraphicsItem* child)
 {
     if (childItems().count() > 2) {
@@ -126,7 +149,8 @@ void SplineItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
         return;
 
     if (m_closed) {
-        QRectF r(event->scenePos() - QPointF(6, 6), QSizeF(12, 12));
+        qreal size = 12 / m_view->matrix().m11();
+        QRectF r(event->scenePos() - QPointF(size / 2, size / 2), QSizeF(size, size));
         if (event->button() == Qt::LeftButton && path().intersects(r) && !path().contains(r)) {
             double t = 0;
             BPointItem *i1, *i2;
@@ -165,11 +189,21 @@ void SplineItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
             updateSpline();
         }
     } else {
-        if (event->button() == Qt::RightButton) {
-            if (childItems().count() > 1) {
+        bool close = false;
+        QList <QGraphicsItem *> items = childItems();
+        if (items.count() > 1) {
+            BPointItem *bp = qgraphicsitem_cast<BPointItem *>(items.at(0));
+            int selectionType = bp->getSelection(mapToItem(bp, event->pos()));
+            // since h1 == p we need to check for both
+            if (selectionType == 0 || selectionType == 1)
+                close = true;
+        }
+
+        if (close || event->button() == Qt::RightButton) {
+            if (items.count() > 1) {
                 // close the spline
-                BPointItem *i1 = qgraphicsitem_cast<BPointItem *>(childItems().first());
-                BPointItem *i2 = qgraphicsitem_cast<BPointItem *>(childItems().last());
+                BPointItem *i1 = qgraphicsitem_cast<BPointItem *>(items.first());
+                BPointItem *i2 = qgraphicsitem_cast<BPointItem *>(items.last());
                 BPoint p1 = i1->getPoint();
                 BPoint p2 = i2->getPoint();
                 p1.h1 = QLineF(p1.p, p2.p).pointAt(.2);
@@ -183,8 +217,8 @@ void SplineItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
         } else if (event->modifiers() == Qt::NoModifier) {
             BPoint p;
             p.p = p.h1 = p.h2 = event->scenePos();
-            if (childItems().count()) {
-                BPointItem *i = qgraphicsitem_cast<BPointItem *>(childItems().last());
+            if (items.count()) {
+                BPointItem *i = qgraphicsitem_cast<BPointItem *>(items.last());
                 BPoint prev = i->getPoint();
                 prev.h2 = QLineF(prev.p, p.p).pointAt(.2);
                 p.h1 = QLineF(prev.p, p.p).pointAt(.8);
@@ -210,26 +244,32 @@ void SplineItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
 {
     QGraphicsItem::hoverMoveEvent(event);
 
-    QRectF r(event->scenePos() - QPointF(6, 6), QSizeF(12, 12));
+    qreal size = 12 / m_view->matrix().m11();
+    QRectF r(event->scenePos() - QPointF(size / 2, size / 2), QSizeF(size, size));
     if (path().intersects(r) && !path().contains(r))
         setCursor(QCursor(Qt::PointingHandCursor));
     else
         unsetCursor();
 }
 
-int SplineItem::getClosestPointOnCurve(QPointF point, double *tFinal)
+int SplineItem::getClosestPointOnCurve(const QPointF &point, double *tFinal)
 {
     // TODO: proper minDiff
     qreal diff = 10000, param = 0;
     BPoint p1, p2;
     int curveSegment = 0, 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();
+    QList <QGraphicsItem *> items = childItems();
+    for (int i = 0; i < items.count(); ++i) {
+        j = (i + 1) % items.count();
+        p1 = qgraphicsitem_cast<BPointItem *>(items.at(i))->getPoint();
+        p2 = qgraphicsitem_cast<BPointItem *>(items.at(j))->getPoint();
         QPolygonF bounding = QPolygonF() << p1.p << p1.h2 << p2.h1 << p2.p;
         QPointF cl = closestPointInRect(point, bounding.boundingRect());
+#if QT_VERSION >= 0x040600
         qreal d = (point - cl).manhattanLength();
+#else
+        qreal d = qAbs((point - cl).x()) + qAbs((point - cl).y());
+#endif
 
         if (d > diff)
             continue;
@@ -253,7 +293,11 @@ int SplineItem::getClosestPointOnCurve(QPointF point, double *tFinal)
         cl.setX(n.x);
         cl.setY(n.y);
 
+#if QT_VERSION >= 0x040600
         d = (point - cl).manhattanLength();
+#else
+        d = qAbs((point - cl).x()) + qAbs((point - cl).y());
+#endif
         if (d < diff) {
             diff = d;
             param = t;