]> git.sesse.net Git - kdenlive/commitdiff
On-Monitor effects:
authorTill Theato <root@ttill.de>
Sat, 7 Aug 2010 21:55:42 +0000 (21:55 +0000)
committerTill Theato <root@ttill.de>
Sat, 7 Aug 2010 21:55:42 +0000 (21:55 +0000)
 - Implement resizing (on the monitor scene)
 - Fix crash when closing Kdenlive (still crashes when monitor scene is open): http://kdenlive.org/mantis/view.php?id=1734

svn path=/trunk/kdenlive/; revision=4685

src/geometrywidget.cpp
src/mainwindow.cpp
src/monitor.cpp
src/monitor.h
src/monitorscene.cpp
src/monitorscene.h

index db965cb30e210f9d759c4fb75559506aa89b2845..9e7dc29a0432f8f26e067c4d15f448f212aa9110 100644 (file)
@@ -23,6 +23,7 @@
 #include "renderer.h"
 #include "monitorscene.h"
 
+#include <QtCore>
 #include <QGraphicsView>
 #include <QGraphicsRectItem>
 
@@ -50,8 +51,8 @@ GeometryWidget::GeometryWidget(Monitor* monitor, int clipPos, QWidget* parent ):
 
 GeometryWidget::~GeometryWidget()
 {
-    m_monitor->slotEffectScene(false);
-    m_scene->disconnect(this);
+    if (m_monitor)
+        m_monitor->slotEffectScene(false);
     delete m_rect;
     delete m_geometry;
 }
index ce8ea7eebe9964e70aa039f7422540b8a532477c..2d26459dfae583f9b50b30c307a1886245b9f921 100644 (file)
@@ -467,13 +467,13 @@ void MainWindow::queryQuit()
     if (queryClose()) {
         if (m_projectMonitor) m_projectMonitor->stop();
         if (m_clipMonitor) m_clipMonitor->stop();
-        delete m_effectStack;
         delete m_activeTimeline;
 #ifndef Q_WS_MAC
         // This sometimes causes crash on exit on OS X for some reason.
         delete m_projectMonitor;
         delete m_clipMonitor;
 #endif
+        delete m_effectStack;
         delete m_activeDocument;
         delete m_shortcutRemoveFocus;
         Mlt::Factory::close();
index 29e4772b65ab4dd83bfba3906e82c88d49d942c1..a39e79111d938320d239e7f42dcbb8182daea71d 100644 (file)
@@ -55,7 +55,8 @@ Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget
         m_isActive(false),
         m_scale(1),
         m_length(0),
-        m_dragStarted(false)
+        m_dragStarted(false),
+        m_delStage(false)
 {
     m_ui.setupUi(this);
     QVBoxLayout *layout = new QVBoxLayout;
@@ -169,6 +170,7 @@ Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget
         m_effectScene = new MonitorScene(render);
         m_effectView = new QGraphicsView(m_effectScene, m_ui.video_frame);
         rendererBox->addWidget(m_effectView);
+        m_effectView->setMouseTracking(true);
         m_effectScene->setUp();
         m_effectView->hide();
     }
@@ -178,12 +180,15 @@ Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget
 
 Monitor::~Monitor()
 {
+    m_delStage = true;
     delete m_ruler;
     delete m_timePos;
     delete m_overlay;
+    if (m_name == "project") {
+        delete m_effectView;
+        delete m_effectScene;
+    }
     delete m_monitorRefresh;
-    delete m_effectView;
-    delete m_effectScene;
     delete render;
 }
 
@@ -834,7 +839,7 @@ QStringList Monitor::getZoneInfo() const
 
 void Monitor::slotEffectScene(bool show)
 {
-    if (m_name == "project") {
+    if (m_name == "project" && !m_delStage) {
         m_monitorRefresh->setVisible(!show);
         m_effectView->setVisible(show);
         if (show)
index afdc611bffd723c25a9f5772d6b8f5c60da7b46b..ecc2b7509250ee3e1d987fd4371da98bb09cbaa8 100644 (file)
@@ -129,6 +129,7 @@ private:
     QPoint m_DragStartPosition;
     MonitorScene *m_effectScene;
     QGraphicsView *m_effectView;
+    bool m_delStage;
 #ifdef Q_WS_MAC
     VideoGLWidget *m_glWidget;
 #endif
index d0a512027d53fd208b9918341f4d64ef4db1dd22..57fdefdd4e05fcfaff79a054bf7beae45da23579 100644 (file)
 #include "renderer.h"
 #include "kdenlivesettings.h"
 
+#include <QtCore>
 #include <QGraphicsView>
 #include <QGraphicsPixmapItem>
-#include <QtCore>
+#include <QGraphicsSceneMouseEvent>
 
 MonitorScene::MonitorScene(Render *renderer, QObject* parent) :
         QGraphicsScene(parent),
-        m_renderer(renderer)
-{
-}
-
-void MonitorScene::setUp()
+        m_renderer(renderer),
+        m_view(NULL),
+        m_selectedItem(NULL),
+        m_resizeMode(NoResize),
+        m_clickPoint(0, 0)
 {
     setBackgroundBrush(QBrush(QColor(KdenliveSettings::window_background().name())));
 
@@ -57,28 +58,210 @@ void MonitorScene::setUp()
 
     connect(m_renderer, SIGNAL(rendererPosition(int)), this, SLOT(slotUpdateBackground()));
     connect(m_renderer, SIGNAL(frameUpdated(int)), this, SLOT(slotUpdateBackground()));
+}
+
+void MonitorScene::setUp()
+{
+    if (views().count() > 0)
+        m_view = views().at(0);
+    else
+        m_view = NULL;
     slotUpdateBackground();
 }
 
 void MonitorScene::slotUpdateBackground()
 {
-    if (views().count() > 0 && views().at(0)->isVisible()) {
+    if (m_view && m_view->isVisible()) {
         if (m_lastUpdate.elapsed() > 200) {
             m_background->setPixmap(QPixmap::fromImage(m_renderer->extractFrame(m_renderer->seekFramePosition())));
-            views().at(0)->fitInView(m_frameBorder, Qt::KeepAspectRatio);
-            views().at(0)->centerOn(m_frameBorder);
+            m_view->fitInView(m_frameBorder, Qt::KeepAspectRatio);
+            m_view->centerOn(m_frameBorder);
             m_lastUpdate.start();
         }
     }
 }
 
-void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent* event)
+resizeModes MonitorScene::getResizeMode(QGraphicsRectItem *item, QPoint pos)
+{
+    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;
+}
+
+void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
 {
+    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;
+            }
+        }
+    }
+
     QGraphicsScene::mousePressEvent(event);
 }
 
+void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+    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);
+                }
+                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()));
+                }
+                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()));
+                }
+                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()));
+                }
+                break;
+            case Right:
+                if (mousePos.x() > pos.x()) {
+                    rect.setRight(mousePosInRect.x());
+                    item->setRect(rect);
+                }
+                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()));
+                }
+                break;
+            case Bottom:
+                if (mousePos.y() > pos.y()) {
+                    rect.setBottom(mousePosInRect.y());
+                    item->setRect(rect);
+                }
+                break;
+            case BottomRight:
+                if (mousePos.x() > pos.x() && mousePos.y() > pos.y()) {
+                    rect.setBottomRight(mousePosInRect);
+                    item->setRect(rect);
+                }
+                break;
+            default:
+                QPointF diff = mousePos - m_clickPoint;
+                m_clickPoint = mousePos;
+                item->moveBy(diff.x(), diff.y());
+                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 != NULL)
+            m_view->setCursor(Qt::ArrowCursor);
+
+        QGraphicsScene::mouseMoveEvent(event);
+    }
+}
 
-void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEventevent)
+void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
     QGraphicsScene::mouseReleaseEvent(event);
     emit actionFinished();
index de9dbb0edc7b660d0ea9b7fea76eb04200af7b88..fe39c68f591beeee0b45f32db0204ed581ffcee4 100644 (file)
 #include <QGraphicsScene>
 #include <QTime>
 
-class QGraphicsPixmapItem;
 class Render;
 
+enum resizeModes { NoResize, TopLeft, BottomLeft, TopRight, BottomRight, Left, Right, Top, Bottom };
+
 class MonitorScene : public QGraphicsScene
 {
     Q_OBJECT
@@ -36,16 +37,24 @@ public:
 
 protected:
     virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
     virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
 
 public slots:
     void slotUpdateBackground();
 
 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;
+
 signals:
     void actionFinished();
 };