]> git.sesse.net Git - kdenlive/blobdiff - src/onmonitoritems/rotoscoping/splineitem.cpp
jogshuttle: cmake files cleaned up a little bit
[kdenlive] / src / onmonitoritems / rotoscoping / splineitem.cpp
index ee29f159dfaf571ba435c9ecc82601d6ad8efcad..a7cdf5f293514dae339b6799ef955b417fe9edad 100644 (file)
@@ -24,6 +24,7 @@
 #include <QGraphicsScene>
 #include <QCursor>
 #include <QGraphicsSceneMouseEvent>
+#include <QGraphicsView>
 
 
 inline QPointF closestPointInRect(QPointF point, QRectF rect)
@@ -54,7 +55,7 @@ void deCasteljau(BPoint *p1, BPoint *p2, BPoint *res, double t)
 
 SplineItem::SplineItem(const QList< BPoint >& points, QGraphicsItem* parent, QGraphicsScene *scene) :
     QGraphicsPathItem(parent, scene),
-    m_closed(false),
+    m_closed(true),
     m_editing(false)
 {
     QPen framepen(Qt::SolidLine);
@@ -63,6 +64,8 @@ SplineItem::SplineItem(const QList< BPoint >& points, QGraphicsItem* parent, QGr
     setBrush(Qt::NoBrush);
     setAcceptHoverEvents(true);
 
+    m_view = scene->views().first();
+
     setPoints(points);
 }
 
@@ -71,7 +74,7 @@ int SplineItem::type() const
     return Type;
 }
 
-bool SplineItem::editing()
+bool SplineItem::editing() const
 {
     return m_editing;
 }
@@ -96,7 +99,7 @@ void SplineItem::updateSpline(bool editing)
         emit changed(editing);
 }
 
-QList <BPoint> SplineItem::getPoints()
+QList <BPoint> SplineItem::getPoints() const
 {
     QList <BPoint> points;
     foreach (QGraphicsItem *child, childItems())
@@ -110,7 +113,7 @@ void SplineItem::setPoints(const QList< BPoint >& points)
         m_closed = false;
         grabMouse();
         return;
-    } else {
+    } else if (!m_closed) {
         ungrabMouse();
         m_closed = true;
     }
@@ -146,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;
@@ -185,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);
@@ -203,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);
@@ -230,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;
@@ -273,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;