Auto status change to "Under Review"
@@ -0,0 +1,26 | |||||
|
1 | #ifndef VISUALIZATIONCURSORITEM_H | |||
|
2 | #define VISUALIZATIONCURSORITEM_H | |||
|
3 | ||||
|
4 | #include <Common/spimpl.h> | |||
|
5 | #include <SqpApplication.h> | |||
|
6 | ||||
|
7 | class QCustomPlot; | |||
|
8 | ||||
|
9 | class VisualizationCursorItem { | |||
|
10 | public: | |||
|
11 | VisualizationCursorItem(QCustomPlot *plot); | |||
|
12 | ||||
|
13 | void setVisible(bool value); | |||
|
14 | bool isVisible() const; | |||
|
15 | ||||
|
16 | void setPosition(double value); | |||
|
17 | void setAbsolutePosition(double value); | |||
|
18 | void setOrientation(Qt::Orientation orientation); | |||
|
19 | void setLabelText(const QString &text); | |||
|
20 | ||||
|
21 | private: | |||
|
22 | class VisualizationCursorItemPrivate; | |||
|
23 | spimpl::unique_impl_ptr<VisualizationCursorItemPrivate> impl; | |||
|
24 | }; | |||
|
25 | ||||
|
26 | #endif // VISUALIZATIONCURSORITEM_H |
@@ -0,0 +1,163 | |||||
|
1 | #include <Common/DateUtils.h> | |||
|
2 | #include <Visualization/VisualizationCursorItem.h> | |||
|
3 | #include <Visualization/qcustomplot.h> | |||
|
4 | ||||
|
5 | /// Width of the cursor in pixel | |||
|
6 | const auto CURSOR_WIDTH = 3; | |||
|
7 | ||||
|
8 | /// Color of the cursor in the graph | |||
|
9 | const auto CURSOR_COLOR = QColor{68, 114, 196}; | |||
|
10 | ||||
|
11 | /// Line style of the cursor in the graph | |||
|
12 | auto CURSOR_PEN_STYLE = Qt::DotLine; | |||
|
13 | ||||
|
14 | struct VisualizationCursorItem::VisualizationCursorItemPrivate { | |||
|
15 | ||||
|
16 | QCustomPlot *m_Plot = nullptr; | |||
|
17 | ||||
|
18 | QCPItemStraightLine *m_LineItem = nullptr; | |||
|
19 | QCPItemText *m_LabelItem = nullptr; | |||
|
20 | ||||
|
21 | Qt::Orientation m_Orientation; | |||
|
22 | double m_Position = 0.0; | |||
|
23 | bool m_IsAbsolutePosition = false; | |||
|
24 | QString m_LabelText; | |||
|
25 | ||||
|
26 | explicit VisualizationCursorItemPrivate(QCustomPlot *plot) | |||
|
27 | : m_Plot(plot), m_Orientation(Qt::Vertical) | |||
|
28 | { | |||
|
29 | } | |||
|
30 | ||||
|
31 | void updateOrientation() | |||
|
32 | { | |||
|
33 | if (m_LineItem) { | |||
|
34 | switch (m_Orientation) { | |||
|
35 | case Qt::Vertical: | |||
|
36 | m_LineItem->point1->setTypeX(m_IsAbsolutePosition | |||
|
37 | ? QCPItemPosition::ptAbsolute | |||
|
38 | : QCPItemPosition::ptPlotCoords); | |||
|
39 | m_LineItem->point1->setTypeY(QCPItemPosition::ptAxisRectRatio); | |||
|
40 | m_LineItem->point2->setTypeX(m_IsAbsolutePosition | |||
|
41 | ? QCPItemPosition::ptAbsolute | |||
|
42 | : QCPItemPosition::ptPlotCoords); | |||
|
43 | m_LineItem->point2->setTypeY(QCPItemPosition::ptAxisRectRatio); | |||
|
44 | m_LabelItem->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); | |||
|
45 | break; | |||
|
46 | case Qt::Horizontal: | |||
|
47 | m_LineItem->point1->setTypeX(QCPItemPosition::ptAxisRectRatio); | |||
|
48 | m_LineItem->point1->setTypeY(m_IsAbsolutePosition | |||
|
49 | ? QCPItemPosition::ptAbsolute | |||
|
50 | : QCPItemPosition::ptPlotCoords); | |||
|
51 | m_LineItem->point2->setTypeX(QCPItemPosition::ptAxisRectRatio); | |||
|
52 | m_LineItem->point2->setTypeY(m_IsAbsolutePosition | |||
|
53 | ? QCPItemPosition::ptAbsolute | |||
|
54 | : QCPItemPosition::ptPlotCoords); | |||
|
55 | m_LabelItem->setPositionAlignment(Qt::AlignRight | Qt::AlignBottom); | |||
|
56 | } | |||
|
57 | } | |||
|
58 | } | |||
|
59 | ||||
|
60 | void updateCursorPosition() | |||
|
61 | { | |||
|
62 | if (m_LineItem) { | |||
|
63 | switch (m_Orientation) { | |||
|
64 | case Qt::Vertical: | |||
|
65 | m_LineItem->point1->setCoords(m_Position, 0); | |||
|
66 | m_LineItem->point2->setCoords(m_Position, 1); | |||
|
67 | m_LabelItem->position->setCoords(5, 5); | |||
|
68 | break; | |||
|
69 | case Qt::Horizontal: | |||
|
70 | m_LineItem->point1->setCoords(1, m_Position); | |||
|
71 | m_LineItem->point2->setCoords(0, m_Position); | |||
|
72 | m_LabelItem->position->setCoords(-5, -5); | |||
|
73 | } | |||
|
74 | } | |||
|
75 | } | |||
|
76 | ||||
|
77 | void updateLabelText() | |||
|
78 | { | |||
|
79 | if (m_LabelItem) { | |||
|
80 | m_LabelItem->setText(m_LabelText); | |||
|
81 | } | |||
|
82 | } | |||
|
83 | }; | |||
|
84 | ||||
|
85 | VisualizationCursorItem::VisualizationCursorItem(QCustomPlot *plot) | |||
|
86 | : impl{spimpl::make_unique_impl<VisualizationCursorItemPrivate>(plot)} | |||
|
87 | { | |||
|
88 | } | |||
|
89 | ||||
|
90 | void VisualizationCursorItem::setVisible(bool value) | |||
|
91 | { | |||
|
92 | if (value != isVisible()) { | |||
|
93 | ||||
|
94 | if (value) { | |||
|
95 | Q_ASSERT(!impl->m_LineItem && !impl->m_Plot); | |||
|
96 | ||||
|
97 | impl->m_LineItem = new QCPItemStraightLine{impl->m_Plot}; | |||
|
98 | auto pen = QPen{CURSOR_PEN_STYLE}; | |||
|
99 | pen.setColor(CURSOR_COLOR); | |||
|
100 | pen.setWidth(CURSOR_WIDTH); | |||
|
101 | impl->m_LineItem->setPen(pen); | |||
|
102 | impl->m_LineItem->setSelectable(false); | |||
|
103 | ||||
|
104 | impl->m_LabelItem = new QCPItemText{impl->m_Plot}; | |||
|
105 | impl->m_LabelItem->setColor(CURSOR_COLOR); | |||
|
106 | impl->m_LabelItem->setSelectable(false); | |||
|
107 | impl->m_LabelItem->position->setParentAnchor(impl->m_LineItem->point1); | |||
|
108 | impl->m_LabelItem->position->setTypeX(QCPItemPosition::ptAbsolute); | |||
|
109 | impl->m_LabelItem->position->setTypeY(QCPItemPosition::ptAbsolute); | |||
|
110 | ||||
|
111 | auto font = impl->m_LabelItem->font(); | |||
|
112 | font.setPointSize(10); | |||
|
113 | font.setBold(true); | |||
|
114 | impl->m_LabelItem->setFont(font); | |||
|
115 | ||||
|
116 | impl->updateOrientation(); | |||
|
117 | impl->updateLabelText(); | |||
|
118 | impl->updateCursorPosition(); | |||
|
119 | } | |||
|
120 | else { | |||
|
121 | Q_ASSERT(impl->m_LineItem && impl->m_Plot); | |||
|
122 | ||||
|
123 | // Note: the items are destroyed by QCustomPlot in removeItem | |||
|
124 | impl->m_Plot->removeItem(impl->m_LineItem); | |||
|
125 | impl->m_LineItem = nullptr; | |||
|
126 | impl->m_Plot->removeItem(impl->m_LabelItem); | |||
|
127 | impl->m_LabelItem = nullptr; | |||
|
128 | } | |||
|
129 | } | |||
|
130 | } | |||
|
131 | ||||
|
132 | bool VisualizationCursorItem::isVisible() const | |||
|
133 | { | |||
|
134 | return impl->m_LineItem != nullptr; | |||
|
135 | } | |||
|
136 | ||||
|
137 | void VisualizationCursorItem::setPosition(double value) | |||
|
138 | { | |||
|
139 | impl->m_Position = value; | |||
|
140 | impl->m_IsAbsolutePosition = false; | |||
|
141 | impl->updateLabelText(); | |||
|
142 | impl->updateCursorPosition(); | |||
|
143 | } | |||
|
144 | ||||
|
145 | void VisualizationCursorItem::setAbsolutePosition(double value) | |||
|
146 | { | |||
|
147 | setPosition(value); | |||
|
148 | impl->m_IsAbsolutePosition = true; | |||
|
149 | } | |||
|
150 | ||||
|
151 | void VisualizationCursorItem::setOrientation(Qt::Orientation orientation) | |||
|
152 | { | |||
|
153 | impl->m_Orientation = orientation; | |||
|
154 | impl->updateLabelText(); | |||
|
155 | impl->updateOrientation(); | |||
|
156 | impl->updateCursorPosition(); | |||
|
157 | } | |||
|
158 | ||||
|
159 | void VisualizationCursorItem::setLabelText(const QString &text) | |||
|
160 | { | |||
|
161 | impl->m_LabelText = text; | |||
|
162 | impl->updateLabelText(); | |||
|
163 | } |
@@ -4,4 +4,5 | |||||
4 | /// Minimum height for graph added in zones (in pixels) |
|
4 | /// Minimum height for graph added in zones (in pixels) | |
5 | extern const int GRAPH_MINIMUM_HEIGHT; |
|
5 | extern const int GRAPH_MINIMUM_HEIGHT; | |
6 |
|
6 | |||
|
7 | ||||
7 | #endif // SCIQLOP_VISUALIZATIONDEF_H |
|
8 | #endif // SCIQLOP_VISUALIZATIONDEF_H |
@@ -62,6 +62,18 public: | |||||
62 | bool isDragAllowed() const override; |
|
62 | bool isDragAllowed() const override; | |
63 | void highlightForMerge(bool highlighted) override; |
|
63 | void highlightForMerge(bool highlighted) override; | |
64 |
|
64 | |||
|
65 | // Cursors | |||
|
66 | /// Adds or moves the vertical cursor at the specified value on the x-axis | |||
|
67 | void addVerticalCursor(double time); | |||
|
68 | /// Adds or moves the vertical cursor at the specified value on the x-axis | |||
|
69 | void addVerticalCursorAtViewportPosition(double position); | |||
|
70 | void removeVerticalCursor(); | |||
|
71 | /// Adds or moves the vertical cursor at the specified value on the y-axis | |||
|
72 | void addHorizontalCursor(double value); | |||
|
73 | /// Adds or moves the vertical cursor at the specified value on the y-axis | |||
|
74 | void addHorizontalCursorAtViewportPosition(double position); | |||
|
75 | void removeHorizontalCursor(); | |||
|
76 | ||||
65 | signals: |
|
77 | signals: | |
66 | void synchronize(const SqpRange &range, const SqpRange &oldRange); |
|
78 | void synchronize(const SqpRange &range, const SqpRange &oldRange); | |
67 | void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range, |
|
79 | void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range, |
@@ -70,6 +70,10 public: | |||||
70 | QMimeData *mimeData() const override; |
|
70 | QMimeData *mimeData() const override; | |
71 | bool isDragAllowed() const override; |
|
71 | bool isDragAllowed() const override; | |
72 |
|
72 | |||
|
73 | void notifyMouseMoveInGraph(const QPointF &graphPosition, const QPointF &plotPosition, | |||
|
74 | VisualizationGraphWidget *graphWidget); | |||
|
75 | void notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget); | |||
|
76 | ||||
73 | protected: |
|
77 | protected: | |
74 | void closeEvent(QCloseEvent *event) override; |
|
78 | void closeEvent(QCloseEvent *event) override; | |
75 |
|
79 |
@@ -79,7 +79,8 gui_sources = [ | |||||
79 | 'src/Visualization/VisualizationDragWidget.cpp', |
|
79 | 'src/Visualization/VisualizationDragWidget.cpp', | |
80 | 'src/Visualization/AxisRenderingUtils.cpp', |
|
80 | 'src/Visualization/AxisRenderingUtils.cpp', | |
81 | 'src/Visualization/PlottablesRenderingUtils.cpp', |
|
81 | 'src/Visualization/PlottablesRenderingUtils.cpp', | |
82 | 'src/Visualization/MacScrollBarStyle.cpp' |
|
82 | 'src/Visualization/MacScrollBarStyle.cpp', | |
|
83 | 'src/Visualization/VisualizationCursorItem.cpp' | |||
83 | ] |
|
84 | ] | |
84 |
|
85 | |||
85 | gui_inc = include_directories(['include']) |
|
86 | gui_inc = include_directories(['include']) |
@@ -21,7 +21,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||||
21 | QVBoxLayout *m_Layout; |
|
21 | QVBoxLayout *m_Layout; | |
22 | QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes; |
|
22 | QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes; | |
23 | QString m_PlaceHolderText; |
|
23 | QString m_PlaceHolderText; | |
24 |
DragDropHelper::PlaceHolderType m_PlaceHolderType |
|
24 | DragDropHelper::PlaceHolderType m_PlaceHolderType; | |
25 |
|
25 | |||
26 | VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun |
|
26 | VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun | |
27 | = [](auto mimeData) { return true; }; |
|
27 | = [](auto mimeData) { return true; }; | |
@@ -29,6 +29,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||||
29 | int m_MinContainerHeight = 0; |
|
29 | int m_MinContainerHeight = 0; | |
30 |
|
30 | |||
31 | explicit VisualizationDragDropContainerPrivate(QWidget *widget) |
|
31 | explicit VisualizationDragDropContainerPrivate(QWidget *widget) | |
|
32 | : m_PlaceHolderType(DragDropHelper::PlaceHolderType::Graph) | |||
32 | { |
|
33 | { | |
33 | m_Layout = new QVBoxLayout(widget); |
|
34 | m_Layout = new QVBoxLayout(widget); | |
34 | m_Layout->setContentsMargins(0, 0, 0, 0); |
|
35 | m_Layout->setContentsMargins(0, 0, 0, 0); |
@@ -1,5 +1,6 | |||||
1 | #include "Visualization/VisualizationGraphWidget.h" |
|
1 | #include "Visualization/VisualizationGraphWidget.h" | |
2 | #include "Visualization/IVisualizationWidgetVisitor.h" |
|
2 | #include "Visualization/IVisualizationWidgetVisitor.h" | |
|
3 | #include "Visualization/VisualizationCursorItem.h" | |||
3 | #include "Visualization/VisualizationDefs.h" |
|
4 | #include "Visualization/VisualizationDefs.h" | |
4 | #include "Visualization/VisualizationGraphHelper.h" |
|
5 | #include "Visualization/VisualizationGraphHelper.h" | |
5 | #include "Visualization/VisualizationGraphRenderingDelegate.h" |
|
6 | #include "Visualization/VisualizationGraphRenderingDelegate.h" | |
@@ -37,6 +38,9 const auto VERTICAL_PAN_MODIFIER = Qt::AltModifier; | |||||
37 | /// Minimum size for the zoom box, in percentage of the axis range |
|
38 | /// Minimum size for the zoom box, in percentage of the axis range | |
38 | const auto ZOOM_BOX_MIN_SIZE = 0.8; |
|
39 | const auto ZOOM_BOX_MIN_SIZE = 0.8; | |
39 |
|
40 | |||
|
41 | /// Format of the dates appearing in the label of a cursor | |||
|
42 | const auto CURSOR_LABELS_DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd\nhh:mm:ss:zzz"); | |||
|
43 | ||||
40 | } // namespace |
|
44 | } // namespace | |
41 |
|
45 | |||
42 | struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { |
|
46 | struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |
@@ -58,6 +62,8 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||||
58 | std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate; |
|
62 | std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate; | |
59 |
|
63 | |||
60 | QCPItemRect *m_DrawingRect = nullptr; |
|
64 | QCPItemRect *m_DrawingRect = nullptr; | |
|
65 | std::unique_ptr<VisualizationCursorItem> m_HorizontalCursor = nullptr; | |||
|
66 | std::unique_ptr<VisualizationCursorItem> m_VerticalCursor = nullptr; | |||
61 |
|
67 | |||
62 | void configureDrawingRect() |
|
68 | void configureDrawingRect() | |
63 | { |
|
69 | { | |
@@ -96,6 +102,14 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||||
96 | auto axisY = plot.axisRect()->axis(QCPAxis::atLeft); |
|
102 | auto axisY = plot.axisRect()->axis(QCPAxis::atLeft); | |
97 | return QPointF{axisX->pixelToCoord(pos.x()), axisY->pixelToCoord(pos.y())}; |
|
103 | return QPointF{axisX->pixelToCoord(pos.x()), axisY->pixelToCoord(pos.y())}; | |
98 | } |
|
104 | } | |
|
105 | ||||
|
106 | bool pointIsInAxisRect(const QPointF &axisPoint, QCustomPlot &plot) const | |||
|
107 | { | |||
|
108 | auto axisX = plot.axisRect()->axis(QCPAxis::atBottom); | |||
|
109 | auto axisY = plot.axisRect()->axis(QCPAxis::atLeft); | |||
|
110 | ||||
|
111 | return axisX->range().contains(axisPoint.x()) && axisY->range().contains(axisPoint.y()); | |||
|
112 | } | |||
99 | }; |
|
113 | }; | |
100 |
|
114 | |||
101 | VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent) |
|
115 | VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent) | |
@@ -116,6 +130,12 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget | |||||
116 | // The delegate must be initialized after the ui as it uses the plot |
|
130 | // The delegate must be initialized after the ui as it uses the plot | |
117 | impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this); |
|
131 | impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this); | |
118 |
|
132 | |||
|
133 | // Init the cursors | |||
|
134 | impl->m_HorizontalCursor = std::make_unique<VisualizationCursorItem>(&plot()); | |||
|
135 | impl->m_HorizontalCursor->setOrientation(Qt::Horizontal); | |||
|
136 | impl->m_VerticalCursor = std::make_unique<VisualizationCursorItem>(&plot()); | |||
|
137 | impl->m_VerticalCursor->setOrientation(Qt::Vertical); | |||
|
138 | ||||
119 | connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress); |
|
139 | connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress); | |
120 | connect(ui->widget, &QCustomPlot::mouseRelease, this, |
|
140 | connect(ui->widget, &QCustomPlot::mouseRelease, this, | |
121 | &VisualizationGraphWidget::onMouseRelease); |
|
141 | &VisualizationGraphWidget::onMouseRelease); | |
@@ -308,6 +328,55 void VisualizationGraphWidget::highlightForMerge(bool highlighted) | |||||
308 | plot().update(); |
|
328 | plot().update(); | |
309 | } |
|
329 | } | |
310 |
|
330 | |||
|
331 | void VisualizationGraphWidget::addVerticalCursor(double time) | |||
|
332 | { | |||
|
333 | impl->m_VerticalCursor->setPosition(time); | |||
|
334 | impl->m_VerticalCursor->setVisible(true); | |||
|
335 | ||||
|
336 | auto text | |||
|
337 | = DateUtils::dateTime(time).toString(CURSOR_LABELS_DATETIME_FORMAT).replace(' ', '\n'); | |||
|
338 | impl->m_VerticalCursor->setLabelText(text); | |||
|
339 | } | |||
|
340 | ||||
|
341 | void VisualizationGraphWidget::addVerticalCursorAtViewportPosition(double position) | |||
|
342 | { | |||
|
343 | impl->m_VerticalCursor->setAbsolutePosition(position); | |||
|
344 | impl->m_VerticalCursor->setVisible(true); | |||
|
345 | ||||
|
346 | auto axis = plot().axisRect()->axis(QCPAxis::atBottom); | |||
|
347 | auto text | |||
|
348 | = DateUtils::dateTime(axis->pixelToCoord(position)).toString(CURSOR_LABELS_DATETIME_FORMAT); | |||
|
349 | impl->m_VerticalCursor->setLabelText(text); | |||
|
350 | } | |||
|
351 | ||||
|
352 | void VisualizationGraphWidget::removeVerticalCursor() | |||
|
353 | { | |||
|
354 | impl->m_VerticalCursor->setVisible(false); | |||
|
355 | plot().replot(QCustomPlot::rpQueuedReplot); | |||
|
356 | } | |||
|
357 | ||||
|
358 | void VisualizationGraphWidget::addHorizontalCursor(double value) | |||
|
359 | { | |||
|
360 | impl->m_HorizontalCursor->setPosition(value); | |||
|
361 | impl->m_HorizontalCursor->setVisible(true); | |||
|
362 | impl->m_HorizontalCursor->setLabelText(QString::number(value)); | |||
|
363 | } | |||
|
364 | ||||
|
365 | void VisualizationGraphWidget::addHorizontalCursorAtViewportPosition(double position) | |||
|
366 | { | |||
|
367 | impl->m_HorizontalCursor->setAbsolutePosition(position); | |||
|
368 | impl->m_HorizontalCursor->setVisible(true); | |||
|
369 | ||||
|
370 | auto axis = plot().axisRect()->axis(QCPAxis::atLeft); | |||
|
371 | impl->m_HorizontalCursor->setLabelText(QString::number(axis->pixelToCoord(position))); | |||
|
372 | } | |||
|
373 | ||||
|
374 | void VisualizationGraphWidget::removeHorizontalCursor() | |||
|
375 | { | |||
|
376 | impl->m_HorizontalCursor->setVisible(false); | |||
|
377 | plot().replot(QCustomPlot::rpQueuedReplot); | |||
|
378 | } | |||
|
379 | ||||
311 | void VisualizationGraphWidget::closeEvent(QCloseEvent *event) |
|
380 | void VisualizationGraphWidget::closeEvent(QCloseEvent *event) | |
312 | { |
|
381 | { | |
313 | Q_UNUSED(event); |
|
382 | Q_UNUSED(event); | |
@@ -328,6 +397,13 void VisualizationGraphWidget::leaveEvent(QEvent *event) | |||||
328 | { |
|
397 | { | |
329 | Q_UNUSED(event); |
|
398 | Q_UNUSED(event); | |
330 | impl->m_RenderingDelegate->showGraphOverlay(false); |
|
399 | impl->m_RenderingDelegate->showGraphOverlay(false); | |
|
400 | ||||
|
401 | if (auto parentZone = parentZoneWidget()) { | |||
|
402 | parentZone->notifyMouseLeaveGraph(this); | |||
|
403 | } | |||
|
404 | else { | |||
|
405 | qCWarning(LOG_VisualizationGraphWidget()) << "leaveEvent: No parent zone widget"; | |||
|
406 | } | |||
331 | } |
|
407 | } | |
332 |
|
408 | |||
333 | QCustomPlot &VisualizationGraphWidget::plot() noexcept |
|
409 | QCustomPlot &VisualizationGraphWidget::plot() noexcept | |
@@ -380,6 +456,20 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange | |||||
380 | emit synchronize(graphRange, oldGraphRange); |
|
456 | emit synchronize(graphRange, oldGraphRange); | |
381 | } |
|
457 | } | |
382 | } |
|
458 | } | |
|
459 | ||||
|
460 | auto pos = mapFromGlobal(QCursor::pos()); | |||
|
461 | auto axisPos = impl->posToAxisPos(pos, plot()); | |||
|
462 | if (auto parentZone = parentZoneWidget()) { | |||
|
463 | if (impl->pointIsInAxisRect(axisPos, plot())) { | |||
|
464 | parentZone->notifyMouseMoveInGraph(pos, axisPos, this); | |||
|
465 | } | |||
|
466 | else { | |||
|
467 | parentZone->notifyMouseLeaveGraph(this); | |||
|
468 | } | |||
|
469 | } | |||
|
470 | else { | |||
|
471 | qCWarning(LOG_VisualizationGraphWidget()) << "onMouseMove: No parent zone widget"; | |||
|
472 | } | |||
383 | } |
|
473 | } | |
384 |
|
474 | |||
385 | void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept |
|
475 | void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept | |
@@ -387,11 +477,24 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept | |||||
387 | // Handles plot rendering when mouse is moving |
|
477 | // Handles plot rendering when mouse is moving | |
388 | impl->m_RenderingDelegate->onMouseMove(event); |
|
478 | impl->m_RenderingDelegate->onMouseMove(event); | |
389 |
|
479 | |||
|
480 | auto axisPos = impl->posToAxisPos(event->pos(), plot()); | |||
|
481 | ||||
390 | if (impl->m_DrawingRect) { |
|
482 | if (impl->m_DrawingRect) { | |
391 | auto axisPos = impl->posToAxisPos(event->pos(), plot()); |
|
|||
392 | impl->m_DrawingRect->bottomRight->setCoords(axisPos); |
|
483 | impl->m_DrawingRect->bottomRight->setCoords(axisPos); | |
393 | } |
|
484 | } | |
394 |
|
485 | |||
|
486 | if (auto parentZone = parentZoneWidget()) { | |||
|
487 | if (impl->pointIsInAxisRect(axisPos, plot())) { | |||
|
488 | parentZone->notifyMouseMoveInGraph(event->pos(), axisPos, this); | |||
|
489 | } | |||
|
490 | else { | |||
|
491 | parentZone->notifyMouseLeaveGraph(this); | |||
|
492 | } | |||
|
493 | } | |||
|
494 | else { | |||
|
495 | qCWarning(LOG_VisualizationGraphWidget()) << "onMouseMove: No parent zone widget"; | |||
|
496 | } | |||
|
497 | ||||
395 | VisualizationDragWidget::mouseMoveEvent(event); |
|
498 | VisualizationDragWidget::mouseMoveEvent(event); | |
396 | } |
|
499 | } | |
397 |
|
500 |
@@ -53,7 +53,7 void processGraphs(QLayout &layout, Fun fun) | |||||
53 | for (auto i = 0; i < layout.count(); ++i) { |
|
53 | for (auto i = 0; i < layout.count(); ++i) { | |
54 | if (auto item = layout.itemAt(i)) { |
|
54 | if (auto item = layout.itemAt(i)) { | |
55 | if (auto visualizationGraphWidget |
|
55 | if (auto visualizationGraphWidget | |
56 |
= |
|
56 | = qobject_cast<VisualizationGraphWidget *>(item->widget())) { | |
57 | fun(*visualizationGraphWidget); |
|
57 | fun(*visualizationGraphWidget); | |
58 | } |
|
58 | } | |
59 | } |
|
59 | } | |
@@ -347,6 +347,59 bool VisualizationZoneWidget::isDragAllowed() const | |||||
347 | return true; |
|
347 | return true; | |
348 | } |
|
348 | } | |
349 |
|
349 | |||
|
350 | void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPosition, | |||
|
351 | const QPointF &plotPosition, | |||
|
352 | VisualizationGraphWidget *graphWidget) | |||
|
353 | { | |||
|
354 | processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget]( | |||
|
355 | VisualizationGraphWidget &processedGraph) { | |||
|
356 | ||||
|
357 | switch (sqpApp->plotsCursorMode()) { | |||
|
358 | case SqpApplication::PlotsCursorMode::Vertical: | |||
|
359 | processedGraph.removeHorizontalCursor(); | |||
|
360 | processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x()); | |||
|
361 | break; | |||
|
362 | case SqpApplication::PlotsCursorMode::Temporal: | |||
|
363 | processedGraph.addVerticalCursor(plotPosition.x()); | |||
|
364 | processedGraph.removeHorizontalCursor(); | |||
|
365 | break; | |||
|
366 | case SqpApplication::PlotsCursorMode::Horizontal: | |||
|
367 | processedGraph.removeVerticalCursor(); | |||
|
368 | if (&processedGraph == graphWidget) { | |||
|
369 | processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y()); | |||
|
370 | } | |||
|
371 | else { | |||
|
372 | processedGraph.removeHorizontalCursor(); | |||
|
373 | } | |||
|
374 | break; | |||
|
375 | case SqpApplication::PlotsCursorMode::Cross: | |||
|
376 | if (&processedGraph == graphWidget) { | |||
|
377 | processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x()); | |||
|
378 | processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y()); | |||
|
379 | } | |||
|
380 | else { | |||
|
381 | processedGraph.removeHorizontalCursor(); | |||
|
382 | processedGraph.removeVerticalCursor(); | |||
|
383 | } | |||
|
384 | break; | |||
|
385 | case SqpApplication::PlotsCursorMode::NoCursor: | |||
|
386 | processedGraph.removeHorizontalCursor(); | |||
|
387 | processedGraph.removeVerticalCursor(); | |||
|
388 | break; | |||
|
389 | } | |||
|
390 | ||||
|
391 | ||||
|
392 | }); | |||
|
393 | } | |||
|
394 | ||||
|
395 | void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget) | |||
|
396 | { | |||
|
397 | processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget &processedGraph) { | |||
|
398 | processedGraph.removeHorizontalCursor(); | |||
|
399 | processedGraph.removeVerticalCursor(); | |||
|
400 | }); | |||
|
401 | } | |||
|
402 | ||||
350 | void VisualizationZoneWidget::closeEvent(QCloseEvent *event) |
|
403 | void VisualizationZoneWidget::closeEvent(QCloseEvent *event) | |
351 | { |
|
404 | { | |
352 | // Closes graphs in the zone |
|
405 | // Closes graphs in the zone |
General Comments 1
You need to be logged in to leave comments.
Login now