]> git.sesse.net Git - kdenlive/blob - src/monitorscene.cpp
8970d82a5a28345c4c23f4e1800ebb56e299df3e
[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 "onmonitoritems/rotoscoping/bpointitem.h"
24 #include "onmonitoritems/rotoscoping/splineitem.h"
25 #include "kdenlivesettings.h"
26
27 #include <QGraphicsView>
28 #include <QGraphicsPixmapItem>
29 #include <QGraphicsSceneMouseEvent>
30 #include <QScrollBar>
31
32
33 MonitorScene::MonitorScene(Render *renderer, QObject* parent) :
34         QGraphicsScene(parent),
35         m_renderer(renderer),
36         m_view(NULL),
37         m_backgroundImage(QImage()),
38         m_enabled(true),
39         m_zoom(1.0),
40         m_groupMove(false)
41 {
42     setBackgroundBrush(QBrush(QColor(KdenliveSettings::window_background().name())));
43
44     QPen framepen(Qt::DotLine);
45     framepen.setColor(Qt::red);
46
47     m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_renderer->frameRenderWidth(), m_renderer->renderHeight()));
48     m_frameBorder->setPen(framepen);
49     m_frameBorder->setZValue(-1);
50     m_frameBorder->setBrush(Qt::transparent);
51     m_frameBorder->setFlags(0);
52     addItem(m_frameBorder);
53
54     m_lastUpdate = QTime::currentTime();
55     m_background = new QGraphicsPixmapItem();
56     m_background->setZValue(-2);
57     m_background->setFlags(0);
58     m_background->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
59     m_background->setTransformationMode(Qt::FastTransformation);
60     QPixmap bg(m_renderer->frameRenderWidth(), m_renderer->renderHeight());
61     bg.fill();
62     m_background->setPixmap(bg);
63     addItem(m_background);
64
65     connect(m_renderer, SIGNAL(frameUpdated(QImage)), this, SLOT(slotSetBackgroundImage(QImage)));
66 }
67
68 void MonitorScene::setUp()
69 {
70     if (views().count() > 0) {
71         m_view = views().at(0);
72         m_view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
73     } else {
74         m_view = NULL;
75     }
76 }
77
78 void MonitorScene::resetProfile()
79 {
80     const QRectF border(0, 0, m_renderer->frameRenderWidth(), m_renderer->renderHeight());
81     m_frameBorder->setRect(border);
82 }
83
84 void MonitorScene::setEnabled(bool enabled)
85 {
86     m_enabled = enabled;
87 }
88
89 void MonitorScene::slotUpdateBackground()
90 {
91     if (m_view && m_view->isVisible()) {
92         if (m_lastUpdate.msecsTo(QTime::currentTime()) > 50) {
93             m_background->setPixmap(QPixmap::fromImage(m_backgroundImage));
94             m_lastUpdate = QTime::currentTime();
95         }
96     }
97 }
98
99 void MonitorScene::slotSetBackgroundImage(const QImage &image)
100 {
101     if (m_view && m_view->isVisible()) {
102         m_backgroundImage = image;
103         slotUpdateBackground();
104     }
105 }
106
107 void MonitorScene::slotZoom(int value)
108 {
109     if (m_view) {
110         m_zoom = value / 100.0;
111         m_view->resetTransform();
112         m_view->scale(m_renderer->renderWidth() * m_zoom / m_renderer->frameRenderWidth(), m_zoom);
113         emit zoomChanged(value);
114     }
115 }
116
117 void MonitorScene::slotZoomFit()
118 {
119     if (m_view) {
120         int xzoom = 100 * m_view->viewport()->height() / m_renderer->renderHeight();
121         int yzoom = 100 * m_view->viewport()->width() / m_renderer->renderWidth();
122         slotZoom(qMin(xzoom, yzoom));
123         m_view->centerOn(m_frameBorder);
124     }
125 }
126
127 void MonitorScene::slotZoomOriginal()
128 {
129     slotZoom(100);
130     if (m_view)
131         m_view->centerOn(m_frameBorder);
132 }
133
134 void MonitorScene::slotZoomOut(int by)
135 {
136     slotZoom(qMax(0, (int)(m_zoom * 100 - by)));
137 }
138
139 void MonitorScene::slotZoomIn(int by)
140 {
141     slotZoom(qMin(300, (int)(m_zoom * 100 + by + 0.5)));
142 }
143
144 void MonitorScene::mousePressEvent(QGraphicsSceneMouseEvent* event)
145 {
146     QList <QGraphicsItem *> selected = selectedItems();
147
148     QGraphicsScene::mousePressEvent(event);
149
150     if (selected.count() < selectedItems().count()) {
151         // mouse click on item not in selection group
152         // -> select only this item
153         foreach (QGraphicsItem *item, selected) {
154             if (item)
155                 item->setSelected(false);
156         }
157     }
158
159     if (event->isAccepted() && selectedItems().count() > 1) {
160         // multiple items selected + mouse pressed on an item
161         selected = selectedItems();
162         foreach (QGraphicsItem *item, selected) {
163             if (qgraphicsitem_cast<BPointItem*>(item)) {
164                 // works with rotoscoping only for now
165                 m_groupMove = true;
166                 m_lastPos = event->scenePos();
167                 return;
168             }
169         }
170     }
171
172     if (!event->isAccepted() && event->buttons() & Qt::LeftButton) {
173         if (event->modifiers() == Qt::ControlModifier)
174             m_view->setDragMode(QGraphicsView::ScrollHandDrag);
175         else if (event->modifiers() == Qt::ShiftModifier)
176             m_view->setDragMode(QGraphicsView::RubberBandDrag);
177     }
178 }
179
180 void MonitorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
181 {
182     if (m_groupMove) {
183         // we want to move multiple items
184         // rotoscoping only for now
185         QPointF diff =  event->scenePos() - m_lastPos;
186         if (diff != QPointF(0, 0)) {
187             m_lastPos = event->scenePos();
188             QList <QGraphicsItem *> selected = selectedItems();
189             int first = -1;
190             int i = 0;
191             foreach (QGraphicsItem *item, selected) {
192                 BPointItem *bpoint = qgraphicsitem_cast<BPointItem *>(item);
193                 if (bpoint) {
194                     if (first < 0)
195                         first = i;
196                     BPoint p = bpoint->getPoint();
197                     p.setP(p.p + diff);
198                     bpoint->setPoint(p);
199                 }
200                 ++i;
201             }
202
203             if (first >= 0) {
204                 QGraphicsItem *item = selected.at(first);
205                 if (item->parentItem()) {
206                     SplineItem *parent = qgraphicsitem_cast<SplineItem*>(item->parentItem());
207                     if (parent)
208                         parent->updateSpline(true);
209                 }
210             }
211         }
212     } else {
213         QGraphicsScene::mouseMoveEvent(event);
214     }
215 }
216
217 void MonitorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
218 {
219     if (m_groupMove) {
220         QList <QGraphicsItem *> selected = selectedItems();
221         foreach (QGraphicsItem *item, selected) {
222             if (qgraphicsitem_cast<BPointItem*>(item) && item->parentItem()) {
223                 SplineItem *parent = qgraphicsitem_cast<SplineItem*>(item->parentItem());
224                 if (parent) {
225                     parent->updateSpline(false);
226                     break;
227                 }
228             }
229         }
230         m_groupMove = false;
231     }
232     QGraphicsScene::mouseReleaseEvent(event);
233     m_view->setDragMode(QGraphicsView::NoDrag);
234 }
235 void MonitorScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
236 {
237     Q_UNUSED(event)
238
239     if (!m_enabled)
240         emit addKeyframe();
241 }
242
243 void MonitorScene::wheelEvent(QGraphicsSceneWheelEvent* event)
244 {
245     if (event->modifiers() == Qt::ControlModifier) {
246         if (event->delta() > 0) {
247             m_view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
248             slotZoomIn(5);
249             m_view->setTransformationAnchor(QGraphicsView::AnchorViewCenter);
250         } else {
251             slotZoomOut(5);
252         }
253     } else {
254         QAbstractSlider::SliderAction action;
255         if (event->delta() > 0)
256             action = QAbstractSlider::SliderSingleStepSub;
257         else
258             action = QAbstractSlider::SliderSingleStepAdd;
259         if (event->orientation() == Qt::Horizontal)
260             m_view->horizontalScrollBar()->triggerAction(action);
261         else
262             m_view->verticalScrollBar()->triggerAction(action);
263     }
264
265     event->accept();
266 }
267
268 #include "monitorscene.moc"