##// END OF EJS Templates
Improves display of selected zones
trabillard -
r1051:ea6e09e4a905
parent child
Show More
1 NO CONTENT: modified file
@@ -1,337 +1,343
1 1 #include "Visualization/VisualizationSelectionZoneItem.h"
2 2
3 3 const QString &DEFAULT_COLOR = QStringLiteral("#E79D41");
4 4
5 5 struct VisualizationSelectionZoneItem::VisualizationSelectionZoneItemPrivate {
6 6
7 7 QCustomPlot *m_Plot;
8 8 double m_T1 = 0;
9 9 double m_T2 = 0;
10 10 QColor m_Color;
11 11
12 12 bool m_IsEditionEnabled = true;
13 13 double m_MovedOrinalT1 = 0;
14 14 double m_MovedOrinalT2 = 0;
15 15
16 16 QCPItemStraightLine *m_LeftLine;
17 17 QCPItemStraightLine *m_RightLine;
18 18 QCPItemText *m_NameLabelItem = nullptr;
19 19
20 20 enum class EditionMode { NoEdition, ResizeLeft, ResizeRight, Move };
21 21 EditionMode m_CurrentEditionMode;
22 22
23 23 QVector<VisualizationSelectionZoneItem *> m_AssociatedEditedZones;
24 24
25 25 VisualizationSelectionZoneItemPrivate(QCustomPlot *plot)
26 26 : m_Plot(plot), m_Color(Qt::blue), m_CurrentEditionMode(EditionMode::NoEdition)
27 27 {
28 28 }
29 29
30 30 void updatePosition(VisualizationSelectionZoneItem *item)
31 31 {
32 32 item->topLeft->setCoords(m_T1, 0);
33 33 item->bottomRight->setCoords(m_T2, 1);
34 34 }
35 35
36 36 EditionMode getEditionMode(const QPoint &pos, const VisualizationSelectionZoneItem *zoneItem)
37 37 {
38 38 auto distanceLeft = m_LeftLine->selectTest(pos, false);
39 39 auto distanceRight = m_RightLine->selectTest(pos, false);
40 40 auto distance = zoneItem->selectTest(pos, false);
41 41
42 42 if (distanceRight <= distance) {
43 43 return VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight;
44 44 }
45 45 else if (distanceLeft <= distance) {
46 46 return VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft;
47 47 }
48 48
49 49 return VisualizationSelectionZoneItemPrivate::EditionMode::Move;
50 50 }
51 51
52 52 double pixelSizeToAxisXSize(double pixels)
53 53 {
54 54 auto axis = m_Plot->axisRect()->axis(QCPAxis::atBottom);
55 55 return axis->pixelToCoord(pixels) - axis->pixelToCoord(0);
56 56 }
57 57 };
58 58
59 59 VisualizationSelectionZoneItem::VisualizationSelectionZoneItem(QCustomPlot *plot)
60 60 : QCPItemRect(plot),
61 61 impl{spimpl::make_unique_impl<VisualizationSelectionZoneItemPrivate>(plot)}
62 62 {
63 63 topLeft->setTypeX(QCPItemPosition::ptPlotCoords);
64 64 topLeft->setTypeY(QCPItemPosition::ptAxisRectRatio);
65 65 bottomRight->setTypeX(QCPItemPosition::ptPlotCoords);
66 66 bottomRight->setTypeY(QCPItemPosition::ptAxisRectRatio);
67 67 setSelectable(false);
68 68
69 69 impl->m_RightLine = new QCPItemStraightLine(plot);
70 70 impl->m_RightLine->point1->setParentAnchor(topRight);
71 71 impl->m_RightLine->point2->setParentAnchor(bottomRight);
72 72 impl->m_RightLine->point1->setTypeX(QCPItemPosition::ptAbsolute);
73 73 impl->m_RightLine->point1->setTypeY(QCPItemPosition::ptAbsolute);
74 74 impl->m_RightLine->point2->setTypeX(QCPItemPosition::ptAbsolute);
75 75 impl->m_RightLine->point2->setTypeY(QCPItemPosition::ptAbsolute);
76 76 impl->m_RightLine->setSelectable(false);
77 77
78 78 impl->m_LeftLine = new QCPItemStraightLine(plot);
79 79 impl->m_LeftLine->point1->setParentAnchor(topLeft);
80 80 impl->m_LeftLine->point2->setParentAnchor(bottomLeft);
81 81 impl->m_LeftLine->point1->setTypeX(QCPItemPosition::ptAbsolute);
82 82 impl->m_LeftLine->point1->setTypeY(QCPItemPosition::ptAbsolute);
83 83 impl->m_LeftLine->point2->setTypeX(QCPItemPosition::ptAbsolute);
84 84 impl->m_LeftLine->point2->setTypeY(QCPItemPosition::ptAbsolute);
85 85 impl->m_LeftLine->setSelectable(false);
86 86
87 connect(this, &VisualizationSelectionZoneItem::selectionChanged, impl->m_RightLine,
88 &QCPItemStraightLine::setSelected);
89 connect(this, &VisualizationSelectionZoneItem::selectionChanged, impl->m_LeftLine,
90 &QCPItemStraightLine::setSelected);
91
87 92 setColor(QColor(DEFAULT_COLOR));
88 93 }
89 94
90 95 VisualizationSelectionZoneItem::~VisualizationSelectionZoneItem()
91 96 {
92 97 impl->m_Plot->removeItem(impl->m_RightLine);
93 98 impl->m_Plot->removeItem(impl->m_LeftLine);
94 99 }
95 100
96 101 void VisualizationSelectionZoneItem::setName(const QString &name)
97 102 {
98 103 if (name.isEmpty() && impl->m_NameLabelItem) {
99 104 impl->m_Plot->removeItem(impl->m_NameLabelItem);
100 105 impl->m_NameLabelItem = nullptr;
101 106 }
102 107 else if (!impl->m_NameLabelItem) {
103 108 impl->m_NameLabelItem = new QCPItemText(impl->m_Plot);
104 109 impl->m_NameLabelItem->setText(name);
105 110 impl->m_NameLabelItem->setPositionAlignment(Qt::AlignHCenter | Qt::AlignTop);
106 111 impl->m_NameLabelItem->setColor(impl->m_Color);
107 112 impl->m_NameLabelItem->position->setParentAnchor(top);
108 113 }
109 114 }
110 115
111 116 QString VisualizationSelectionZoneItem::name() const
112 117 {
113 118 if (!impl->m_NameLabelItem) {
114 119 return QString();
115 120 }
116 121
117 122 return impl->m_NameLabelItem->text();
118 123 }
119 124
120 125 SqpRange VisualizationSelectionZoneItem::range() const
121 126 {
122 127 SqpRange range;
123 128 range.m_TStart = impl->m_T1 <= impl->m_T2 ? impl->m_T1 : impl->m_T2;
124 129 range.m_TEnd = impl->m_T1 > impl->m_T2 ? impl->m_T1 : impl->m_T2;
125 130 return range;
126 131 }
127 132
128 133 void VisualizationSelectionZoneItem::setRange(double tstart, double tend)
129 134 {
130 135 impl->m_T1 = tstart;
131 136 impl->m_T2 = tend;
132 137 impl->updatePosition(this);
133 138 }
134 139
135 140 void VisualizationSelectionZoneItem::setStart(double tstart)
136 141 {
137 142 impl->m_T1 = tstart;
138 143 impl->updatePosition(this);
139 144 }
140 145
141 146 void VisualizationSelectionZoneItem::setEnd(double tend)
142 147 {
143 148 impl->m_T2 = tend;
144 149 impl->updatePosition(this);
145 150 }
146 151
147 152 void VisualizationSelectionZoneItem::setColor(const QColor &color)
148 153 {
149 154 impl->m_Color = color;
150 155
151 156 auto brushColor = color;
152 brushColor.setAlpha(40);
157 brushColor.setAlpha(80);
153 158 setBrush(QBrush(brushColor));
154 159 setPen(QPen(Qt::NoPen));
155 160
156 161 auto selectedBrushColor = brushColor;
157 selectedBrushColor.setAlpha(65);
162 selectedBrushColor.setAlpha(150);
158 163 setSelectedBrush(QBrush(selectedBrushColor));
159 164 setSelectedPen(QPen(Qt::NoPen));
160 165
161 166 auto linePen = QPen(color);
162 167 linePen.setStyle(Qt::SolidLine);
163 linePen.setWidth(2);
168 linePen.setWidth(4);
164 169
165 170 auto selectedLinePen = linePen;
166 selectedLinePen.setColor(color.darker(30));
171 selectedLinePen.setColor(color.darker(120));
172 selectedLinePen.setWidth(4);
167 173
168 174 impl->m_LeftLine->setPen(linePen);
169 175 impl->m_RightLine->setPen(linePen);
170 176
171 177 impl->m_LeftLine->setSelectedPen(selectedLinePen);
172 178 impl->m_RightLine->setSelectedPen(selectedLinePen);
173 179 }
174 180
175 181 void VisualizationSelectionZoneItem::setEditionEnabled(bool value)
176 182 {
177 183 impl->m_IsEditionEnabled = value;
178 184 setSelectable(value);
179 185 if (!value) {
180 186 setSelected(false);
181 187 impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
182 188 }
183 189 }
184 190
185 191 bool VisualizationSelectionZoneItem::isEditionEnabled() const
186 192 {
187 193 return impl->m_IsEditionEnabled;
188 194 }
189 195
190 196 Qt::CursorShape
191 197 VisualizationSelectionZoneItem::curshorShapeForPosition(const QPoint &position) const
192 198 {
193 199 auto mode = impl->m_CurrentEditionMode
194 200 == VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition
195 201 ? impl->getEditionMode(position, this)
196 202 : impl->m_CurrentEditionMode;
197 203 switch (mode) {
198 204 case VisualizationSelectionZoneItemPrivate::EditionMode::Move:
199 205 return Qt::SizeAllCursor;
200 206 case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft:
201 207 case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight: // fallthrough
202 208 return Qt::SizeHorCursor;
203 209 default:
204 210 return Qt::ArrowCursor;
205 211 }
206 212 }
207 213
208 214 void VisualizationSelectionZoneItem::setHovered(bool value)
209 215 {
210 216 if (value) {
211 217 auto linePen = impl->m_LeftLine->pen();
212 218 linePen.setStyle(Qt::DotLine);
213 219 linePen.setWidth(3);
214 220
215 221 auto selectedLinePen = impl->m_LeftLine->selectedPen();
216 222 ;
217 223 selectedLinePen.setStyle(Qt::DotLine);
218 224 selectedLinePen.setWidth(3);
219 225
220 226 impl->m_LeftLine->setPen(linePen);
221 227 impl->m_RightLine->setPen(linePen);
222 228
223 229 impl->m_LeftLine->setSelectedPen(selectedLinePen);
224 230 impl->m_RightLine->setSelectedPen(selectedLinePen);
225 231 }
226 232 else {
227 233 setColor(impl->m_Color);
228 234 }
229 235 }
230 236
231 237 void VisualizationSelectionZoneItem::setAssociatedEditedZones(
232 238 const QVector<VisualizationSelectionZoneItem *> &associatedZones)
233 239 {
234 240 impl->m_AssociatedEditedZones = associatedZones;
235 241 impl->m_AssociatedEditedZones.removeAll(this);
236 242 }
237 243
238 244 void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details)
239 245 {
240 246 if (isEditionEnabled() && event->button() == Qt::LeftButton) {
241 247 impl->m_CurrentEditionMode = impl->getEditionMode(event->pos(), this);
242 248
243 249 impl->m_MovedOrinalT1 = impl->m_T1;
244 250 impl->m_MovedOrinalT2 = impl->m_T2;
245 251 for (auto associatedZone : impl->m_AssociatedEditedZones) {
246 252 associatedZone->impl->m_MovedOrinalT1 = associatedZone->impl->m_T1;
247 253 associatedZone->impl->m_MovedOrinalT2 = associatedZone->impl->m_T2;
248 254 }
249 255 }
250 256 else {
251 257 impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
252 258 event->ignore();
253 259 }
254 260 }
255 261
256 262 void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
257 263 {
258 264 if (isEditionEnabled()) {
259 265 auto axis = impl->m_Plot->axisRect()->axis(QCPAxis::atBottom);
260 266 auto pixelDiff = event->pos().x() - startPos.x();
261 267 auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
262 268
263 269 switch (impl->m_CurrentEditionMode) {
264 270 case VisualizationSelectionZoneItemPrivate::EditionMode::Move:
265 271 setRange(impl->m_MovedOrinalT1 + diff, impl->m_MovedOrinalT2 + diff);
266 272 for (auto associatedZone : impl->m_AssociatedEditedZones) {
267 273 associatedZone->move(pixelDiff);
268 274 }
269 275 break;
270 276 case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft:
271 277 setStart(impl->m_MovedOrinalT1 + diff);
272 278 for (auto associatedZone : impl->m_AssociatedEditedZones) {
273 279 impl->m_MovedOrinalT1 < impl->m_MovedOrinalT2
274 280 ? associatedZone->resizeLeft(pixelDiff)
275 281 : associatedZone->resizeRight(pixelDiff);
276 282 }
277 283 break;
278 284 case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight:
279 285 setEnd(impl->m_MovedOrinalT2 + diff);
280 286 for (auto associatedZone : impl->m_AssociatedEditedZones) {
281 287 impl->m_MovedOrinalT1 < impl->m_MovedOrinalT2
282 288 ? associatedZone->resizeRight(pixelDiff)
283 289 : associatedZone->resizeLeft(pixelDiff);
284 290 }
285 291 break;
286 292 default:
287 293 break;
288 294 }
289 295
290 296 for (auto associatedZone : impl->m_AssociatedEditedZones) {
291 297 associatedZone->parentPlot()->replot();
292 298 }
293 299 }
294 300 else {
295 301 event->ignore();
296 302 }
297 303 }
298 304
299 305 void VisualizationSelectionZoneItem::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
300 306 {
301 307 if (isEditionEnabled()) {
302 308 impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
303 309 }
304 310 else {
305 311 event->ignore();
306 312 }
307 313
308 314 impl->m_AssociatedEditedZones.clear();
309 315 }
310 316
311 317 void VisualizationSelectionZoneItem::resizeLeft(double pixelDiff)
312 318 {
313 319 auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
314 320 if (impl->m_MovedOrinalT1 <= impl->m_MovedOrinalT2) {
315 321 setStart(impl->m_MovedOrinalT1 + diff);
316 322 }
317 323 else {
318 324 setEnd(impl->m_MovedOrinalT2 + diff);
319 325 }
320 326 }
321 327
322 328 void VisualizationSelectionZoneItem::resizeRight(double pixelDiff)
323 329 {
324 330 auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
325 331 if (impl->m_MovedOrinalT1 > impl->m_MovedOrinalT2) {
326 332 setStart(impl->m_MovedOrinalT1 + diff);
327 333 }
328 334 else {
329 335 setEnd(impl->m_MovedOrinalT2 + diff);
330 336 }
331 337 }
332 338
333 339 void VisualizationSelectionZoneItem::move(double pixelDiff)
334 340 {
335 341 auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
336 342 setRange(impl->m_MovedOrinalT1 + diff, impl->m_MovedOrinalT2 + diff);
337 343 }
General Comments 0
You need to be logged in to leave comments. Login now