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::SolidLine);
44 framepen.setColor(Qt::red);
46 m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_renderer->renderWidth(), m_renderer->renderHeight()));
47 m_frameBorder->setPen(framepen);
48 m_frameBorder->setZValue(-2);
49 m_frameBorder->setBrush(Qt::transparent);
50 m_frameBorder->setFlags(0);
51 addItem(m_frameBorder);
54 m_background = new QGraphicsPixmapItem();
55 m_background->setZValue(-1);
56 m_background->setFlags(0);
57 m_background->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
58 m_background->setTransformationMode(Qt::FastTransformation);
59 QPixmap bg(m_renderer->renderWidth(), 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->renderWidth(), 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() > 200) {
93 m_background->setPixmap(QPixmap::fromImage(m_backgroundImage, Qt::ThresholdDither));
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_zoom, m_zoom);
119 emit zoomChanged(value);
123 void MonitorScene::slotZoomFit()
126 m_view->fitInView(m_frameBorder, Qt::KeepAspectRatio);
127 m_view->centerOn(m_frameBorder);
128 m_zoom = m_view->matrix().m11();
129 emit zoomChanged((int)(m_zoom * 100));
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 slotZoom(qMin(300, (int)(m_zoom * 100 + 1)));
151 resizeModes MonitorScene::getResizeMode(QGraphicsRectItem *item, QPoint pos)
156 QRectF rect = item->rect().normalized();
157 // Item mapped coordinates
158 QPolygon pol = item->deviceTransform(m_view->viewportTransform()).map(rect).toPolygon();
159 QPainterPath top(pol.point(0));
160 top.lineTo(pol.point(1));
161 QPainterPath bottom(pol.point(2));
162 bottom.lineTo(pol.point(3));
163 QPainterPath left(pol.point(0));
164 left.lineTo(pol.point(3));
165 QPainterPath right(pol.point(1));
166 right.lineTo(pol.point(2));
168 QPainterPath mouseArea;
169 mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
171 // Check for collisions between the mouse and the borders
172 if (mouseArea.contains(pol.point(0)))
174 else if (mouseArea.contains(pol.point(2)))
176 else if (mouseArea.contains(pol.point(1)))
178 else if (mouseArea.contains(pol.point(3)))
180 else if (top.intersects(mouseArea))
182 else if (bottom.intersects(mouseArea))
184 else if (right.intersects(mouseArea))
186 else if (left.intersects(mouseArea))
192 void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
197 m_resizeMode = NoResize;
198 m_selectedItem = NULL;
200 m_clickPoint = event->scenePos();
201 QList<QGraphicsItem *> itemList = items(QRectF(m_clickPoint - QPoint(4, 4), QSizeF(4, 4)).toRect());
203 for (int i = 0; i < itemList.count(); ++i) {
204 if (itemList.at(i)->zValue() >= 0 && itemList.at(i)->flags() & QGraphicsItem::ItemIsMovable) {
205 m_selectedItem = itemList.at(i);
207 if (itemList.at(i)->type() == 3) {
208 m_resizeMode = getResizeMode((QGraphicsRectItem*)m_selectedItem, m_view->mapFromScene(m_clickPoint));
214 QGraphicsScene::mousePressEvent(event);
217 void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
222 QPointF mousePos = event->scenePos();
224 if (m_selectedItem && event->buttons() & Qt::LeftButton) {
226 if (m_selectedItem->type() == 3) {
227 QGraphicsRectItem *item = static_cast <QGraphicsRectItem *>(m_selectedItem);
228 QRectF rect = item->rect().normalized();
229 QPointF pos = item->pos();
230 QPointF mousePosInRect = item->mapFromScene(mousePos);
231 switch (m_resizeMode) {
233 if (mousePos.x() < pos.x() + rect.height() && mousePos.y() < pos.y() + rect.height()) {
234 item->setRect(rect.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
235 item->setPos(mousePos);
240 if (mousePos.y() < pos.y() + rect.height()) {
241 rect.setBottom(rect.height() - mousePosInRect.y());
243 item->setPos(QPointF(pos.x(), mousePos.y()));
248 if (mousePos.x() > pos.x() && mousePos.y() < pos.y() + rect.height()) {
249 rect.setBottomRight(QPointF(mousePosInRect.x(), rect.bottom() - mousePosInRect.y()));
251 item->setPos(QPointF(pos.x(), mousePos.y()));
256 if (mousePos.x() < pos.x() + rect.width()) {
257 rect.setRight(rect.width() - mousePosInRect.x());
259 item->setPos(QPointF(mousePos.x(), pos.y()));
264 if (mousePos.x() > pos.x()) {
265 rect.setRight(mousePosInRect.x());
271 if (mousePos.x() < pos.x() + rect.width() && mousePos.y() > pos.y()) {
272 rect.setBottomRight(QPointF(rect.width() - mousePosInRect.x(), mousePosInRect.y()));
274 item->setPos(QPointF(mousePos.x(), pos.y()));
279 if (mousePos.y() > pos.y()) {
280 rect.setBottom(mousePosInRect.y());
286 if (mousePos.x() > pos.x() && mousePos.y() > pos.y()) {
287 rect.setBottomRight(mousePosInRect);
293 QPointF diff = mousePos - m_clickPoint;
294 m_clickPoint = mousePos;
295 item->moveBy(diff.x(), diff.y());
301 mousePos -= QPoint(4, 4);
302 bool itemFound = false;
303 QList<QGraphicsItem *> itemList = items(QRectF(mousePos, QSizeF(4, 4)).toRect());
305 foreach(const QGraphicsItem* item, itemList) {
306 if (item->zValue() >= 0 && item->flags() &QGraphicsItem::ItemIsMovable) {
308 if (item->type() == 3) {
314 switch (getResizeMode((QGraphicsRectItem*)item, m_view->mapFromScene(event->scenePos()))) {
317 m_view->setCursor(Qt::SizeFDiagCursor);
321 m_view->setCursor(Qt::SizeBDiagCursor);
325 m_view->setCursor(Qt::SizeVerCursor);
329 m_view->setCursor(Qt::SizeHorCursor);
332 m_view->setCursor(Qt::OpenHandCursor);
339 if (!itemFound && m_view)
340 m_view->setCursor(Qt::ArrowCursor);
342 QGraphicsScene::mouseMoveEvent(event);
344 if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
345 emit actionFinished();
350 void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
355 QGraphicsScene::mouseReleaseEvent(event);
358 emit actionFinished();
362 #include "monitorscene.moc"