]> git.sesse.net Git - kdenlive/blob - src/graphicsscenerectmove.cpp
897902d9dd1e89cdfed97a0c89b01fe9f7e9fa3a
[kdenlive] / src / graphicsscenerectmove.cpp
1
2 #include <KDebug>
3 #include <QGraphicsSceneMouseEvent>
4 #include <QGraphicsRectItem>
5 #include <QGraphicsSvgItem>
6 #include <QGraphicsView>
7 #include <QCursor>
8 #include <QList>
9 #include <QKeyEvent>
10 #include <QApplication>
11
12 #include "graphicsscenerectmove.h"
13
14 GraphicsSceneRectMove::GraphicsSceneRectMove(QObject *parent): QGraphicsScene(parent), m_selectedItem(NULL), resizeMode(NoResize), m_tool(TITLE_RECTANGLE) {
15     //grabMouse();
16     zoom = 1.0;
17     setBackgroundBrush(QBrush(QColor(0, 0, 0, 0)));
18 }
19
20 void GraphicsSceneRectMove::setSelectedItem(QGraphicsItem *item) {
21     clearSelection();
22     m_selectedItem = item;
23     item->setSelected(true);
24     update();
25 }
26
27 TITLETOOL GraphicsSceneRectMove::tool() {
28     return m_tool;
29 }
30
31 void GraphicsSceneRectMove::setTool(TITLETOOL tool) {
32     m_tool = tool;
33     switch (m_tool) {
34     case TITLE_RECTANGLE:
35         setCursor(Qt::CrossCursor);
36         break;
37     case TITLE_TEXT:
38         setCursor(Qt::IBeamCursor);
39         break;
40     default:
41         setCursor(Qt::ArrowCursor);
42     }
43 }
44
45 //virtual
46 void GraphicsSceneRectMove::keyPressEvent(QKeyEvent * keyEvent) {
47     if (m_selectedItem == NULL) {
48         QGraphicsScene::keyPressEvent(keyEvent);
49         return;
50     }
51     int diff = 1;
52     if (m_selectedItem->type() == 8) {
53         QGraphicsTextItem *t = static_cast<QGraphicsTextItem *>(m_selectedItem);
54         if (t->textInteractionFlags() & Qt::TextEditorInteraction) {
55             QGraphicsScene::keyPressEvent(keyEvent);
56             return;
57         }
58     }
59     if (keyEvent->modifiers() & Qt::ControlModifier) diff = 10;
60     switch (keyEvent->key()) {
61     case Qt::Key_Left:
62         m_selectedItem->setPos(m_selectedItem->pos() - QPointF(diff, 0));
63         emit itemMoved();
64         break;
65     case Qt::Key_Right:
66         m_selectedItem->setPos(m_selectedItem->pos() + QPointF(diff, 0));
67         emit itemMoved();
68         break;
69     case Qt::Key_Up:
70         m_selectedItem->setPos(m_selectedItem->pos() - QPointF(0, diff));
71         emit itemMoved();
72         break;
73     case Qt::Key_Down:
74         m_selectedItem->setPos(m_selectedItem->pos() + QPointF(0, diff));
75         emit itemMoved();
76         break;
77     case Qt::Key_Delete:
78     case Qt::Key_Backspace:
79         delete m_selectedItem;
80         m_selectedItem = NULL;
81         emit selectionChanged();
82         break;
83     default:
84         QGraphicsScene::keyPressEvent(keyEvent);
85     }
86 }
87
88 //virtual
89 void GraphicsSceneRectMove::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* e) {
90     QPointF p = e->scenePos();
91     p += QPoint(-2, -2);
92     resizeMode = NoResize;
93     m_selectedItem = NULL;
94     QGraphicsItem* g = items(QRectF(p , QSizeF(4, 4)).toRect()).at(0);
95     if (g) {
96         if (g->type() == 8) {
97             QGraphicsTextItem *t = static_cast<QGraphicsTextItem *>(g);
98             t->setTextInteractionFlags(Qt::TextEditorInteraction);
99         }
100     }
101     QGraphicsScene::mouseDoubleClickEvent(e);
102 }
103
104 void GraphicsSceneRectMove::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
105     if (m_tool == TITLE_RECTANGLE && m_selectedItem) setSelectedItem(m_selectedItem);
106     emit actionFinished();
107     QGraphicsScene::mouseReleaseEvent(e);
108 }
109
110 void GraphicsSceneRectMove::mousePressEvent(QGraphicsSceneMouseEvent* e) {
111     QPointF p = e->scenePos();
112     p += QPoint(-2, -2);
113     resizeMode = NoResize;
114     const QList <QGraphicsItem *> list = items(QRectF(p , QSizeF(4, 4)).toRect());
115     QGraphicsItem *item = NULL;
116     bool hasSelected = false;
117
118     if (m_tool == TITLE_SELECT) {
119         foreach(QGraphicsItem *g, list) {
120             kDebug() << " - - CHECKING ITEM Z:" << g->zValue() << ", TYPE: " << g->type();
121             // check is there is a selected item in list
122             if (g->zValue() > -1000 && g->isSelected()) {
123                 hasSelected = true;
124                 item = g;
125                 break;
126             }
127         }
128         if (item == NULL) {
129             if (m_selectedItem && m_selectedItem->type() == 8) {
130                 // disable text editing
131                 QGraphicsTextItem *t = static_cast<QGraphicsTextItem *>(m_selectedItem);
132                 t->setTextInteractionFlags(Qt::NoTextInteraction);
133             }
134             m_selectedItem = NULL;
135             foreach(QGraphicsItem* g, list) {
136                 if (g->zValue() > -1000) {
137                     item = g;
138                     break;
139                 }
140             }
141         }
142         if (item != NULL) {
143             m_clickPoint = e->scenePos();
144             m_selectedItem = item;
145             kDebug() << "/////////  ITEM TYPE: " << item->type();
146             if (item->type() == 8) {
147                 QGraphicsTextItem *t = static_cast<QGraphicsTextItem *>(item);
148                 if (t->textInteractionFlags() == Qt::TextEditorInteraction) {
149                     QGraphicsScene::mousePressEvent(e);
150                     return;
151                 }
152                 t->setTextInteractionFlags(Qt::NoTextInteraction);
153                 setCursor(Qt::ClosedHandCursor);
154             } else if (item->type() == 3 || item->type() == 13 || item->type() == 7) {
155                 QRectF r;
156                 if (m_selectedItem->type() == 3) {
157                     r = ((QGraphicsRectItem*)m_selectedItem)->rect();
158                 } else r = m_selectedItem->boundingRect();
159
160                 r.translate(item->scenePos());
161                 if ((r.toRect().topLeft() - e->scenePos().toPoint()).manhattanLength() < 6 / zoom) {
162                     resizeMode = TopLeft;
163                 } else if ((r.toRect().bottomLeft() - e->scenePos().toPoint()).manhattanLength() < 6 / zoom) {
164                     resizeMode = BottomLeft;
165                 } else if ((r.toRect().topRight() - e->scenePos().toPoint()).manhattanLength() < 6 / zoom) {
166                     resizeMode = TopRight;
167                 } else if ((r.toRect().bottomRight() - e->scenePos().toPoint()).manhattanLength() < 6 / zoom) {
168                     resizeMode = BottomRight;
169                 } else if (qAbs(r.toRect().left() - e->scenePos().toPoint().x()) < 3 / zoom) {
170                     resizeMode = Left;
171                 } else if (qAbs(r.toRect().right() - e->scenePos().toPoint().x()) < 3 / zoom) {
172                     resizeMode = Right;
173                 } else if (qAbs(r.toRect().top() - e->scenePos().toPoint().y()) < 3 / zoom) {
174                     resizeMode = Up;
175                 } else if (qAbs(r.toRect().bottom() - e->scenePos().toPoint().y()) < 3 / zoom) {
176                     resizeMode = Down;
177                 } else setCursor(Qt::ClosedHandCursor);
178             }
179         }
180         QGraphicsScene::mousePressEvent(e);
181     } else if (m_tool == TITLE_RECTANGLE) {
182         m_clickPoint = e->scenePos();
183         m_selectedItem = NULL;
184     } else if (m_tool == TITLE_TEXT) {
185         m_selectedItem = addText(QString());
186         emit newText((QGraphicsTextItem *) m_selectedItem);
187         m_selectedItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
188         ((QGraphicsTextItem *)m_selectedItem)->setTextInteractionFlags(Qt::TextEditorInteraction);
189         m_selectedItem->setPos(e->scenePos());
190         QGraphicsScene::mousePressEvent(e);
191     }
192
193     kDebug() << "//////  MOUSE CLICK, RESIZE MODE: " << resizeMode;
194
195 }
196
197
198 //virtual
199 void GraphicsSceneRectMove::mouseMoveEvent(QGraphicsSceneMouseEvent* e) {
200
201     if (m_selectedItem && e->buttons() & Qt::LeftButton) {
202         if (m_selectedItem->type() == 3 || m_selectedItem->type() == 13 || m_selectedItem->type() == 7) {
203             QRectF newrect;
204             if (m_selectedItem->type() == 3) {
205                 newrect = ((QGraphicsRectItem*)m_selectedItem)->rect();
206             } else newrect = m_selectedItem->boundingRect();
207
208             QPointF newpoint = e->scenePos();
209             //newpoint -= m_selectedItem->scenePos();
210             switch (resizeMode) {
211             case TopLeft:
212                 newrect.setBottomRight(newrect.bottomRight() + m_selectedItem->pos() - newpoint);
213                 m_selectedItem->setPos(newpoint);
214                 break;
215             case BottomLeft:
216                 newrect.setBottomRight(QPointF(newrect.bottomRight().x() + m_selectedItem->pos().x() - newpoint.x(), newpoint.y() - m_selectedItem->pos().y()));
217                 m_selectedItem->setPos(QPointF(newpoint.x(), m_selectedItem->pos().y()));
218                 break;
219             case TopRight:
220                 newrect.setBottomRight(QPointF(newpoint.x() - m_selectedItem->pos().x(), newrect.bottom() + m_selectedItem->pos().y() - newpoint.y()));
221                 m_selectedItem->setPos(QPointF(m_selectedItem->pos().x(), newpoint.y()));
222                 break;
223             case BottomRight:
224                 newrect.setBottomRight(newpoint - m_selectedItem->pos());
225                 break;
226             case Left:
227                 newrect.setRight(m_selectedItem->pos().x() + newrect.width() - newpoint.x());
228                 m_selectedItem->setPos(QPointF(newpoint.x(), m_selectedItem->pos().y()));
229                 break;
230             case Right:
231                 newrect.setRight(newpoint.x() - m_selectedItem->pos().x());
232                 break;
233             case Up:
234                 newrect.setBottom(m_selectedItem->pos().y() + newrect.bottom() - newpoint.y());
235                 m_selectedItem->setPos(QPointF(m_selectedItem->pos().x(), newpoint.y()));
236                 break;
237             case Down:
238                 newrect.setBottom(newpoint.y() - m_selectedItem->pos().y());
239                 break;
240             default:
241                 QPointF diff = e->scenePos() - m_clickPoint;
242                 m_clickPoint = e->scenePos();
243                 m_selectedItem->moveBy(diff.x(), diff.y());
244                 break;
245             }
246             if (m_selectedItem->type() == 3 && resizeMode != NoResize) {
247                 QGraphicsRectItem *gi = (QGraphicsRectItem*)m_selectedItem;
248                 gi->setRect(newrect);
249             }
250             /*else {
251             qreal s;
252             if (resizeMode == Left || resizeMode == Right ) s = m_selectedItem->boundingRect().width() / newrect.width();
253             else s = m_selectedItem->boundingRect().height() / newrect.height();
254             m_selectedItem->scale( 1 / s, 1 / s );
255             kDebug()<<"/// SCALING SVG, RESIZE MODE: "<<resizeMode<<", RECT:"<<m_selectedItem->boundingRect();
256             }*/
257             //gi->setPos(m_selectedItem->scenePos());
258             /*if (resizeMode == NoResize) {
259                 QGraphicsScene::mouseMoveEvent(e);
260                 return;
261             }*/
262         } else if (m_selectedItem->type() == 8) {
263             QGraphicsTextItem *t = static_cast<QGraphicsTextItem *>(m_selectedItem);
264             if (t->textInteractionFlags() & Qt::TextEditorInteraction) {
265                 QGraphicsScene::mouseMoveEvent(e);
266                 return;
267             }
268             QPointF diff = e->scenePos() - m_clickPoint;
269             m_clickPoint = e->scenePos();
270             m_selectedItem->moveBy(diff.x(), diff.y());
271         }
272         emit itemMoved();
273     } else if (m_tool == TITLE_SELECT) {
274
275         QPointF p = e->scenePos();
276         p += QPoint(-2, -2);
277         resizeMode = NoResize;
278         bool itemFound = false;
279         foreach(const QGraphicsItem* g, items(QRectF(p , QSizeF(4, 4)).toRect())) {
280             if ((g->type() == 13 || g->type() == 7) && g->zValue() > -1000) {
281                 // image or svg item
282                 setCursor(Qt::OpenHandCursor);
283                 break;
284             } else if (g->type() == 3 && g->zValue() > -1000) {
285                 QRectF r = ((QGraphicsRectItem*)g)->rect();
286                 r.translate(g->scenePos());
287                 itemFound = true;
288                 if ((r.toRect().topLeft() - e->scenePos().toPoint()).manhattanLength() < 6 / zoom) {
289                     setCursor(QCursor(Qt::SizeFDiagCursor));
290                 } else if ((r.toRect().bottomLeft() - e->scenePos().toPoint()).manhattanLength() < 6 / zoom) {
291                     setCursor(QCursor(Qt::SizeBDiagCursor));
292                 } else if ((r.toRect().topRight() - e->scenePos().toPoint()).manhattanLength() < 6 / zoom) {
293                     setCursor(QCursor(Qt::SizeBDiagCursor));
294                 } else if ((r.toRect().bottomRight() - e->scenePos().toPoint()).manhattanLength() < 6 / zoom) {
295                     setCursor(QCursor(Qt::SizeFDiagCursor));
296                 } else if (qAbs(r.toRect().left() - e->scenePos().toPoint().x()) < 3 / zoom) {
297                     setCursor(Qt::SizeHorCursor);
298                 } else if (qAbs(r.toRect().right() - e->scenePos().toPoint().x()) < 3 / zoom) {
299                     setCursor(Qt::SizeHorCursor);
300                 } else if (qAbs(r.toRect().top() - e->scenePos().toPoint().y()) < 3 / zoom) {
301                     setCursor(Qt::SizeVerCursor);
302                 } else if (qAbs(r.toRect().bottom() - e->scenePos().toPoint().y()) < 3 / zoom) {
303                     setCursor(Qt::SizeVerCursor);
304                 } else setCursor(Qt::OpenHandCursor);
305                 break;
306             }
307             if (!itemFound) setCursor(Qt::ArrowCursor);
308         }
309         QGraphicsScene::mouseMoveEvent(e);
310     } else if (m_tool == TITLE_RECTANGLE && e->buttons() & Qt::LeftButton) {
311         if (m_selectedItem == NULL && (m_clickPoint.toPoint() - e->scenePos().toPoint()).manhattanLength() >= QApplication::startDragDistance()) {
312             // create new rect item
313             m_selectedItem = addRect(0, 0, e->scenePos().x() - m_clickPoint.x(), e->scenePos().y() - m_clickPoint.y());
314             emit newRect((QGraphicsRectItem *) m_selectedItem);
315             m_selectedItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
316             m_selectedItem->setPos(m_clickPoint);
317             resizeMode = BottomRight;
318             QGraphicsScene::mouseMoveEvent(e);
319         }
320     }
321 }
322
323 void GraphicsSceneRectMove::wheelEvent(QGraphicsSceneWheelEvent * wheelEvent) {
324     QList<QGraphicsView*> viewlist = views();
325     //kDebug() << wheelEvent->delta() << " " << zoom;
326     double scale = 1.0;
327     if (viewlist.size() > 0) {
328         if (wheelEvent->delta() < 0) emit sceneZoom(true);
329         else emit sceneZoom(false);
330     }
331 }
332
333 void GraphicsSceneRectMove::setScale(double s) {
334     if (zoom < 1.0 / 7.0 && s < 1.0) return;
335     else if (zoom > 10.0 / 7.9 && s > 1.0) return;
336     QList<QGraphicsView*> viewlist = views();
337     if (viewlist.size() > 0) {
338         viewlist[0]->scale(s, s);
339         zoom = zoom * s;
340     }
341     //kDebug()<<"//////////  ZOOM: "<<zoom;
342 }
343
344 void GraphicsSceneRectMove::setZoom(double s) {
345     QList<QGraphicsView*> viewlist = views();
346     if (viewlist.size() > 0) {
347         viewlist[0]->resetTransform();
348         viewlist[0]->scale(s, s);
349         zoom = s;
350     }
351
352     //kDebug()<<"//////////  ZOOM: "<<zoom;
353 }
354
355 void GraphicsSceneRectMove::setCursor(QCursor c) {
356     const QList<QGraphicsView*> l = views();
357     foreach(QGraphicsView* v, l) {
358         v->setCursor(c);
359     }
360 }