From 210660d057e5a6e2ee1b61472156abff0d046d6a Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Tue, 26 Oct 2021 16:37:38 +0200 Subject: [PATCH] profile: rewrite ProfileScene::pointOnProfile() This function was used to check wether a screen-point is located on the profile. Bizzarely, this was done by transforming into local coordinates and checking min/max value. Simply check the screen coordinates directly. Moreover, make the function return whether the point is inside the region, not outside the region, to make logic more straight forward. Signed-off-by: Berthold Stoeger --- profile-widget/divecartesianaxis.cpp | 21 +++++++++++++++++---- profile-widget/divecartesianaxis.h | 1 + profile-widget/divehandler.cpp | 2 +- profile-widget/profilescene.cpp | 9 ++------- profile-widget/profilescene.h | 2 +- profile-widget/profilewidget2.cpp | 2 +- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/profile-widget/divecartesianaxis.cpp b/profile-widget/divecartesianaxis.cpp index 7d0ed34e4..69e885ba4 100644 --- a/profile-widget/divecartesianaxis.cpp +++ b/profile-widget/divecartesianaxis.cpp @@ -375,18 +375,31 @@ qreal DiveCartesianAxis::posAtValue(qreal value) const return adjusted; } +static std::pair getLineFromTo(const QLineF &l, bool horizontal) +{ + if (horizontal) + return std::make_pair(l.x1(), l.x2()); + else + return std::make_pair(l.y1(), l.y2()); +} + double DiveCartesianAxis::screenPosition(double pos) const { - QLineF m = line(); - double from = position == Position::Bottom ? m.x1() : m.y1(); - double to = position == Position::Bottom ? m.x2() : m.y2(); - if ((position == Position::Bottom) == inverted) pos = 1.0 - pos; + auto [from, to] = getLineFromTo(line(), position == Position::Bottom); return (to - from) * pos + from; } +double DiveCartesianAxis::pointInRange(double pos) const +{ + auto [from, to] = getLineFromTo(line(), position == Position::Bottom); + if (from > to) + std::swap(from, to); + return pos >= from && pos <= to; +} + double DiveCartesianAxis::maximum() const { return max; diff --git a/profile-widget/divecartesianaxis.h b/profile-widget/divecartesianaxis.h index 7ee727313..89874415a 100644 --- a/profile-widget/divecartesianaxis.h +++ b/profile-widget/divecartesianaxis.h @@ -40,6 +40,7 @@ public: qreal posAtValue(qreal value) const; void setPosition(const QRectF &rect); double screenPosition(double pos) const; // 0.0 = begin, 1.0 = end of axis, independent of represented values + double pointInRange(double pos) const; // Point on screen is in range of axis void setTextVisible(bool arg1); void setLinesVisible(bool arg1); void updateTicks(int animSpeed); diff --git a/profile-widget/divehandler.cpp b/profile-widget/divehandler.cpp index 28ac90ffe..d9edf342a 100644 --- a/profile-widget/divehandler.cpp +++ b/profile-widget/divehandler.cpp @@ -75,7 +75,7 @@ void DiveHandler::mouseMoveEvent(QGraphicsSceneMouseEvent *event) t.start(); ProfileWidget2 *view = qobject_cast(scene()->views().first()); - if(view->profileScene->isPointOutOfBoundaries(event->scenePos())) + if(!view->profileScene->pointOnProfile(event->scenePos())) return; QGraphicsEllipseItem::mouseMoveEvent(event); diff --git a/profile-widget/profilescene.cpp b/profile-widget/profilescene.cpp index 0b422856f..d5e089538 100644 --- a/profile-widget/profilescene.cpp +++ b/profile-widget/profilescene.cpp @@ -313,14 +313,9 @@ void ProfileScene::updateAxes(bool diveHasHeartBeat, bool simplified) temperatureAxis->setTransform(slope(mkelvin_to_F), intercept(mkelvin_to_F)); } -bool ProfileScene::isPointOutOfBoundaries(const QPointF &point) const +bool ProfileScene::pointOnProfile(const QPointF &point) const { - double xpos = timeAxis->valueAt(point); - double ypos = profileYAxis->valueAt(point); - return xpos > timeAxis->maximum() || - xpos < timeAxis->minimum() || - ypos > profileYAxis->maximum() || - ypos < profileYAxis->minimum(); + return timeAxis->pointInRange(point.x()) && profileYAxis->pointInRange(point.y()); } void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsModel *plannerModel, diff --git a/profile-widget/profilescene.h b/profile-widget/profilescene.h index 2147e8c85..5477597f6 100644 --- a/profile-widget/profilescene.h +++ b/profile-widget/profilescene.h @@ -38,7 +38,7 @@ public: void resize(QSizeF size); void clear(); - bool isPointOutOfBoundaries(const QPointF &point) const; + bool pointOnProfile(const QPointF &point) const; // If a plannerModel is passed, the deco-information is taken from there. void plotDive(const struct dive *d, int dc, DivePlannerPointsModel *plannerModel = nullptr, bool inPlanner = false, diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index d0d2ccadf..924877790 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -332,7 +332,7 @@ void ProfileWidget2::mouseDoubleClickEvent(QMouseEvent *event) { if ((currentState == PLAN || currentState == EDIT) && plannerModel) { QPointF mappedPos = mapToScene(event->pos()); - if (profileScene->isPointOutOfBoundaries(mappedPos)) + if (!profileScene->pointOnProfile(mappedPos)) return; int minutes = lrint(profileScene->timeAxis->valueAt(mappedPos) / 60);