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::resetProfile()
82 const QRectF border(0, 0, m_renderer->renderWidth(), m_renderer->renderHeight());
83 m_frameBorder->setRect(border);
86 void MonitorScene::setEnabled(bool enabled)
91 void MonitorScene::slotUpdateBackground(bool fit)
93 if (m_view && m_view->isVisible()) {
94 if (m_lastUpdate.elapsed() > 200) {
95 m_background->setPixmap(QPixmap::fromImage(m_backgroundImage, Qt::ThresholdDither));
97 m_view->fitInView(m_frameBorder, Qt::KeepAspectRatio);
98 m_view->centerOn(m_frameBorder);
100 m_lastUpdate.start();
105 void MonitorScene::slotSetDirectUpdate(bool directUpdate)
107 m_directUpdate = directUpdate;
110 bool MonitorScene::getDirectUpdate()
112 return m_directUpdate;
115 void MonitorScene::slotSetBackgroundImage(const QImage &image)
117 m_backgroundImage = image;
118 slotUpdateBackground();
121 resizeModes MonitorScene::getResizeMode(QGraphicsRectItem *item, QPoint pos)
126 QRectF rect = item->rect().normalized();
127 // Item mapped coordinates
128 QPolygon pol = item->deviceTransform(m_view->viewportTransform()).map(rect).toPolygon();
129 QPainterPath top(pol.point(0));
130 top.lineTo(pol.point(1));
131 QPainterPath bottom(pol.point(2));
132 bottom.lineTo(pol.point(3));
133 QPainterPath left(pol.point(0));
134 left.lineTo(pol.point(3));
135 QPainterPath right(pol.point(1));
136 right.lineTo(pol.point(2));
138 QPainterPath mouseArea;
139 mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
141 // Check for collisions between the mouse and the borders
142 if (mouseArea.contains(pol.point(0)))
144 else if (mouseArea.contains(pol.point(2)))
146 else if (mouseArea.contains(pol.point(1)))
148 else if (mouseArea.contains(pol.point(3)))
150 else if (top.intersects(mouseArea))
152 else if (bottom.intersects(mouseArea))
154 else if (right.intersects(mouseArea))
156 else if (left.intersects(mouseArea))
162 void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
167 m_resizeMode = NoResize;
168 m_selectedItem = NULL;
170 m_clickPoint = event->scenePos();
171 QList<QGraphicsItem *> itemList = items(QRectF(m_clickPoint - QPoint(4, 4), QSizeF(4, 4)).toRect());
173 for (int i = 0; i < itemList.count(); ++i) {
174 if (itemList.at(i)->zValue() >= 0 && itemList.at(i)->flags() & QGraphicsItem::ItemIsMovable) {
175 m_selectedItem = itemList.at(i);
177 if (itemList.at(i)->type() == 3) {
178 m_resizeMode = getResizeMode((QGraphicsRectItem*)m_selectedItem, m_view->mapFromScene(m_clickPoint));
184 QGraphicsScene::mousePressEvent(event);
187 void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
192 QPointF mousePos = event->scenePos();
194 if (m_selectedItem && event->buttons() & Qt::LeftButton) {
196 if (m_selectedItem->type() == 3) {
197 QGraphicsRectItem *item = static_cast <QGraphicsRectItem *>(m_selectedItem);
198 QRectF rect = item->rect().normalized();
199 QPointF pos = item->pos();
200 QPointF mousePosInRect = item->mapFromScene(mousePos);
201 switch (m_resizeMode) {
203 if (mousePos.x() < pos.x() + rect.height() && mousePos.y() < pos.y() + rect.height()) {
204 item->setRect(rect.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
205 item->setPos(mousePos);
210 if (mousePos.y() < pos.y() + rect.height()) {
211 rect.setBottom(rect.height() - mousePosInRect.y());
213 item->setPos(QPointF(pos.x(), mousePos.y()));
218 if (mousePos.x() > pos.x() && mousePos.y() < pos.y() + rect.height()) {
219 rect.setBottomRight(QPointF(mousePosInRect.x(), rect.bottom() - mousePosInRect.y()));
221 item->setPos(QPointF(pos.x(), mousePos.y()));
226 if (mousePos.x() < pos.x() + rect.width()) {
227 rect.setRight(rect.width() - mousePosInRect.x());
229 item->setPos(QPointF(mousePos.x(), pos.y()));
234 if (mousePos.x() > pos.x()) {
235 rect.setRight(mousePosInRect.x());
241 if (mousePos.x() < pos.x() + rect.width() && mousePos.y() > pos.y()) {
242 rect.setBottomRight(QPointF(rect.width() - mousePosInRect.x(), mousePosInRect.y()));
244 item->setPos(QPointF(mousePos.x(), pos.y()));
249 if (mousePos.y() > pos.y()) {
250 rect.setBottom(mousePosInRect.y());
256 if (mousePos.x() > pos.x() && mousePos.y() > pos.y()) {
257 rect.setBottomRight(mousePosInRect);
263 QPointF diff = mousePos - m_clickPoint;
264 m_clickPoint = mousePos;
265 item->moveBy(diff.x(), diff.y());
271 mousePos -= QPoint(4, 4);
272 bool itemFound = false;
273 QList<QGraphicsItem *> itemList = items(QRectF(mousePos, QSizeF(4, 4)).toRect());
275 foreach(const QGraphicsItem* item, itemList) {
276 if (item->zValue() >= 0 && item->flags() &QGraphicsItem::ItemIsMovable) {
278 if (item->type() == 3) {
284 switch (getResizeMode((QGraphicsRectItem*)item, m_view->mapFromScene(event->scenePos()))) {
287 m_view->setCursor(Qt::SizeFDiagCursor);
291 m_view->setCursor(Qt::SizeBDiagCursor);
295 m_view->setCursor(Qt::SizeVerCursor);
299 m_view->setCursor(Qt::SizeHorCursor);
302 m_view->setCursor(Qt::OpenHandCursor);
309 if (!itemFound && m_view)
310 m_view->setCursor(Qt::ArrowCursor);
312 QGraphicsScene::mouseMoveEvent(event);
314 if (m_modified && m_directUpdate) {
315 emit actionFinished();
320 void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
325 QGraphicsScene::mouseReleaseEvent(event);
328 emit actionFinished();
332 #include "monitorscene.moc"