1 /***************************************************************************
2 * Copyright (C) 2010 by Till Theato (root@ttill.de) *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
21 #include "monitorscene.h"
23 #include "kdenlivesettings.h"
25 #include <QGraphicsView>
26 #include <QGraphicsPixmapItem>
27 #include <QGraphicsSceneMouseEvent>
29 MonitorScene::MonitorScene(Render *renderer, QObject* parent) :
30 QGraphicsScene(parent),
34 m_resizeMode(NoResize),
36 m_backgroundImage(QImage()),
41 setBackgroundBrush(QBrush(QColor(KdenliveSettings::window_background().name())));
43 QPen framepen(Qt::DotLine);
44 framepen.setColor(Qt::red);
46 m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_renderer->frameRenderWidth(), m_renderer->renderHeight()));
47 m_frameBorder->setPen(framepen);
48 m_frameBorder->setZValue(-1);
49 m_frameBorder->setBrush(Qt::transparent);
50 m_frameBorder->setFlags(0);
51 addItem(m_frameBorder);
54 m_background = new QGraphicsPixmapItem();
55 m_background->setZValue(-2);
56 m_background->setFlags(0);
57 m_background->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
58 m_background->setTransformationMode(Qt::FastTransformation);
59 QPixmap bg(m_renderer->frameRenderWidth(), m_renderer->renderHeight());
61 m_background->setPixmap(bg);
62 addItem(m_background);
64 //connect(m_renderer, SIGNAL(rendererPosition(int)), this, SLOT(slotUpdateBackground()));
65 connect(m_renderer, SIGNAL(frameUpdated(QImage)), this, SLOT(slotSetBackgroundImage(QImage)));
68 void MonitorScene::setUp()
70 if (views().count() > 0)
71 m_view = views().at(0);
75 m_view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
78 void MonitorScene::resetProfile()
80 const QRectF border(0, 0, m_renderer->frameRenderWidth(), m_renderer->renderHeight());
81 m_frameBorder->setRect(border);
84 void MonitorScene::setEnabled(bool enabled)
89 void MonitorScene::slotUpdateBackground()
91 if (m_view && m_view->isVisible()) {
92 if (m_lastUpdate.elapsed() > 100) {
93 m_background->setPixmap(QPixmap::fromImage(m_backgroundImage));
99 void MonitorScene::slotSetDirectUpdate(bool directUpdate)
101 KdenliveSettings::setMonitorscene_directupdate(directUpdate);
104 void MonitorScene::slotSetBackgroundImage(const QImage &image)
106 if (m_view && m_view->isVisible()) {
107 m_backgroundImage = image;
108 slotUpdateBackground();
113 void MonitorScene::slotZoom(int value)
116 m_zoom = value / 100.0;
117 m_view->resetTransform();
118 m_view->scale(m_renderer->renderWidth() * m_zoom / m_renderer->frameRenderWidth(), m_zoom);
119 emit zoomChanged(value);
123 void MonitorScene::slotZoomFit()
126 int xzoom = 100 * m_view->viewport()->height() / m_renderer->renderHeight();
127 int yzoom = 100 * m_view->viewport()->width() / m_renderer->renderWidth();
128 slotZoom(qMin(xzoom, yzoom));
129 m_view->centerOn(m_frameBorder);
133 void MonitorScene::slotZoomOriginal()
137 m_view->centerOn(m_frameBorder);
140 void MonitorScene::slotZoomOut()
142 slotZoom(qMax(0, (int)(m_zoom * 100 - 1)));
145 void MonitorScene::slotZoomIn()
147 int newzoom = (100 * m_zoom + 0.5);
149 slotZoom(qMin(300, newzoom));
153 resizeModes MonitorScene::getResizeMode(QGraphicsRectItem *item, QPoint pos)
158 QRectF rect = item->rect().normalized();
159 // Item mapped coordinates
160 QPolygon pol = item->deviceTransform(m_view->viewportTransform()).map(rect).toPolygon();
161 QPainterPath top(pol.point(0));
162 top.lineTo(pol.point(1));
163 QPainterPath bottom(pol.point(2));
164 bottom.lineTo(pol.point(3));
165 QPainterPath left(pol.point(0));
166 left.lineTo(pol.point(3));
167 QPainterPath right(pol.point(1));
168 right.lineTo(pol.point(2));
170 QPainterPath mouseArea;
171 mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
173 // Check for collisions between the mouse and the borders
174 if (mouseArea.contains(pol.point(0)))
176 else if (mouseArea.contains(pol.point(2)))
178 else if (mouseArea.contains(pol.point(1)))
180 else if (mouseArea.contains(pol.point(3)))
182 else if (top.intersects(mouseArea))
184 else if (bottom.intersects(mouseArea))
186 else if (right.intersects(mouseArea))
188 else if (left.intersects(mouseArea))
194 void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
199 m_resizeMode = NoResize;
200 m_selectedItem = NULL;
202 m_clickPoint = event->scenePos();
203 QList<QGraphicsItem *> itemList = items(QRectF(m_clickPoint - QPoint(4, 4), QSizeF(4, 4)).toRect());
205 for (int i = 0; i < itemList.count(); ++i) {
206 if (itemList.at(i)->zValue() >= 0 && itemList.at(i)->flags() & QGraphicsItem::ItemIsMovable) {
207 m_selectedItem = itemList.at(i);
209 if (itemList.at(i)->type() == 3) {
210 m_resizeMode = getResizeMode((QGraphicsRectItem*)m_selectedItem, m_view->mapFromScene(m_clickPoint));
216 QGraphicsScene::mousePressEvent(event);
219 void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
223 m_view->setCursor(Qt::ArrowCursor);
227 /*if (event->buttons() != Qt::NoButton && (event->screenPos() - m_screenClickPoint).manhattanLength() < QApplication::startDragDistance()) {
232 QPointF mousePos = event->scenePos();
234 if (m_selectedItem && event->buttons() & Qt::LeftButton) {
236 if (m_selectedItem->type() == 3) {
237 QGraphicsRectItem *item = static_cast <QGraphicsRectItem *>(m_selectedItem);
238 QRectF rect = item->rect().normalized();
239 QPointF pos = item->pos();
240 QPointF mousePosInRect = item->mapFromScene(mousePos);
241 switch (m_resizeMode) {
243 if (mousePos.x() < pos.x() + rect.height() && mousePos.y() < pos.y() + rect.height()) {
244 item->setRect(rect.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
245 item->setPos(mousePos);
250 if (mousePos.y() < pos.y() + rect.height()) {
251 rect.setBottom(rect.height() - mousePosInRect.y());
253 item->setPos(QPointF(pos.x(), mousePos.y()));
258 if (mousePos.x() > pos.x() && mousePos.y() < pos.y() + rect.height()) {
259 rect.setBottomRight(QPointF(mousePosInRect.x(), rect.bottom() - mousePosInRect.y()));
261 item->setPos(QPointF(pos.x(), mousePos.y()));
266 if (mousePos.x() < pos.x() + rect.width()) {
267 rect.setRight(rect.width() - mousePosInRect.x());
269 item->setPos(QPointF(mousePos.x(), pos.y()));
274 if (mousePos.x() > pos.x()) {
275 rect.setRight(mousePosInRect.x());
281 if (mousePos.x() < pos.x() + rect.width() && mousePos.y() > pos.y()) {
282 rect.setBottomRight(QPointF(rect.width() - mousePosInRect.x(), mousePosInRect.y()));
284 item->setPos(QPointF(mousePos.x(), pos.y()));
289 if (mousePos.y() > pos.y()) {
290 rect.setBottom(mousePosInRect.y());
296 if (mousePos.x() > pos.x() && mousePos.y() > pos.y()) {
297 rect.setBottomRight(mousePosInRect);
303 QPointF diff = mousePos - m_clickPoint;
304 m_clickPoint = mousePos;
305 item->moveBy(diff.x(), diff.y());
311 mousePos -= QPoint(4, 4);
312 bool itemFound = false;
313 QList<QGraphicsItem *> itemList = items(QRectF(mousePos, QSizeF(4, 4)).toRect());
315 foreach(const QGraphicsItem* item, itemList) {
316 if (item->zValue() >= 0 && item->flags() &QGraphicsItem::ItemIsMovable) {
318 if (item->type() == 3) {
324 switch (getResizeMode((QGraphicsRectItem*)item, m_view->mapFromScene(event->scenePos()))) {
327 m_view->setCursor(Qt::SizeFDiagCursor);
331 m_view->setCursor(Qt::SizeBDiagCursor);
335 m_view->setCursor(Qt::SizeVerCursor);
339 m_view->setCursor(Qt::SizeHorCursor);
342 m_view->setCursor(Qt::OpenHandCursor);
349 if (!itemFound && m_view)
350 m_view->setCursor(Qt::ArrowCursor);
352 QGraphicsScene::mouseMoveEvent(event);
354 if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
355 emit actionFinished();
360 void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
369 emit actionFinished();
373 void MonitorScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
382 #include "monitorscene.moc"