profile: move zooming/panning code to ProfileView

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2023-05-20 17:12:33 +02:00
parent 9ab7819fd1
commit 413b236867
4 changed files with 94 additions and 85 deletions

View file

@ -255,7 +255,7 @@ void ProfileWidget::plotDive(dive *dIn, int dcIn)
setDive(editedDive.get(), dc); setDive(editedDive.get(), dc);
} else if (d) { } else if (d) {
//view->setProfileState(d, dc); //view->setProfileState(d, dc);
//view->resetZoom(); // when switching dive, reset the zoomLevel view->resetZoom(); // when switching dive, reset the zoomLevel
view->plotDive(d, dc); view->plotDive(d, dc);
setDive(d, dc); setDive(d, dc);
} else { } else {

View file

@ -11,6 +11,7 @@
#include "qt-quick/chartitem.h" #include "qt-quick/chartitem.h"
#include <QAbstractAnimation> #include <QAbstractAnimation>
#include <QCursor>
#include <QDebug> #include <QDebug>
#include <QElapsedTimer> #include <QElapsedTimer>
@ -53,6 +54,7 @@ ProfileView::ProfileView(QQuickItem *parent) : ChartView(parent, ProfileZValue::
dc(0), dc(0),
zoomLevel(0), zoomLevel(0),
zoomedPosition(0.0), zoomedPosition(0.0),
panning(false),
empty(true), empty(true),
shouldCalculateMax(true) shouldCalculateMax(true)
{ {
@ -86,6 +88,8 @@ ProfileView::ProfileView(QQuickItem *parent) : ChartView(parent, ProfileZValue::
connect(pp_gas, &qPrefPartialPressureGas::pheChanged, this, &ProfileView::replot); connect(pp_gas, &qPrefPartialPressureGas::pheChanged, this, &ProfileView::replot);
connect(pp_gas, &qPrefPartialPressureGas::pn2Changed, this, &ProfileView::replot); connect(pp_gas, &qPrefPartialPressureGas::pn2Changed, this, &ProfileView::replot);
connect(pp_gas, &qPrefPartialPressureGas::po2Changed, this, &ProfileView::replot); connect(pp_gas, &qPrefPartialPressureGas::po2Changed, this, &ProfileView::replot);
setAcceptTouchEvents(true);
} }
ProfileView::ProfileView() : ProfileView(nullptr) ProfileView::ProfileView() : ProfileView(nullptr)
@ -213,3 +217,82 @@ void ProfileView::anim(double fraction)
profileItem->draw(size(), background, *profileScene); profileItem->draw(size(), background, *profileScene);
update(); update();
} }
void ProfileView::resetZoom()
{
zoomLevel = 0;
zoomedPosition = 0.0;
}
void ProfileView::setZoom(int level)
{
zoomLevel = level;
plotDive(d, dc, RenderFlags::DontRecalculatePlotInfo);
}
void ProfileView::wheelEvent(QWheelEvent *event)
{
if (!d)
return;
if (panning)
return; // No change in zoom level while panning.
if (event->buttons() == Qt::LeftButton)
return;
if (event->angleDelta().y() > 0 && zoomLevel < 20)
setZoom(++zoomLevel);
else if (event->angleDelta().y() < 0 && zoomLevel > 0)
setZoom(--zoomLevel);
else if (event->angleDelta().x() && zoomLevel > 0) {
double oldPos = zoomedPosition;
zoomedPosition = profileScene->calcZoomPosition(calcZoom(zoomLevel),
oldPos,
oldPos - event->angleDelta().x());
if (oldPos != zoomedPosition)
plotDive(d, dc, RenderFlags::Instant | RenderFlags::DontRecalculatePlotInfo);
}
}
void ProfileView::mousePressEvent(QMouseEvent *event)
{
panning = true;
panningOriginalMousePosition = mapToScene(event->pos()).x();
panningOriginalProfilePosition = zoomedPosition;
setCursor(Qt::ClosedHandCursor);
event->accept();
}
void ProfileView::mouseReleaseEvent(QMouseEvent *)
{
if (panning) {
panning = false;
unsetCursor();
}
//if (currentState == PLAN || currentState == EDIT) {
// shouldCalculateMax = true;
// replot();
//}
}
void ProfileView::mouseMoveEvent(QMouseEvent *event)
{
QPointF pos = mapToScene(event->pos());
if (panning) {
double oldPos = zoomedPosition;
zoomedPosition = profileScene->calcZoomPosition(calcZoom(zoomLevel),
panningOriginalProfilePosition,
panningOriginalMousePosition - pos.x());
if (oldPos != zoomedPosition)
plotDive(d, dc, RenderFlags::Instant | RenderFlags::DontRecalculatePlotInfo); // TODO: animations don't work when scrolling
}
//toolTipItem->refresh(d, mapToScene(mapFromGlobal(QCursor::pos())), currentState == PLAN);
//if (currentState == PLAN || currentState == EDIT) {
//QRectF rect = profileScene->profileRegion;
//auto [miny, maxy] = profileScene->profileYAxis->screenMinMax();
//double x = std::clamp(pos.x(), rect.left(), rect.right());
//double y = std::clamp(pos.y(), miny, maxy);
//mouseFollowerHorizontal->setLine(rect.left(), y, rect.right(), y);
//mouseFollowerVertical->setLine(x, rect.top(), x, rect.bottom());
//}
}

View file

@ -26,12 +26,16 @@ public:
void plotDive(const struct dive *d, int dc, int flags = RenderFlags::None); void plotDive(const struct dive *d, int dc, int flags = RenderFlags::None);
void clear(); void clear();
void resetZoom();
void anim(double fraction); void anim(double fraction);
private: private:
const struct dive *d; const struct dive *d;
int dc; int dc;
int zoomLevel; int zoomLevel;
double zoomedPosition; // Position when zoomed: 0.0 = beginning, 1.0 = end. double zoomedPosition; // Position when zoomed: 0.0 = beginning, 1.0 = end.
bool panning; // Currently panning.
double panningOriginalMousePosition;
double panningOriginalProfilePosition;
bool empty; // No dive shown. bool empty; // No dive shown.
bool shouldCalculateMax; // Calculate maximum time and depth (default). False when dragging handles. bool shouldCalculateMax; // Calculate maximum time and depth (default). False when dragging handles.
QColor background; QColor background;
@ -42,6 +46,12 @@ private:
void plotAreaChanged(const QSizeF &size) override; void plotAreaChanged(const QSizeF &size) override;
void resetPointers() override; void resetPointers() override;
void replot(); void replot();
void setZoom(int level);
void wheelEvent(QWheelEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
}; };
#endif #endif

View file

@ -156,12 +156,6 @@ void ProfileWidget2::setupSceneAndFlags()
setMouseTracking(true); setMouseTracking(true);
} }
void ProfileWidget2::resetZoom()
{
zoomLevel = 0;
zoomedPosition = 0.0;
}
// Currently just one dive, but the plan is to enable All of the selected dives. // Currently just one dive, but the plan is to enable All of the selected dives.
void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, int flags) void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, int flags)
{ {
@ -245,18 +239,6 @@ void ProfileWidget2::resizeEvent(QResizeEvent *event)
} }
#ifndef SUBSURFACE_MOBILE #ifndef SUBSURFACE_MOBILE
void ProfileWidget2::mousePressEvent(QMouseEvent *event)
{
QGraphicsView::mousePressEvent(event);
if (!event->isAccepted()) {
panning = true;
panningOriginalMousePosition = mapToScene(event->pos()).x();
panningOriginalProfilePosition = zoomedPosition;
viewport()->setCursor(Qt::ClosedHandCursor);
}
}
void ProfileWidget2::divePlannerHandlerClicked() void ProfileWidget2::divePlannerHandlerClicked()
{ {
shouldCalculateMax = false; shouldCalculateMax = false;
@ -270,49 +252,9 @@ void ProfileWidget2::divePlannerHandlerReleased()
replot(); replot();
} }
void ProfileWidget2::mouseReleaseEvent(QMouseEvent *event)
{
QGraphicsView::mouseReleaseEvent(event);
if (panning) {
panning = false;
viewport()->setCursor(Qt::ArrowCursor);
}
if (currentState == PLAN || currentState == EDIT) {
shouldCalculateMax = true;
replot();
}
}
#endif #endif
void ProfileWidget2::setZoom(int level)
{
zoomLevel = level;
plotDive(d, dc, RenderFlags::DontRecalculatePlotInfo);
}
#ifndef SUBSURFACE_MOBILE #ifndef SUBSURFACE_MOBILE
void ProfileWidget2::wheelEvent(QWheelEvent *event)
{
if (!d)
return;
if (event->angleDelta().x() && zoomLevel > 0) {
double oldPos = zoomedPosition;
zoomedPosition = profileScene->calcZoomPosition(calcZoom(zoomLevel),
oldPos,
oldPos - event->angleDelta().x());
if (oldPos != zoomedPosition)
plotDive(d, dc, RenderFlags::Instant | RenderFlags::DontRecalculatePlotInfo);
}
if (panning)
return; // No change in zoom level while panning.
if (event->buttons() == Qt::LeftButton)
return;
if (event->angleDelta().y() > 0 && zoomLevel < 20)
setZoom(++zoomLevel);
else if (event->angleDelta().y() < 0 && zoomLevel > 0)
setZoom(--zoomLevel);
}
void ProfileWidget2::mouseDoubleClickEvent(QMouseEvent *event) void ProfileWidget2::mouseDoubleClickEvent(QMouseEvent *event)
{ {
if ((currentState == PLAN || currentState == EDIT) && plannerModel) { if ((currentState == PLAN || currentState == EDIT) && plannerModel) {
@ -328,32 +270,6 @@ void ProfileWidget2::mouseDoubleClickEvent(QMouseEvent *event)
} }
} }
void ProfileWidget2::mouseMoveEvent(QMouseEvent *event)
{
QGraphicsView::mouseMoveEvent(event);
QPointF pos = mapToScene(event->pos());
if (panning) {
double oldPos = zoomedPosition;
zoomedPosition = profileScene->calcZoomPosition(calcZoom(zoomLevel),
panningOriginalProfilePosition,
panningOriginalMousePosition - pos.x());
if (oldPos != zoomedPosition)
plotDive(d, dc, RenderFlags::Instant | RenderFlags::DontRecalculatePlotInfo); // TODO: animations don't work when scrolling
}
toolTipItem->refresh(d, mapToScene(mapFromGlobal(QCursor::pos())), currentState == PLAN);
if (currentState == PLAN || currentState == EDIT) {
QRectF rect = profileScene->profileRegion;
auto [miny, maxy] = profileScene->profileYAxis->screenMinMax();
double x = std::clamp(pos.x(), rect.left(), rect.right());
double y = std::clamp(pos.y(), miny, maxy);
mouseFollowerHorizontal->setLine(rect.left(), y, rect.right(), y);
mouseFollowerVertical->setLine(x, rect.top(), x, rect.bottom());
}
}
bool ProfileWidget2::eventFilter(QObject *object, QEvent *event) bool ProfileWidget2::eventFilter(QObject *object, QEvent *event)
{ {
QGraphicsScene *s = qobject_cast<QGraphicsScene *>(object); QGraphicsScene *s = qobject_cast<QGraphicsScene *>(object);