diff --git a/profile-widget/divecartesianaxis.cpp b/profile-widget/divecartesianaxis.cpp index c048a3a17..1f6f5a81f 100644 --- a/profile-widget/divecartesianaxis.cpp +++ b/profile-widget/divecartesianaxis.cpp @@ -7,7 +7,7 @@ #include "qt-models/diveplotdatamodel.h" #include "profile-widget/animationfunctions.h" #include "profile-widget/divelineitem.h" -#include "profile-widget/profilewidget2.h" +#include "profile-widget/profilescene.h" QPen DiveCartesianAxis::gridPen() const { @@ -60,10 +60,10 @@ void DiveCartesianAxis::setTextColor(const QColor &color) textColor = color; } -DiveCartesianAxis::DiveCartesianAxis(double fontPrintScale, ProfileWidget2 *widget) : QObject(), +DiveCartesianAxis::DiveCartesianAxis(double fontPrintScale, ProfileScene &scene) : QObject(), QGraphicsLineItem(), printMode(false), - profileWidget(widget), + scene(scene), orientation(LeftToRight), min(0), max(0), @@ -133,11 +133,9 @@ void emptyList(QList &list, int steps, int speed) void DiveCartesianAxis::updateTicks(color_index_t color) { - if (!scene() || (!changed && !printMode)) + if (!changed && !printMode) return; QLineF m = line(); - // unused so far: - // QGraphicsView *view = scene()->views().first(); double stepsInRange = (max - min) / interval; int steps = (int)stepsInRange; double currValueText = min; @@ -146,8 +144,8 @@ void DiveCartesianAxis::updateTicks(color_index_t color) if (steps < 1) return; - emptyList(labels, steps, profileWidget->animSpeed); - emptyList(lines, steps, profileWidget->animSpeed); + emptyList(labels, steps, scene.animSpeed); + emptyList(lines, steps, scene.animSpeed); // Move the remaining ticks / text to their correct positions // regarding the possible new values for the axis @@ -174,9 +172,9 @@ void DiveCartesianAxis::updateTicks(color_index_t color) labels[i]->setText(textForValue(currValueText)); if (orientation == LeftToRight || orientation == RightToLeft) { - Animations::moveTo(labels[i], profileWidget->animSpeed, childPos, m.y1() + tick_size); + Animations::moveTo(labels[i], scene.animSpeed, childPos, m.y1() + tick_size); } else { - Animations::moveTo(labels[i], profileWidget->animSpeed ,m.x1() - tick_size, childPos); + Animations::moveTo(labels[i], scene.animSpeed ,m.x1() - tick_size, childPos); } } @@ -186,9 +184,9 @@ void DiveCartesianAxis::updateTicks(color_index_t color) begin - i * stepSize; if (orientation == LeftToRight || orientation == RightToLeft) { - Animations::moveTo(lines[i], profileWidget->animSpeed, childPos, m.y1()); + Animations::moveTo(lines[i], scene.animSpeed, childPos, m.y1()); } else { - Animations::moveTo(lines[i], profileWidget->animSpeed, m.x1(), childPos); + Animations::moveTo(lines[i], scene.animSpeed, m.x1(), childPos); } } @@ -208,12 +206,12 @@ void DiveCartesianAxis::updateTicks(color_index_t color) labels.push_back(label); if (orientation == RightToLeft || orientation == LeftToRight) { label->setAlignment(Qt::AlignBottom | Qt::AlignHCenter); - label->setPos(scene()->sceneRect().width() + 10, m.y1() + tick_size); // position it outside of the scene); - Animations::moveTo(label, profileWidget->animSpeed,childPos , m.y1() + tick_size); + label->setPos(scene.sceneRect().width() + 10, m.y1() + tick_size); // position it outside of the scene; + Animations::moveTo(label, scene.animSpeed,childPos , m.y1() + tick_size); } else { label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); - label->setPos(m.x1() - tick_size, scene()->sceneRect().height() + 10); - Animations::moveTo(label, profileWidget->animSpeed, m.x1() - tick_size, childPos); + label->setPos(m.x1() - tick_size, scene.sceneRect().height() + 10); + Animations::moveTo(label, scene.animSpeed, m.x1() - tick_size, childPos); } } @@ -233,14 +231,14 @@ void DiveCartesianAxis::updateTicks(color_index_t color) lines.push_back(line); if (orientation == RightToLeft || orientation == LeftToRight) { line->setLine(0, -line_size, 0, 0); - line->setPos(scene()->sceneRect().width() + 10, m.y1()); // position it outside of the scene); - Animations::moveTo(line, profileWidget->animSpeed, childPos, m.y1()); + line->setPos(scene.sceneRect().width() + 10, m.y1()); // position it outside of the scene); + Animations::moveTo(line, scene.animSpeed, childPos, m.y1()); } else { QPointF p1 = mapFromScene(3, 0); QPointF p2 = mapFromScene(line_size, 0); line->setLine(p1.x(), 0, p2.x(), 0); - line->setPos(m.x1(), scene()->sceneRect().height() + 10); - Animations::moveTo(line, profileWidget->animSpeed, m.x1(), childPos); + line->setPos(m.x1(), scene.sceneRect().height() + 10); + Animations::moveTo(line, scene.animSpeed, m.x1(), childPos); } } @@ -355,7 +353,7 @@ QColor DepthAxis::colorForValue(double) const return QColor(Qt::red); } -DepthAxis::DepthAxis(double fontPrintScale, ProfileWidget2 *widget) : DiveCartesianAxis(fontPrintScale, widget), +DepthAxis::DepthAxis(double fontPrintScale, ProfileScene &scene) : DiveCartesianAxis(fontPrintScale, scene), unitSystem(prefs.units.length) { connect(&diveListNotifier, &DiveListNotifier::settingsChanged, this, &DepthAxis::settingsChanged); @@ -399,8 +397,8 @@ QString TemperatureAxis::textForValue(double value) const return QString::number(mkelvin_to_C((int)value)); } -PartialGasPressureAxis::PartialGasPressureAxis(const DivePlotDataModel &model, double fontPrintScale, ProfileWidget2 *widget) : - DiveCartesianAxis(fontPrintScale, widget), +PartialGasPressureAxis::PartialGasPressureAxis(const DivePlotDataModel &model, double fontPrintScale, ProfileScene &scene) : + DiveCartesianAxis(fontPrintScale, scene), model(model) { connect(&diveListNotifier, &DiveListNotifier::settingsChanged, this, &PartialGasPressureAxis::update); diff --git a/profile-widget/divecartesianaxis.h b/profile-widget/divecartesianaxis.h index ecd46cbd0..253f4e467 100644 --- a/profile-widget/divecartesianaxis.h +++ b/profile-widget/divecartesianaxis.h @@ -5,8 +5,9 @@ #include #include #include "core/color.h" -#include "profilewidget2.h" +#include "core/units.h" +class ProfileScene; class QPropertyAnimation; class DiveTextItem; class DiveLineItem; @@ -28,7 +29,7 @@ public: LeftToRight, RightToLeft }; - DiveCartesianAxis(double fontPrintScale, ProfileWidget2 *widget); + DiveCartesianAxis(double fontPrintScale, ProfileScene &scene); ~DiveCartesianAxis(); void setPrintMode(bool mode); void setMinimum(double minimum); @@ -54,7 +55,7 @@ signals: void sizeChanged(); protected: - ProfileWidget2 *profileWidget; + ProfileScene &scene; virtual QString textForValue(double value) const; virtual QColor colorForValue(double value) const; Orientation orientation; @@ -76,7 +77,7 @@ protected: class DepthAxis : public DiveCartesianAxis { Q_OBJECT public: - DepthAxis(double fontPrintScale, ProfileWidget2 *widget); + DepthAxis(double fontPrintScale, ProfileScene &scene); private: QString textForValue(double value) const override; QColor colorForValue(double value) const override; @@ -107,7 +108,7 @@ private: class PartialGasPressureAxis : public DiveCartesianAxis { Q_OBJECT public: - PartialGasPressureAxis(const DivePlotDataModel &model, double fontPrintScale, ProfileWidget2 *widget); + PartialGasPressureAxis(const DivePlotDataModel &model, double fontPrintScale, ProfileScene &scene); public slots: void update(); diff --git a/profile-widget/divehandler.cpp b/profile-widget/divehandler.cpp index 2f06ea661..28ac90ffe 100644 --- a/profile-widget/divehandler.cpp +++ b/profile-widget/divehandler.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "divehandler.h" #include "profilewidget2.h" +#include "profilescene.h" #include "core/dive.h" #include "core/gettextfromc.h" #include "core/qthelper.h" @@ -74,7 +75,7 @@ void DiveHandler::mouseMoveEvent(QGraphicsSceneMouseEvent *event) t.start(); ProfileWidget2 *view = qobject_cast(scene()->views().first()); - if(view->isPointOutOfBoundaries(event->scenePos())) + if(view->profileScene->isPointOutOfBoundaries(event->scenePos())) return; QGraphicsEllipseItem::mouseMoveEvent(event); diff --git a/profile-widget/profilescene.cpp b/profile-widget/profilescene.cpp index 14ebc1299..3d2081064 100644 --- a/profile-widget/profilescene.cpp +++ b/profile-widget/profilescene.cpp @@ -1,12 +1,294 @@ // SPDX-License-Identifier: GPL-2.0 #include "profilescene.h" +#include "divecartesianaxis.h" +#include "core/pref.h" +#include "qt-models/diveplotdatamodel.h" -ProfileScene::ProfileScene() +const static struct ProfileItemPos { + struct Pos { + QPointF on; + QPointF off; + }; + struct Axis : public Pos { + QLineF shrinked; + QLineF expanded; + QLineF intermediate; + }; + Axis depth; + Axis partialPressure; + Axis partialPressureTissue; + Axis partialPressureWithTankBar; + Axis percentage; + Axis percentageWithTankBar; + Axis time; + Axis cylinder; + Axis temperature; + Axis temperatureAll; + Axis heartBeat; + Axis heartBeatWithTankBar; + ProfileItemPos(); +} itemPos; + +ProfileScene::ProfileScene(double fontPrintScale) : + dataModel(new DivePlotDataModel(this)), + profileYAxis(new DepthAxis(fontPrintScale, *this)), + gasYAxis(new PartialGasPressureAxis(*dataModel, fontPrintScale, *this)), + temperatureAxis(new TemperatureAxis(fontPrintScale, *this)), + timeAxis(new TimeAxis(fontPrintScale, *this)), + cylinderPressureAxis(new DiveCartesianAxis(fontPrintScale, *this)), + heartBeatAxis(new DiveCartesianAxis(fontPrintScale, *this)), + percentageAxis(new DiveCartesianAxis(fontPrintScale, *this)) { setSceneRect(0, 0, 100, 100); setItemIndexMethod(QGraphicsScene::NoIndex); + + // Initialize axes. Perhaps part of this should be moved down to the axes code? + profileYAxis->setOrientation(DiveCartesianAxis::TopToBottom); + profileYAxis->setMinimum(0); + profileYAxis->setTickInterval(M_OR_FT(10, 30)); + profileYAxis->setTickSize(0.5); + profileYAxis->setLineSize(96); + + timeAxis->setLineSize(92); + timeAxis->setTickSize(-0.5); + + gasYAxis->setOrientation(DiveCartesianAxis::BottomToTop); + gasYAxis->setTickInterval(1); + gasYAxis->setTickSize(1); + gasYAxis->setMinimum(0); + gasYAxis->setFontLabelScale(0.7); + gasYAxis->setLineSize(96); + +#ifndef SUBSURFACE_MOBILE + heartBeatAxis->setOrientation(DiveCartesianAxis::BottomToTop); + heartBeatAxis->setTickSize(0.2); + heartBeatAxis->setTickInterval(10); + heartBeatAxis->setFontLabelScale(0.7); + heartBeatAxis->setLineSize(96); + + percentageAxis->setOrientation(DiveCartesianAxis::BottomToTop); + percentageAxis->setTickSize(0.2); + percentageAxis->setTickInterval(10); + percentageAxis->setFontLabelScale(0.7); + percentageAxis->setLineSize(96); +#endif + + temperatureAxis->setOrientation(DiveCartesianAxis::BottomToTop); + temperatureAxis->setTickSize(2); + temperatureAxis->setTickInterval(300); + + cylinderPressureAxis->setOrientation(DiveCartesianAxis::BottomToTop); + cylinderPressureAxis->setTickSize(2); + cylinderPressureAxis->setTickInterval(30000); + + heartBeatAxis->setTextVisible(true); + heartBeatAxis->setLinesVisible(true); + percentageAxis->setTextVisible(true); + percentageAxis->setLinesVisible(true); + + temperatureAxis->setTextVisible(false); + temperatureAxis->setLinesVisible(false); + cylinderPressureAxis->setTextVisible(false); + cylinderPressureAxis->setLinesVisible(false); + timeAxis->setLinesVisible(true); + profileYAxis->setLinesVisible(true); + gasYAxis->setZValue(timeAxis->zValue() + 1); + + // Add items to scene + addItem(profileYAxis); + addItem(gasYAxis); + addItem(temperatureAxis); + addItem(timeAxis); + addItem(cylinderPressureAxis); + addItem(percentageAxis); + addItem(heartBeatAxis); } ProfileScene::~ProfileScene() { } + +static bool ppGraphsEnabled() +{ + return prefs.pp_graphs.po2 || prefs.pp_graphs.pn2 || prefs.pp_graphs.phe; +} + +void ProfileScene::updateAxes() +{ + profileYAxis->setPos(itemPos.depth.on); + +#ifndef SUBSURFACE_MOBILE + gasYAxis->update(); // Initialize ticks of partial pressure graph + if ((prefs.percentagegraph||prefs.hrgraph) && ppGraphsEnabled()) { + profileYAxis->animateChangeLine(itemPos.depth.shrinked); + temperatureAxis->setPos(itemPos.temperatureAll.on); + temperatureAxis->animateChangeLine(itemPos.temperature.shrinked); + cylinderPressureAxis->animateChangeLine(itemPos.cylinder.shrinked); + + if (prefs.tankbar) { + percentageAxis->setPos(itemPos.percentageWithTankBar.on); + percentageAxis->animateChangeLine(itemPos.percentageWithTankBar.expanded); + heartBeatAxis->setPos(itemPos.heartBeatWithTankBar.on); + heartBeatAxis->animateChangeLine(itemPos.heartBeatWithTankBar.expanded); + } else { + percentageAxis->setPos(itemPos.percentage.on); + percentageAxis->animateChangeLine(itemPos.percentage.expanded); + heartBeatAxis->setPos(itemPos.heartBeat.on); + heartBeatAxis->animateChangeLine(itemPos.heartBeat.expanded); + } + gasYAxis->setPos(itemPos.partialPressureTissue.on); + gasYAxis->animateChangeLine(itemPos.partialPressureTissue.expanded); + } else if (ppGraphsEnabled() || prefs.hrgraph || prefs.percentagegraph) { + profileYAxis->animateChangeLine(itemPos.depth.intermediate); + temperatureAxis->setPos(itemPos.temperature.on); + temperatureAxis->animateChangeLine(itemPos.temperature.intermediate); + cylinderPressureAxis->animateChangeLine(itemPos.cylinder.intermediate); + if (prefs.tankbar) { + percentageAxis->setPos(itemPos.percentageWithTankBar.on); + percentageAxis->animateChangeLine(itemPos.percentageWithTankBar.expanded); + gasYAxis->setPos(itemPos.partialPressureWithTankBar.on); + gasYAxis->animateChangeLine(itemPos.partialPressureWithTankBar.expanded); + heartBeatAxis->setPos(itemPos.heartBeatWithTankBar.on); + heartBeatAxis->animateChangeLine(itemPos.heartBeatWithTankBar.expanded); + } else { + gasYAxis->setPos(itemPos.partialPressure.on); + gasYAxis->animateChangeLine(itemPos.partialPressure.expanded); + percentageAxis->setPos(itemPos.percentage.on); + percentageAxis->animateChangeLine(itemPos.percentage.expanded); + heartBeatAxis->setPos(itemPos.heartBeat.on); + heartBeatAxis->animateChangeLine(itemPos.heartBeat.expanded); + } + } else { +#else + { +#endif + profileYAxis->animateChangeLine(itemPos.depth.expanded); + if (prefs.tankbar) { + temperatureAxis->setPos(itemPos.temperatureAll.on); + } else { + temperatureAxis->setPos(itemPos.temperature.on); + } + temperatureAxis->animateChangeLine(itemPos.temperature.expanded); + cylinderPressureAxis->animateChangeLine(itemPos.cylinder.expanded); + } + + timeAxis->setPos(itemPos.time.on); + timeAxis->setLine(itemPos.time.expanded); + + cylinderPressureAxis->setPos(itemPos.cylinder.on); +} + +bool ProfileScene::isPointOutOfBoundaries(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(); +} + +ProfileItemPos::ProfileItemPos() +{ + // Scene is *always* (double) 100 / 100. + // TODO: The relative scaling doesn't work well with large or small + // profiles and needs to be fixed. + + //Depth Axis Config + depth.on.setX(3); + depth.on.setY(3); + depth.off.setX(-2); + depth.off.setY(3); + depth.expanded.setP1(QPointF(0, 0)); +#ifndef SUBSURFACE_MOBILE + depth.expanded.setP2(QPointF(0, 85)); +#else + depth.expanded.setP2(QPointF(0, 65)); +#endif + depth.shrinked.setP1(QPointF(0, 0)); + depth.shrinked.setP2(QPointF(0, 55)); + depth.intermediate.setP1(QPointF(0, 0)); + depth.intermediate.setP2(QPointF(0, 65)); + + // Time Axis Config + time.on.setX(3); +#ifndef SUBSURFACE_MOBILE + time.on.setY(95); +#else + time.on.setY(89.5); +#endif + time.off.setX(3); + time.off.setY(110); + time.expanded.setP1(QPointF(0, 0)); + time.expanded.setP2(QPointF(94, 0)); + + // Partial Gas Axis Config + partialPressure.on.setX(97); +#ifndef SUBSURFACE_MOBILE + partialPressure.on.setY(75); +#else + partialPressure.on.setY(70); +#endif + partialPressure.off.setX(110); + partialPressure.off.setY(63); + partialPressure.expanded.setP1(QPointF(0, 0)); +#ifndef SUBSURFACE_MOBILE + partialPressure.expanded.setP2(QPointF(0, 19)); +#else + partialPressure.expanded.setP2(QPointF(0, 20)); +#endif + partialPressureWithTankBar = partialPressure; + partialPressureWithTankBar.expanded.setP2(QPointF(0, 17)); + partialPressureTissue = partialPressure; + partialPressureTissue.on.setX(97); + partialPressureTissue.on.setY(65); + partialPressureTissue.expanded.setP2(QPointF(0, 16)); + + // cylinder axis config + cylinder.on.setX(3); + cylinder.on.setY(20); + cylinder.off.setX(-10); + cylinder.off.setY(20); + cylinder.expanded.setP1(QPointF(0, 15)); + cylinder.expanded.setP2(QPointF(0, 50)); + cylinder.shrinked.setP1(QPointF(0, 0)); + cylinder.shrinked.setP2(QPointF(0, 20)); + cylinder.intermediate.setP1(QPointF(0, 0)); + cylinder.intermediate.setP2(QPointF(0, 20)); + + // Temperature axis config + temperature.on.setX(3); + temperature.off.setX(-10); + temperature.off.setY(40); + temperature.expanded.setP1(QPointF(0, 20)); + temperature.expanded.setP2(QPointF(0, 33)); + temperature.shrinked.setP1(QPointF(0, 2)); + temperature.shrinked.setP2(QPointF(0, 12)); +#ifndef SUBSURFACE_MOBILE + temperature.on.setY(60); + temperatureAll.on.setY(51); + temperature.intermediate.setP1(QPointF(0, 2)); + temperature.intermediate.setP2(QPointF(0, 12)); +#else + temperature.on.setY(51); + temperatureAll.on.setY(47); + temperature.intermediate.setP1(QPointF(0, 2)); + temperature.intermediate.setP2(QPointF(0, 12)); +#endif + + // Heart rate axis config + heartBeat.on.setX(3); + heartBeat.on.setY(82); + heartBeat.expanded.setP1(QPointF(0, 0)); + heartBeat.expanded.setP2(QPointF(0, 10)); + heartBeatWithTankBar = heartBeat; + heartBeatWithTankBar.expanded.setP2(QPointF(0, 7)); + + // Percentage axis config + percentage.on.setX(3); + percentage.on.setY(80); + percentage.expanded.setP1(QPointF(0, 0)); + percentage.expanded.setP2(QPointF(0, 15)); + percentageWithTankBar = percentage; + percentageWithTankBar.expanded.setP2(QPointF(0, 11.9)); +} diff --git a/profile-widget/profilescene.h b/profile-widget/profilescene.h index 13d25700a..03dc61552 100644 --- a/profile-widget/profilescene.h +++ b/profile-widget/profilescene.h @@ -1,15 +1,38 @@ -// SPDX-License-Identifier: GPL-2.0 -// Displays the dive profile. Used by the interactive profile widget -// and the printing/exporting code. + // SPDX-License-Identifier: GPL-2.0 + // Displays the dive profile. Used by the interactive profile widget + // and the printing/exporting code. #ifndef PROFILESCENE_H #define PROFILESCENE_H #include +class DivePlotDataModel; + +class DepthAxis; +class DiveCartesianAxis; +class PartialGasPressureAxis; +class TemperatureAxis; +class TimeAxis; + class ProfileScene : public QGraphicsScene { public: - ProfileScene(); + ProfileScene(double fontPrintScale); ~ProfileScene(); + + void updateAxes(); // Update axes according to preferences + bool isPointOutOfBoundaries(const QPointF &point) const; + + int animSpeed; +private: + friend class ProfileWidget2; // For now, give the ProfileWidget full access to the objects on the scene + DivePlotDataModel *dataModel; + DepthAxis *profileYAxis; + PartialGasPressureAxis *gasYAxis; + TemperatureAxis *temperatureAxis; + TimeAxis *timeAxis; + DiveCartesianAxis *cylinderPressureAxis; + DiveCartesianAxis *heartBeatAxis; + DiveCartesianAxis *percentageAxis; }; #endif diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index be26a5e50..dda0f0a29 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -42,8 +42,6 @@ #include #endif -#define PP_GRAPHS_ENABLED (prefs.pp_graphs.po2 || prefs.pp_graphs.pn2 || prefs.pp_graphs.phe) - /* This is the global 'Item position' variable. * it should tell you where to position things up * on the canvas. @@ -57,26 +55,8 @@ const static struct ItemPos { QPointF on; QPointF off; }; - struct Axis { - Pos pos; - QLineF shrinked; - QLineF expanded; - QLineF intermediate; - }; Pos dcLabel; Pos tankBar; - Axis depth; - Axis partialPressure; - Axis partialPressureTissue; - Axis partialPressureWithTankBar; - Axis percentage; - Axis percentageWithTankBar; - Axis time; - Axis cylinder; - Axis temperature; - Axis temperatureAll; - Axis heartBeat; - Axis heartBeatWithTankBar; ItemPos(); } itemPos; @@ -89,7 +69,7 @@ static const double thumbnailBaseZValue = 100.0; template T *ProfileWidget2::createItem(const DiveCartesianAxis &vAxis, int vColumn, int z, Args&&... args) { - T *res = new T(*dataModel, *timeAxis, DivePlotDataModel::TIME, vAxis, vColumn, + T *res = new T(*profileScene->dataModel, *profileScene->timeAxis, DivePlotDataModel::TIME, vAxis, vColumn, std::forward(args)...); res->setZValue(static_cast(z)); profileItems.push_back(res); @@ -97,9 +77,8 @@ T *ProfileWidget2::createItem(const DiveCartesianAxis &vAxis, int vColumn, int z } ProfileWidget2::ProfileWidget2(DivePlannerPointsModel *plannerModelIn, double fontPrintScale, QWidget *parent) : QGraphicsView(parent), - profileScene(new ProfileScene), + profileScene(new ProfileScene(fontPrintScale)), currentState(INVALID), - dataModel(new DivePlotDataModel(this)), plannerModel(plannerModelIn), zoomLevel(0), zoomFactor(1.15), @@ -110,17 +89,12 @@ ProfileWidget2::ProfileWidget2(DivePlannerPointsModel *plannerModelIn, double fo #ifndef SUBSURFACE_MOBILE toolTipItem(new ToolTipItem()), #endif - profileYAxis(new DepthAxis(fontPrintScale, this)), - gasYAxis(new PartialGasPressureAxis(*dataModel, fontPrintScale, this)), - temperatureAxis(new TemperatureAxis(fontPrintScale, this)), - timeAxis(new TimeAxis(fontPrintScale, this)), - diveProfileItem(createItem(*profileYAxis, DivePlotDataModel::DEPTH, 0, fontPrintScale)), - temperatureItem(createItem(*temperatureAxis, DivePlotDataModel::TEMPERATURE, 1, fontPrintScale)), - meanDepthItem(createItem(*profileYAxis, DivePlotDataModel::INSTANT_MEANDEPTH, 1, fontPrintScale)), - cylinderPressureAxis(new DiveCartesianAxis(fontPrintScale, this)), - gasPressureItem(createItem(*cylinderPressureAxis, DivePlotDataModel::TEMPERATURE, 1, fontPrintScale)), + diveProfileItem(createItem(*profileScene->profileYAxis, DivePlotDataModel::DEPTH, 0, fontPrintScale)), + temperatureItem(createItem(*profileScene->temperatureAxis, DivePlotDataModel::TEMPERATURE, 1, fontPrintScale)), + meanDepthItem(createItem(*profileScene->profileYAxis, DivePlotDataModel::INSTANT_MEANDEPTH, 1, fontPrintScale)), + gasPressureItem(createItem(*profileScene->cylinderPressureAxis, DivePlotDataModel::TEMPERATURE, 1, fontPrintScale)), diveComputerText(new DiveTextItem(fontPrintScale)), - reportedCeiling(createItem(*profileYAxis, DivePlotDataModel::CEILING, 1, fontPrintScale)), + reportedCeiling(createItem(*profileScene->profileYAxis, DivePlotDataModel::CEILING, 1, fontPrintScale)), pn2GasItem(createPPGas(DivePlotDataModel::PN2, PN2, PN2_ALERT, NULL, &prefs.pp_graphs.pn2_threshold)), pheGasItem(createPPGas(DivePlotDataModel::PHE, PHE, PHE_ALERT, NULL, &prefs.pp_graphs.phe_threshold)), po2GasItem(createPPGas(DivePlotDataModel::PO2, PO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)), @@ -129,17 +103,15 @@ ProfileWidget2::ProfileWidget2(DivePlannerPointsModel *plannerModelIn, double fo ccrsensor2GasItem(createPPGas(DivePlotDataModel::CCRSENSOR2, CCRSENSOR2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)), ccrsensor3GasItem(createPPGas(DivePlotDataModel::CCRSENSOR3, CCRSENSOR3, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)), ocpo2GasItem(createPPGas(DivePlotDataModel::SCR_OC_PO2, SCR_OCPO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)), - diveCeiling(createItem(*profileYAxis, DivePlotDataModel::CEILING, 1, fontPrintScale)), + diveCeiling(createItem(*profileScene->profileYAxis, DivePlotDataModel::CEILING, 1, fontPrintScale)), decoModelParameters(new DiveTextItem(fontPrintScale)), #ifndef SUBSURFACE_MOBILE - heartBeatAxis(new DiveCartesianAxis(fontPrintScale, this)), - heartBeatItem(createItem(*heartBeatAxis, DivePlotDataModel::HEARTBEAT, 1, fontPrintScale)), - percentageAxis(new DiveCartesianAxis(fontPrintScale, this)), + heartBeatItem(createItem(*profileScene->heartBeatAxis, DivePlotDataModel::HEARTBEAT, 1, fontPrintScale)), mouseFollowerVertical(new DiveLineItem()), mouseFollowerHorizontal(new DiveLineItem()), rulerItem(new RulerItem2()), #endif - tankItem(new TankItem(*timeAxis, fontPrintScale)), + tankItem(new TankItem(*profileScene->timeAxis, fontPrintScale)), shouldCalculateMax(true), fontPrintScale(fontPrintScale) { @@ -171,7 +143,7 @@ ProfileWidget2::ProfileWidget2(DivePlannerPointsModel *plannerModelIn, double fo #if !defined(QT_NO_DEBUG) && defined(SHOW_PLOT_INFO_TABLE) QTableView *diveDepthTableView = new QTableView(); - diveDepthTableView->setModel(dataModel); + diveDepthTableView->setModel(profileScene->dataModel); diveDepthTableView->show(); #endif @@ -219,18 +191,11 @@ void ProfileWidget2::addActionShortcut(const Qt::Key shortcut, void (ProfileWidg void ProfileWidget2::addItemsToScene() { scene()->addItem(background); - scene()->addItem(profileYAxis); - scene()->addItem(gasYAxis); - scene()->addItem(temperatureAxis); - scene()->addItem(timeAxis); - scene()->addItem(cylinderPressureAxis); scene()->addItem(diveComputerText); scene()->addItem(tankItem); scene()->addItem(decoModelParameters); #ifndef SUBSURFACE_MOBILE scene()->addItem(toolTipItem); - scene()->addItem(percentageAxis); - scene()->addItem(heartBeatAxis); scene()->addItem(rulerItem); scene()->addItem(rulerItem->sourceNode()); scene()->addItem(rulerItem->destNode()); @@ -250,55 +215,16 @@ void ProfileWidget2::setupItemOnScene() background->setZValue(9999); #ifndef SUBSURFACE_MOBILE toolTipItem->setZValue(9998); - toolTipItem->setTimeAxis(timeAxis); + toolTipItem->setTimeAxis(profileScene->timeAxis); rulerItem->setZValue(9997); #endif tankItem->setZValue(100); - profileYAxis->setOrientation(DiveCartesianAxis::TopToBottom); - profileYAxis->setMinimum(0); - profileYAxis->setTickInterval(M_OR_FT(10, 30)); - profileYAxis->setTickSize(0.5); - profileYAxis->setLineSize(96); - - timeAxis->setLineSize(92); - timeAxis->setTickSize(-0.5); - - gasYAxis->setOrientation(DiveCartesianAxis::BottomToTop); - gasYAxis->setTickInterval(1); - gasYAxis->setTickSize(1); - gasYAxis->setMinimum(0); - gasYAxis->setFontLabelScale(0.7); - gasYAxis->setLineSize(96); - -#ifndef SUBSURFACE_MOBILE - heartBeatAxis->setOrientation(DiveCartesianAxis::BottomToTop); - heartBeatAxis->setTickSize(0.2); - heartBeatAxis->setTickInterval(10); - heartBeatAxis->setFontLabelScale(0.7); - heartBeatAxis->setLineSize(96); - - percentageAxis->setOrientation(DiveCartesianAxis::BottomToTop); - percentageAxis->setTickSize(0.2); - percentageAxis->setTickInterval(10); - percentageAxis->setFontLabelScale(0.7); - percentageAxis->setLineSize(96); -#endif - - temperatureAxis->setOrientation(DiveCartesianAxis::BottomToTop); - temperatureAxis->setTickSize(2); - temperatureAxis->setTickInterval(300); - - cylinderPressureAxis->setOrientation(DiveCartesianAxis::BottomToTop); - cylinderPressureAxis->setTickSize(2); - cylinderPressureAxis->setTickInterval(30000); - - diveComputerText->setAlignment(Qt::AlignRight | Qt::AlignTop); diveComputerText->setBrush(getColor(TIME_TEXT, isGrayscale)); #ifndef SUBSURFACE_MOBILE - rulerItem->setAxis(timeAxis, profileYAxis); + rulerItem->setAxis(profileScene->timeAxis, profileScene->profileYAxis); #endif // show the deco model parameters at the top in the center decoModelParameters->setY(0); @@ -307,26 +233,12 @@ void ProfileWidget2::setupItemOnScene() decoModelParameters->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); #ifndef SUBSURFACE_MOBILE for (int i = 0; i < 16; i++) { - DiveCalculatedTissue *tissueItem = createItem(*profileYAxis, DivePlotDataModel::TISSUE_1 + i, i + 1, fontPrintScale); + DiveCalculatedTissue *tissueItem = createItem(*profileScene->profileYAxis, DivePlotDataModel::TISSUE_1 + i, i + 1, fontPrintScale); allTissues.append(tissueItem); - DivePercentageItem *percentageItem = createItem(*percentageAxis, DivePlotDataModel::PERCENTAGE_1 + i, i + 1, i, fontPrintScale); + DivePercentageItem *percentageItem = createItem(*profileScene->percentageAxis, DivePlotDataModel::PERCENTAGE_1 + i, i + 1, i, fontPrintScale); allPercentages.append(percentageItem); } #endif - -#ifndef SUBSURFACE_MOBILE - heartBeatAxis->setTextVisible(true); - heartBeatAxis->setLinesVisible(true); - percentageAxis->setTextVisible(true); - percentageAxis->setLinesVisible(true); -#endif - temperatureAxis->setTextVisible(false); - temperatureAxis->setLinesVisible(false); - cylinderPressureAxis->setTextVisible(false); - cylinderPressureAxis->setLinesVisible(false); - timeAxis->setLinesVisible(true); - profileYAxis->setLinesVisible(true); - gasYAxis->setZValue(timeAxis->zValue() + 1); } void ProfileWidget2::replot() @@ -337,7 +249,7 @@ void ProfileWidget2::replot() PartialPressureGasItem *ProfileWidget2::createPPGas(int column, color_index_t color, color_index_t colorAlert, const double *thresholdSettingsMin, const double *thresholdSettingsMax) { - PartialPressureGasItem *item = createItem(*gasYAxis, column, 99, fontPrintScale); + PartialPressureGasItem *item = createItem(*profileScene->gasYAxis, column, 99, fontPrintScale); item->setThresholdSettingsKey(thresholdSettingsMin, thresholdSettingsMax); item->setColors(getColor(color, isGrayscale), getColor(colorAlert, isGrayscale)); return item; @@ -352,104 +264,6 @@ ItemPos::ItemPos() * Axis and everything else is auto-adjusted.* */ - //Depth Axis Config - depth.pos.on.setX(3); - depth.pos.on.setY(3); - depth.pos.off.setX(-2); - depth.pos.off.setY(3); - depth.expanded.setP1(QPointF(0, 0)); -#ifndef SUBSURFACE_MOBILE - depth.expanded.setP2(QPointF(0, 85)); -#else - depth.expanded.setP2(QPointF(0, 65)); -#endif - depth.shrinked.setP1(QPointF(0, 0)); - depth.shrinked.setP2(QPointF(0, 55)); - depth.intermediate.setP1(QPointF(0, 0)); - depth.intermediate.setP2(QPointF(0, 65)); - - // Time Axis Config - time.pos.on.setX(3); -#ifndef SUBSURFACE_MOBILE - time.pos.on.setY(95); -#else - time.pos.on.setY(89.5); -#endif - time.pos.off.setX(3); - time.pos.off.setY(110); - time.expanded.setP1(QPointF(0, 0)); - time.expanded.setP2(QPointF(94, 0)); - - // Partial Gas Axis Config - partialPressure.pos.on.setX(97); -#ifndef SUBSURFACE_MOBILE - partialPressure.pos.on.setY(75); -#else - partialPressure.pos.on.setY(70); -#endif - partialPressure.pos.off.setX(110); - partialPressure.pos.off.setY(63); - partialPressure.expanded.setP1(QPointF(0, 0)); -#ifndef SUBSURFACE_MOBILE - partialPressure.expanded.setP2(QPointF(0, 19)); -#else - partialPressure.expanded.setP2(QPointF(0, 20)); -#endif - partialPressureWithTankBar = partialPressure; - partialPressureWithTankBar.expanded.setP2(QPointF(0, 17)); - partialPressureTissue = partialPressure; - partialPressureTissue.pos.on.setX(97); - partialPressureTissue.pos.on.setY(65); - partialPressureTissue.expanded.setP2(QPointF(0, 16)); - - // cylinder axis config - cylinder.pos.on.setX(3); - cylinder.pos.on.setY(20); - cylinder.pos.off.setX(-10); - cylinder.pos.off.setY(20); - cylinder.expanded.setP1(QPointF(0, 15)); - cylinder.expanded.setP2(QPointF(0, 50)); - cylinder.shrinked.setP1(QPointF(0, 0)); - cylinder.shrinked.setP2(QPointF(0, 20)); - cylinder.intermediate.setP1(QPointF(0, 0)); - cylinder.intermediate.setP2(QPointF(0, 20)); - - // Temperature axis config - temperature.pos.on.setX(3); - temperature.pos.off.setX(-10); - temperature.pos.off.setY(40); - temperature.expanded.setP1(QPointF(0, 20)); - temperature.expanded.setP2(QPointF(0, 33)); - temperature.shrinked.setP1(QPointF(0, 2)); - temperature.shrinked.setP2(QPointF(0, 12)); -#ifndef SUBSURFACE_MOBILE - temperature.pos.on.setY(60); - temperatureAll.pos.on.setY(51); - temperature.intermediate.setP1(QPointF(0, 2)); - temperature.intermediate.setP2(QPointF(0, 12)); -#else - temperature.pos.on.setY(51); - temperatureAll.pos.on.setY(47); - temperature.intermediate.setP1(QPointF(0, 2)); - temperature.intermediate.setP2(QPointF(0, 12)); -#endif - - // Heart rate axis config - heartBeat.pos.on.setX(3); - heartBeat.pos.on.setY(82); - heartBeat.expanded.setP1(QPointF(0, 0)); - heartBeat.expanded.setP2(QPointF(0, 10)); - heartBeatWithTankBar = heartBeat; - heartBeatWithTankBar.expanded.setP2(QPointF(0, 7)); - - // Percentage axis config - percentage.pos.on.setX(3); - percentage.pos.on.setY(80); - percentage.expanded.setP1(QPointF(0, 0)); - percentage.expanded.setP2(QPointF(0, 15)); - percentageWithTankBar = percentage; - percentageWithTankBar.expanded.setP2(QPointF(0, 11.9)); - dcLabel.on.setX(3); dcLabel.on.setY(100); dcLabel.off.setX(-10); @@ -521,7 +335,7 @@ void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, bool doClearPict } // special handling when switching from empty state - animSpeed = instant || currentState == EMPTY || printMode ? 0 : qPrefDisplay::animation_speed(); + profileScene->animSpeed = instant || currentState == EMPTY || printMode ? 0 : qPrefDisplay::animation_speed(); // restore default zoom level resetZoom(); @@ -577,17 +391,17 @@ void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, bool doClearPict maxdepth = newMaxDepth; } - dataModel->setDive(plotInfo); + profileScene->dataModel->setDive(plotInfo); #ifndef SUBSURFACE_MOBILE toolTipItem->setPlotInfo(plotInfo); #endif // It seems that I'll have a lot of boilerplate setting the model / axis for // each item, I'll mostly like to fix this in the future, but I'll keep at this for now. - profileYAxis->setMaximum(maxdepth); - profileYAxis->updateTicks(); + profileScene->profileYAxis->setMaximum(maxdepth); + profileScene->profileYAxis->updateTicks(); - temperatureAxis->setMinimum(plotInfo.mintemp); - temperatureAxis->setMaximum(plotInfo.maxtemp - plotInfo.mintemp > 2000 ? plotInfo.maxtemp : plotInfo.mintemp + 2000); + profileScene->temperatureAxis->setMinimum(plotInfo.mintemp); + profileScene->temperatureAxis->setMaximum(plotInfo.maxtemp - plotInfo.mintemp > 2000 ? plotInfo.maxtemp : plotInfo.mintemp + 2000); #ifndef SUBSURFACE_MOBILE if (plotInfo.maxhr) { @@ -602,20 +416,20 @@ void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, bool doClearPict else heartBeatAxisTick = 50; for (heartBeatAxisMax = heartBeatAxisMin; heartBeatAxisMax < plotInfo.maxhr; heartBeatAxisMax += heartBeatAxisTick); - heartBeatAxis->setMinimum(heartBeatAxisMin); - heartBeatAxis->setMaximum(heartBeatAxisMax + 1); - heartBeatAxis->setTickInterval(heartBeatAxisTick); - heartBeatAxis->updateTicks(HR_AXIS); // this shows the ticks + profileScene->heartBeatAxis->setMinimum(heartBeatAxisMin); + profileScene->heartBeatAxis->setMaximum(heartBeatAxisMax + 1); + profileScene->heartBeatAxis->setTickInterval(heartBeatAxisTick); + profileScene->heartBeatAxis->updateTicks(HR_AXIS); // this shows the ticks } - heartBeatAxis->setVisible(prefs.hrgraph && plotInfo.maxhr); + profileScene->heartBeatAxis->setVisible(prefs.hrgraph && plotInfo.maxhr); - percentageAxis->setMinimum(0); - percentageAxis->setMaximum(100); - percentageAxis->setVisible(false); - percentageAxis->updateTicks(HR_AXIS); + profileScene->percentageAxis->setMinimum(0); + profileScene->percentageAxis->setMaximum(100); + profileScene->percentageAxis->setVisible(false); + profileScene->percentageAxis->updateTicks(HR_AXIS); #endif if (shouldCalculateMax) - timeAxis->setMaximum(maxtime); + profileScene->timeAxis->setMaximum(maxtime); int i, incr; static int increments[8] = { 10, 20, 30, 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60 }; /* Time markers: at most every 10 seconds, but no more than 12 markers. @@ -631,18 +445,18 @@ void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, bool doClearPict incr = increments[i]; while (maxtime / incr > 12) incr *= 2; - timeAxis->setTickInterval(incr); - timeAxis->updateTicks(); - cylinderPressureAxis->setMinimum(plotInfo.minpressure); - cylinderPressureAxis->setMaximum(plotInfo.maxpressure); + profileScene->timeAxis->setTickInterval(incr); + profileScene->timeAxis->updateTicks(); + profileScene->cylinderPressureAxis->setMinimum(plotInfo.minpressure); + profileScene->cylinderPressureAxis->setMaximum(plotInfo.maxpressure); #ifndef SUBSURFACE_MOBILE rulerItem->setPlotInfo(d, plotInfo); #endif #ifdef SUBSURFACE_MOBILE if (currentdc->divemode == CCR) { - gasYAxis->setPos(itemPos.partialPressure.pos.on); - gasYAxis->setLine(itemPos.partialPressure.expanded); + profileScene->gasYAxis->setPos(itemPos.partialPressure.pos.on); + profileScene->gasYAxis->setLine(itemPos.partialPressure.expanded); tankItem->setVisible(false); pn2GasItem->setVisible(false); @@ -665,7 +479,7 @@ void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, bool doClearPict temperatureItem->setVisible(false); } else { tankItem->setVisible(prefs.tankbar); - gasYAxis->setPos(itemPos.partialPressure.pos.off); + profileScene->gasYAxis->setPos(itemPos.partialPressure.pos.off); pn2GasItem->setVisible(false); po2GasItem->setVisible(false); pheGasItem->setVisible(false); @@ -678,7 +492,7 @@ void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, bool doClearPict #endif tankItem->setData(&plotInfo, d); - gasYAxis->update(); + profileScene->gasYAxis->update(); // Replot dive items for (AbstractProfilePolygonItem *item: profileItems) @@ -709,7 +523,9 @@ void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, bool doClearPict // printMode is always selected for SUBSURFACE_MOBILE due to font problems // BUT events are wanted. #endif - DiveEventItem *item = new DiveEventItem(d, event, lastgasmix, dataModel, timeAxis, profileYAxis, animSpeed, fontPrintScale); + DiveEventItem *item = new DiveEventItem(d, event, lastgasmix, profileScene->dataModel, + profileScene->timeAxis, profileScene->profileYAxis, profileScene->animSpeed, + fontPrintScale); item->setZValue(2); scene()->addItem(item); eventItems.push_back(item); @@ -775,67 +591,9 @@ void ProfileWidget2::actionRequestedReplot(bool) settingsChanged(); } -void ProfileWidget2::updateAxes() -{ -#ifndef SUBSURFACE_MOBILE - gasYAxis->update(); // Initialize ticks of partial pressure graph - if ((prefs.percentagegraph||prefs.hrgraph) && PP_GRAPHS_ENABLED) { - profileYAxis->animateChangeLine(itemPos.depth.shrinked); - temperatureAxis->setPos(itemPos.temperatureAll.pos.on); - temperatureAxis->animateChangeLine(itemPos.temperature.shrinked); - cylinderPressureAxis->animateChangeLine(itemPos.cylinder.shrinked); - - if (prefs.tankbar) { - percentageAxis->setPos(itemPos.percentageWithTankBar.pos.on); - percentageAxis->animateChangeLine(itemPos.percentageWithTankBar.expanded); - heartBeatAxis->setPos(itemPos.heartBeatWithTankBar.pos.on); - heartBeatAxis->animateChangeLine(itemPos.heartBeatWithTankBar.expanded); - } else { - percentageAxis->setPos(itemPos.percentage.pos.on); - percentageAxis->animateChangeLine(itemPos.percentage.expanded); - heartBeatAxis->setPos(itemPos.heartBeat.pos.on); - heartBeatAxis->animateChangeLine(itemPos.heartBeat.expanded); - } - gasYAxis->setPos(itemPos.partialPressureTissue.pos.on); - gasYAxis->animateChangeLine(itemPos.partialPressureTissue.expanded); - } else if (PP_GRAPHS_ENABLED || prefs.hrgraph || prefs.percentagegraph) { - profileYAxis->animateChangeLine(itemPos.depth.intermediate); - temperatureAxis->setPos(itemPos.temperature.pos.on); - temperatureAxis->animateChangeLine(itemPos.temperature.intermediate); - cylinderPressureAxis->animateChangeLine(itemPos.cylinder.intermediate); - if (prefs.tankbar) { - percentageAxis->setPos(itemPos.percentageWithTankBar.pos.on); - percentageAxis->animateChangeLine(itemPos.percentageWithTankBar.expanded); - gasYAxis->setPos(itemPos.partialPressureWithTankBar.pos.on); - gasYAxis->animateChangeLine(itemPos.partialPressureWithTankBar.expanded); - heartBeatAxis->setPos(itemPos.heartBeatWithTankBar.pos.on); - heartBeatAxis->animateChangeLine(itemPos.heartBeatWithTankBar.expanded); - } else { - gasYAxis->setPos(itemPos.partialPressure.pos.on); - gasYAxis->animateChangeLine(itemPos.partialPressure.expanded); - percentageAxis->setPos(itemPos.percentage.pos.on); - percentageAxis->animateChangeLine(itemPos.percentage.expanded); - heartBeatAxis->setPos(itemPos.heartBeat.pos.on); - heartBeatAxis->animateChangeLine(itemPos.heartBeat.expanded); - } - } else { -#else - { -#endif - profileYAxis->animateChangeLine(itemPos.depth.expanded); - if (prefs.tankbar) { - temperatureAxis->setPos(itemPos.temperatureAll.pos.on); - } else { - temperatureAxis->setPos(itemPos.temperature.pos.on); - } - temperatureAxis->animateChangeLine(itemPos.temperature.expanded); - cylinderPressureAxis->animateChangeLine(itemPos.cylinder.expanded); - } -} - void ProfileWidget2::settingsChanged() { - updateAxes(); + profileScene->updateAxes(); tankItem->setVisible(prefs.tankbar); replot(); } @@ -912,16 +670,6 @@ void ProfileWidget2::scale(qreal sx, qreal sy) #endif } -bool ProfileWidget2::isPointOutOfBoundaries(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(); -} - #ifndef SUBSURFACE_MOBILE void ProfileWidget2::wheelEvent(QWheelEvent *event) { @@ -950,11 +698,11 @@ void ProfileWidget2::mouseDoubleClickEvent(QMouseEvent *event) { if ((currentState == PLAN || currentState == EDIT) && plannerModel) { QPointF mappedPos = mapToScene(event->pos()); - if (isPointOutOfBoundaries(mappedPos)) + if (profileScene->isPointOutOfBoundaries(mappedPos)) return; - int minutes = lrint(timeAxis->valueAt(mappedPos) / 60); - int milimeters = lrint(profileYAxis->valueAt(mappedPos) / M_OR_FT(1, 1)) * M_OR_FT(1, 1); + int minutes = lrint(profileScene->timeAxis->valueAt(mappedPos) / 60); + int milimeters = lrint(profileScene->profileYAxis->valueAt(mappedPos) / M_OR_FT(1, 1)) * M_OR_FT(1, 1); plannerModel->addStop(milimeters, minutes * 60); } } @@ -986,14 +734,14 @@ void ProfileWidget2::mouseMoveEvent(QMouseEvent *event) toolTipItem->setPos(mapToScene(toolTipPos)); } - qreal vValue = profileYAxis->valueAt(pos); - qreal hValue = timeAxis->valueAt(pos); + qreal vValue = profileScene->profileYAxis->valueAt(pos); + qreal hValue = profileScene->timeAxis->valueAt(pos); - if (profileYAxis->maximum() >= vValue && profileYAxis->minimum() <= vValue) { - mouseFollowerHorizontal->setPos(timeAxis->pos().x(), pos.y()); + if (profileScene->profileYAxis->maximum() >= vValue && profileScene->profileYAxis->minimum() <= vValue) { + mouseFollowerHorizontal->setPos(profileScene->timeAxis->pos().x(), pos.y()); } - if (timeAxis->maximum() >= hValue && timeAxis->minimum() <= hValue) { - mouseFollowerVertical->setPos(pos.x(), profileYAxis->line().y1()); + if (profileScene->timeAxis->maximum() >= hValue && profileScene->timeAxis->minimum() <= hValue) { + mouseFollowerVertical->setPos(pos.x(), profileScene->profileYAxis->line().y1()); } } @@ -1026,17 +774,17 @@ void ProfileWidget2::setEmptyState() #endif disconnectTemporaryConnections(); setBackgroundBrush(getColor(::BACKGROUND, isGrayscale)); - dataModel->clear(); + profileScene->dataModel->clear(); currentState = EMPTY; fixBackgroundPos(); background->setVisible(true); - profileYAxis->setVisible(false); - gasYAxis->setVisible(false); - timeAxis->setVisible(false); - temperatureAxis->setVisible(false); - cylinderPressureAxis->setVisible(false); + profileScene->profileYAxis->setVisible(false); + profileScene->gasYAxis->setVisible(false); + profileScene->timeAxis->setVisible(false); + profileScene->temperatureAxis->setVisible(false); + profileScene->cylinderPressureAxis->setVisible(false); diveComputerText->setVisible(false); reportedCeiling->setVisible(false); tankItem->setVisible(false); @@ -1056,7 +804,7 @@ void ProfileWidget2::setEmptyState() rulerItem->setVisible(false); mouseFollowerHorizontal->setVisible(false); mouseFollowerVertical->setVisible(false); - heartBeatAxis->setVisible(false); + profileScene->heartBeatAxis->setVisible(false); heartBeatItem->setVisible(false); #endif for (AbstractProfilePolygonItem *item: profileItems) @@ -1128,24 +876,19 @@ void ProfileWidget2::setProfileState() setBackgroundBrush(getColor(::BACKGROUND, isGrayscale)); background->setVisible(false); - profileYAxis->setVisible(true); - gasYAxis->setVisible(true); - timeAxis->setVisible(true); - temperatureAxis->setVisible(true); - cylinderPressureAxis->setVisible(true); + profileScene->profileYAxis->setVisible(true); + profileScene->gasYAxis->setVisible(true); + profileScene->timeAxis->setVisible(true); + profileScene->temperatureAxis->setVisible(true); + profileScene->cylinderPressureAxis->setVisible(true); - profileYAxis->setPos(itemPos.depth.pos.on); - updateAxes(); + profileScene->updateAxes(); #ifndef SUBSURFACE_MOBILE toolTipItem->readPos(); toolTipItem->setVisible(true); rulerItem->setVisible(prefs.rulergraph); #endif - timeAxis->setPos(itemPos.time.pos.on); - timeAxis->setLine(itemPos.time.expanded); - - cylinderPressureAxis->setPos(itemPos.cylinder.pos.on); diveComputerText->setVisible(true); diveComputerText->setPos(itemPos.dcLabel.on); @@ -1179,8 +922,8 @@ void ProfileWidget2::setEditState(const dive *d, int dc) setProfileState(d, dc); mouseFollowerHorizontal->setVisible(true); mouseFollowerVertical->setVisible(true); - mouseFollowerHorizontal->setLine(timeAxis->line()); - mouseFollowerVertical->setLine(QLineF(0, profileYAxis->pos().y(), 0, timeAxis->pos().y())); + mouseFollowerHorizontal->setLine(profileScene->timeAxis->line()); + mouseFollowerVertical->setLine(QLineF(0, profileScene->profileYAxis->pos().y(), 0, profileScene->timeAxis->pos().y())); disconnectTemporaryConnections(); actionsForKeys[Qt::Key_Left]->setShortcut(Qt::Key_Left); actionsForKeys[Qt::Key_Right]->setShortcut(Qt::Key_Right); @@ -1209,8 +952,8 @@ void ProfileWidget2::setPlanState(const dive *d, int dc) setProfileState(d, dc); mouseFollowerHorizontal->setVisible(true); mouseFollowerVertical->setVisible(true); - mouseFollowerHorizontal->setLine(timeAxis->line()); - mouseFollowerVertical->setLine(QLineF(0, profileYAxis->pos().y(), 0, timeAxis->pos().y())); + mouseFollowerHorizontal->setLine(profileScene->timeAxis->line()); + mouseFollowerVertical->setLine(QLineF(0, profileScene->profileYAxis->pos().y(), 0, profileScene->timeAxis->pos().y())); disconnectTemporaryConnections(); actionsForKeys[Qt::Key_Left]->setShortcut(Qt::Key_Left); actionsForKeys[Qt::Key_Right]->setShortcut(Qt::Key_Right); @@ -1306,7 +1049,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) // create the profile context menu QPointF scenePos = mapToScene(mapFromGlobal(event->globalPos())); - qreal sec_val = timeAxis->valueAt(scenePos); + qreal sec_val = profileScene->timeAxis->valueAt(scenePos); int seconds = (sec_val < 0.0) ? 0 : (int)sec_val; DiveEventItem *item = dynamic_cast(sceneItem); @@ -1525,15 +1268,15 @@ void ProfileWidget2::setPrintMode(bool mode, bool grayscale) resetZoom(); // set printMode for axes - profileYAxis->setPrintMode(mode); - gasYAxis->setPrintMode(mode); - temperatureAxis->setPrintMode(mode); - timeAxis->setPrintMode(mode); - cylinderPressureAxis->setPrintMode(mode); + profileScene->profileYAxis->setPrintMode(mode); + profileScene->gasYAxis->setPrintMode(mode); + profileScene->temperatureAxis->setPrintMode(mode); + profileScene->timeAxis->setPrintMode(mode); + profileScene->cylinderPressureAxis->setPrintMode(mode); isGrayscale = mode ? grayscale : false; #ifndef SUBSURFACE_MOBILE - heartBeatAxis->setPrintMode(mode); - percentageAxis->setPrintMode(mode); + profileScene->heartBeatAxis->setPrintMode(mode); + profileScene->percentageAxis->setPrintMode(mode); mouseFollowerHorizontal->setVisible(!mode); mouseFollowerVertical->setVisible(!mode); @@ -1662,16 +1405,16 @@ void ProfileWidget2::repositionDiveHandlers() continue; DiveHandler *h = handles[i].get(); h->setVisible(datapoint.entered); - h->setPos(timeAxis->posAtValue(datapoint.time), profileYAxis->posAtValue(datapoint.depth.mm)); + h->setPos(profileScene->timeAxis->posAtValue(datapoint.time), profileScene->profileYAxis->posAtValue(datapoint.depth.mm)); QPointF p1; if (i == 0) { if (prefs.drop_stone_mode) // place the text on the straight line from the drop to stone position - p1 = QPointF(timeAxis->posAtValue(datapoint.depth.mm / prefs.descrate), - profileYAxis->posAtValue(datapoint.depth.mm)); + p1 = QPointF(profileScene->timeAxis->posAtValue(datapoint.depth.mm / prefs.descrate), + profileScene->profileYAxis->posAtValue(datapoint.depth.mm)); else // place the text on the straight line from the origin to the first position - p1 = QPointF(timeAxis->posAtValue(0), profileYAxis->posAtValue(0)); + p1 = QPointF(profileScene->timeAxis->posAtValue(0), profileScene->profileYAxis->posAtValue(0)); } else { // place the text on the line from the last position p1 = handles[i - 1]->pos(); @@ -1695,13 +1438,13 @@ void ProfileWidget2::divePlannerHandlerMoved() int index = handleIndex(activeHandler); // Grow the time axis if necessary. - int minutes = lrint(timeAxis->valueAt(activeHandler->pos()) / 60); - if (minutes * 60 > timeAxis->maximum() * 0.9) - timeAxis->setMaximum(timeAxis->maximum() * 1.02); + int minutes = lrint(profileScene->timeAxis->valueAt(activeHandler->pos()) / 60); + if (minutes * 60 > profileScene->timeAxis->maximum() * 0.9) + profileScene->timeAxis->setMaximum(profileScene->timeAxis->maximum() * 1.02); divedatapoint data = plannerModel->at(index); - data.depth.mm = lrint(profileYAxis->valueAt(activeHandler->pos()) / M_OR_FT(1, 1)) * M_OR_FT(1, 1); - data.time = lrint(timeAxis->valueAt(activeHandler->pos())); + data.depth.mm = lrint(profileScene->profileYAxis->valueAt(activeHandler->pos()) / M_OR_FT(1, 1)) * M_OR_FT(1, 1); + data.time = lrint(profileScene->timeAxis->valueAt(activeHandler->pos())); plannerModel->editStop(index, data); } @@ -1819,8 +1562,8 @@ void ProfileWidget2::updateDurationLine(PictureEntry &e) { if (e.duration.seconds > 0) { // We know the duration of this video, reset the line symbolizing its extent accordingly - double begin = timeAxis->posAtValue(e.offset.seconds); - double end = timeAxis->posAtValue(e.offset.seconds + e.duration.seconds); + double begin = profileScene->timeAxis->posAtValue(e.offset.seconds); + double end = profileScene->timeAxis->posAtValue(e.offset.seconds + e.duration.seconds); double y = e.thumbnail->y(); // Undo scaling for pen-width and line-width. For this purpose, we use the scaling of the y-axis. @@ -1935,7 +1678,7 @@ void ProfileWidget2::updateThumbnailXPos(PictureEntry &e) { // Here, we only set the x-coordinate of the picture. The y-coordinate // will be set later in calculatePictureYPositions(). - double x = timeAxis->posAtValue(e.offset.seconds); + double x = profileScene->timeAxis->posAtValue(e.offset.seconds); e.thumbnail->setX(x); } @@ -2028,7 +1771,7 @@ void ProfileWidget2::dropEvent(QDropEvent *event) QString filename; dataStream >> filename; QPointF mappedPos = mapToScene(event->pos()); - offset_t offset { (int32_t)lrint(timeAxis->valueAt(mappedPos)) }; + offset_t offset { (int32_t)lrint(profileScene->timeAxis->valueAt(mappedPos)) }; Command::setPictureOffset(mutable_dive(), filename, offset); if (event->source() == this) { diff --git a/profile-widget/profilewidget2.h b/profile-widget/profilewidget2.h index 515de6660..104d4e915 100644 --- a/profile-widget/profilewidget2.h +++ b/profile-widget/profilewidget2.h @@ -31,23 +31,18 @@ struct plot_info; class ToolTipItem; class DiveReportedCeiling; class DiveTextItem; -class TemperatureAxis; class DiveEventItem; -class DivePlotDataModel; class DivePixmapItem; class DiveRectItem; -class DepthAxis; class DiveCartesianAxis; class DiveProfileItem; class DivePlannerPointsModel; -class TimeAxis; class DiveTemperatureItem; class DiveHeartrateItem; class DiveGasPressureItem; class DiveCalculatedCeiling; class DiveCalculatedTissue; class PartialPressureGasItem; -class PartialGasPressureAxis; class AbstractProfilePolygonItem; class TankItem; class DiveHandler; @@ -76,7 +71,6 @@ public: void setPlanState(const struct dive *d, int dc); void setEditState(const struct dive *d, int dc); void setPrintMode(bool mode, bool grayscale = false); - bool isPointOutOfBoundaries(const QPointF &point) const; bool isPlanner() const; void draw(QPainter *painter, const QRect &pos); QImage toImage(QSize size); @@ -85,7 +79,6 @@ public: #endif std::unique_ptr profileScene; State currentState; - int animSpeed; signals: void editCurrentDive(); @@ -126,7 +119,6 @@ slots: // Necessary to call from QAction's signals. private: void setProfileState(); // keep currently displayed dive - void updateAxes(); // Update axes according to preferences void updateVisibility(); // Update visibility of non-interactive chart features according to preferences void resizeEvent(QResizeEvent *event) override; #ifndef SUBSURFACE_MOBILE @@ -169,7 +161,6 @@ private: void splitCurrentDC(); void renameCurrentDC(); - DivePlotDataModel *dataModel; DivePlannerPointsModel *plannerModel; // If null, no planning supported. int zoomLevel; qreal zoomFactor; @@ -186,15 +177,10 @@ private: const struct dive *d; int dc; struct plot_info plotInfo; - DepthAxis *profileYAxis; - PartialGasPressureAxis *gasYAxis; - TemperatureAxis *temperatureAxis; - TimeAxis *timeAxis; std::vector profileItems; DiveProfileItem *diveProfileItem; DiveTemperatureItem *temperatureItem; DiveMeanDepthItem *meanDepthItem; - DiveCartesianAxis *cylinderPressureAxis; DiveGasPressureItem *gasPressureItem; QList eventItems; DiveTextItem *diveComputerText; @@ -211,9 +197,7 @@ private: DiveTextItem *decoModelParameters; #ifndef SUBSURFACE_MOBILE QList allTissues; - DiveCartesianAxis *heartBeatAxis; DiveHeartrateItem *heartBeatItem; - DiveCartesianAxis *percentageAxis; QList allPercentages; DiveLineItem *mouseFollowerVertical; DiveLineItem *mouseFollowerHorizontal;