]> git.sesse.net Git - kdenlive/blob - src/onmonitoritems/rotoscoping/bpointitem.cpp
a91cc22815029708d27603bc4ef6f039f5b3fe96
[kdenlive] / src / onmonitoritems / rotoscoping / bpointitem.cpp
1 /***************************************************************************
2  *   Copyright (C) 2011 by Till Theato (root@ttill.de)                     *
3  *   This file is part of Kdenlive (www.kdenlive.org).                     *
4  *                                                                         *
5  *   Kdenlive 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  *   Kdenlive 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 Kdenlive.  If not, see <http://www.gnu.org/licenses/>.     *
17  ***************************************************************************/
18
19 #include "bpointitem.h"
20 #include "splineitem.h"
21
22 #include <QPainter>
23 #include <QGraphicsSceneMouseEvent>
24 #include <QCursor>
25 #include <QGraphicsScene>
26 #include <QGraphicsView>
27
28
29 BPointItem::BPointItem(const BPoint &point, QGraphicsItem* parent) :
30         QAbstractGraphicsShapeItem(parent),
31         m_selection(-1)
32 {
33     setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
34
35     setAcceptHoverEvents(true);
36
37     setPos(point.p);
38     m_point.h1 = mapFromScene(point.h1);
39     m_point.p = mapFromScene(point.p);
40     m_point.h2 = mapFromScene(point.h2);
41     m_point.handlesLinked = false;
42
43     m_view = scene()->views()[0];
44 }
45
46 BPoint BPointItem::getPoint() const
47 {
48     return BPoint(mapToScene(m_point.h1), mapToScene(m_point.p), mapToScene(m_point.h2));
49 }
50
51 void BPointItem::setPoint(const BPoint &point)
52 {
53     setPos(point.p);
54     prepareGeometryChange();
55     m_point.h1 = mapFromScene(point.h1);
56     m_point.p = mapFromScene(point.p);
57     m_point.h2 = mapFromScene(point.h2);
58 }
59
60 int BPointItem::type() const
61 {
62     return Type;
63 }
64
65 QRectF BPointItem::boundingRect() const
66 {
67     QPolygonF p = QPolygonF() << m_point.h1 << m_point.p << m_point.h2;
68     return p.boundingRect().adjusted(-6, -6, 6, 6);
69 }
70
71 void BPointItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
72 {
73     Q_UNUSED(option)
74     Q_UNUSED(widget)
75
76     if (isEnabled()) {
77         painter->setPen(QPen(Qt::yellow, 1, Qt::SolidLine));
78         painter->setBrush(QBrush(isSelected() ? Qt::red : Qt::yellow));
79     } else {
80         painter->setPen(QPen(Qt::gray, 1, Qt::SolidLine));
81         painter->setBrush(QBrush(Qt::gray));
82     }
83     painter->setRenderHint(QPainter::Antialiasing);
84
85     double handleSize = 6 / painter->worldTransform().m11();
86     double handleSizeHalf = handleSize / 2;
87
88     QPolygonF handle = QPolygonF() << QPointF(0, -handleSizeHalf) << QPointF(handleSizeHalf, 0) << QPointF(0, handleSizeHalf) << QPointF(-handleSizeHalf, 0);
89
90     painter->drawLine(m_point.h1, m_point.p);
91     painter->drawLine(m_point.p, m_point.h2);
92
93 #if QT_VERSION >= 0x040600
94     painter->drawConvexPolygon(handle.translated(m_point.h1.x(), m_point.h1.y()));
95     painter->drawConvexPolygon(handle.translated(m_point.h2.x(), m_point.h2.y()));
96 #else
97     QPolygonF tmp;
98     tmp = handle;
99     tmp.translate(m_point.h1.x(), m_point.h1.y());
100     painter->drawConvexPolygon(tmp);
101     tmp = handle;
102     tmp.translate(m_point.h2.x(), m_point.h2.y());
103     painter->drawConvexPolygon(tmp);
104 #endif
105
106     painter->drawEllipse(QRectF(m_point.p.x() - handleSizeHalf,
107                                 m_point.p.y() - handleSizeHalf, handleSize, handleSize));
108 }
109
110 int BPointItem::getSelection(const QPointF &pos)
111 {
112     QList <qreal> d;
113     d << QLineF(pos, m_point.h1).length() << QLineF(pos, m_point.p).length() << QLineF(pos, m_point.h2).length();
114     // index of point nearest to pos
115     int i = ( d[1] < d[0] && d[1] < d[2]) ? 1 : (d[0] < d[2] ? 0 : 2);
116
117     if (d[i] < 6 / m_view->matrix().m11())
118         return i;
119
120     return -1;
121 }
122
123 void BPointItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
124 {
125     m_selection = getSelection(event->pos());
126
127     if (m_selection < 0) {
128         event->ignore();
129         setSelected(false);
130     } else {
131         if (event->button() == Qt::RightButton && m_selection == 1) {
132             SplineItem *parent = qgraphicsitem_cast<SplineItem*>(parentItem());
133             if (parent) {
134                 parent->removeChild(this);
135                 return;
136             }
137         }
138         setSelected(true);
139     }
140 }
141
142 void BPointItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
143 {
144     prepareGeometryChange();
145     switch (m_selection) {
146     case 0:
147         m_point.setH1(event->pos());
148         break;
149     case 1:
150         m_point.setP(event->pos());
151         break;
152     case 2:
153         m_point.setH2(event->pos());
154         break;
155     }
156
157     if (parentItem()) {
158         SplineItem *parent = qgraphicsitem_cast<SplineItem*>(parentItem());
159         if (parent)
160             parent->updateSpline(true);
161     }
162 }
163
164 void BPointItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
165 {
166     if (parentItem()) {
167         SplineItem *parent = qgraphicsitem_cast<SplineItem*>(parentItem());
168         if (parent)
169             parent->updateSpline(false);
170     }
171     QGraphicsItem::mouseReleaseEvent(event);
172 }
173
174 void BPointItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
175 {
176     if (getSelection(event->pos()) < 0)
177         unsetCursor();
178     else
179         setCursor(QCursor(Qt::PointingHandCursor));
180 }