##// END OF EJS Templates
Fix mouse event interception by scatter chart....
Miikka Heikkinen -
r2747:31ef05db7ba9
parent child
Show More
@@ -1,252 +1,251
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and Digia.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 #include <private/scatterchartitem_p.h>
20 20 #include <QtCharts/QScatterSeries>
21 21 #include <private/qscatterseries_p.h>
22 22 #include <private/chartpresenter_p.h>
23 23 #include <private/abstractdomain_p.h>
24 24 #include <QtCharts/QChart>
25 25 #include <QtGui/QPainter>
26 26 #include <QtWidgets/QGraphicsScene>
27 27 #include <QtCore/QDebug>
28 28 #include <QtWidgets/QGraphicsSceneMouseEvent>
29 29
30 30 QT_CHARTS_BEGIN_NAMESPACE
31 31
32 32 ScatterChartItem::ScatterChartItem(QScatterSeries *series, QGraphicsItem *item)
33 33 : XYChart(series,item),
34 34 m_series(series),
35 35 m_items(this),
36 36 m_visible(true),
37 37 m_shape(QScatterSeries::MarkerShapeRectangle),
38 38 m_size(15),
39 39 m_pointLabelsVisible(false),
40 40 m_pointLabelsFormat(series->pointLabelsFormat()),
41 41 m_pointLabelsFont(series->pointLabelsFont()),
42 42 m_pointLabelsColor(series->pointLabelsColor()),
43 43 m_mousePressed(false)
44 44 {
45 45 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
46 46 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
47 47 QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
48 48 QObject::connect(series, SIGNAL(pointLabelsFormatChanged(QString)),
49 49 this, SLOT(handleUpdated()));
50 50 QObject::connect(series, SIGNAL(pointLabelsVisibilityChanged(bool)),
51 51 this, SLOT(handleUpdated()));
52 52 QObject::connect(series, SIGNAL(pointLabelsFontChanged(QFont)), this, SLOT(handleUpdated()));
53 53 QObject::connect(series, SIGNAL(pointLabelsColorChanged(QColor)), this, SLOT(handleUpdated()));
54 54
55 55 setZValue(ChartPresenter::ScatterSeriesZValue);
56 56 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
57 setFlag(QGraphicsItem::ItemIsSelectable);
58 57
59 58 handleUpdated();
60 59
61 60 m_items.setHandlesChildEvents(false);
62 61 }
63 62
64 63 QRectF ScatterChartItem::boundingRect() const
65 64 {
66 65 return m_rect;
67 66 }
68 67
69 68 void ScatterChartItem::createPoints(int count)
70 69 {
71 70 for (int i = 0; i < count; ++i) {
72 71
73 72 QGraphicsItem *item = 0;
74 73
75 74 switch (m_shape) {
76 75 case QScatterSeries::MarkerShapeCircle: {
77 76 item = new CircleMarker(0, 0, m_size, m_size, this);
78 77 const QRectF &rect = item->boundingRect();
79 78 item->setPos(-rect.width() / 2, -rect.height() / 2);
80 79 break;
81 80 }
82 81 case QScatterSeries::MarkerShapeRectangle:
83 82 item = new RectangleMarker(0, 0, m_size, m_size, this);
84 83 item->setPos(-m_size / 2, -m_size / 2);
85 84 break;
86 85 default:
87 86 qWarning() << "Unsupported marker type";
88 87 break;
89 88 }
90 89 m_items.addToGroup(item);
91 90 }
92 91 }
93 92
94 93 void ScatterChartItem::deletePoints(int count)
95 94 {
96 95 QList<QGraphicsItem *> items = m_items.childItems();
97 96
98 97 for (int i = 0; i < count; ++i) {
99 98 QGraphicsItem *item = items.takeLast();
100 99 m_markerMap.remove(item);
101 100 delete(item);
102 101 }
103 102 }
104 103
105 104 void ScatterChartItem::markerSelected(QGraphicsItem *marker)
106 105 {
107 106 emit XYChart::clicked(m_markerMap[marker]);
108 107 }
109 108
110 109 void ScatterChartItem::markerHovered(QGraphicsItem *marker, bool state)
111 110 {
112 111 emit XYChart::hovered(m_markerMap[marker], state);
113 112 }
114 113
115 114 void ScatterChartItem::markerPressed(QGraphicsItem *marker)
116 115 {
117 116 emit XYChart::pressed(m_markerMap[marker]);
118 117 }
119 118
120 119 void ScatterChartItem::markerReleased(QGraphicsItem *marker)
121 120 {
122 121 emit XYChart::released(m_markerMap[marker]);
123 122 }
124 123
125 124 void ScatterChartItem::markerDoubleClicked(QGraphicsItem *marker)
126 125 {
127 126 emit XYChart::doubleClicked(m_markerMap[marker]);
128 127 }
129 128
130 129 void ScatterChartItem::updateGeometry()
131 130 {
132 131
133 132 const QVector<QPointF>& points = geometryPoints();
134 133
135 134 if (points.size() == 0) {
136 135 deletePoints(m_items.childItems().count());
137 136 return;
138 137 }
139 138
140 139 int diff = m_items.childItems().size() - points.size();
141 140
142 141 if (diff > 0)
143 142 deletePoints(diff);
144 143 else if (diff < 0)
145 144 createPoints(-diff);
146 145
147 146 if (diff != 0)
148 147 handleUpdated();
149 148
150 149 QList<QGraphicsItem *> items = m_items.childItems();
151 150
152 151 QRectF clipRect(QPointF(0,0),domain()->size());
153 152
154 153 // Only zoom in if the clipRect fits inside int limits. QWidget::update() uses
155 154 // a region that has to be compatible with QRect.
156 155 if (clipRect.height() <= INT_MAX
157 156 && clipRect.width() <= INT_MAX) {
158 157 QVector<bool> offGridStatus = offGridStatusVector();
159 158 const int seriesLastIndex = m_series->count() - 1;
160 159
161 160 for (int i = 0; i < points.size(); i++) {
162 161 QGraphicsItem *item = items.at(i);
163 162 const QPointF &point = points.at(i);
164 163 const QRectF &rect = item->boundingRect();
165 164 // During remove animation series may have different number of points,
166 165 // so ensure we don't go over the index. Animation handling itself ensures that
167 166 // if there is actually no points in the series, then it won't generate a fake point,
168 167 // so we can be assured there is always at least one point in m_series here.
169 168 // Note that marker map values can be technically incorrect during the animation,
170 169 // if it was caused by an insert, but this shouldn't be a problem as the points are
171 170 // fake anyway. After remove animation stops, geometry is updated to correct one.
172 171 m_markerMap[item] = m_series->at(qMin(seriesLastIndex, i));
173 172 item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2);
174 173
175 174 if (!m_visible || offGridStatus.at(i))
176 175 item->setVisible(false);
177 176 else
178 177 item->setVisible(true);
179 178 }
180 179
181 180 prepareGeometryChange();
182 181 m_rect = clipRect;
183 182 }
184 183 }
185 184
186 185 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
187 186 {
188 187 Q_UNUSED(option)
189 188 Q_UNUSED(widget)
190 189
191 190 QRectF clipRect = QRectF(QPointF(0, 0), domain()->size());
192 191
193 192 painter->save();
194 193 painter->setClipRect(clipRect);
195 194
196 195 if (m_pointLabelsVisible) {
197 196 m_series->d_func()->drawSeriesPointLabels(painter, m_points,
198 197 m_series->markerSize() / 2
199 198 + m_series->pen().width());
200 199 }
201 200
202 201 painter->restore();
203 202 }
204 203
205 204 void ScatterChartItem::setPen(const QPen &pen)
206 205 {
207 206 foreach (QGraphicsItem *item , m_items.childItems())
208 207 static_cast<QAbstractGraphicsShapeItem*>(item)->setPen(pen);
209 208 }
210 209
211 210 void ScatterChartItem::setBrush(const QBrush &brush)
212 211 {
213 212 foreach (QGraphicsItem *item , m_items.childItems())
214 213 static_cast<QAbstractGraphicsShapeItem*>(item)->setBrush(brush);
215 214 }
216 215
217 216 void ScatterChartItem::handleUpdated()
218 217 {
219 218 int count = m_items.childItems().count();
220 219
221 220 if (count == 0)
222 221 return;
223 222
224 223 bool recreate = m_visible != m_series->isVisible()
225 224 || m_size != m_series->markerSize()
226 225 || m_shape != m_series->markerShape();
227 226
228 227 m_visible = m_series->isVisible();
229 228 m_size = m_series->markerSize();
230 229 m_shape = m_series->markerShape();
231 230 setOpacity(m_series->opacity());
232 231 m_pointLabelsFormat = m_series->pointLabelsFormat();
233 232 m_pointLabelsVisible = m_series->pointLabelsVisible();
234 233 m_pointLabelsFont = m_series->pointLabelsFont();
235 234 m_pointLabelsColor = m_series->pointLabelsColor();
236 235
237 236 if (recreate) {
238 237 deletePoints(count);
239 238 createPoints(count);
240 239
241 240 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
242 241 updateGeometry();
243 242 }
244 243
245 244 setPen(m_series->pen());
246 245 setBrush(m_series->brush());
247 246 update();
248 247 }
249 248
250 249 #include "moc_scatterchartitem_p.cpp"
251 250
252 251 QT_CHARTS_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now