#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->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);
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()
void MonitorScene::slotUpdateBackground()
{
if (m_view && m_view->isVisible()) {
- if (m_lastUpdate.elapsed() > 100) {
- 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()) {
}
}
-
void MonitorScene::slotZoom(int value)
{
if (m_view) {
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)
{
- int newzoom = (100 * m_zoom + 0.5);
- newzoom++;
- slotZoom(qMin(300, newzoom));
+ 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) {
- 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;
+ 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 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;
+ ++i;
}
- }
- } 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 (first >= 0) {
+ QGraphicsItem *item = selected.at(first);
+ if (item->parentItem()) {
+ SplineItem *parent = qgraphicsitem_cast<SplineItem*>(item->parentItem());
+ if (parent)
+ parent->updateSpline(true);
}
}
}
-
- if (!itemFound && m_view)
- m_view->setCursor(Qt::ArrowCursor);
-
+ } else {
QGraphicsScene::mouseMoveEvent(event);
}
- if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
- emit actionFinished();
- m_modified = false;
- }
}
-void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
- Q_UNUSED(event);
-
- if (!m_enabled)
- return;
-
- if (m_modified) {
- m_modified = false;
- emit actionFinished();
+ 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;
+ }
+ }
+ }
+ m_groupMove = false;
}
+ QGraphicsScene::mouseReleaseEvent(event);
+ m_view->setDragMode(QGraphicsView::NoDrag);
}
-
void MonitorScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
if (!m_enabled)
emit addKeyframe();
}
+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"