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));
103 void MonitorScene::slotSetDirectUpdate(bool directUpdate)
105 KdenliveSettings::setMonitorscene_directupdate(directUpdate);
108 void MonitorScene::slotSetBackgroundImage(const QImage &image)
110 m_backgroundImage = image;
111 slotUpdateBackground();
115 void MonitorScene::slotZoom(int value)
118 m_zoom = value / 100.0;
119 m_view->resetTransform();
120 m_view->scale(m_zoom, m_zoom);
121 emit zoomChanged(value);
125 void MonitorScene::slotZoomFit()
128 m_view->fitInView(m_frameBorder, Qt::KeepAspectRatio);
129 m_view->centerOn(m_frameBorder);
130 m_zoom = m_view->matrix().m11();
131 emit zoomChanged((int)(m_zoom * 100));
135 void MonitorScene::slotZoomOriginal()
139 m_view->centerOn(m_frameBorder);
142 void MonitorScene::slotZoomOut()
144 slotZoom(qMax(0, (int)(m_zoom * 100 - 1)));
147 void MonitorScene::slotZoomIn()
149 slotZoom(qMin(300, (int)(m_zoom * 100 + 1)));
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)
224 QPointF mousePos = event->scenePos();
226 if (m_selectedItem && event->buttons() & Qt::LeftButton) {
228 if (m_selectedItem->type() == 3) {
229 QGraphicsRectItem *item = static_cast <QGraphicsRectItem *>(m_selectedItem);
230 QRectF rect = item->rect().normalized();
231 QPointF pos = item->pos();
232 QPointF mousePosInRect = item->mapFromScene(mousePos);
233 switch (m_resizeMode) {
235 if (mousePos.x() < pos.x() + rect.height() && mousePos.y() < pos.y() + rect.height()) {
236 item->setRect(rect.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
237 item->setPos(mousePos);
242 if (mousePos.y() < pos.y() + rect.height()) {
243 rect.setBottom(rect.height() - mousePosInRect.y());
245 item->setPos(QPointF(pos.x(), mousePos.y()));
250 if (mousePos.x() > pos.x() && mousePos.y() < pos.y() + rect.height()) {
251 rect.setBottomRight(QPointF(mousePosInRect.x(), rect.bottom() - mousePosInRect.y()));
253 item->setPos(QPointF(pos.x(), mousePos.y()));
258 if (mousePos.x() < pos.x() + rect.width()) {
259 rect.setRight(rect.width() - mousePosInRect.x());
261 item->setPos(QPointF(mousePos.x(), pos.y()));
266 if (mousePos.x() > pos.x()) {
267 rect.setRight(mousePosInRect.x());
273 if (mousePos.x() < pos.x() + rect.width() && mousePos.y() > pos.y()) {
274 rect.setBottomRight(QPointF(rect.width() - mousePosInRect.x(), mousePosInRect.y()));
276 item->setPos(QPointF(mousePos.x(), pos.y()));
281 if (mousePos.y() > pos.y()) {
282 rect.setBottom(mousePosInRect.y());
288 if (mousePos.x() > pos.x() && mousePos.y() > pos.y()) {
289 rect.setBottomRight(mousePosInRect);
295 QPointF diff = mousePos - m_clickPoint;
296 m_clickPoint = mousePos;
297 item->moveBy(diff.x(), diff.y());
303 mousePos -= QPoint(4, 4);
304 bool itemFound = false;
305 QList<QGraphicsItem *> itemList = items(QRectF(mousePos, QSizeF(4, 4)).toRect());
307 foreach(const QGraphicsItem* item, itemList) {
308 if (item->zValue() >= 0 && item->flags() &QGraphicsItem::ItemIsMovable) {
310 if (item->type() == 3) {
316 switch (getResizeMode((QGraphicsRectItem*)item, m_view->mapFromScene(event->scenePos()))) {
319 m_view->setCursor(Qt::SizeFDiagCursor);
323 m_view->setCursor(Qt::SizeBDiagCursor);
327 m_view->setCursor(Qt::SizeVerCursor);
331 m_view->setCursor(Qt::SizeHorCursor);
334 m_view->setCursor(Qt::OpenHandCursor);
341 if (!itemFound && m_view)
342 m_view->setCursor(Qt::ArrowCursor);
344 QGraphicsScene::mouseMoveEvent(event);
346 if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
347 emit actionFinished();
352 void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
357 QGraphicsScene::mouseReleaseEvent(event);
360 emit actionFinished();
364 #include "monitorscene.moc"