##// END OF EJS Templates
fixed mouse event delta handling
sauimone -
r2188:ad6cfe65c3e1
parent child
Show More
@@ -1,195 +1,199
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include <QPainter>
22 22 #include <QGraphicsSceneEvent>
23 23 #include <QGraphicsSimpleTextItem>
24 24 #include <QDebug>
25 25
26 26 #include "qlegend.h"
27 27 #include "qlegend_p.h"
28 28 #include "qlegendmarker.h"
29 29 #include "qlegendmarker_p.h"
30 30 #include "legendmarkeritem_p.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 LegendMarkerItem::LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent) :
35 35 QGraphicsObject(parent),
36 36 m_marker(marker),
37 37 m_markerRect(0,0,10.0,10.0),
38 38 m_boundingRect(0,0,0,0),
39 39 m_textItem(new QGraphicsSimpleTextItem(this)),
40 40 m_rectItem(new QGraphicsRectItem(this)),
41 41 m_margin(4),
42 42 m_space(4)
43 43 {
44 44 m_rectItem->setRect(m_markerRect);
45 45 }
46 46
47 47 void LegendMarkerItem::setPen(const QPen &pen)
48 48 {
49 49 m_rectItem->setPen(pen);
50 50 }
51 51
52 52 QPen LegendMarkerItem::pen() const
53 53 {
54 54 return m_rectItem->pen();
55 55 }
56 56
57 57 void LegendMarkerItem::setBrush(const QBrush &brush)
58 58 {
59 59 m_rectItem->setBrush(brush);
60 60 }
61 61
62 62 QBrush LegendMarkerItem::brush() const
63 63 {
64 64 return m_rectItem->brush();
65 65 }
66 66
67 67 void LegendMarkerItem::setFont(const QFont &font)
68 68 {
69 69 m_textItem->setFont(font);
70 70 QFontMetrics fn(font);
71 71 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
72 72 updateGeometry();
73 73 }
74 74
75 75 QFont LegendMarkerItem::font() const
76 76 {
77 77 return m_textItem->font();
78 78 }
79 79
80 80 void LegendMarkerItem::setLabel(const QString label)
81 81 {
82 82 m_label = label;
83 83 updateGeometry();
84 84 }
85 85
86 86 QString LegendMarkerItem::label() const
87 87 {
88 88 return m_label;
89 89 }
90 90
91 91 void LegendMarkerItem::setLabelBrush(const QBrush &brush)
92 92 {
93 93 m_textItem->setBrush(brush);
94 94 }
95 95
96 96 QBrush LegendMarkerItem::labelBrush() const
97 97 {
98 98 return m_textItem->brush();
99 99 }
100 100
101 101 void LegendMarkerItem::setGeometry(const QRectF& rect)
102 102 {
103 103 QFontMetrics fn (m_font);
104 104
105 105 int width = rect.width();
106 106 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
107 107 qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin);
108 108
109 109 if (fn.boundingRect(m_label).width() + x > width)
110 110 {
111 111 QString string = m_label + "...";
112 112 while(fn.boundingRect(string).width() + x > width && string.length() > 3)
113 113 string.remove(string.length() - 4, 1);
114 114 m_textItem->setText(string);
115 115 }
116 116 else
117 117 m_textItem->setText(m_label);
118 118
119 119 const QRectF& textRect = m_textItem->boundingRect();
120 120
121 121
122 122 m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2);
123 123 m_rectItem->setRect(m_markerRect);
124 124 m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2);
125 125
126 126 prepareGeometryChange();
127 127 m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
128 128 }
129 129
130 130 QRectF LegendMarkerItem::boundingRect() const
131 131 {
132 132 return m_boundingRect;
133 133 }
134 134
135 135 void LegendMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
136 136 {
137 137 Q_UNUSED(option)
138 138 Q_UNUSED(widget)
139 139 Q_UNUSED(painter)
140 140 }
141 141
142 142 QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
143 143 {
144 144 Q_UNUSED(constraint)
145 145
146 146 QFontMetrics fn(m_textItem->font());
147 147 QSizeF sh;
148 148
149 149 switch (which) {
150 150 case Qt::MinimumSize:
151 151 sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
152 152 break;
153 153 case Qt::PreferredSize:
154 154 sh = QSizeF(fn.boundingRect(m_label).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
155 155 break;
156 156 default:
157 157 break;
158 158 }
159 159
160 160 return sh;
161 161 }
162 162
163 163 void LegendMarkerItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
164 164 {
165 165 MouseEventHandler::handleMousePressEvent(event);
166 166 }
167 167
168 168 void LegendMarkerItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
169 169 {
170 170 MouseEventHandler::handleMouseMoveEvent(event);
171 171 }
172 172
173 173 void LegendMarkerItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
174 174 {
175 175 MouseEventHandler::handleMouseReleaseEvent(event);
176 176 }
177 177
178 178 void LegendMarkerItem::mouseClicked()
179 179 {
180 180 emit m_marker->q_func()->clicked();
181 181 }
182 182
183 183 void LegendMarkerItem::mouseMoved(QPointF delta)
184 184 {
185 m_marker->m_legend->d_ptr->setOffset(-delta.x(), -delta.y());
185 qreal dx = m_marker->m_legend->d_ptr->offset().x() - delta.x();
186 qreal dy = m_marker->m_legend->d_ptr->offset().y() - delta.y();
187 m_marker->m_legend->d_ptr->setOffset(dx, dy);
186 188 }
187 189
188 190 void LegendMarkerItem::mouseReleased(QPointF delta)
189 191 {
190 m_marker->m_legend->d_ptr->setOffset(-delta.x(), -delta.y());
192 qreal dx = m_marker->m_legend->d_ptr->offset().x() - delta.x();
193 qreal dy = m_marker->m_legend->d_ptr->offset().y() - delta.y();
194 m_marker->m_legend->d_ptr->setOffset(dx, dy);
191 195 }
192 196
193 197 #include "moc_legendmarkeritem_p.cpp"
194 198
195 199 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,104 +1,107
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "mouseeventhandler_p.h"
22 22 #include <QGraphicsSceneMouseEvent>
23 23
24 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 25
26 26 MouseEventHandler::MouseEventHandler() :
27 m_pressedPos(0,0),
27 m_lastPos(0,0),
28 28 m_state(Idle),
29 29 m_treshold(10)
30 30 {
31 31 }
32 32
33 33 MouseEventHandler::~MouseEventHandler()
34 34 {
35 35 }
36 36
37 37 void MouseEventHandler::setMoveTreshold(qreal treshold)
38 38 {
39 39 m_treshold = treshold;
40 40 }
41 41
42 42 void MouseEventHandler::handleMousePressEvent(QGraphicsSceneMouseEvent* event)
43 43 {
44 m_pressedPos = event->pos();
44 m_lastPos = event->screenPos();
45 45 m_state = Pressed;
46 46 event->accept();
47 47 }
48 48
49 49 void MouseEventHandler::handleMouseMoveEvent(QGraphicsSceneMouseEvent* event)
50 50 {
51 QPointF delta = event->pos() - m_pressedPos;
51 QPointF delta = event->screenPos() - m_lastPos;
52 52
53 53 switch (m_state) {
54 54 case Pressed: {
55 55 // calculate treshold. If enough, change to move state and send out move deltas.
56 56 if (qAbs(delta.x()) > m_treshold || qAbs(delta.y()) > m_treshold) {
57 57 m_state = Moved;
58 m_lastPos = event->screenPos();
58 59 mouseMoved(delta);
59 60 }
60 61 event->accept();
61 62 break;
62 63 }
63 64 case Moved: {
65 m_lastPos = event->screenPos();
64 66 mouseMoved(delta);
65 67 event->accept();
66 68 break;
67 69 }
68 70 case Idle:
69 71 default: {
70 72 event->ignore();
71 73 break;
72 74 }
73 75 }
74 76 }
75 77
76 78 void MouseEventHandler::handleMouseReleaseEvent(QGraphicsSceneMouseEvent* event)
77 79 {
78 QPointF delta = event->pos() - m_pressedPos;
80 QPointF delta = event->screenPos() - m_lastPos;
81 m_lastPos = event->screenPos();
79 82
80 83 switch (m_state) {
81 84 case Pressed:
82 85 {
83 86 m_state = Idle;
84 87 mouseClicked();
85 88 event->accept();
86 89 break;
87 90 }
88 91 case Moved:
89 92 {
90 93 m_state = Idle;
91 94 mouseReleased(delta);
92 95 event->accept();
93 96 break;
94 97 }
95 98 default:
96 99 {
97 100 m_state = Idle;
98 101 event->ignore();
99 102 break;
100 103 }
101 104 }
102 105 }
103 106
104 107 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,89 +1,89
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 /*
31 31 Purpose of this class is to resolve what happens during MousePress - MouseMove - MouseRelease event chain.
32 32 Threre can be many MouseMove events and if they all are below our treshold, the result is clicked call.
33 33 If any move event goes over treshold, result will be many moved(QPointF delta) calls,
34 34 where delta is calculated from original position.
35 35
36 36 Reason for this is, that legend marker don't know when it should emit clicked and when it should
37 37 allow legend to scroll. We only get this information when some move goes beyond treshold, but
38 38 then it will be too late to let the scroller handle events, because marker is already handling.
39 39
40 40 By handling clicked calls in markers and moved calls in scroller, the problem is solved.
41 41 Derived class descides, should the virtual method be implemented as signal or not.
42 42
43 43 This could be implemented in LegendMarkerItem, but this way the code is reusable and in one place only.
44 44 */
45 45
46 46 #ifndef MOUSEEVENTHANDLER_H
47 47 #define MOUSEEVENTHANDLER_H
48 48
49 49 #include "qchartglobal.h"
50 50 #include <QBasicTimer>
51 51 #include <QTime>
52 52 #include <QPointF>
53 53
54 54 class QGraphicsSceneMouseEvent;
55 55
56 56 QTCOMMERCIALCHART_BEGIN_NAMESPACE
57 57
58 58 class MouseEventHandler
59 59 {
60 60 public:
61 61 enum State {
62 62 Idle,
63 63 Pressed,
64 64 Moved,
65 65 Released
66 66 };
67 67
68 68 MouseEventHandler();
69 69 virtual ~MouseEventHandler();
70 70
71 71 void setMoveTreshold(qreal treshold);
72 72
73 73 virtual void mouseClicked() = 0;
74 74 virtual void mouseMoved(QPointF delta) = 0;
75 75 virtual void mouseReleased(QPointF delta) = 0;
76 76
77 77 void handleMousePressEvent(QGraphicsSceneMouseEvent* event);
78 78 void handleMouseMoveEvent(QGraphicsSceneMouseEvent* event);
79 79 void handleMouseReleaseEvent(QGraphicsSceneMouseEvent* event);
80 80
81 81 private:
82 QPointF m_pressedPos;
82 QPointF m_lastPos;
83 83 State m_state;
84 84 qreal m_treshold;
85 85 };
86 86
87 87 QTCOMMERCIALCHART_END_NAMESPACE
88 88
89 89 #endif // MOUSEEVENTHANDLER_H
General Comments 0
You need to be logged in to leave comments. Login now