Auto status change to "Under Review"
@@ -31,8 +31,22 public: | |||||
31 | Qt::CursorShape curshorShapeForPosition(const QPoint &position) const; |
|
31 | Qt::CursorShape curshorShapeForPosition(const QPoint &position) const; | |
32 | void setHovered(bool value); |
|
32 | void setHovered(bool value); | |
33 |
|
33 | |||
|
34 | /// Sets the zones which should be moved or reisized together with this zone | |||
34 | void setAssociatedEditedZones(const QVector<VisualizationSelectionZoneItem *> &associatedZones); |
|
35 | void setAssociatedEditedZones(const QVector<VisualizationSelectionZoneItem *> &associatedZones); | |
35 |
|
36 | |||
|
37 | /// Align the specified zones with this one, vertically with the left border | |||
|
38 | bool alignZonesVerticallyOnLeft(const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, | |||
|
39 | bool allowResize); | |||
|
40 | /// Align the specified zones with this one, vertically with the right border | |||
|
41 | bool alignZonesVerticallyOnRight(const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, | |||
|
42 | bool allowResize); | |||
|
43 | /// Align the specified zones with this one, temporally with the left border | |||
|
44 | bool alignZonesTemporallyOnLeft(const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, | |||
|
45 | bool allowResize); | |||
|
46 | /// Align the specified zones with this one, temporally with the right border | |||
|
47 | bool alignZonesTemporallyOnRight(const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, | |||
|
48 | bool allowResize); | |||
|
49 | ||||
36 | protected: |
|
50 | protected: | |
37 | void mousePressEvent(QMouseEvent *event, const QVariant &details) override; |
|
51 | void mousePressEvent(QMouseEvent *event, const QVariant &details) override; | |
38 | void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) override; |
|
52 | void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) override; | |
@@ -42,7 +56,6 protected: | |||||
42 | void resizeRight(double pixelDiff); |
|
56 | void resizeRight(double pixelDiff); | |
43 | void move(double pixelDiff); |
|
57 | void move(double pixelDiff); | |
44 |
|
58 | |||
45 |
|
||||
46 | private: |
|
59 | private: | |
47 | class VisualizationSelectionZoneItemPrivate; |
|
60 | class VisualizationSelectionZoneItemPrivate; | |
48 | spimpl::unique_impl_ptr<VisualizationSelectionZoneItemPrivate> impl; |
|
61 | spimpl::unique_impl_ptr<VisualizationSelectionZoneItemPrivate> impl; |
@@ -11,7 +11,7 void VisualizationActionManager::installSelectionZoneActions() | |||||
11 | { |
|
11 | { | |
12 | auto &actionController = sqpApp->actionsGuiController(); |
|
12 | auto &actionController = sqpApp->actionsGuiController(); | |
13 |
|
13 | |||
14 |
actionController.addSectionZoneAction("Remove Selected Zone(s)", [](auto |
|
14 | actionController.addSectionZoneAction("Remove Selected Zone(s)", [](auto zones) { | |
15 | for (auto selectionZone : zones) { |
|
15 | for (auto selectionZone : zones) { | |
16 | if (auto graph = selectionZone->parentGraphWidget()) { |
|
16 | if (auto graph = selectionZone->parentGraphWidget()) { | |
17 | graph->removeSelectionZone(selectionZone); |
|
17 | graph->removeSelectionZone(selectionZone); | |
@@ -19,12 +19,89 void VisualizationActionManager::installSelectionZoneActions() | |||||
19 | } |
|
19 | } | |
20 | }); |
|
20 | }); | |
21 |
|
21 | |||
22 |
auto alignEnableFuntion = [](auto |
|
22 | auto alignEnableFuntion = [](auto items) { return items.count() > 1; }; | |
23 |
|
23 | |||
24 | auto alignLeftAction = actionController.addSectionZoneAction("Align Left Vertically", [](auto &zones) {}); |
|
24 | // Vertical alignment actions | |
|
25 | auto alignLeftAction | |||
|
26 | = actionController.addSectionZoneAction("Align Vertically / Left", [](auto zones) { | |||
|
27 | Q_ASSERT(zones.count() > 1); | |||
|
28 | auto ref = zones.takeFirst(); | |||
|
29 | ref->alignZonesVerticallyOnLeft(zones, false); | |||
|
30 | }); | |||
25 | alignLeftAction->setEnableFunction(alignEnableFuntion); |
|
31 | alignLeftAction->setEnableFunction(alignEnableFuntion); | |
26 |
|
32 | |||
|
33 | auto alignLeftBorderAction | |||
|
34 | = actionController.addSectionZoneAction("Align Vertically / Left Borders", [](auto zones) { | |||
|
35 | Q_ASSERT(zones.count() > 1); | |||
|
36 | auto ref = zones.takeFirst(); | |||
|
37 | ref->alignZonesVerticallyOnLeft(zones, true); | |||
|
38 | }); | |||
|
39 | alignLeftBorderAction->setEnableFunction(alignEnableFuntion); | |||
|
40 | ||||
27 | auto alignRightAction |
|
41 | auto alignRightAction | |
28 |
= actionController.addSectionZoneAction("Align |
|
42 | = actionController.addSectionZoneAction("Align Vertically / Right", [](auto zones) { | |
|
43 | Q_ASSERT(zones.count() > 1); | |||
|
44 | auto ref = zones.takeFirst(); | |||
|
45 | ref->alignZonesVerticallyOnRight(zones, false); | |||
|
46 | }); | |||
29 | alignRightAction->setEnableFunction(alignEnableFuntion); |
|
47 | alignRightAction->setEnableFunction(alignEnableFuntion); | |
|
48 | ||||
|
49 | auto alignRightBorderAction | |||
|
50 | = actionController.addSectionZoneAction("Align Vertically / Right Borders", [](auto zones) { | |||
|
51 | Q_ASSERT(zones.count() > 1); | |||
|
52 | auto ref = zones.takeFirst(); | |||
|
53 | ref->alignZonesVerticallyOnRight(zones, true); | |||
|
54 | }); | |||
|
55 | alignRightBorderAction->setEnableFunction(alignEnableFuntion); | |||
|
56 | ||||
|
57 | auto alignLeftAndRightAction = actionController.addSectionZoneAction( | |||
|
58 | "Align Vertically / Left and Right", [](auto zones) { | |||
|
59 | Q_ASSERT(zones.count() > 1); | |||
|
60 | auto ref = zones.takeFirst(); | |||
|
61 | ref->alignZonesVerticallyOnLeft(zones, false); | |||
|
62 | ref->alignZonesVerticallyOnRight(zones, true); | |||
|
63 | }); | |||
|
64 | alignLeftAndRightAction->setEnableFunction(alignEnableFuntion); | |||
|
65 | ||||
|
66 | // Temporal alignment actions | |||
|
67 | auto alignLeftTemporallyAction | |||
|
68 | = actionController.addSectionZoneAction("Align Temporally / Left", [](auto zones) { | |||
|
69 | Q_ASSERT(zones.count() > 1); | |||
|
70 | auto ref = zones.takeFirst(); | |||
|
71 | ref->alignZonesTemporallyOnLeft(zones, false); | |||
|
72 | }); | |||
|
73 | alignLeftTemporallyAction->setEnableFunction(alignEnableFuntion); | |||
|
74 | ||||
|
75 | auto alignLeftBorderTemporallyAction | |||
|
76 | = actionController.addSectionZoneAction("Align Temporally / Left Borders", [](auto zones) { | |||
|
77 | Q_ASSERT(zones.count() > 1); | |||
|
78 | auto ref = zones.takeFirst(); | |||
|
79 | ref->alignZonesTemporallyOnLeft(zones, true); | |||
|
80 | }); | |||
|
81 | alignLeftBorderTemporallyAction->setEnableFunction(alignEnableFuntion); | |||
|
82 | ||||
|
83 | auto alignRightTemporallyAction | |||
|
84 | = actionController.addSectionZoneAction("Align Temporally / Right", [](auto zones) { | |||
|
85 | Q_ASSERT(zones.count() > 1); | |||
|
86 | auto ref = zones.takeFirst(); | |||
|
87 | ref->alignZonesTemporallyOnRight(zones, false); | |||
|
88 | }); | |||
|
89 | alignRightTemporallyAction->setEnableFunction(alignEnableFuntion); | |||
|
90 | ||||
|
91 | auto alignRightBorderTemporallyAction | |||
|
92 | = actionController.addSectionZoneAction("Align Temporally / Right Borders", [](auto zones) { | |||
|
93 | Q_ASSERT(zones.count() > 1); | |||
|
94 | auto ref = zones.takeFirst(); | |||
|
95 | ref->alignZonesTemporallyOnRight(zones, true); | |||
|
96 | }); | |||
|
97 | alignRightBorderTemporallyAction->setEnableFunction(alignEnableFuntion); | |||
|
98 | ||||
|
99 | auto alignLeftAndRightTemporallyAction = actionController.addSectionZoneAction( | |||
|
100 | "Align Temporally / Left and Right", [](auto zones) { | |||
|
101 | Q_ASSERT(zones.count() > 1); | |||
|
102 | auto ref = zones.takeFirst(); | |||
|
103 | ref->alignZonesTemporallyOnLeft(zones, false); | |||
|
104 | ref->alignZonesTemporallyOnRight(zones, true); | |||
|
105 | }); | |||
|
106 | alignLeftAndRightTemporallyAction->setEnableFunction(alignEnableFuntion); | |||
30 | } |
|
107 | } |
@@ -614,6 +614,9 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept | |||||
614 | auto selectionZoneItem = impl->selectionZoneAt(pos, plot()); |
|
614 | auto selectionZoneItem = impl->selectionZoneAt(pos, plot()); | |
615 | if (selectionZoneItem) { |
|
615 | if (selectionZoneItem) { | |
616 | auto selectedItems = parentVisualizationWidget()->selectionZoneManager().selectedItems(); |
|
616 | auto selectedItems = parentVisualizationWidget()->selectionZoneManager().selectedItems(); | |
|
617 | selectedItems.removeAll(selectionZoneItem); | |||
|
618 | selectedItems.prepend(selectionZoneItem); // Put the current selection zone first | |||
|
619 | ||||
617 | auto zoneActions = sqpApp->actionsGuiController().selectionZoneActions(); |
|
620 | auto zoneActions = sqpApp->actionsGuiController().selectionZoneActions(); | |
618 | if (!zoneActions.isEmpty() && !graphMenu.isEmpty()) { |
|
621 | if (!zoneActions.isEmpty() && !graphMenu.isEmpty()) { | |
619 | graphMenu.addSeparator(); |
|
622 | graphMenu.addSeparator(); | |
@@ -622,9 +625,8 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept | |||||
622 | for (auto zoneAction : zoneActions) { |
|
625 | for (auto zoneAction : zoneActions) { | |
623 | auto action = graphMenu.addAction(zoneAction->name()); |
|
626 | auto action = graphMenu.addAction(zoneAction->name()); | |
624 | action->setEnabled(zoneAction->isEnabled(selectedItems)); |
|
627 | action->setEnabled(zoneAction->isEnabled(selectedItems)); | |
625 |
QObject::connect(action, &QAction::triggered, |
|
628 | QObject::connect(action, &QAction::triggered, | |
626 | zoneAction->execute(selectedItems); |
|
629 | [zoneAction, selectedItems]() { zoneAction->execute(selectedItems); }); | |
627 | }); |
|
|||
628 | } |
|
630 | } | |
629 | } |
|
631 | } | |
630 |
|
632 |
@@ -55,6 +55,53 struct VisualizationSelectionZoneItem::VisualizationSelectionZoneItemPrivate { | |||||
55 | auto axis = m_Plot->axisRect()->axis(QCPAxis::atBottom); |
|
55 | auto axis = m_Plot->axisRect()->axis(QCPAxis::atBottom); | |
56 | return axis->pixelToCoord(pixels) - axis->pixelToCoord(0); |
|
56 | return axis->pixelToCoord(pixels) - axis->pixelToCoord(0); | |
57 | } |
|
57 | } | |
|
58 | ||||
|
59 | bool alignZones(VisualizationSelectionZoneItem *referenceZone, | |||
|
60 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool alignOnLeft, | |||
|
61 | bool allowResize, bool vertically) | |||
|
62 | { | |||
|
63 | auto result = false; | |||
|
64 | ||||
|
65 | auto referenceTime | |||
|
66 | = alignOnLeft ? referenceZone->range().m_TStart : referenceZone->range().m_TEnd; | |||
|
67 | ||||
|
68 | auto referenceBottomAxis = m_Plot->axisRect()->axis(QCPAxis::atBottom); | |||
|
69 | auto referenceVerticalPosition = referenceBottomAxis->coordToPixel(referenceTime); | |||
|
70 | ||||
|
71 | for (auto otherZone : zonesToAlign) { | |||
|
72 | ||||
|
73 | auto otherZoneRange = otherZone->range(); | |||
|
74 | auto newZoneStart = otherZoneRange.m_TStart; | |||
|
75 | auto newZoneEnd = otherZoneRange.m_TEnd; | |||
|
76 | ||||
|
77 | auto alignedTime = referenceTime; | |||
|
78 | if (vertically) { | |||
|
79 | auto otherZoneAxis = otherZone->parentPlot()->axisRect()->axis(QCPAxis::atBottom); | |||
|
80 | alignedTime = otherZoneAxis->pixelToCoord(referenceVerticalPosition); | |||
|
81 | } | |||
|
82 | ||||
|
83 | if (alignOnLeft) { | |||
|
84 | newZoneStart = alignedTime; | |||
|
85 | if (!allowResize) { | |||
|
86 | newZoneEnd = alignedTime + (otherZoneRange.m_TEnd - otherZoneRange.m_TStart); | |||
|
87 | } | |||
|
88 | } | |||
|
89 | else { // align on right | |||
|
90 | newZoneEnd = alignedTime; | |||
|
91 | if (!allowResize) { | |||
|
92 | newZoneStart = alignedTime - (otherZoneRange.m_TEnd - otherZoneRange.m_TStart); | |||
|
93 | } | |||
|
94 | } | |||
|
95 | ||||
|
96 | if (newZoneStart < newZoneEnd) { | |||
|
97 | result = true; | |||
|
98 | otherZone->setRange(newZoneStart, newZoneEnd); | |||
|
99 | otherZone->parentPlot()->replot(); | |||
|
100 | } | |||
|
101 | } | |||
|
102 | ||||
|
103 | return result; | |||
|
104 | } | |||
58 | }; |
|
105 | }; | |
59 |
|
106 | |||
60 | VisualizationSelectionZoneItem::VisualizationSelectionZoneItem(QCustomPlot *plot) |
|
107 | VisualizationSelectionZoneItem::VisualizationSelectionZoneItem(QCustomPlot *plot) | |
@@ -252,6 +299,30 void VisualizationSelectionZoneItem::setAssociatedEditedZones( | |||||
252 | impl->m_AssociatedEditedZones.removeAll(this); |
|
299 | impl->m_AssociatedEditedZones.removeAll(this); | |
253 | } |
|
300 | } | |
254 |
|
301 | |||
|
302 | bool VisualizationSelectionZoneItem::alignZonesVerticallyOnLeft( | |||
|
303 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize) | |||
|
304 | { | |||
|
305 | return impl->alignZones(this, zonesToAlign, true, allowResize, true); | |||
|
306 | } | |||
|
307 | ||||
|
308 | bool VisualizationSelectionZoneItem::alignZonesVerticallyOnRight( | |||
|
309 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize) | |||
|
310 | { | |||
|
311 | return impl->alignZones(this, zonesToAlign, false, allowResize, true); | |||
|
312 | } | |||
|
313 | ||||
|
314 | bool VisualizationSelectionZoneItem::alignZonesTemporallyOnLeft( | |||
|
315 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize) | |||
|
316 | { | |||
|
317 | return impl->alignZones(this, zonesToAlign, true, allowResize, false); | |||
|
318 | } | |||
|
319 | ||||
|
320 | bool VisualizationSelectionZoneItem::alignZonesTemporallyOnRight( | |||
|
321 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize) | |||
|
322 | { | |||
|
323 | return impl->alignZones(this, zonesToAlign, false, allowResize, false); | |||
|
324 | } | |||
|
325 | ||||
255 | void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details) |
|
326 | void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details) | |
256 | { |
|
327 | { | |
257 | if (isEditionEnabled() && event->button() == Qt::LeftButton) { |
|
328 | if (isEditionEnabled() && event->button() == Qt::LeftButton) { |
General Comments 4
Status change > Approved
Status change > Approved
You need to be logged in to leave comments.
Login now