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