]> git.sesse.net Git - kdenlive/commitdiff
Add OnMonitorRectItem to separate rect move and resize code from MonitorScene
authorTill Theato <root@ttill.de>
Sat, 9 Oct 2010 20:05:46 +0000 (20:05 +0000)
committerTill Theato <root@ttill.de>
Sat, 9 Oct 2010 20:05:46 +0000 (20:05 +0000)
svn path=/trunk/kdenlive/; revision=4972

src/CMakeLists.txt
src/geometrywidget.cpp
src/geometrywidget.h
src/monitorscene.cpp
src/monitorscene.h
src/onmonitoritems/onmonitorrectitem.cpp [new file with mode: 0644]
src/onmonitoritems/onmonitorrectitem.h [new file with mode: 0644]

index cecbc0cca80dce701d013a875c9321b2b9f14b5d..d246aacbddbb0bd9393fd3bff9199055ec674ca2 100644 (file)
@@ -32,6 +32,7 @@ include_directories (
 
     ${CMAKE_SOURCE_DIR}/src/widgets
     ${CMAKE_SOURCE_DIR}/src/colorcorrection
+    ${CMAKE_SOURCE_DIR}/src/onmonitoritems
 )
 
 LINK_LIBRARIES(
@@ -225,10 +226,12 @@ set(kdenlive_SRCS
   blackmagic/capture.cpp
   blackmagic/devices.cpp
   stopmotion/stopmotion.cpp
+  onmonitoritems/onmonitorrectitem.cpp
 )
 
 
 add_subdirectory( ${CMAKE_SOURCE_DIR}/src/colorcorrection )
+add_subdirectory( ${CMAKE_SOURCE_DIR}/src/onmonitoritems )
 
 add_definitions( ${KDE4_DEFINITIONS} )
 
index 41159724830bcae050682102f6b210145b23e923..93c4f470c1e8242225ba6aa93195a7a237591dd7 100644 (file)
@@ -24,6 +24,7 @@
 #include "keyframehelper.h"
 #include "timecodedisplay.h"
 #include "monitorscene.h"
+#include "onmonitoritems/onmonitorrectitem.h"
 #include "kdenlivesettings.h"
 
 #include <QtCore>
@@ -209,15 +210,9 @@ void GeometryWidget::setupParam(const QDomElement elem, int minframe, int maxfra
 
     m_geometry->fetch(&item, 0);
     delete m_rect;
-    m_rect = new QGraphicsRectHandleItem(QRectF(0, 0, item.w(), item.h()));
+    m_rect = new OnMonitorRectItem(QRectF(0, 0, item.w(), item.h()));
     m_rect->setPos(item.x(), item.y());
     m_rect->setZValue(0);
-    m_rect->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
-
-    QPen framepen(Qt::SolidLine);
-    framepen.setColor(Qt::yellow);
-    m_rect->setPen(framepen);
-    m_rect->setBrush(Qt::transparent);
     m_scene->addItem(m_rect);
 
     slotPositionChanged(0, false);
@@ -250,14 +245,14 @@ void GeometryWidget::slotPositionChanged(int pos, bool seek)
     Mlt::GeometryItem item;
     if (m_geometry->fetch(&item, pos) || item.key() == false) {
         // no keyframe
-        m_rect->drawHandles = false;
+        m_rect->setEnabled(false);
         m_scene->setEnabled(false);
         m_ui.widgetGeometry->setEnabled(false);
         m_ui.buttonAddDelete->setIcon(KIcon("document-new"));
         m_ui.buttonAddDelete->setToolTip(i18n("Add keyframe"));
     } else {
         // keyframe
-        m_rect->drawHandles = true;
+        m_rect->setEnabled(true);
         m_scene->setEnabled(true);
         m_ui.widgetGeometry->setEnabled(true);
         m_ui.buttonAddDelete->setIcon(KIcon("edit-delete"));
index 378501c2cde7c0dc97e37444836fcd574391fa36..7a7ff090710ed3603620a1cfc44e2b60ea80f5bf 100644 (file)
 #include <mlt++/Mlt.h>
 
 #include <QWidget>
-#include <QGraphicsRectItem>
-#include <QPainter>
 
 class QDomElement;
-class QGraphicsRectItem;
 class Monitor;
 class MonitorScene;
 class KeyframeHelper;
 class TimecodeDisplay;
+class OnMonitorRectItem;
 
 
-class QGraphicsRectHandleItem: public QGraphicsRectItem
-{
-public:
-
-    QGraphicsRectHandleItem(const QRectF & rect, QGraphicsItem * parent = 0):
-            QGraphicsRectItem(rect, parent),
-            drawHandles(false) {
-    }
-
-    bool drawHandles;
-
-
-    virtual void paint(QPainter *painter,
-                       const QStyleOptionGraphicsItem * option,
-                       QWidget* widget = 0) {
-        QGraphicsRectItem::paint(painter, option, widget);
-        if (!drawHandles) return;
-        double handleSize = 6 / painter->matrix().m11();
-        painter->fillRect(0, 0, handleSize, handleSize, QColor(Qt::yellow));
-        painter->fillRect(option->rect.width() - handleSize, 0, handleSize, handleSize, QColor(Qt::yellow));
-        painter->fillRect(option->rect.width() - handleSize, option->rect.height() - handleSize, handleSize, handleSize, QColor(Qt::yellow));
-        painter->fillRect(0, option->rect.height() - handleSize, handleSize, handleSize, QColor(Qt::yellow));
-    }
-};
-
 class GeometryWidget : public QWidget
 {
     Q_OBJECT
@@ -98,7 +71,7 @@ private:
     int m_outPoint;
     bool m_isEffect;
     MonitorScene *m_scene;
-    QGraphicsRectHandleItem *m_rect;
+    OnMonitorRectItem *m_rect;
     KeyframeHelper *m_timeline;
     /** Stores the different settings in the MLT geometry format. */
     Mlt::Geometry *m_geometry;
index 655425e27ed769deec4dc8e86452593711e9aa57..eec47da33f49cb73a2b0a96cf6d8295469cbe13b 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "monitorscene.h"
 #include "renderer.h"
+#include "onmonitoritems/onmonitorrectitem.h"
 #include "kdenlivesettings.h"
 
 #include <QGraphicsView>
@@ -30,12 +31,8 @@ MonitorScene::MonitorScene(Render *renderer, QObject* parent) :
         QGraphicsScene(parent),
         m_renderer(renderer),
         m_view(NULL),
-        m_selectedItem(NULL),
-        m_resizeMode(NoResize),
-        m_clickPoint(0, 0),
         m_backgroundImage(QImage()),
         m_enabled(true),
-        m_modified(false),
         m_zoom(1.0)
 {
     setBackgroundBrush(QBrush(QColor(KdenliveSettings::window_background().name())));
@@ -50,7 +47,7 @@ MonitorScene::MonitorScene(Render *renderer, QObject* parent) :
     m_frameBorder->setFlags(0);
     addItem(m_frameBorder);
 
-    m_lastUpdate.start();
+    m_lastUpdate = QTime::currentTime();
     m_background = new QGraphicsPixmapItem();
     m_background->setZValue(-2);
     m_background->setFlags(0);
@@ -61,18 +58,17 @@ MonitorScene::MonitorScene(Render *renderer, QObject* parent) :
     m_background->setPixmap(bg);
     addItem(m_background);
 
-    //connect(m_renderer, SIGNAL(rendererPosition(int)), this, SLOT(slotUpdateBackground()));
     connect(m_renderer, SIGNAL(frameUpdated(QImage)), this, SLOT(slotSetBackgroundImage(QImage)));
 }
 
 void MonitorScene::setUp()
 {
-    if (views().count() > 0)
+    if (views().count() > 0) {
         m_view = views().at(0);
-    else
+        m_view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+    } else {
         m_view = NULL;
-
-    m_view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+    }
 }
 
 void MonitorScene::resetProfile()
@@ -89,9 +85,9 @@ void MonitorScene::setEnabled(bool enabled)
 void MonitorScene::slotUpdateBackground()
 {
     if (m_view && m_view->isVisible()) {
-        if (m_lastUpdate.elapsed() > 100) {
+        if (m_lastUpdate.msecsTo(QTime::currentTime()) > 100) {
             m_background->setPixmap(QPixmap::fromImage(m_backgroundImage));
-            m_lastUpdate.start();
+            m_lastUpdate = QTime::currentTime();
         }
     }
 }
@@ -109,7 +105,6 @@ void MonitorScene::slotSetBackgroundImage(const QImage &image)
     }
 }
 
-
 void MonitorScene::slotZoom(int value)
 {
     if (m_view) {
@@ -149,225 +144,49 @@ void MonitorScene::slotZoomIn()
     slotZoom(qMin(300, newzoom));
 }
 
+void MonitorScene::addItem(QGraphicsItem* item)
+{
+    QGraphicsScene::addItem(item);
 
-resizeModes MonitorScene::getResizeMode(QGraphicsRectItem *item, QPoint pos)
+    OnMonitorRectItem *rect = qgraphicsitem_cast<OnMonitorRectItem*>(item);
+    if (rect) {
+        connect(this, SIGNAL(mousePressed(QGraphicsSceneMouseEvent*)), rect, SLOT(slotMousePressed(QGraphicsSceneMouseEvent*)));
+        connect(this, SIGNAL(mouseReleased(QGraphicsSceneMouseEvent*)), rect, SLOT(slotMouseReleased(QGraphicsSceneMouseEvent*)));
+        connect(this, SIGNAL(mouseMoved(QGraphicsSceneMouseEvent*)), rect, SLOT(slotMouseMoved(QGraphicsSceneMouseEvent*)));
+        connect(rect, SIGNAL(actionFinished()), this, SIGNAL(actionFinished()));
+        connect(rect, SIGNAL(setCursor(const QCursor &)), this, SLOT(slotSetCursor(const QCursor &)));
+    }
+}
+
+void MonitorScene::slotSetCursor(const QCursor &cursor)
 {
-    if (!m_view)
-        return NoResize;
-
-    QRectF rect = item->rect().normalized();
-    // Item mapped coordinates
-    QPolygon pol = item->deviceTransform(m_view->viewportTransform()).map(rect).toPolygon();
-    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 mouseArea;
-    mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
-
-    // Check for collisions between the mouse and the borders
-    if (mouseArea.contains(pol.point(0)))
-        return TopLeft;
-    else if (mouseArea.contains(pol.point(2)))
-        return BottomRight;
-    else if (mouseArea.contains(pol.point(1)))
-        return TopRight;
-    else if (mouseArea.contains(pol.point(3)))
-        return BottomLeft;
-    else if (top.intersects(mouseArea))
-        return Top;
-    else if (bottom.intersects(mouseArea))
-        return Bottom;
-    else if (right.intersects(mouseArea))
-        return Right;
-    else if (left.intersects(mouseArea))
-        return Left;
-    else
-        return NoResize;
+    if (m_view)
+        m_view->setCursor(cursor);
 }
 
+
 void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
 {
-    if (!m_enabled)
-        return;
-
-    m_resizeMode = NoResize;
-    m_selectedItem = NULL;
-
-    m_clickPoint = event->scenePos();
-    QList<QGraphicsItem *> itemList = items(QRectF(m_clickPoint - QPoint(4, 4), QSizeF(4, 4)).toRect());
-
-    for (int i = 0; i < itemList.count(); ++i) {
-        if (itemList.at(i)->zValue() >= 0 && itemList.at(i)->flags() & QGraphicsItem::ItemIsMovable) {
-            m_selectedItem = itemList.at(i);
-            // Rect
-            if (itemList.at(i)->type() == 3) {
-                m_resizeMode = getResizeMode((QGraphicsRectItem*)m_selectedItem, m_view->mapFromScene(m_clickPoint));
-                break;
-            }
-        }
-    }
+    emit mousePressed(event);
 
-    QGraphicsScene::mousePressEvent(event);
+    if (!event->isAccepted() && m_enabled)
+        QGraphicsScene::mousePressEvent(event);
 }
 
 void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
 {
-    if (!m_enabled) {
-        if (m_view)
-            m_view->setCursor(Qt::ArrowCursor);
-        return;
-    }
-
-    /*if (event->buttons() != Qt::NoButton && (event->screenPos() - m_screenClickPoint).manhattanLength() < QApplication::startDragDistance()) {
-        event->accept();
-        return;
-    }*/
-
-    QPointF mousePos = event->scenePos();
-
-    if (m_selectedItem && event->buttons() & Qt::LeftButton) {
-        // Rect
-        if (m_selectedItem->type() == 3) {
-            QGraphicsRectItem *item = static_cast <QGraphicsRectItem *>(m_selectedItem);
-            QRectF rect = item->rect().normalized();
-            QPointF pos = item->pos();
-            QPointF mousePosInRect = item->mapFromScene(mousePos);
-            switch (m_resizeMode) {
-            case TopLeft:
-                if (mousePos.x() < pos.x() + rect.height() && mousePos.y() < pos.y() + rect.height()) {
-                    item->setRect(rect.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
-                    item->setPos(mousePos);
-                    m_modified = true;
-                }
-                break;
-            case Top:
-                if (mousePos.y() < pos.y() + rect.height()) {
-                    rect.setBottom(rect.height() - mousePosInRect.y());
-                    item->setRect(rect);
-                    item->setPos(QPointF(pos.x(), mousePos.y()));
-                    m_modified = true;
-                }
-                break;
-            case TopRight:
-                if (mousePos.x() > pos.x() && mousePos.y() < pos.y() + rect.height()) {
-                    rect.setBottomRight(QPointF(mousePosInRect.x(), rect.bottom() - mousePosInRect.y()));
-                    item->setRect(rect);
-                    item->setPos(QPointF(pos.x(), mousePos.y()));
-                    m_modified = true;
-                }
-                break;
-            case Left:
-                if (mousePos.x() < pos.x() + rect.width()) {
-                    rect.setRight(rect.width() - mousePosInRect.x());
-                    item->setRect(rect);
-                    item->setPos(QPointF(mousePos.x(), pos.y()));
-                    m_modified = true;
-                }
-                break;
-            case Right:
-                if (mousePos.x() > pos.x()) {
-                    rect.setRight(mousePosInRect.x());
-                    item->setRect(rect);
-                    m_modified = true;
-                }
-                break;
-            case BottomLeft:
-                if (mousePos.x() < pos.x() + rect.width() && mousePos.y() > pos.y()) {
-                    rect.setBottomRight(QPointF(rect.width() - mousePosInRect.x(), mousePosInRect.y()));
-                    item->setRect(rect);
-                    item->setPos(QPointF(mousePos.x(), pos.y()));
-                    m_modified = true;
-                }
-                break;
-            case Bottom:
-                if (mousePos.y() > pos.y()) {
-                    rect.setBottom(mousePosInRect.y());
-                    item->setRect(rect);
-                    m_modified = true;
-                }
-                break;
-            case BottomRight:
-                if (mousePos.x() > pos.x() && mousePos.y() > pos.y()) {
-                    rect.setBottomRight(mousePosInRect);
-                    item->setRect(rect);
-                    m_modified = true;
-                }
-                break;
-            default:
-                QPointF diff = mousePos - m_clickPoint;
-                m_clickPoint = mousePos;
-                item->moveBy(diff.x(), diff.y());
-                m_modified = true;
-                break;
-            }
-        }
-    } else {
-        mousePos -= QPoint(4, 4);
-        bool itemFound = false;
-        QList<QGraphicsItem *> itemList = items(QRectF(mousePos, QSizeF(4, 4)).toRect());
-
-        foreach(const QGraphicsItem* item, itemList) {
-            if (item->zValue() >= 0 && item->flags() &QGraphicsItem::ItemIsMovable) {
-                // Rect
-                if (item->type() == 3) {
-                    if (m_view == NULL)
-                        continue;
-
-                    itemFound = true;
-
-                    switch (getResizeMode((QGraphicsRectItem*)item, m_view->mapFromScene(event->scenePos()))) {
-                    case TopLeft:
-                    case BottomRight:
-                        m_view->setCursor(Qt::SizeFDiagCursor);
-                        break;
-                    case TopRight:
-                    case BottomLeft:
-                        m_view->setCursor(Qt::SizeBDiagCursor);
-                        break;
-                    case Top:
-                    case Bottom:
-                        m_view->setCursor(Qt::SizeVerCursor);
-                        break;
-                    case Left:
-                    case Right:
-                        m_view->setCursor(Qt::SizeHorCursor);
-                        break;
-                    default:
-                        m_view->setCursor(Qt::OpenHandCursor);
-                    }
-                    break;
-                }
-            }
-        }
-
-        if (!itemFound && m_view)
-            m_view->setCursor(Qt::ArrowCursor);
+    emit mouseMoved(event);
 
+    if (!event->isAccepted() && m_enabled)
         QGraphicsScene::mouseMoveEvent(event);
-    }
-    if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
-        emit actionFinished();
-        m_modified = false;
-    }
 }
 
 void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
-    Q_UNUSED(event);
+    emit mouseReleased(event);
 
-    if (!m_enabled)
-        return;
-
-    if (m_modified) {
-        m_modified = false;
-        emit actionFinished();
-    }
+    if (!event->isAccepted() && m_enabled)
+        QGraphicsScene::mouseReleaseEvent(event);
 }
 
 void MonitorScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
index 3dccf2b498b774a826f12a27b1720bc37a486e1a..8831eb9ac246c8adb0c81c45fd03c3065215807a 100644 (file)
 
 class Render;
 
-enum resizeModes { NoResize, TopLeft, BottomLeft, TopRight, BottomRight, Left, Right, Top, Bottom };
 
 class MonitorScene : public QGraphicsScene
 {
     Q_OBJECT
 public:
     MonitorScene(Render *renderer, QObject* parent = 0);
+
+    /** @brief Sets m_view to this scenes view. */
     void setUp();
+
+    /** @brief Enables/Disables the scene for usage (background still updated).
+     * @param enabled (default = true) */
     void setEnabled(bool enabled = true);
+
+    /** @brief Makes the background frame fit again after the profile changed (and therefore the resolution might have changed). */
     void resetProfile();
 
+    /** @brief Adds an item to the scene and connects mouse events + change signals if it is a onmonitor item. */
+    void addItem(QGraphicsItem *item);
+
 protected:
+    /** @brief Emits signal mousePressed to be used in onmonitor items. */
     virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+    /** @brief Emits signal mouseMoveEvent to be used in onmonitor items. */
     virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+    /** @brief Emits signal mouseReleaseEvent to be used in onmonitor items. */
     virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+    /** @brief Adds a keyframe if scene is disabled. */
     virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
 
 public slots:
+    /** @brief Sets the backgrounditem's pixmap to m_backgroundImage (only if a certain amount of time has passed since last update). */
     void slotUpdateBackground();
+    
+    /** @brief Sets the KdenliveSetting directupdate with true = update parameters (rerender frame) during mouse move (before mouse button is released) */
     void slotSetDirectUpdate(bool directUpdate);
 
+    /** @brief Sets the scene's zoom level.
+     * @param value zoom level with 100 = show frame at original size */
     void slotZoom(int value);
+    /** @brief Makes the zoom level fit the viewport's size. */
     void slotZoomFit();
+    /** @brief Shows the frame at it's original size and center. */
     void slotZoomOriginal();
+    /** @brief Zooms in by 1%. */
     void slotZoomIn();
+    /** @brief Zooms out by 1%. */
     void slotZoomOut();
 
 private slots:
+    /** @brief Sets m_backgroundImage to @param image and requests updating the background item. */
     void slotSetBackgroundImage(const QImage &image);
+    /** @brief Sets the mouse curors to @param cursor for the scene. */
+    void slotSetCursor(const QCursor &cursor);
 
 private:
-    resizeModes getResizeMode(QGraphicsRectItem *item, QPoint pos);
-
     Render *m_renderer;
     QGraphicsPixmapItem *m_background;
     QGraphicsRectItem *m_frameBorder;
     QTime m_lastUpdate;
     QGraphicsView *m_view;
-    QGraphicsItem *m_selectedItem;
-    resizeModes m_resizeMode;
-    QPointF m_clickPoint;
     QImage m_backgroundImage;
     bool m_enabled;
-    bool m_modified;
     qreal m_zoom;
 
 signals:
     void actionFinished();
     void zoomChanged(int);
     void addKeyframe();
+    void mouseMoved(QGraphicsSceneMouseEvent *event);
+    void mousePressed(QGraphicsSceneMouseEvent *event);
+    void mouseReleased(QGraphicsSceneMouseEvent *event);
 };
 
 #endif
diff --git a/src/onmonitoritems/onmonitorrectitem.cpp b/src/onmonitoritems/onmonitorrectitem.cpp
new file mode 100644 (file)
index 0000000..8031820
--- /dev/null
@@ -0,0 +1,245 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Till Theato (root@ttill.de)                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+#include "onmonitorrectitem.h"
+#include "kdenlivesettings.h"
+
+#include <QGraphicsSceneMouseEvent>
+#include <QPainter>
+#include <QStyleOptionGraphicsItem>
+#include <QCursor>
+
+OnMonitorRectItem::OnMonitorRectItem(const QRectF &rect, QGraphicsItem* parent) :
+        QGraphicsRectItem(rect, parent)
+{
+    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+
+    QPen framepen(Qt::SolidLine);
+    framepen.setColor(Qt::yellow);
+    setPen(framepen);
+    setBrush(Qt::transparent);
+}
+
+rectActions OnMonitorRectItem::getMode(QPoint pos)
+{
+    pos = mapFromScene(pos).toPoint();
+    // Item mapped coordinates
+    QPolygon pol(rect().normalized().toRect());
+
+    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 mouseArea;
+    mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
+
+    // Check for collisions between the mouse and the borders
+    if (mouseArea.contains(pol.point(0)))
+        return ResizeTopLeft;
+    else if (mouseArea.contains(pol.point(2)))
+        return ResizeBottomRight;
+    else if (mouseArea.contains(pol.point(1)))
+        return ResizeTopRight;
+    else if (mouseArea.contains(pol.point(3)))
+        return ResizeBottomLeft;
+    else if (top.intersects(mouseArea))
+        return ResizeTop;
+    else if (bottom.intersects(mouseArea))
+        return ResizeBottom;
+    else if (right.intersects(mouseArea))
+        return ResizeRight;
+    else if (left.intersects(mouseArea))
+        return ResizeLeft;
+    else if (rect().normalized().contains(pos))
+        return Move;
+    else
+        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)
+{
+    if (m_modified) {
+        m_modified = false;
+        emit actionFinished();
+    }
+
+    event->accept();
+}
+
+void OnMonitorRectItem::slotMouseMoved(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);
+        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()));
+                setPos(mousePos);
+                m_modified = true;
+            }
+            break;
+        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;
+            }
+            break;
+        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;
+            }
+            break;
+        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;
+            }
+            break;
+        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;
+            }
+            break;
+        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;
+        }
+    }
+    if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
+        emit actionFinished();
+        m_modified = false;
+    }
+
+    event->accept();
+}
+
+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));
+    }
+}
+
+
+
+#include "onmonitorrectitem.moc"
diff --git a/src/onmonitoritems/onmonitorrectitem.h b/src/onmonitoritems/onmonitorrectitem.h
new file mode 100644 (file)
index 0000000..44e9104
--- /dev/null
@@ -0,0 +1,69 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Till Theato (root@ttill.de)                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+
+#ifndef ONMONITORRECTITEM_H
+#define ONMONITORRECTITEM_H
+
+#include <QtCore>
+#include <QGraphicsRectItem>
+
+enum rectActions { Move, ResizeTopLeft, ResizeBottomLeft, ResizeTopRight, ResizeBottomRight, ResizeLeft, ResizeRight, ResizeTop, ResizeBottom, NoAction };
+
+class OnMonitorRectItem : public QObject, public QGraphicsRectItem
+{
+    Q_OBJECT
+public:
+    OnMonitorRectItem(const QRectF &rect, QGraphicsItem *parent = 0);
+
+    /** @brief Enables/Disables the ability to modify the item.
+     * @param enabled (default = true) */
+    void setEnabled(bool enabled = true);
+
+    /** @brief Gets The action mode for the area @param pos +- 4.
+     * e.g. pos(0,0) returns ResizeTopLeft */
+    rectActions getMode(QPoint pos);
+    
+    enum { Type = UserType + 1};
+    /** @brief Reimplemented to make sure casting works. */
+    int type() const;
+
+    /** @brief Reimplemented to draw the handles. */
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0 );
+
+public slots:
+    /** @brief Saves current mouse position and mode. */
+    void slotMousePressed(QGraphicsSceneMouseEvent *event);
+    /** @brief emits actionFinished signal if item was modified. */
+    void slotMouseReleased(QGraphicsSceneMouseEvent *event);
+    /** @brief Modifies item according to mouse position and mode. */
+    void slotMouseMoved(QGraphicsSceneMouseEvent *event);
+
+private:
+    rectActions m_mode;
+    QPointF m_clickPoint;
+    bool m_enabled;
+    bool m_modified;
+
+signals:
+    void actionFinished();
+    void setCursor(const QCursor &);
+};
+
+#endif