From: Till Theato Date: Fri, 7 Jan 2011 14:49:34 +0000 (+0000) Subject: on monitor corners: add control to move all corners at once X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=8e54d119735a50496034714460476e86c017d6b6;p=kdenlive on monitor corners: add control to move all corners at once svn path=/trunk/kdenlive/; revision=5291 --- diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 44de178e..3b6e48e3 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -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: "<sceneBoundingRect(); dragGroup = static_cast (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); diff --git a/src/onmonitoritems/onmonitorcornersitem.cpp b/src/onmonitoritems/onmonitorcornersitem.cpp index 7c0ee552..0a6efa2d 100644 --- a/src/onmonitoritems/onmonitorcornersitem.cpp +++ b/src/onmonitoritems/onmonitorcornersitem.cpp @@ -20,11 +20,14 @@ #include "onmonitorcornersitem.h" #include "kdenlivesettings.h" +#include + #include #include #include #include +#include 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 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 OnMonitorCornersItem::sortedClockwise() +{ + QList 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" diff --git a/src/onmonitoritems/onmonitorcornersitem.h b/src/onmonitoritems/onmonitorcornersitem.h index c21a6278..8d7cacee 100644 --- a/src/onmonitoritems/onmonitorcornersitem.h +++ b/src/onmonitoritems/onmonitorcornersitem.h @@ -26,17 +26,16 @@ #include #include -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 sortedClockwise(); + cornersActions m_mode; - QPointF m_clickPoint; + QPointF m_lastPoint; }; #endif