@@ -51,6 +51,9 public: | |||||
51 | SqpRange graphRange() const noexcept; |
|
51 | SqpRange graphRange() const noexcept; | |
52 | void setGraphRange(const SqpRange &range); |
|
52 | void setGraphRange(const SqpRange &range); | |
53 |
|
53 | |||
|
54 | /// Undo the last zoom done with a zoom box | |||
|
55 | void undoZoom(); | |||
|
56 | ||||
54 | // IVisualizationWidget interface |
|
57 | // IVisualizationWidget interface | |
55 | void accept(IVisualizationWidgetVisitor *visitor) override; |
|
58 | void accept(IVisualizationWidgetVisitor *visitor) override; | |
56 | bool canDrop(const Variable &variable) const override; |
|
59 | bool canDrop(const Variable &variable) const override; |
@@ -73,6 +73,7 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||||
73 | std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate; |
|
73 | std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate; | |
74 |
|
74 | |||
75 | QCPItemRect *m_DrawingZoomRect = nullptr; |
|
75 | QCPItemRect *m_DrawingZoomRect = nullptr; | |
|
76 | QStack<QPair<QCPRange, QCPRange> > m_ZoomStack; | |||
76 |
|
77 | |||
77 | std::unique_ptr<VisualizationCursorItem> m_HorizontalCursor = nullptr; |
|
78 | std::unique_ptr<VisualizationCursorItem> m_HorizontalCursor = nullptr; | |
78 | std::unique_ptr<VisualizationCursorItem> m_VerticalCursor = nullptr; |
|
79 | std::unique_ptr<VisualizationCursorItem> m_VerticalCursor = nullptr; | |
@@ -315,6 +316,18 void VisualizationGraphWidget::setGraphRange(const SqpRange &range) | |||||
315 | qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END"); |
|
316 | qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END"); | |
316 | } |
|
317 | } | |
317 |
|
318 | |||
|
319 | void VisualizationGraphWidget::undoZoom() | |||
|
320 | { | |||
|
321 | auto zoom = impl->m_ZoomStack.pop(); | |||
|
322 | auto axisX = plot().axisRect()->axis(QCPAxis::atBottom); | |||
|
323 | auto axisY = plot().axisRect()->axis(QCPAxis::atLeft); | |||
|
324 | ||||
|
325 | axisX->setRange(zoom.first); | |||
|
326 | axisY->setRange(zoom.second); | |||
|
327 | ||||
|
328 | plot().replot(QCustomPlot::rpQueuedReplot); | |||
|
329 | } | |||
|
330 | ||||
318 | void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor) |
|
331 | void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor) | |
319 | { |
|
332 | { | |
320 | if (visitor) { |
|
333 | if (visitor) { | |
@@ -487,6 +500,14 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept | |||||
487 | [ this, var = it->first ]() { removeVariable(var); }); |
|
500 | [ this, var = it->first ]() { removeVariable(var); }); | |
488 | } |
|
501 | } | |
489 |
|
502 | |||
|
503 | if (!impl->m_ZoomStack.isEmpty()) { | |||
|
504 | if (!graphMenu.isEmpty()) { | |||
|
505 | graphMenu.addSeparator(); | |||
|
506 | } | |||
|
507 | ||||
|
508 | graphMenu.addAction(tr("Undo Zoom"), [this]() { undoZoom(); }); | |||
|
509 | } | |||
|
510 | ||||
490 | if (!graphMenu.isEmpty()) { |
|
511 | if (!graphMenu.isEmpty()) { | |
491 | graphMenu.exec(QCursor::pos()); |
|
512 | graphMenu.exec(QCursor::pos()); | |
492 | } |
|
513 | } | |
@@ -686,6 +707,7 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept | |||||
686 |
|
707 | |||
687 | if (newAxisXRange.size() > axisX->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0) |
|
708 | if (newAxisXRange.size() > axisX->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0) | |
688 | && newAxisYRange.size() > axisY->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)) { |
|
709 | && newAxisYRange.size() > axisY->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)) { | |
|
710 | impl->m_ZoomStack.push(qMakePair(axisX->range(), axisY->range())); | |||
689 | axisX->setRange(newAxisXRange); |
|
711 | axisX->setRange(newAxisXRange); | |
690 | axisY->setRange(newAxisYRange); |
|
712 | axisY->setRange(newAxisYRange); | |
691 |
|
713 |
General Comments 0
You need to be logged in to leave comments.
Login now