]> git.sesse.net Git - kdenlive/commitdiff
on monitor corners: add control to move all corners at once
authorTill Theato <root@ttill.de>
Fri, 7 Jan 2011 14:49:34 +0000 (14:49 +0000)
committerTill Theato <root@ttill.de>
Fri, 7 Jan 2011 14:49:34 +0000 (14:49 +0000)
svn path=/trunk/kdenlive/; revision=5291

src/customtrackview.cpp
src/onmonitoritems/onmonitorcornersitem.cpp
src/onmonitoritems/onmonitorcornersitem.h

index 44de178e2f30c5714728a5e8dd28054ba5ffdc25..3b6e48e3fee6377aab0988f4bb9a1dc6c63e6ea6 100644 (file)
@@ -925,7 +925,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
         } else resetSelectionGroup();
         dragGroup = NULL;
         if (m_dragItem->parentItem() && m_dragItem->parentItem()->type() == GROUPWIDGET) {
-            //kDebug()<<"// KLIK FOUND GRP: "<<m_dragItem->sceneBoundingRect();
             dragGroup = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
         }
         bool selected = !m_dragItem->isSelected();
@@ -4474,7 +4473,7 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol
             }
 
             /*
-                TODO: cleanup the effect update process
+             * TODO: cleanup the effect update process
              */
             ClipItem *clip = static_cast < ClipItem * >(item);
 
index 7c0ee55274cd17a2dd435e037d020cc1afeb8f4d..0a6efa2d5dfe5583dfc13b6663a356c382aecb16 100644 (file)
 #include "onmonitorcornersitem.h"
 #include "kdenlivesettings.h"
 
+#include <algorithm>
+
 #include <QGraphicsSceneMouseEvent>
 #include <QPainter>
 #include <QStyleOptionGraphicsItem>
 #include <QCursor>
 
+#include <KDebug>
 OnMonitorCornersItem::OnMonitorCornersItem(MonitorScene* scene, QGraphicsItem* parent) :
         AbstractOnMonitorItem(scene),
         QGraphicsPolygonItem(parent)
@@ -37,10 +40,10 @@ OnMonitorCornersItem::OnMonitorCornersItem(MonitorScene* scene, QGraphicsItem* p
     setBrush(Qt::NoBrush);
 }
 
-cornersActions OnMonitorCornersItem::getMode(QPoint pos)
+OnMonitorCornersItem::cornersActions OnMonitorCornersItem::getMode(QPointF pos)
 {
     QPainterPath mouseArea;
-    pos = mapFromScene(pos).toPoint();
+    pos = mapFromScene(pos);
     mouseArea.addRect(pos.x() - 6, pos.y() - 6, 12, 12);
     if (mouseArea.contains(polygon().at(0)))
         return Corner1;
@@ -50,6 +53,8 @@ cornersActions OnMonitorCornersItem::getMode(QPoint pos)
         return Corner3;
     else if (mouseArea.contains(polygon().at(3)))
         return Corner4;
+    else if (mouseArea.contains(getCentroid()))
+        return Move;
     else
         return NoAction;
 }
@@ -61,7 +66,8 @@ void OnMonitorCornersItem::slotMousePressed(QGraphicsSceneMouseEvent* event)
     if (!isEnabled())
         return;
 
-    m_mode = getMode(event->scenePos().toPoint());
+    m_mode = getMode(event->scenePos());
+    m_lastPoint = event->scenePos();
 }
 
 void OnMonitorCornersItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
@@ -79,8 +85,8 @@ void OnMonitorCornersItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
     }*/
 
     if (event->buttons() & Qt::LeftButton) {
-        QPoint mousePos = mapFromScene(event->scenePos()).toPoint();
-        QPolygon p = polygon().toPolygon();
+        QPointF mousePos = mapFromScene(event->scenePos());
+        QPolygonF p = polygon();
         switch (m_mode) {
         case Corner1:
             p.replace(0, mousePos);
@@ -98,12 +104,17 @@ void OnMonitorCornersItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
             p.replace(3, mousePos);
             m_modified = true;
             break;
+        case Move:
+            p.translate(mousePos - m_lastPoint);
+            m_modified = true;
+            break;
         default:
             break;
         }
+        m_lastPoint = mousePos;
         setPolygon(p);
     } else {
-        switch (getMode(event->scenePos().toPoint())) {
+        switch (getMode(event->scenePos())) {
         case NoAction:
             emit requestCursor(QCursor(Qt::ArrowCursor));
             break;
@@ -120,6 +131,8 @@ void OnMonitorCornersItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
 
 void OnMonitorCornersItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
 {
+    painter->setPen(QPen(Qt::yellow, 1, Qt::SolidLine));
+
     if (KdenliveSettings::onmonitoreffects_cornersshowlines())
         QGraphicsPolygonItem::paint(painter, option, widget);
 
@@ -130,6 +143,84 @@ void OnMonitorCornersItem::paint(QPainter* painter, const QStyleOptionGraphicsIt
     painter->drawEllipse(polygon().at(1), handleSize, handleSize);
     painter->drawEllipse(polygon().at(2), handleSize, handleSize);
     painter->drawEllipse(polygon().at(3), handleSize, handleSize);
+
+    // TODO: allow to disable
+    if (1) {
+        painter->setPen(QPen(Qt::red, 2, Qt::SolidLine));
+        QPointF c = getCentroid();
+        handleSize *= 1.5;
+        painter->drawLine(QLineF(c - QPointF(handleSize, handleSize), c + QPointF(handleSize, handleSize)));
+        painter->drawLine(QLineF(c - QPointF(-handleSize, handleSize), c + QPointF(-handleSize, handleSize)));
+    }
+}
+
+QPointF OnMonitorCornersItem::getCentroid()
+{
+    QList <QPointF> p = sortedClockwise();
+
+    /*
+     * See: http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/
+     */
+
+    double A = 0;
+    int i, j;
+    for (i = 0; i < 4; ++i) {
+        j = (i + 1) % 4;
+        A += p[j].x() * p[i].y() - p[i].x() * p[j].y();
+    }
+    A /= 2.;
+    A = qAbs(A);
+
+    double x = 0, y = 0, f;
+    for (i = 0; i < 4; ++i) {
+        j = (i + 1) % 4;
+        f = (p[i].x() * p[j].y() - p[j].x() * p[i].y());
+        x += f * (p[i].x() + p[j].x());
+        y += f * (p[i].y() + p[j].y());
+    }
+    x /= 6*A;
+    y /= 6*A;
+    return QPointF(x, y);
+}
+
+QList <QPointF> OnMonitorCornersItem::sortedClockwise()
+{
+    QList <QPointF> points = polygon().toList();
+    QPointF& a = points[0];
+    QPointF& b = points[1];
+    QPointF& c = points[2];
+    QPointF& d = points[3];
+
+    /*
+     * http://stackoverflow.com/questions/242404/sort-four-points-in-clockwise-order
+     */
+
+    double abc = a.x() * b.y() - a.y() * b.x() + b.x() * c.y() - b.y() * c.x() + c.x() * a.y() - c.y() * a.x();
+    if (abc > 0) {
+        double acd = a.x() * c.y() - a.y() * c.x() + c.x() * d.y() - c.y() * d.x() + d.x() * a.y() - d.y() * a.x();
+        if (acd > 0) {
+            ;
+        } else {
+            double abd = a.x() * b.y() - a.y() * b.x() + b.x() * d.y() - b.y() * d.x() + d.x() * a.y() - d.y() * a.x();
+            if (abd > 0) {
+                std::swap(d, c);
+            } else{
+                std::swap(a, d);
+            }
+        }
+    } else {
+        double acd = a.x() * c.y() - a.y() * c.x() + c.x() * d.y() - c.y() * d.x() + d.x() * a.y() - d.y() * a.x();
+        if (acd > 0) {
+            double abd = a.x() * b.y() - a.y() * b.x() + b.x() * d.y() - b.y() * d.x() + d.x() * a.y() - d.y() * a.x();
+            if (abd > 0) {
+                std::swap(b, c);
+            } else {
+                std::swap(a, b);
+            }
+        } else {
+            std::swap(a, c);
+        }
+    }
 }
 
 #include "onmonitorcornersitem.moc"
index c21a6278fb16841d4de292fb3ca2f44225ea8bf6..8d7caceeeb505773072eba18b251be7021457dca 100644 (file)
 #include <QtCore>
 #include <QGraphicsPolygonItem>
 
-enum cornersActions { Corner1, Corner2, Corner3, Corner4, NoAction };
-
 class OnMonitorCornersItem : public AbstractOnMonitorItem, public QGraphicsPolygonItem
 {
     Q_OBJECT
 public:
     OnMonitorCornersItem(MonitorScene *scene, QGraphicsItem *parent = 0);
 
+    enum cornersActions { Corner1, Corner2, Corner3, Corner4, Move, NoAction };
     /** @brief Gets The action mode for the area @param pos +- 4. */
-    cornersActions getMode(QPoint pos);
-    
+    cornersActions getMode(QPointF pos);
+
     /** @brief Reimplemented to draw the handles. */
     virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0 );
 
@@ -47,8 +46,14 @@ public slots:
     void slotMouseMoved(QGraphicsSceneMouseEvent *event);
 
 private:
+    /** @brief Returns the centroid (= 'center of mass') of this polygon. */
+    QPointF getCentroid();
+
+    /** @brief Returns the points of this polygon but sorted clockwise. */
+    QList <QPointF> sortedClockwise();
+
     cornersActions m_mode;
-    QPointF m_clickPoint;
+    QPointF m_lastPoint;
 };
 
 #endif