##// END OF EJS Templates
Alignment actions for zone selections
trabillard -
r1116:13a66582f6e0
parent child
Show More
@@ -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 &zones) {
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 &items) { return items.count() > 0; };
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 Right vertically", [](auto &zones) {});
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, [zoneAction, &selectedItems]() {
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
Under Review
author

Auto status change to "Under Review"

Approved

Status change > Approved

Approved

Status change > Approved

You need to be logged in to leave comments. Login now