]> git.sesse.net Git - kdenlive/blob - src/monitorscene.cpp
- Use a frame image from the consumer-frame-show event handler as monitor scene backg...
[kdenlive] / src / monitorscene.cpp
1 /***************************************************************************
2  *   Copyright (C) 2010 by Till Theato (root@ttill.de)                     *
3  *                                                                         *
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.                                   *
8  *                                                                         *
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.                          *
13  *                                                                         *
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  ***************************************************************************/
19
20
21 #include "monitorscene.h"
22 #include "renderer.h"
23 #include "kdenlivesettings.h"
24
25 #include <QtCore>
26 #include <QGraphicsView>
27 #include <QGraphicsPixmapItem>
28 #include <QGraphicsSceneMouseEvent>
29
30 MonitorScene::MonitorScene(Render *renderer, QObject* parent) :
31         QGraphicsScene(parent),
32         m_renderer(renderer),
33         m_view(NULL),
34         m_selectedItem(NULL),
35         m_resizeMode(NoResize),
36         m_clickPoint(0, 0),
37         m_backgroundImage(QImage())
38 {
39     setBackgroundBrush(QBrush(QColor(KdenliveSettings::window_background().name())));
40
41     QPen framepen(Qt::DotLine);
42     framepen.setColor(Qt::red);
43
44     m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_renderer->renderWidth(), m_renderer->renderHeight()));
45     m_frameBorder->setPen(framepen);
46     m_frameBorder->setZValue(-9);
47     m_frameBorder->setBrush(Qt::transparent);
48     m_frameBorder->setFlags(0);
49     addItem(m_frameBorder);
50
51     m_lastUpdate.start();
52     m_background = new QGraphicsPixmapItem();
53     m_background->setZValue(-10);
54     m_background->setFlags(0);
55     QPixmap bg(m_renderer->renderWidth(), m_renderer->renderHeight());
56     bg.fill();
57     m_background->setPixmap(bg);
58     addItem(m_background);
59
60     //connect(m_renderer, SIGNAL(rendererPosition(int)), this, SLOT(slotUpdateBackground()));
61     connect(m_renderer, SIGNAL(frameUpdated(QImage)), this, SLOT(slotSetBackgroundImage(QImage)));
62 }
63
64 void MonitorScene::setUp()
65 {
66     if (views().count() > 0)
67         m_view = views().at(0);
68     else
69         m_view = NULL;
70     slotUpdateBackground(true);
71 }
72
73 void MonitorScene::slotUpdateBackground(bool fit)
74 {
75     if (m_view && m_view->isVisible()) {
76         if (m_lastUpdate.elapsed() > 200) {
77             m_background->setPixmap(QPixmap::fromImage(m_backgroundImage));
78             if (fit) {
79                 m_view->fitInView(m_frameBorder, Qt::KeepAspectRatio);
80                 m_view->centerOn(m_frameBorder);
81             }
82             m_lastUpdate.start();
83         }
84     }
85 }
86
87 void MonitorScene::slotSetBackgroundImage(QImage image)
88 {
89     m_backgroundImage = image;
90     slotUpdateBackground();
91 }
92
93 resizeModes MonitorScene::getResizeMode(QGraphicsRectItem *item, QPoint pos)
94 {
95     if(!m_view)
96         return NoResize;
97
98     QRectF rect = item->rect().normalized();
99     // Item mapped coordinates
100     QPolygon pol = item->deviceTransform(m_view->viewportTransform()).map(rect).toPolygon();
101     QPainterPath top(pol.point(0));
102     top.lineTo(pol.point(1));
103     QPainterPath bottom(pol.point(2));
104     bottom.lineTo(pol.point(3));
105     QPainterPath left(pol.point(0));
106     left.lineTo(pol.point(3));
107     QPainterPath right(pol.point(1));
108     right.lineTo(pol.point(2));
109
110     QPainterPath mouseArea;
111     mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
112
113     // Check for collisions between the mouse and the borders
114     if (mouseArea.contains(pol.point(0)))
115         return TopLeft;
116     else if (mouseArea.contains(pol.point(2)))
117         return BottomRight;
118     else if (mouseArea.contains(pol.point(1)))
119         return TopRight;
120     else if (mouseArea.contains(pol.point(3)))
121         return BottomLeft;
122     else if (top.intersects(mouseArea))
123         return Top;
124     else if (bottom.intersects(mouseArea))
125         return Bottom;
126     else if (right.intersects(mouseArea))
127         return Right;
128     else if (left.intersects(mouseArea))
129         return Left;
130     else
131         return NoResize;
132 }
133
134 void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
135 {
136     m_resizeMode = NoResize;
137     m_selectedItem = NULL;
138
139     m_clickPoint = event->scenePos();
140     QList<QGraphicsItem *> itemList = items(QRectF(m_clickPoint - QPoint(4, 4), QSizeF(4, 4)).toRect());
141
142     for (int i = 0; i < itemList.count(); ++i) {
143         if (itemList.at(i)->zValue() >= 0 && itemList.at(i)->flags() & QGraphicsItem::ItemIsMovable) {
144             m_selectedItem = itemList.at(i);
145             // Rect
146             if (itemList.at(i)->type() == 3) {
147                 m_resizeMode = getResizeMode((QGraphicsRectItem*)m_selectedItem, m_view->mapFromScene(m_clickPoint));
148                 break;
149             }
150         }
151     }
152
153     QGraphicsScene::mousePressEvent(event);
154 }
155
156 void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
157 {
158     QPointF mousePos = event->scenePos();
159
160     if (m_selectedItem && event->buttons() & Qt::LeftButton) {
161         // Rect
162         if (m_selectedItem->type() == 3) {
163             QGraphicsRectItem *item = static_cast <QGraphicsRectItem *>(m_selectedItem);
164             QRectF rect = item->rect().normalized();
165             QPointF pos = item->pos();
166             QPointF mousePosInRect = item->mapFromScene(mousePos);
167             switch (m_resizeMode) {
168             case TopLeft:
169                 if (mousePos.x() < pos.x() + rect.height() && mousePos.y() < pos.y() + rect.height()) {
170                     item->setRect(rect.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
171                     item->setPos(mousePos);
172                 }
173                 break;
174             case Top:
175                 if (mousePos.y() < pos.y() + rect.height()) {
176                     rect.setBottom(rect.height() - mousePosInRect.y());
177                     item->setRect(rect);
178                     item->setPos(QPointF(pos.x(), mousePos.y()));
179                 }
180                 break;
181             case TopRight:
182                 if (mousePos.x() > pos.x() && mousePos.y() < pos.y() + rect.height()) {
183                     rect.setBottomRight(QPointF(mousePosInRect.x(), rect.bottom() - mousePosInRect.y()));
184                     item->setRect(rect);
185                     item->setPos(QPointF(pos.x(), mousePos.y()));
186                 }
187                 break;
188             case Left:
189                 if (mousePos.x() < pos.x() + rect.width()) {
190                     rect.setRight(rect.width() - mousePosInRect.x());
191                     item->setRect(rect);
192                     item->setPos(QPointF(mousePos.x(), pos.y()));
193                 }
194                 break;
195             case Right:
196                 if (mousePos.x() > pos.x()) {
197                     rect.setRight(mousePosInRect.x());
198                     item->setRect(rect);
199                 }
200                 break;
201             case BottomLeft:
202                 if (mousePos.x() < pos.x() + rect.width() && mousePos.y() > pos.y()) {
203                     rect.setBottomRight(QPointF(rect.width() - mousePosInRect.x(), mousePosInRect.y()));
204                     item->setRect(rect);
205                     item->setPos(QPointF(mousePos.x(), pos.y()));
206                 }
207                 break;
208             case Bottom:
209                 if (mousePos.y() > pos.y()) {
210                     rect.setBottom(mousePosInRect.y());
211                     item->setRect(rect);
212                 }
213                 break;
214             case BottomRight:
215                 if (mousePos.x() > pos.x() && mousePos.y() > pos.y()) {
216                     rect.setBottomRight(mousePosInRect);
217                     item->setRect(rect);
218                 }
219                 break;
220             default:
221                 QPointF diff = mousePos - m_clickPoint;
222                 m_clickPoint = mousePos;
223                 item->moveBy(diff.x(), diff.y());
224                 break;
225             }
226         }
227     } else {
228         mousePos -= QPoint(4, 4);
229         bool itemFound = false;
230         QList<QGraphicsItem *> itemList = items(QRectF(mousePos, QSizeF(4, 4)).toRect());
231
232         foreach (const QGraphicsItem* item, itemList) {
233             if (item->zValue() >= 0 && item->flags() &QGraphicsItem::ItemIsMovable) {
234                 // Rect
235                 if (item->type() == 3) {
236                     if (m_view == NULL)
237                         continue;
238
239                     itemFound = true;
240
241                     switch (getResizeMode((QGraphicsRectItem*)item, m_view->mapFromScene(event->scenePos()))) {
242                     case TopLeft:
243                     case BottomRight:
244                         m_view->setCursor(Qt::SizeFDiagCursor);
245                         break;
246                     case TopRight:
247                     case BottomLeft:
248                         m_view->setCursor(Qt::SizeBDiagCursor);
249                         break;
250                     case Top:
251                     case Bottom:
252                         m_view->setCursor(Qt::SizeVerCursor);
253                         break;
254                     case Left:
255                     case Right:
256                         m_view->setCursor(Qt::SizeHorCursor);
257                         break;
258                     default:
259                         m_view->setCursor(Qt::OpenHandCursor);
260                     }
261                     break;
262                 }
263             }
264         }
265
266         if (!itemFound && m_view != NULL)
267             m_view->setCursor(Qt::ArrowCursor);
268
269         QGraphicsScene::mouseMoveEvent(event);
270     }
271 }
272
273 void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
274 {
275     QGraphicsScene::mouseReleaseEvent(event);
276     emit actionFinished();
277 }
278
279 #include "monitorscene.moc"