]> git.sesse.net Git - kdenlive/blobdiff - src/onmonitoritems/onmonitorrectitem.cpp
Replace roles into projectlistview. Turn const int into enum.
[kdenlive] / src / onmonitoritems / onmonitorrectitem.cpp
index 8031820bfb7a9454dfe1104f12a643b6e59b80ce..fc1b822da8f1c25d4117f97ae93991ba60963cc4 100644 (file)
 #include <QPainter>
 #include <QStyleOptionGraphicsItem>
 #include <QCursor>
+#include <QGraphicsView>
 
-OnMonitorRectItem::OnMonitorRectItem(const QRectF &rect, QGraphicsItem* parent) :
-        QGraphicsRectItem(rect, parent)
+OnMonitorRectItem::OnMonitorRectItem(const QRectF &rect, double dar, QGraphicsItem* parent) :
+    QGraphicsRectItem(rect, parent)
+  , m_dar(dar)
+  , m_mode(NoAction)
+  , m_modified(false)
+  , m_view(NULL)
 {
     setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
 
@@ -34,34 +39,40 @@ OnMonitorRectItem::OnMonitorRectItem(const QRectF &rect, QGraphicsItem* parent)
     framepen.setColor(Qt::yellow);
     setPen(framepen);
     setBrush(Qt::transparent);
+    setAcceptHoverEvents(true);
 }
 
-rectActions OnMonitorRectItem::getMode(QPoint pos)
+rectActions OnMonitorRectItem::getMode(const QPointF &pos)
 {
-    pos = mapFromScene(pos).toPoint();
     // Item mapped coordinates
-    QPolygon pol(rect().normalized().toRect());
+    QPolygonF pol(rect().normalized());
 
-    QPainterPath top(pol.point(0));
-    top.lineTo(pol.point(1));
-    QPainterPath bottom(pol.point(2));
-    bottom.lineTo(pol.point(3));
-    QPainterPath left(pol.point(0));
-    left.lineTo(pol.point(3));
-    QPainterPath right(pol.point(1));
-    right.lineTo(pol.point(2));
+    QPainterPath top(pol.at(0));
+    top.lineTo(pol.at(1));
+    QPainterPath bottom(pol.at(2));
+    bottom.lineTo(pol.at(3));
+    QPainterPath left(pol.at(0));
+    left.lineTo(pol.at(3));
+    QPainterPath right(pol.at(1));
+    right.lineTo(pol.at(2));
 
     QPainterPath mouseArea;
-    mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
+    qreal xsize = 12;
+    qreal ysize = 12;
+    if (getView()) {
+        xsize /= m_view->matrix().m11();
+        ysize /= m_view->matrix().m22();
+    }
+    mouseArea.addRect(pos.x() - xsize / 2, pos.y() - ysize / 2, xsize, ysize);
 
     // Check for collisions between the mouse and the borders
-    if (mouseArea.contains(pol.point(0)))
+    if (mouseArea.contains(pol.at(0)))
         return ResizeTopLeft;
-    else if (mouseArea.contains(pol.point(2)))
+    else if (mouseArea.contains(pol.at(2)))
         return ResizeBottomRight;
-    else if (mouseArea.contains(pol.point(1)))
+    else if (mouseArea.contains(pol.at(1)))
         return ResizeTopRight;
-    else if (mouseArea.contains(pol.point(3)))
+    else if (mouseArea.contains(pol.at(3)))
         return ResizeBottomLeft;
     else if (top.intersects(mouseArea))
         return ResizeTop;
@@ -77,57 +88,34 @@ rectActions OnMonitorRectItem::getMode(QPoint pos)
         return NoAction;
 }
 
-int OnMonitorRectItem::type() const
-{
-    return Type;
-}
-
-void OnMonitorRectItem::setEnabled(bool enabled)
-{
-    m_enabled = enabled;
-}
-
-void OnMonitorRectItem::slotMousePressed(QGraphicsSceneMouseEvent* event)
-{
-    if (!m_enabled)
-        return;
-
-    m_clickPoint = event->scenePos();
-    m_mode = getMode(m_clickPoint.toPoint());
-}
-
-void OnMonitorRectItem::slotMouseReleased(QGraphicsSceneMouseEvent* event)
+void OnMonitorRectItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
 {
-    if (m_modified) {
-        m_modified = false;
-        emit actionFinished();
-    }
-
     event->accept();
+
+    m_lastPoint = event->scenePos();
+    m_oldRect = rect().normalized();
+    m_mode = getMode(event->pos());
 }
 
-void OnMonitorRectItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
+void OnMonitorRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
 {
-    if (!m_enabled) {
-        emit setCursor(QCursor(Qt::ArrowCursor));
-        return;
-    }
-
     /*if (event->buttons() != Qt::NoButton && (event->screenPos() - m_screenClickPoint).manhattanLength() < QApplication::startDragDistance()) {
      *   event->accept();
      *   return;
     }*/
 
-    QPointF mousePos = event->scenePos();
-
     if (event->buttons() & Qt::LeftButton) {
         QRectF r = rect().normalized();
         QPointF p = pos();
-        QPointF mousePosInRect = mapFromScene(mousePos);
+        QPointF mousePos = event->scenePos();
+        QPointF mousePosInRect = event->pos();
+        QPointF diff = mousePos - m_lastPoint;
+        m_lastPoint = mousePos;
+
         switch (m_mode) {
         case ResizeTopLeft:
             if (mousePos.x() < p.x() + r.height() && mousePos.y() < p.y() + r.height()) {
-                setRect(r.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
+                r.adjust(0, 0, -mousePosInRect.x(), -mousePosInRect.y());
                 setPos(mousePos);
                 m_modified = true;
             }
@@ -135,7 +123,6 @@ void OnMonitorRectItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
         case ResizeTop:
             if (mousePos.y() < p.y() + r.height()) {
                 r.setBottom(r.height() - mousePosInRect.y());
-                setRect(r);
                 setPos(QPointF(p.x(), mousePos.y()));
                 m_modified = true;
             }
@@ -143,7 +130,6 @@ void OnMonitorRectItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
         case ResizeTopRight:
             if (mousePos.x() > p.x() && mousePos.y() < p.y() + r.height()) {
                 r.setBottomRight(QPointF(mousePosInRect.x(), r.bottom() - mousePosInRect.y()));
-                setRect(r);
                 setPos(QPointF(p.x(), mousePos.y()));
                 m_modified = true;
             }
@@ -151,7 +137,6 @@ void OnMonitorRectItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
         case ResizeLeft:
             if (mousePos.x() < p.x() + r.width()) {
                 r.setRight(r.width() - mousePosInRect.x());
-                setRect(r);
                 setPos(QPointF(mousePos.x(), p.y()));
                 m_modified = true;
             }
@@ -159,14 +144,12 @@ void OnMonitorRectItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
         case ResizeRight:
             if (mousePos.x() > p.x()) {
                 r.setRight(mousePosInRect.x());
-                setRect(r);
                 m_modified = true;
             }
             break;
         case ResizeBottomLeft:
             if (mousePos.x() < p.x() + r.width() && mousePos.y() > p.y()) {
                 r.setBottomRight(QPointF(r.width() - mousePosInRect.x(), mousePosInRect.y()));
-                setRect(r);
                 setPos(QPointF(mousePos.x(), p.y()));
                 m_modified = true;
             }
@@ -174,72 +157,147 @@ void OnMonitorRectItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
         case ResizeBottom:
             if (mousePos.y() > p.y()) {
                 r.setBottom(mousePosInRect.y());
-                setRect(r);
                 m_modified = true;
             }
             break;
         case ResizeBottomRight:
             if (mousePos.x() > p.x() && mousePos.y() > p.y()) {
                 r.setBottomRight(mousePosInRect);
-                setRect(r);
                 m_modified = true;
             }
             break;
         case Move:
-            QPointF diff = mousePos - m_clickPoint;
-            m_clickPoint = mousePos;
             moveBy(diff.x(), diff.y());
             m_modified = true;
             break;
-        }
-    } else {
-        switch (getMode(event->scenePos().toPoint())) {
-        case ResizeTopLeft:
-        case ResizeBottomRight:
-            emit setCursor(QCursor(Qt::SizeFDiagCursor));
-            break;
-        case ResizeTopRight:
-        case ResizeBottomLeft:
-            emit setCursor(QCursor(Qt::SizeBDiagCursor));
-            break;
-        case ResizeTop:
-        case ResizeBottom:
-            emit setCursor(QCursor(Qt::SizeVerCursor));
-            break;
-        case ResizeLeft:
-        case ResizeRight:
-            emit setCursor(QCursor(Qt::SizeHorCursor));
-            break;
-        case Move:
-            emit setCursor(QCursor(Qt::OpenHandCursor));
-            break;
         default:
-            emit setCursor(QCursor(Qt::ArrowCursor));
             break;
         }
+
+        // Keep aspect ratio
+        if (event->modifiers() == Qt::ControlModifier) {
+            // compare to rect during mouse press:
+            // if we subtract rect() we'll get a whole lot of flickering
+            // because of diffWidth > diffHeight changing all the time
+            int diffWidth = qAbs(r.width() - m_oldRect.width());
+            int diffHeight = qAbs(r.height() - m_oldRect.height());
+
+            if (diffHeight != 0 || diffWidth != 0) {
+                if (diffWidth > diffHeight)
+                    r.setBottom(r.width() / m_dar);
+                else
+                    r.setRight(r.height() * m_dar);
+
+                // the rect's position changed
+                if (p - pos() != QPointF()) {
+                    if (diffWidth > diffHeight) {
+                        if (m_mode != ResizeBottomLeft)
+#if QT_VERSION >= 0x040600
+                            setY(p.y() - r.height() + rect().normalized().height());
+#else
+                            setPos(x(), p.y() - r.height() + rect().normalized().height());
+#endif
+                    } else {
+                        if (m_mode != ResizeTopRight)
+#if QT_VERSION >= 0x040600
+                            setX(p.x() - r.width() + rect().normalized().width());
+#else
+                            setPos(p.x() - r.width() + rect().normalized().width(), y());
+#endif
+                    }
+                }
+            }
+        }
+
+        setRect(r);
     }
-    if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
-        emit actionFinished();
-        m_modified = false;
+
+    if (m_modified) {
+        event->accept();
+        if (KdenliveSettings::monitorscene_directupdate()) {
+            emit changed();
+            m_modified = false;
+        }
+    } else {
+        event->ignore();
     }
+}
 
+void OnMonitorRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
+{
+    if (m_modified) {
+        m_modified = false;
+        emit changed();
+    }
     event->accept();
 }
 
+void OnMonitorRectItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
+{
+    switch (getMode(event->pos())) {
+    case ResizeTopLeft:
+    case ResizeBottomRight:
+        setCursor(QCursor(Qt::SizeFDiagCursor));
+        break;
+    case ResizeTopRight:
+    case ResizeBottomLeft:
+        setCursor(QCursor(Qt::SizeBDiagCursor));
+        break;
+    case ResizeTop:
+    case ResizeBottom:
+        setCursor(QCursor(Qt::SizeVerCursor));
+        break;
+    case ResizeLeft:
+    case ResizeRight:
+        setCursor(QCursor(Qt::SizeHorCursor));
+        break;
+    case Move:
+        setCursor(QCursor(Qt::OpenHandCursor));
+        break;
+    default:
+        unsetCursor();
+        break;
+    }
+}
+
 void OnMonitorRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
 {
-    QGraphicsRectItem::paint(painter, option, widget);
-
-    if (m_enabled) {
-        double handleSize = 6 / painter->matrix().m11();
-        double halfHandleSize = handleSize / 2;
-        painter->fillRect(-halfHandleSize, -halfHandleSize, handleSize, handleSize, QColor(Qt::yellow));
-        painter->fillRect(option->rect.width() - halfHandleSize, -halfHandleSize, handleSize, handleSize, QColor(Qt::yellow));
-        painter->fillRect(option->rect.width() - halfHandleSize, option->rect.height() - halfHandleSize, handleSize, handleSize, QColor(Qt::yellow));
-        painter->fillRect(-halfHandleSize, option->rect.height() - halfHandleSize, handleSize, handleSize, QColor(Qt::yellow));
+    Q_UNUSED(widget)
+    Q_UNUSED(option)
+
+    painter->setPen(pen());
+    //painter->setClipRect(option->rect);
+    const QRectF r = rect();
+    painter->drawRect(r);
+    QRectF handle = painter->worldTransform().inverted().mapRect(QRectF(0, 0, 6, 6));
+    if (isEnabled()) {
+        handle.moveTopLeft(r.topLeft());
+        painter->fillRect(handle, QColor(Qt::yellow));
+        handle.moveTopRight(r.topRight());
+        painter->fillRect(handle, QColor(Qt::yellow));
+        handle.moveBottomLeft(r.bottomLeft());
+        painter->fillRect(handle, QColor(Qt::yellow));
+        handle.moveBottomRight(r.bottomRight());
+        painter->fillRect(handle, QColor(Qt::yellow));
     }
+    
+    // Draw cross at center
+    QPointF center = r.center();
+    painter->drawLine(center + QPointF(-handle.width(), 0), center + QPointF(handle.width(), 0));
+    painter->drawLine(center + QPointF(0, handle.height()), center + QPointF(0, -handle.height()));
 }
 
+bool OnMonitorRectItem::getView()
+{
+    if (m_view)
+        return true;
 
+    if (scene() && !scene()->views().isEmpty()) {
+        m_view = scene()->views().first();
+        return true;
+    } else {
+        return false;
+    }
+}
 
 #include "onmonitorrectitem.moc"