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