]> git.sesse.net Git - kdenlive/blobdiff - src/monitorscene.cpp
Integrate with the required MLT hooks for getting Movit to work.
[kdenlive] / src / monitorscene.cpp
index 857caab990d0a56ee7b64c9bfda77f659efc5ada..e6be3de10188933da55b54a6b60c13e3dd682076 100644 (file)
 
 #include "monitorscene.h"
 #include "renderer.h"
+#include "onmonitoritems/rotoscoping/bpointitem.h"
+#include "onmonitoritems/rotoscoping/splineitem.h"
 #include "kdenlivesettings.h"
 
 #include <QGraphicsView>
 #include <QGraphicsPixmapItem>
 #include <QGraphicsSceneMouseEvent>
+#include <QScrollBar>
+
 
 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)
+        m_zoom(1.0),
+        m_groupMove(false)
 {
     setBackgroundBrush(QBrush(QColor(KdenliveSettings::window_background().name())));
 
-    QPen framepen(Qt::SolidLine);
+    QPen framepen(Qt::DotLine);
     framepen.setColor(Qt::red);
 
-    m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_renderer->renderWidth(), m_renderer->renderHeight()));
+    m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_renderer->frameRenderWidth(), m_renderer->renderHeight()));
     m_frameBorder->setPen(framepen);
-    m_frameBorder->setZValue(-2);
+    m_frameBorder->setZValue(-1);
     m_frameBorder->setBrush(Qt::transparent);
     m_frameBorder->setFlags(0);
     addItem(m_frameBorder);
 
-    m_lastUpdate.start();
+    m_lastUpdate = QTime::currentTime();
     m_background = new QGraphicsPixmapItem();
-    m_background->setZValue(-1);
+    m_background->setZValue(-2);
     m_background->setFlags(0);
     m_background->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
     m_background->setTransformationMode(Qt::FastTransformation);
-    QPixmap bg(m_renderer->renderWidth(), m_renderer->renderHeight());
+    QPixmap bg(m_renderer->frameRenderWidth(), m_renderer->renderHeight());
     bg.fill();
     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::centerView()
+{
+    if (m_view) m_view->centerOn(m_frameBorder);
+}
+
+void MonitorScene::cleanup()
+{
+    // Reset scene rect
+    setSceneRect(m_frameBorder->boundingRect());
+}
+
 void MonitorScene::setUp()
 {
-    if (views().count() > 0)
+    if (!views().isEmpty()) {
         m_view = views().at(0);
-    else
+        m_view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+    } else {
         m_view = NULL;
-
-    m_view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+    }
 }
 
 void MonitorScene::resetProfile()
 {
-    const QRectF border(0, 0, m_renderer->renderWidth(), m_renderer->renderHeight());
+    const QRectF border(0, 0, m_renderer->frameRenderWidth(), m_renderer->renderHeight());
     m_frameBorder->setRect(border);
 }
 
@@ -89,18 +100,13 @@ void MonitorScene::setEnabled(bool enabled)
 void MonitorScene::slotUpdateBackground()
 {
     if (m_view && m_view->isVisible()) {
-        if (m_lastUpdate.elapsed() > 200) {
-            m_background->setPixmap(QPixmap::fromImage(m_backgroundImage, Qt::ThresholdDither));
-            m_lastUpdate.start();
+        if (m_lastUpdate.msecsTo(QTime::currentTime()) > 50) {
+            m_background->setPixmap(QPixmap::fromImage(m_backgroundImage));
+            m_lastUpdate = QTime::currentTime();
         }
     }
 }
 
-void MonitorScene::slotSetDirectUpdate(bool directUpdate)
-{
-    KdenliveSettings::setMonitorscene_directupdate(directUpdate);
-}
-
 void MonitorScene::slotSetBackgroundImage(const QImage &image)
 {
     if (m_view && m_view->isVisible()) {
@@ -109,13 +115,12 @@ void MonitorScene::slotSetBackgroundImage(const QImage &image)
     }
 }
 
-
 void MonitorScene::slotZoom(int value)
 {
     if (m_view) {
         m_zoom = value / 100.0;
         m_view->resetTransform();
-        m_view->scale(m_zoom, m_zoom);
+        m_view->scale(m_renderer->renderWidth() * m_zoom / m_renderer->frameRenderWidth(), m_zoom);
         emit zoomChanged(value);
     }
 }
@@ -123,10 +128,10 @@ void MonitorScene::slotZoom(int value)
 void MonitorScene::slotZoomFit()
 {
     if (m_view) {
-        m_view->fitInView(m_frameBorder, Qt::KeepAspectRatio);
+        int xzoom = 100 * m_view->viewport()->height() / m_renderer->renderHeight();
+        int yzoom = 100 * m_view->viewport()->width() / m_renderer->renderWidth();
+        slotZoom(qMin(xzoom, yzoom));
         m_view->centerOn(m_frameBorder);
-        m_zoom = m_view->matrix().m11();
-        emit zoomChanged((int)(m_zoom * 100));
     }
 }
 
@@ -137,231 +142,138 @@ void MonitorScene::slotZoomOriginal()
         m_view->centerOn(m_frameBorder);
 }
 
-void MonitorScene::slotZoomOut()
+void MonitorScene::slotZoomOut(int by)
 {
-    slotZoom(qMax(0, (int)(m_zoom * 100 - 1)));
+    slotZoom(qMax(0, (int)(m_zoom * 100 - by)));
 }
 
-void MonitorScene::slotZoomIn()
+void MonitorScene::slotZoomIn(int by)
 {
-    slotZoom(qMin(300, (int)(m_zoom * 100 + 1)));
+    slotZoom(qMin(300, (int)(m_zoom * 100 + by + 0.5)));
 }
 
-
-resizeModes MonitorScene::getResizeMode(QGraphicsRectItem *item, QPoint pos)
+void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent* event)
 {
-    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;
-}
+    QList <QGraphicsItem *> selected = selectedItems();
 
-void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
-    if (!m_enabled)
-        return;
-
-    m_resizeMode = NoResize;
-    m_selectedItem = NULL;
+    QGraphicsScene::mousePressEvent(event);
 
-    m_clickPoint = event->scenePos();
-    QList<QGraphicsItem *> itemList = items(QRectF(m_clickPoint - QPoint(4, 4), QSizeF(4, 4)).toRect());
+    if (selected.count() < selectedItems().count()) {
+        // mouse click on item not in selection group
+        // -> select only this item
+        foreach (QGraphicsItem *item, selected) {
+            if (item)
+                item->setSelected(false);
+        }
+    }
 
-    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;
+    if (event->isAccepted() && selectedItems().count() > 1) {
+        // multiple items selected + mouse pressed on an item
+        selected = selectedItems();
+        foreach (QGraphicsItem *item, selected) {
+            if (qgraphicsitem_cast<BPointItem*>(item)) {
+                // works with rotoscoping only for now
+                m_groupMove = true;
+                m_lastPos = event->scenePos();
+                return;
             }
         }
     }
 
-    QGraphicsScene::mousePressEvent(event);
+    if (!event->isAccepted() && event->buttons() & Qt::LeftButton) {
+        if (event->modifiers() == Qt::ControlModifier)
+            m_view->setDragMode(QGraphicsView::ScrollHandDrag);
+        else if (event->modifiers() == Qt::ShiftModifier)
+            m_view->setDragMode(QGraphicsView::RubberBandDrag);
+    }
 }
 
 void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
 {
-    if (!m_enabled)
-        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;
+    if (m_groupMove) {
+        // we want to move multiple items
+        // rotoscoping only for now
+        QPointF diff =  event->scenePos() - m_lastPos;
+        if (diff != QPointF(0, 0)) {
+            m_lastPos = event->scenePos();
+            QList <QGraphicsItem *> selected = selectedItems();
+            int first = -1;
+            int i = 0;
+            foreach (QGraphicsItem *item, selected) {
+                BPointItem *bpoint = qgraphicsitem_cast<BPointItem *>(item);
+                if (bpoint) {
+                    if (first < 0)
+                        first = i;
+                    BPoint p = bpoint->getPoint();
+                    p.setP(p.p + diff);
+                    bpoint->setPoint(p);
                 }
-                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;
+                ++i;
+            }
+
+            if (first >= 0) {
+                QGraphicsItem *item = selected.at(first);
+                if (item->parentItem()) {
+                    SplineItem *parent = qgraphicsitem_cast<SplineItem*>(item->parentItem());
+                    if (parent)
+                        parent->updateSpline(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);
-                    }
+        QGraphicsScene::mouseMoveEvent(event);
+    }
+}
+
+void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
+{
+    if (m_groupMove) {
+        QList <QGraphicsItem *> selected = selectedItems();
+        foreach (QGraphicsItem *item, selected) {
+            if (qgraphicsitem_cast<BPointItem*>(item) && item->parentItem()) {
+                SplineItem *parent = qgraphicsitem_cast<SplineItem*>(item->parentItem());
+                if (parent) {
+                    parent->updateSpline(false);
                     break;
                 }
             }
         }
-
-        if (!itemFound && m_view)
-            m_view->setCursor(Qt::ArrowCursor);
-
-        QGraphicsScene::mouseMoveEvent(event);
-    }
-    if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
-        emit actionFinished();
-        m_modified = false;
+        m_groupMove = false;
     }
+    QGraphicsScene::mouseReleaseEvent(event);
+    m_view->setDragMode(QGraphicsView::NoDrag);
 }
-
-void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void MonitorScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
 {
+    Q_UNUSED(event)
+
     if (!m_enabled)
-        return;
+        emit addKeyframe();
+}
 
-    QGraphicsScene::mouseReleaseEvent(event);
-    if (m_modified) {
-        m_modified = false;
-        emit actionFinished();
+void MonitorScene::wheelEvent(QGraphicsSceneWheelEvent* event)
+{
+    if (event->modifiers() == Qt::ControlModifier) {
+        if (event->delta() > 0) {
+            m_view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
+            slotZoomIn(5);
+            m_view->setTransformationAnchor(QGraphicsView::AnchorViewCenter);
+        } else {
+            slotZoomOut(5);
+        }
+    } else {
+        QAbstractSlider::SliderAction action;
+        if (event->delta() > 0)
+            action = QAbstractSlider::SliderSingleStepSub;
+        else
+            action = QAbstractSlider::SliderSingleStepAdd;
+        if (event->orientation() == Qt::Horizontal)
+            m_view->horizontalScrollBar()->triggerAction(action);
+        else
+            m_view->verticalScrollBar()->triggerAction(action);
     }
+
+    event->accept();
 }
 
 #include "monitorscene.moc"