##// END OF EJS Templates
More refactoring and added back plot tooltip...
jeandet -
r1363:e20b3853c9bd
parent child
Show More
@@ -20,7 +20,7 public:
20 explicit VisualizationGraphRenderingDelegate(VisualizationGraphWidget &graphWidget);
20 explicit VisualizationGraphRenderingDelegate(VisualizationGraphWidget &graphWidget);
21
21
22 void onMouseDoubleClick(QMouseEvent *event) noexcept;
22 void onMouseDoubleClick(QMouseEvent *event) noexcept;
23 void onMouseMove(QMouseEvent *event) noexcept;
23 void updateTooltip(QMouseEvent *event) noexcept;
24 /// Updates rendering when data of plot changed
24 /// Updates rendering when data of plot changed
25 void onPlotUpdated() noexcept;
25 void onPlotUpdated() noexcept;
26
26
@@ -130,6 +130,7 protected:
130 void mouseMoveEvent(QMouseEvent *event) override;
130 void mouseMoveEvent(QMouseEvent *event) override;
131 void mouseReleaseEvent(QMouseEvent *event) override;
131 void mouseReleaseEvent(QMouseEvent *event) override;
132 void mousePressEvent(QMouseEvent *event) override;
132 void mousePressEvent(QMouseEvent *event) override;
133 void mouseDoubleClickEvent(QMouseEvent *event) override;
133 void keyReleaseEvent(QKeyEvent * event) override;
134 void keyReleaseEvent(QKeyEvent * event) override;
134 void keyPressEvent(QKeyEvent * event) override;
135 void keyPressEvent(QKeyEvent * event) override;
135
136
@@ -146,7 +147,7 private slots:
146 void onGraphMenuRequested(const QPoint &pos) noexcept;
147 void onGraphMenuRequested(const QPoint &pos) noexcept;
147
148
148 /// Rescale the X axe to range parameter
149 /// Rescale the X axe to range parameter
149 void onRangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
150 // void onRangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
150
151
151 /// Slot called when a mouse double click was made
152 /// Slot called when a mouse double click was made
152 void onMouseDoubleClick(QMouseEvent *event) noexcept;
153 void onMouseDoubleClick(QMouseEvent *event) noexcept;
@@ -233,7 +233,7 void VisualizationGraphRenderingDelegate::onMouseDoubleClick(QMouseEvent *event)
233 }
233 }
234 }
234 }
235
235
236 void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexcept
236 void VisualizationGraphRenderingDelegate::updateTooltip(QMouseEvent *event) noexcept
237 {
237 {
238 // Cancels pending refresh
238 // Cancels pending refresh
239 impl->m_TracerTimer.disconnect();
239 impl->m_TracerTimer.disconnect();
@@ -210,6 +210,46 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
210 auto axisY = plot.axisRect()->axis(QCPAxis::atLeft);
210 auto axisY = plot.axisRect()->axis(QCPAxis::atLeft);
211 return axisX->range().contains(axisPoint.x()) && axisY->range().contains(axisPoint.y());
211 return axisX->range().contains(axisPoint.x()) && axisY->range().contains(axisPoint.y());
212 }
212 }
213
214 inline QCPRange _pixDistanceToRange(double pos1, double pos2, QCPAxis *axis)
215 {
216 if (axis->scaleType() == QCPAxis::stLinear)
217 {
218 auto diff = axis->pixelToCoord(pos1) - axis->pixelToCoord(pos2);
219 return QCPRange{axis->range().lower + diff, axis->range().upper + diff};
220 }
221 else
222 {
223 auto diff = axis->pixelToCoord(pos1) / axis->pixelToCoord(pos2);
224 return QCPRange{axis->range().lower * diff, axis->range().upper * diff};
225 }
226 }
227
228 void setRange(const QCPRange &newRange)
229 {
230 auto graphRange = DateTimeRange{newRange.lower, newRange.upper};
231
232 if (m_Flags.testFlag(GraphFlag::EnableAcquisition))
233 {
234 for (auto it = m_VariableToPlotMultiMap.begin(),
235 end = m_VariableToPlotMultiMap.end();
236 it != end; it = m_VariableToPlotMultiMap.upper_bound(it->first))
237 {
238 sqpApp->variableController().asyncChangeRange(it->first, graphRange);
239 }
240 }
241 }
242
243 void moveGraph(const QPoint& origin, const QPoint& destination, QCustomPlot* plot)
244 {
245 auto currentPos = destination;
246 auto xAxis = plot->axisRect()->rangeDragAxis(Qt::Horizontal);
247 auto yAxis = plot->axisRect()->rangeDragAxis(Qt::Vertical);
248 xAxis->setRange(_pixDistanceToRange(origin.x(), currentPos.x(), xAxis));
249 yAxis->setRange(_pixDistanceToRange(origin.y(), currentPos.y(), yAxis));
250 setRange(xAxis->range());
251 plot->replot(QCustomPlot::rpQueuedReplot);
252 }
213 };
253 };
214
254
215 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
255 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
@@ -233,6 +273,7 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget
233
273
234 // ↓ swhitch to this ASAP, VisualizationGraphWidget should intercept all UI events
274 // ↓ swhitch to this ASAP, VisualizationGraphWidget should intercept all UI events
235 this->setFocusPolicy(Qt::WheelFocus);
275 this->setFocusPolicy(Qt::WheelFocus);
276 this->setMouseTracking(true);
236 ui->widget->setAttribute(Qt::WA_TransparentForMouseEvents);
277 ui->widget->setAttribute(Qt::WA_TransparentForMouseEvents);
237 // connect(ui->widget, &QCustomPlot::mousePress, this,
278 // connect(ui->widget, &QCustomPlot::mousePress, this,
238 // &VisualizationGraphWidget::onMousePress); connect(ui->widget, &QCustomPlot::mouseRelease,
279 // &VisualizationGraphWidget::onMousePress); connect(ui->widget, &QCustomPlot::mouseRelease,
@@ -455,11 +496,10 void VisualizationGraphWidget::undoZoom()
455 void VisualizationGraphWidget::zoom(double factor, int center, Qt::Orientation orientation)
496 void VisualizationGraphWidget::zoom(double factor, int center, Qt::Orientation orientation)
456
497
457 {
498 {
458 auto oldRange = ui->widget->xAxis->range();
459 QCPAxis *axis = ui->widget->axisRect()->rangeZoomAxis(orientation);
499 QCPAxis *axis = ui->widget->axisRect()->rangeZoomAxis(orientation);
460 axis->scaleRange(factor, axis->pixelToCoord(center));
500 axis->scaleRange(factor, axis->pixelToCoord(center));
461 if (orientation == Qt::Horizontal)
501 if (orientation == Qt::Horizontal)
462 onRangeChanged(axis->range(), oldRange);
502 impl->setRange(axis->range());
463 ui->widget->replot(QCustomPlot::rpQueuedReplot);
503 ui->widget->replot(QCustomPlot::rpQueuedReplot);
464 }
504 }
465
505
@@ -488,7 +528,7 void VisualizationGraphWidget::move(double factor, Qt::Orientation orientation)
488 ui->widget->axisRect()->rangeDragAxis(orientation)->range().upper * diff);
528 ui->widget->axisRect()->rangeDragAxis(orientation)->range().upper * diff);
489 }
529 }
490 if (orientation == Qt::Horizontal)
530 if (orientation == Qt::Horizontal)
491 onRangeChanged(axis->range(), oldRange);
531 impl->setRange(axis->range());
492 ui->widget->replot(QCustomPlot::rpQueuedReplot);
532 ui->widget->replot(QCustomPlot::rpQueuedReplot);
493 }
533 }
494
534
@@ -709,33 +749,29 void VisualizationGraphWidget::wheelEvent(QWheelEvent *event)
709 QWidget::wheelEvent(event);
749 QWidget::wheelEvent(event);
710 }
750 }
711
751
712 inline QCPRange _pixDistanceToRange(double pos1, double pos2, QCPAxis *axis)
752
753
754 void VisualizationGraphWidget::mouseMoveEvent(QMouseEvent *event)
713 {
755 {
714 if (axis->scaleType() == QCPAxis::stLinear)
756 if (event->buttons() == Qt::LeftButton)
715 {
757 {
716 auto diff = axis->pixelToCoord(pos1) - axis->pixelToCoord(pos2);
758 impl->moveGraph(_dragLastPos, event->pos(), ui->widget);
717 return QCPRange{axis->range().lower + diff, axis->range().upper + diff};
759 _dragLastPos = event->pos();
718 }
760 }
719 else
761 else if(impl->m_DrawingZoomRect)
720 {
762 {
721 auto diff = axis->pixelToCoord(pos1) / axis->pixelToCoord(pos2);
763 QPointF pos{ui->widget->xAxis->pixelToCoord(event->pos().x()), ui->widget->yAxis->pixelToCoord(event->pos().y())};
722 return QCPRange{axis->range().lower * diff, axis->range().upper * diff};
764 impl->m_DrawingZoomRect->bottomRight->setCoords(pos);
723 }
765 }
724 }
766 else if (impl->m_DrawingZone)
725
767 {
726 void VisualizationGraphWidget::mouseMoveEvent(QMouseEvent *event)
768 impl->m_DrawingZone->setEnd(ui->widget->xAxis->pixelToCoord(event->pos().x()));
727 {
728 if (event->buttons() & Qt::LeftButton) {
729 auto currentPos = event->pos();
730 auto xAxis = ui->widget->axisRect()->rangeDragAxis(Qt::Horizontal);
731 auto yAxis = ui->widget->axisRect()->rangeDragAxis(Qt::Vertical);
732 auto oldXRange = xAxis->range();
733 xAxis->setRange(_pixDistanceToRange(_dragLastPos.x(), currentPos.x(), xAxis));
734 yAxis->setRange(_pixDistanceToRange(_dragLastPos.y(), currentPos.y(), yAxis));
735 onRangeChanged(oldXRange, xAxis->range());
736 ui->widget->replot(QCustomPlot::rpQueuedReplot);
737 _dragLastPos = currentPos;
738 }
769 }
770 else
771 {
772 impl->m_RenderingDelegate->updateTooltip(event);
773 }
774 event->accept();
739 QWidget::mouseMoveEvent(event);
775 QWidget::mouseMoveEvent(event);
740 }
776 }
741
777
@@ -752,12 +788,21 void VisualizationGraphWidget::mousePressEvent(QMouseEvent *event)
752 }
788 }
753 else {
789 else {
754 setCursor(Qt::ClosedHandCursor);
790 setCursor(Qt::ClosedHandCursor);
755 this->_dragLastPos= event->pos();
791 this->_dragLastPos = event->pos();
756 }
792 }
757 }
793 }
794 else if (event->button()==Qt::RightButton)
795 {
796 onGraphMenuRequested(event->pos());
797 }
758 QWidget::mousePressEvent(event);
798 QWidget::mousePressEvent(event);
759 }
799 }
760
800
801 void VisualizationGraphWidget::mouseDoubleClickEvent(QMouseEvent *event)
802 {
803 impl->m_RenderingDelegate->onMouseDoubleClick(event);
804 }
805
761 void VisualizationGraphWidget::keyReleaseEvent(QKeyEvent *event)
806 void VisualizationGraphWidget::keyReleaseEvent(QKeyEvent *event)
762 {
807 {
763 switch (event->key()) {
808 switch (event->key()) {
@@ -921,38 +966,38 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
921 }
966 }
922 }
967 }
923
968
924 void VisualizationGraphWidget::onRangeChanged(const QCPRange &newRange, const QCPRange &oldRange)
969 //void VisualizationGraphWidget::onRangeChanged(const QCPRange &newRange, const QCPRange &oldRange)
925 {
970 //{
926 auto graphRange = DateTimeRange{newRange.lower, newRange.upper};
971 // auto graphRange = DateTimeRange{newRange.lower, newRange.upper};
927 auto oldGraphRange = DateTimeRange{oldRange.lower, oldRange.upper};
972 // auto oldGraphRange = DateTimeRange{oldRange.lower, oldRange.upper};
928
973
929 if (impl->m_Flags.testFlag(GraphFlag::EnableAcquisition)) {
974 // if (impl->m_Flags.testFlag(GraphFlag::EnableAcquisition)) {
930 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
975 // for (auto it = impl->m_VariableToPlotMultiMap.begin(),
931 end = impl->m_VariableToPlotMultiMap.end();
976 // end = impl->m_VariableToPlotMultiMap.end();
932 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
977 // it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
933 sqpApp->variableController().asyncChangeRange(it->first, graphRange);
978 // sqpApp->variableController().asyncChangeRange(it->first, graphRange);
934 }
979 // }
935 }
980 // }
936
981
937 // if (impl->m_Flags.testFlag(GraphFlag::EnableSynchronization) && !impl->m_IsCalibration)
982 // // if (impl->m_Flags.testFlag(GraphFlag::EnableSynchronization) && !impl->m_IsCalibration)
938 // {
983 // // {
939 // emit synchronize(graphRange, oldGraphRange);
984 // // emit synchronize(graphRange, oldGraphRange);
940 // }
985 // // }
941
986
942 // auto pos = mapFromGlobal(QCursor::pos());
987 // // auto pos = mapFromGlobal(QCursor::pos());
943 // auto axisPos = impl->posToAxisPos(pos, plot());
988 // // auto axisPos = impl->posToAxisPos(pos, plot());
944 // if (auto parentZone = parentZoneWidget()) {
989 // // if (auto parentZone = parentZoneWidget()) {
945 // if (impl->pointIsInAxisRect(axisPos, plot())) {
990 // // if (impl->pointIsInAxisRect(axisPos, plot())) {
946 // parentZone->notifyMouseMoveInGraph(pos, axisPos, this);
991 // // parentZone->notifyMouseMoveInGraph(pos, axisPos, this);
947 // }
992 // // }
948 // else {
993 // // else {
949 // parentZone->notifyMouseLeaveGraph(this);
994 // // parentZone->notifyMouseLeaveGraph(this);
950 // }
995 // // }
951 // }
996 // // }
952
997
953 // Quits calibration
998 // // Quits calibration
954 // impl->m_IsCalibration = false;
999 // // impl->m_IsCalibration = false;
955 }
1000 //}
956
1001
957 void VisualizationGraphWidget::onMouseDoubleClick(QMouseEvent *event) noexcept
1002 void VisualizationGraphWidget::onMouseDoubleClick(QMouseEvent *event) noexcept
958 {
1003 {
@@ -962,7 +1007,7 void VisualizationGraphWidget::onMouseDoubleClick(QMouseEvent *event) noexcept
962 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
1007 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
963 {
1008 {
964 // Handles plot rendering when mouse is moving
1009 // Handles plot rendering when mouse is moving
965 impl->m_RenderingDelegate->onMouseMove(event);
1010 impl->m_RenderingDelegate->updateTooltip(event);
966
1011
967 auto axisPos = impl->posToAxisPos(event->pos(), plot());
1012 auto axisPos = impl->posToAxisPos(event->pos(), plot());
968
1013
@@ -1074,11 +1119,6 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
1074 }
1119 }
1075 }
1120 }
1076
1121
1077 // Allows mouse panning only in default mode
1078 // plot().setInteraction(QCP::iRangeDrag, sqpApp->plotsInteractionMode()
1079 // ==
1080 // SqpApplication::PlotsInteractionMode::None
1081 // && !isDragDropClick);
1082
1122
1083 // Allows zone edition only in selection zone mode without drag&drop
1123 // Allows zone edition only in selection zone mode without drag&drop
1084 impl->setSelectionZonesEditionEnabled(isSelectionZoneMode && !isDragDropClick);
1124 impl->setSelectionZonesEditionEnabled(isSelectionZoneMode && !isDragDropClick);
@@ -19,18 +19,19
19 ALIAS_TEMPLATE_FUNCTION(isReady, static_cast<SqpApplication *>(qApp)->variableController().isReady)
19 ALIAS_TEMPLATE_FUNCTION(isReady, static_cast<SqpApplication *>(qApp)->variableController().isReady)
20
20
21 #define A_SIMPLE_GRAPH_FIXTURE \
21 #define A_SIMPLE_GRAPH_FIXTURE \
22 VisualizationGraphWidget w;\
22 VisualizationGraphWidget w;\
23 PREPARE_GUI_TEST(w);\
23 PREPARE_GUI_TEST(w);\
24 auto provider = std::make_shared<SimpleRange<10> >();\
24 auto provider = std::make_shared<SimpleRange<10> >();\
25 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), QDate(2018, 8, 7),\
25 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), QDate(2018, 8, 7),\
26 QTime(16, 00));\
26 QTime(16, 00));\
27 auto var = static_cast<SqpApplication *>(qApp)->variableController().createVariable(\
27 auto var = static_cast<SqpApplication *>(qApp)->variableController().createVariable(\
28 "V1", {{"", "scalar"}}, provider, range);\
28 "V1", {{"", "scalar"}}, provider, range);\
29 while (!isReady(var))\
29 while (!isReady(var))\
30 QCoreApplication::processEvents();\
30 QCoreApplication::processEvents();\
31 w.addVariable(var, range);\
31 w.addVariable(var, range);\
32 GET_CHILD_WIDGET_FOR_GUI_TESTS(w, plot, QCustomPlot, "widget");\
32 GET_CHILD_WIDGET_FOR_GUI_TESTS(w, plot, QCustomPlot, "widget");\
33 auto cent = center(&w);\
33 auto cent = center(&w);
34
34
35
35
36
36 class A_SimpleGraph : public QObject {
37 class A_SimpleGraph : public QObject {
@@ -39,19 +40,19 public:
39 explicit A_SimpleGraph(QObject *parent = Q_NULLPTR) : QObject(parent) {}
40 explicit A_SimpleGraph(QObject *parent = Q_NULLPTR) : QObject(parent) {}
40
41
41 private slots:
42 private slots:
42 void scrolls_with_mouse()
43 void scrolls_left_with_mouse()
43 {
44 {
44 A_SIMPLE_GRAPH_FIXTURE
45 A_SIMPLE_GRAPH_FIXTURE;
45
46
46 for (auto i = 0; i < 10; i++) {
47 for (auto i = 0; i < 100; i++) {
47 QTest::mousePress(&w, Qt::LeftButton, Qt::NoModifier, cent, 500);
48 QTest::mousePress(&w, Qt::LeftButton, Qt::NoModifier, cent, 1);
48 mouseMove(&w, {cent.x() + 200, cent.y()}, Qt::LeftButton);
49 mouseMove(&w, {cent.x() + 200, cent.y()}, Qt::LeftButton);
49 QTest::mouseRelease(&w, Qt::LeftButton);
50 QTest::mouseRelease(&w, Qt::LeftButton);
50 while (!isReady(var))
51 while (!isReady(var))
51 QCoreApplication::processEvents();
52 QCoreApplication::processEvents();
52 }
53 }
53 while (!isReady(var))
54 while (!isReady(var))
54 QCoreApplication::processEvents();
55 QCoreApplication::processEvents();
55 auto r = var->range();
56 auto r = var->range();
56 /*
57 /*
57 * Scrolling to the left implies going back in time
58 * Scrolling to the left implies going back in time
@@ -60,6 +61,28 private slots:
60 QVERIFY(r.m_TEnd < range.m_TEnd);
61 QVERIFY(r.m_TEnd < range.m_TEnd);
61 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(),range.delta(),1));
62 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(),range.delta(),1));
62 }
63 }
64
65 void scrolls_right_with_mouse()
66 {
67 A_SIMPLE_GRAPH_FIXTURE;
68
69 for (auto i = 0; i < 100; i++) {
70 QTest::mousePress(&w, Qt::LeftButton, Qt::NoModifier, cent, 1);
71 mouseMove(&w, {cent.x() - 200, cent.y()}, Qt::LeftButton);
72 QTest::mouseRelease(&w, Qt::LeftButton);
73 while (!isReady(var))
74 QCoreApplication::processEvents();
75 }
76 while (!isReady(var))
77 QCoreApplication::processEvents();
78 auto r = var->range();
79 /*
80 * Scrolling to the right implies going forward in time
81 * Scroll only implies keeping the same delta T -> shit only transformation
82 */
83 QVERIFY(r.m_TEnd > range.m_TEnd);
84 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(),range.delta(),1));
85 }
63 };
86 };
64
87
65 QT_BEGIN_NAMESPACE
88 QT_BEGIN_NAMESPACE
@@ -69,10 +92,10 int main(int argc, char *argv[])
69 {
92 {
70 SqpApplication app{argc, argv};
93 SqpApplication app{argc, argv};
71 app.setAttribute(Qt::AA_Use96Dpi, true);
94 app.setAttribute(Qt::AA_Use96Dpi, true);
72 QTEST_DISABLE_KEYPAD_NAVIGATION
95 QTEST_DISABLE_KEYPAD_NAVIGATION;
73 QTEST_ADD_GPU_BLACKLIST_SUPPORT
96 QTEST_ADD_GPU_BLACKLIST_SUPPORT;
74 A_SimpleGraph tc;
97 A_SimpleGraph tc;
75 QTEST_SET_MAIN_SOURCE_PATH
98 QTEST_SET_MAIN_SOURCE_PATH;
76 return QTest::qExec(&tc, argc, argv);
99 return QTest::qExec(&tc, argc, argv);
77 }
100 }
78
101
General Comments 0
You need to be logged in to leave comments. Login now