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);
77 slotUpdateBackground(true);
80 void MonitorScene::setEnabled(bool enabled)
85 void MonitorScene::slotUpdateBackground(bool fit)
87 if (m_view && m_view->isVisible()) {
88 if (m_lastUpdate.elapsed() > 200) {
89 m_background->setPixmap(QPixmap::fromImage(m_backgroundImage, Qt::ThresholdDither));
91 m_view->fitInView(m_frameBorder, Qt::KeepAspectRatio);
92 m_view->centerOn(m_frameBorder);
99 void MonitorScene::slotSetDirectUpdate(bool directUpdate)
101 m_directUpdate = directUpdate;
104 bool MonitorScene::getDirectUpdate()
106 return m_directUpdate;
109 void MonitorScene::slotSetBackgroundImage(QImage image)
111 m_backgroundImage = image;
112 slotUpdateBackground();
115 resizeModes MonitorScene::getResizeMode(QGraphicsRectItem *item, QPoint pos)
120 QRectF rect = item->rect().normalized();
121 // Item mapped coordinates
122 QPolygon pol = item->deviceTransform(m_view->viewportTransform()).map(rect).toPolygon();
123 QPainterPath top(pol.point(0));
124 top.lineTo(pol.point(1));
125 QPainterPath bottom(pol.point(2));
126 bottom.lineTo(pol.point(3));
127 QPainterPath left(pol.point(0));
128 left.lineTo(pol.point(3));
129 QPainterPath right(pol.point(1));
130 right.lineTo(pol.point(2));
132 QPainterPath mouseArea;
133 mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
135 // Check for collisions between the mouse and the borders
136 if (mouseArea.contains(pol.point(0)))
138 else if (mouseArea.contains(pol.point(2)))
140 else if (mouseArea.contains(pol.point(1)))
142 else if (mouseArea.contains(pol.point(3)))
144 else if (top.intersects(mouseArea))
146 else if (bottom.intersects(mouseArea))
148 else if (right.intersects(mouseArea))
150 else if (left.intersects(mouseArea))
156 void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
161 m_resizeMode = NoResize;
162 m_selectedItem = NULL;
164 m_clickPoint = event->scenePos();
165 QList<QGraphicsItem *> itemList = items(QRectF(m_clickPoint - QPoint(4, 4), QSizeF(4, 4)).toRect());
167 for (int i = 0; i < itemList.count(); ++i) {
168 if (itemList.at(i)->zValue() >= 0 && itemList.at(i)->flags() & QGraphicsItem::ItemIsMovable) {
169 m_selectedItem = itemList.at(i);
171 if (itemList.at(i)->type() == 3) {
172 m_resizeMode = getResizeMode((QGraphicsRectItem*)m_selectedItem, m_view->mapFromScene(m_clickPoint));
178 QGraphicsScene::mousePressEvent(event);
181 void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
186 QPointF mousePos = event->scenePos();
188 if (m_selectedItem && event->buttons() & Qt::LeftButton) {
190 if (m_selectedItem->type() == 3) {
191 QGraphicsRectItem *item = static_cast <QGraphicsRectItem *>(m_selectedItem);
192 QRectF rect = item->rect().normalized();
193 QPointF pos = item->pos();
194 QPointF mousePosInRect = item->mapFromScene(mousePos);
195 switch (m_resizeMode) {
197 if (mousePos.x() < pos.x() + rect.height() && mousePos.y() < pos.y() + rect.height()) {
198 item->setRect(rect.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
199 item->setPos(mousePos);
204 if (mousePos.y() < pos.y() + rect.height()) {
205 rect.setBottom(rect.height() - mousePosInRect.y());
207 item->setPos(QPointF(pos.x(), mousePos.y()));
212 if (mousePos.x() > pos.x() && mousePos.y() < pos.y() + rect.height()) {
213 rect.setBottomRight(QPointF(mousePosInRect.x(), rect.bottom() - mousePosInRect.y()));
215 item->setPos(QPointF(pos.x(), mousePos.y()));
220 if (mousePos.x() < pos.x() + rect.width()) {
221 rect.setRight(rect.width() - mousePosInRect.x());
223 item->setPos(QPointF(mousePos.x(), pos.y()));
228 if (mousePos.x() > pos.x()) {
229 rect.setRight(mousePosInRect.x());
235 if (mousePos.x() < pos.x() + rect.width() && mousePos.y() > pos.y()) {
236 rect.setBottomRight(QPointF(rect.width() - mousePosInRect.x(), mousePosInRect.y()));
238 item->setPos(QPointF(mousePos.x(), pos.y()));
243 if (mousePos.y() > pos.y()) {
244 rect.setBottom(mousePosInRect.y());
250 if (mousePos.x() > pos.x() && mousePos.y() > pos.y()) {
251 rect.setBottomRight(mousePosInRect);
257 QPointF diff = mousePos - m_clickPoint;
258 m_clickPoint = mousePos;
259 item->moveBy(diff.x(), diff.y());
265 mousePos -= QPoint(4, 4);
266 bool itemFound = false;
267 QList<QGraphicsItem *> itemList = items(QRectF(mousePos, QSizeF(4, 4)).toRect());
269 foreach (const QGraphicsItem* item, itemList) {
270 if (item->zValue() >= 0 && item->flags() &QGraphicsItem::ItemIsMovable) {
272 if (item->type() == 3) {
278 switch (getResizeMode((QGraphicsRectItem*)item, m_view->mapFromScene(event->scenePos()))) {
281 m_view->setCursor(Qt::SizeFDiagCursor);
285 m_view->setCursor(Qt::SizeBDiagCursor);
289 m_view->setCursor(Qt::SizeVerCursor);
293 m_view->setCursor(Qt::SizeHorCursor);
296 m_view->setCursor(Qt::OpenHandCursor);
303 if (!itemFound && m_view)
304 m_view->setCursor(Qt::ArrowCursor);
306 QGraphicsScene::mouseMoveEvent(event);
308 if (m_modified && m_directUpdate) {
309 emit actionFinished();
314 void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
319 QGraphicsScene::mouseReleaseEvent(event);
322 emit actionFinished();
326 #include "monitorscene.moc"