mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
profile: access profile data directly
The profile was using a Qt-model to access its data. This means routing everything through Qt's QVariants and lead to verbose code such as double prev_y = dataModel.index(i-1, vDataColumn).data().toReal(); Instead of storing a data-column and do access via a template, simply store accessor functions. The code from above now reads as double prev_y = accessor(data[i-1]); This should also be distinctly faster for the ns-optimizers among us. Only one case was somewhat nasty to convert: The accessors for the 16 tissues are now generated via a recursive template. Thanks to C++17's constexpr if, such a template is pleasantly easy to follow, though. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
11913e614c
commit
6f2965c5af
4 changed files with 112 additions and 63 deletions
|
@ -13,8 +13,9 @@
|
||||||
#include "profile-widget/profilewidget2.h"
|
#include "profile-widget/profilewidget2.h"
|
||||||
|
|
||||||
AbstractProfilePolygonItem::AbstractProfilePolygonItem(const DivePlotDataModel &model, const DiveCartesianAxis &horizontal,
|
AbstractProfilePolygonItem::AbstractProfilePolygonItem(const DivePlotDataModel &model, const DiveCartesianAxis &horizontal,
|
||||||
const DiveCartesianAxis &vertical, int vColumn, double dpr) :
|
const DiveCartesianAxis &vertical, DataAccessor accessor,
|
||||||
hAxis(horizontal), vAxis(vertical), dataModel(model), vDataColumn(vColumn), dpr(dpr), from(0), to(0)
|
double dpr) :
|
||||||
|
hAxis(horizontal), vAxis(vertical), dataModel(model), accessor(accessor), dpr(dpr), from(0), to(0)
|
||||||
{
|
{
|
||||||
setCacheMode(DeviceCoordinateCache);
|
setCacheMode(DeviceCoordinateCache);
|
||||||
}
|
}
|
||||||
|
@ -46,18 +47,19 @@ void AbstractProfilePolygonItem::clipStop(double &x, double &y, double prev_x, d
|
||||||
|
|
||||||
std::pair<double, double> AbstractProfilePolygonItem::getPoint(int i) const
|
std::pair<double, double> AbstractProfilePolygonItem::getPoint(int i) const
|
||||||
{
|
{
|
||||||
double x = dataModel.index(i, DivePlotDataModel::TIME).data().toReal();
|
const struct plot_data *data = dataModel.data().entry;
|
||||||
double y = dataModel.index(i, vDataColumn).data().toReal();
|
double x = data[i].sec;
|
||||||
|
double y = accessor(data[i]);
|
||||||
|
|
||||||
// Do clipping of first and last value
|
// Do clipping of first and last value
|
||||||
if (i == from && i < to) {
|
if (i == from && i < to) {
|
||||||
double next_x = dataModel.index(i+1, DivePlotDataModel::TIME).data().toReal();
|
double next_x = data[i+1].sec;
|
||||||
double next_y = dataModel.index(i+1, vDataColumn).data().toReal();
|
double next_y = accessor(data[i+1]);
|
||||||
clipStart(x, y, next_x, next_y);
|
clipStart(x, y, next_x, next_y);
|
||||||
}
|
}
|
||||||
if (i == to - 1 && i > 0) {
|
if (i == to - 1 && i > 0) {
|
||||||
double prev_x = dataModel.index(i-1, DivePlotDataModel::TIME).data().toReal();
|
double prev_x = data[i-1].sec;
|
||||||
double prev_y = dataModel.index(i-1, vDataColumn).data().toReal();
|
double prev_y = accessor(data[i-1]);
|
||||||
clipStop(x, y, prev_x, prev_y);
|
clipStop(x, y, prev_x, prev_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +98,8 @@ void AbstractProfilePolygonItem::makePolygon(int fromIn, int toIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
DiveProfileItem::DiveProfileItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveProfileItem::DiveProfileItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr) :
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) :
|
||||||
AbstractProfilePolygonItem(model, hAxis, vAxis, vColumn, dpr),
|
AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr),
|
||||||
show_reported_ceiling(0), reported_ceiling_in_red(0)
|
show_reported_ceiling(0), reported_ceiling_in_red(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -119,10 +121,11 @@ void DiveProfileItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
pen.setWidth(2);
|
pen.setWidth(2);
|
||||||
QPolygonF poly = polygon();
|
QPolygonF poly = polygon();
|
||||||
|
const struct plot_data *data = dataModel.data().entry;
|
||||||
// This paints the colors of the velocities.
|
// This paints the colors of the velocities.
|
||||||
for (int i = from + 1; i < to; i++) {
|
for (int i = from + 1; i < to; i++) {
|
||||||
QModelIndex colorIndex = dataModel.index(i, DivePlotDataModel::COLOR);
|
QColor color = getColor((color_index_t)(VELOCITY_COLORS_START_IDX + data[i].velocity));
|
||||||
pen.setBrush(QBrush(colorIndex.data(Qt::BackgroundRole).value<QColor>()));
|
pen.setBrush(QBrush(color));
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
if (i - from < poly.count() - 1)
|
if (i - from < poly.count() - 1)
|
||||||
painter->drawLine(poly[i - from], poly[i - from + 1]);
|
painter->drawLine(poly[i - from], poly[i - from + 1]);
|
||||||
|
@ -259,8 +262,8 @@ void DiveProfileItem::plot_depth_sample(const struct plot_data &entry, QFlags<Qt
|
||||||
}
|
}
|
||||||
|
|
||||||
DiveHeartrateItem::DiveHeartrateItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveHeartrateItem::DiveHeartrateItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr) :
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) :
|
||||||
AbstractProfilePolygonItem(model, hAxis, vAxis, vColumn, dpr)
|
AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr)
|
||||||
{
|
{
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setBrush(QBrush(getColor(::HR_PLOT)));
|
pen.setBrush(QBrush(getColor(::HR_PLOT)));
|
||||||
|
@ -349,8 +352,8 @@ void DiveHeartrateItem::paint(QPainter *painter, const QStyleOptionGraphicsItem*
|
||||||
}
|
}
|
||||||
|
|
||||||
DiveTemperatureItem::DiveTemperatureItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveTemperatureItem::DiveTemperatureItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr) :
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) :
|
||||||
AbstractProfilePolygonItem(model, hAxis, vAxis, vColumn, dpr)
|
AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr)
|
||||||
{
|
{
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setBrush(QBrush(getColor(::TEMP_PLOT)));
|
pen.setBrush(QBrush(getColor(::TEMP_PLOT)));
|
||||||
|
@ -435,8 +438,8 @@ void DiveTemperatureItem::paint(QPainter *painter, const QStyleOptionGraphicsIte
|
||||||
static const double diveMeanDepthItemLabelScale = 0.8;
|
static const double diveMeanDepthItemLabelScale = 0.8;
|
||||||
|
|
||||||
DiveMeanDepthItem::DiveMeanDepthItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveMeanDepthItem::DiveMeanDepthItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr) :
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) :
|
||||||
AbstractProfilePolygonItem(model, hAxis, vAxis, vColumn, dpr),
|
AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr),
|
||||||
labelWidth(DiveTextItem::getLabelSize(dpr, diveMeanDepthItemLabelScale, QStringLiteral("999.9ft")).first)
|
labelWidth(DiveTextItem::getLabelSize(dpr, diveMeanDepthItemLabelScale, QStringLiteral("999.9ft")).first)
|
||||||
{
|
{
|
||||||
QPen pen;
|
QPen pen;
|
||||||
|
@ -683,8 +686,8 @@ void DiveGasPressureItem::paint(QPainter *painter, const QStyleOptionGraphicsIte
|
||||||
}
|
}
|
||||||
|
|
||||||
DiveCalculatedCeiling::DiveCalculatedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveCalculatedCeiling::DiveCalculatedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr) :
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) :
|
||||||
AbstractProfilePolygonItem(model, hAxis, vAxis, vColumn, dpr)
|
AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,14 +710,14 @@ void DiveCalculatedCeiling::paint(QPainter *painter, const QStyleOptionGraphicsI
|
||||||
}
|
}
|
||||||
|
|
||||||
DiveCalculatedTissue::DiveCalculatedTissue(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveCalculatedTissue::DiveCalculatedTissue(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr) :
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) :
|
||||||
DiveCalculatedCeiling(model, hAxis, vAxis, vColumn, dpr)
|
DiveCalculatedCeiling(model, hAxis, vAxis, accessor, dpr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DiveReportedCeiling::DiveReportedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveReportedCeiling::DiveReportedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr) :
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) :
|
||||||
AbstractProfilePolygonItem(model, hAxis, vAxis, vColumn, dpr)
|
AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,8 +842,8 @@ void PartialPressureGasItem::setThresholdSettingsKey(const double *prefPointerMi
|
||||||
}
|
}
|
||||||
|
|
||||||
PartialPressureGasItem::PartialPressureGasItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
PartialPressureGasItem::PartialPressureGasItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr) :
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) :
|
||||||
AbstractProfilePolygonItem(model, hAxis, vAxis, vColumn, dpr),
|
AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr),
|
||||||
thresholdPtrMin(NULL),
|
thresholdPtrMin(NULL),
|
||||||
thresholdPtrMax(NULL)
|
thresholdPtrMax(NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,9 @@ struct dive;
|
||||||
|
|
||||||
class AbstractProfilePolygonItem : public QGraphicsPolygonItem {
|
class AbstractProfilePolygonItem : public QGraphicsPolygonItem {
|
||||||
public:
|
public:
|
||||||
AbstractProfilePolygonItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
using DataAccessor = double (*)(const plot_data &data); // The pointer-to-function syntax is hilarious.
|
||||||
|
AbstractProfilePolygonItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis,
|
||||||
|
DataAccessor accessor, double dpr);
|
||||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0;
|
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ protected:
|
||||||
const DiveCartesianAxis &hAxis;
|
const DiveCartesianAxis &hAxis;
|
||||||
const DiveCartesianAxis &vAxis;
|
const DiveCartesianAxis &vAxis;
|
||||||
const DivePlotDataModel &dataModel;
|
const DivePlotDataModel &dataModel;
|
||||||
int vDataColumn;
|
DataAccessor accessor;
|
||||||
double dpr;
|
double dpr;
|
||||||
int from, to;
|
int from, to;
|
||||||
QList<DiveTextItem *> texts;
|
QList<DiveTextItem *> texts;
|
||||||
|
@ -47,7 +49,8 @@ protected:
|
||||||
|
|
||||||
class DiveProfileItem : public AbstractProfilePolygonItem {
|
class DiveProfileItem : public AbstractProfilePolygonItem {
|
||||||
public:
|
public:
|
||||||
DiveProfileItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
DiveProfileItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis,
|
||||||
|
DataAccessor accessor, double dpr);
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
||||||
void replot(const dive *d, int from, int to, bool in_planner) override;
|
void replot(const dive *d, int from, int to, bool in_planner) override;
|
||||||
void plot_depth_sample(const struct plot_data &entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color);
|
void plot_depth_sample(const struct plot_data &entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color);
|
||||||
|
@ -61,7 +64,8 @@ private:
|
||||||
|
|
||||||
class DiveMeanDepthItem : public AbstractProfilePolygonItem {
|
class DiveMeanDepthItem : public AbstractProfilePolygonItem {
|
||||||
public:
|
public:
|
||||||
DiveMeanDepthItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
DiveMeanDepthItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis,
|
||||||
|
DataAccessor accessor, double dpr);
|
||||||
void replot(const dive *d, int from, int to, bool in_planner) override;
|
void replot(const dive *d, int from, int to, bool in_planner) override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
||||||
double labelWidth;
|
double labelWidth;
|
||||||
|
@ -74,7 +78,8 @@ private:
|
||||||
|
|
||||||
class DiveTemperatureItem : public AbstractProfilePolygonItem {
|
class DiveTemperatureItem : public AbstractProfilePolygonItem {
|
||||||
public:
|
public:
|
||||||
DiveTemperatureItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
DiveTemperatureItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis,
|
||||||
|
DataAccessor accessor, double dpr);
|
||||||
void replot(const dive *d, int from, int to, bool in_planner) override;
|
void replot(const dive *d, int from, int to, bool in_planner) override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
||||||
|
|
||||||
|
@ -84,7 +89,8 @@ private:
|
||||||
|
|
||||||
class DiveHeartrateItem : public AbstractProfilePolygonItem {
|
class DiveHeartrateItem : public AbstractProfilePolygonItem {
|
||||||
public:
|
public:
|
||||||
DiveHeartrateItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
DiveHeartrateItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis,
|
||||||
|
DataAccessor accessor, double dpr);
|
||||||
void replot(const dive *d, int from, int to, bool in_planner) override;
|
void replot(const dive *d, int from, int to, bool in_planner) override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||||
|
|
||||||
|
@ -120,14 +126,14 @@ private:
|
||||||
class DiveCalculatedCeiling : public AbstractProfilePolygonItem {
|
class DiveCalculatedCeiling : public AbstractProfilePolygonItem {
|
||||||
public:
|
public:
|
||||||
DiveCalculatedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveCalculatedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr);
|
||||||
void replot(const dive *d, int from, int to, bool in_planner) override;
|
void replot(const dive *d, int from, int to, bool in_planner) override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiveReportedCeiling : public AbstractProfilePolygonItem {
|
class DiveReportedCeiling : public AbstractProfilePolygonItem {
|
||||||
public:
|
public:
|
||||||
DiveReportedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
DiveReportedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr);
|
||||||
void replot(const dive *d, int from, int to, bool in_planner) override;
|
void replot(const dive *d, int from, int to, bool in_planner) override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
||||||
private:
|
private:
|
||||||
|
@ -138,12 +144,12 @@ private:
|
||||||
class DiveCalculatedTissue : public DiveCalculatedCeiling {
|
class DiveCalculatedTissue : public DiveCalculatedCeiling {
|
||||||
public:
|
public:
|
||||||
DiveCalculatedTissue(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
DiveCalculatedTissue(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis,
|
||||||
const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PartialPressureGasItem : public AbstractProfilePolygonItem {
|
class PartialPressureGasItem : public AbstractProfilePolygonItem {
|
||||||
public:
|
public:
|
||||||
PartialPressureGasItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, int vColumn, double dpr);
|
PartialPressureGasItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr);
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
||||||
void replot(const dive *d, int from, int to, bool in_planner) override;
|
void replot(const dive *d, int from, int to, bool in_planner) override;
|
||||||
void setThresholdSettingsKey(const double *prefPointerMin, const double *prefPointerMax);
|
void setThresholdSettingsKey(const double *prefPointerMin, const double *prefPointerMax);
|
||||||
|
|
|
@ -48,23 +48,42 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, class... Args>
|
template<typename T, class... Args>
|
||||||
T *ProfileScene::createItem(const DiveCartesianAxis &vAxis, int vColumn, int z, Args&&... args)
|
T *ProfileScene::createItem(const DiveCartesianAxis &vAxis, DataAccessor accessor, int z, Args&&... args)
|
||||||
{
|
{
|
||||||
T *res = new T(*dataModel, *timeAxis, vAxis, vColumn, std::forward<Args>(args)...);
|
T *res = new T(*dataModel, *timeAxis, vAxis, accessor, std::forward<Args>(args)...);
|
||||||
res->setZValue(static_cast<double>(z));
|
res->setZValue(static_cast<double>(z));
|
||||||
profileItems.push_back(res);
|
profileItems.push_back(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartialPressureGasItem *ProfileScene::createPPGas(int column, color_index_t color, color_index_t colorAlert,
|
PartialPressureGasItem *ProfileScene::createPPGas(DataAccessor accessor, color_index_t color, color_index_t colorAlert,
|
||||||
const double *thresholdSettingsMin, const double *thresholdSettingsMax)
|
const double *thresholdSettingsMin, const double *thresholdSettingsMax)
|
||||||
{
|
{
|
||||||
PartialPressureGasItem *item = createItem<PartialPressureGasItem>(*gasYAxis, column, 99, dpr);
|
PartialPressureGasItem *item = createItem<PartialPressureGasItem>(*gasYAxis, accessor, 99, dpr);
|
||||||
item->setThresholdSettingsKey(thresholdSettingsMin, thresholdSettingsMax);
|
item->setThresholdSettingsKey(thresholdSettingsMin, thresholdSettingsMax);
|
||||||
item->setColors(getColor(color, isGrayscale), getColor(colorAlert, isGrayscale));
|
item->setColors(getColor(color, isGrayscale), getColor(colorAlert, isGrayscale));
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <int IDX>
|
||||||
|
double accessTissue(const plot_data &item)
|
||||||
|
{
|
||||||
|
return item.ceilings[IDX];
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now, the accessor functions for the profile data do not possess a payload.
|
||||||
|
// To generate the 16 tissue (ceiling) accessor functions, use iterative templates.
|
||||||
|
// Thanks to C++17's constexpr if, this is actually easy to read and follow.
|
||||||
|
template <int ACT, int MAX>
|
||||||
|
void ProfileScene::addTissueItems(double dpr)
|
||||||
|
{
|
||||||
|
if constexpr (ACT < MAX) {
|
||||||
|
DiveCalculatedTissue *tissueItem = createItem<DiveCalculatedTissue>(*profileYAxis, &accessTissue<ACT>, ACT + 1, dpr);
|
||||||
|
allTissues.push_back(tissueItem);
|
||||||
|
addTissueItems<ACT + 1, MAX>(dpr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
|
ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
|
||||||
d(nullptr),
|
d(nullptr),
|
||||||
dc(-1),
|
dc(-1),
|
||||||
|
@ -88,23 +107,45 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
|
||||||
dpr, 0.7, printMode, isGrayscale, *this)),
|
dpr, 0.7, printMode, isGrayscale, *this)),
|
||||||
percentageAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, false, 2, 0, TIME_GRID, Qt::black, false, false,
|
percentageAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, false, 2, 0, TIME_GRID, Qt::black, false, false,
|
||||||
dpr, 0.7, printMode, isGrayscale, *this)),
|
dpr, 0.7, printMode, isGrayscale, *this)),
|
||||||
diveProfileItem(createItem<DiveProfileItem>(*profileYAxis, DivePlotDataModel::DEPTH, 0, dpr)),
|
diveProfileItem(createItem<DiveProfileItem>(*profileYAxis,
|
||||||
temperatureItem(createItem<DiveTemperatureItem>(*temperatureAxis, DivePlotDataModel::TEMPERATURE, 1, dpr)),
|
[](const plot_data &item) { return (double)item.depth; },
|
||||||
meanDepthItem(createItem<DiveMeanDepthItem>(*profileYAxis, DivePlotDataModel::INSTANT_MEANDEPTH, 1, dpr)),
|
0, dpr)),
|
||||||
gasPressureItem(createItem<DiveGasPressureItem>(*cylinderPressureAxis, DivePlotDataModel::TEMPERATURE, 1, dpr)),
|
temperatureItem(createItem<DiveTemperatureItem>(*temperatureAxis,
|
||||||
|
[](const plot_data &item) { return (double)item.temperature; },
|
||||||
|
1, dpr)),
|
||||||
|
meanDepthItem(createItem<DiveMeanDepthItem>(*profileYAxis,
|
||||||
|
[](const plot_data &item) { return (double)item.running_sum; },
|
||||||
|
1, dpr)),
|
||||||
|
gasPressureItem(createItem<DiveGasPressureItem>(*cylinderPressureAxis,
|
||||||
|
[](const plot_data &item) { return 0.0; }, // unused
|
||||||
|
1, dpr)),
|
||||||
diveComputerText(new DiveTextItem(dpr, 1.0, Qt::AlignRight | Qt::AlignTop, nullptr)),
|
diveComputerText(new DiveTextItem(dpr, 1.0, Qt::AlignRight | Qt::AlignTop, nullptr)),
|
||||||
reportedCeiling(createItem<DiveReportedCeiling>(*profileYAxis, DivePlotDataModel::CEILING, 1, dpr)),
|
reportedCeiling(createItem<DiveReportedCeiling>(*profileYAxis,
|
||||||
pn2GasItem(createPPGas(DivePlotDataModel::PN2, PN2, PN2_ALERT, NULL, &prefs.pp_graphs.pn2_threshold)),
|
[](const plot_data &item) { return (double)item.ceiling; },
|
||||||
pheGasItem(createPPGas(DivePlotDataModel::PHE, PHE, PHE_ALERT, NULL, &prefs.pp_graphs.phe_threshold)),
|
1, dpr)),
|
||||||
po2GasItem(createPPGas(DivePlotDataModel::PO2, PO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
pn2GasItem(createPPGas([](const plot_data &item) { return (double)item.pressures.n2; },
|
||||||
o2SetpointGasItem(createPPGas(DivePlotDataModel::O2SETPOINT, O2SETPOINT, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
PN2, PN2_ALERT, NULL, &prefs.pp_graphs.pn2_threshold)),
|
||||||
ccrsensor1GasItem(createPPGas(DivePlotDataModel::CCRSENSOR1, CCRSENSOR1, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
pheGasItem(createPPGas([](const plot_data &item) { return (double)item.pressures.he; },
|
||||||
ccrsensor2GasItem(createPPGas(DivePlotDataModel::CCRSENSOR2, CCRSENSOR2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
PHE, PHE_ALERT, NULL, &prefs.pp_graphs.phe_threshold)),
|
||||||
ccrsensor3GasItem(createPPGas(DivePlotDataModel::CCRSENSOR3, CCRSENSOR3, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
po2GasItem(createPPGas([](const plot_data &item) { return (double)item.pressures.o2; },
|
||||||
ocpo2GasItem(createPPGas(DivePlotDataModel::SCR_OC_PO2, SCR_OCPO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
PO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
||||||
diveCeiling(createItem<DiveCalculatedCeiling>(*profileYAxis, DivePlotDataModel::CEILING, 1, dpr)),
|
o2SetpointGasItem(createPPGas([](const plot_data &item) { return item.o2setpoint.mbar / 1000.0; },
|
||||||
|
O2SETPOINT, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
||||||
|
ccrsensor1GasItem(createPPGas([](const plot_data &item) { return item.o2sensor[0].mbar / 1000.0; },
|
||||||
|
CCRSENSOR1, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
||||||
|
ccrsensor2GasItem(createPPGas([](const plot_data &item) { return item.o2sensor[1].mbar / 1000.0; },
|
||||||
|
CCRSENSOR2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
||||||
|
ccrsensor3GasItem(createPPGas([](const plot_data &item) { return item.o2sensor[2].mbar / 1000.0; },
|
||||||
|
CCRSENSOR3, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
||||||
|
ocpo2GasItem(createPPGas([](const plot_data &item) { return item.scr_OC_pO2.mbar / 1000.0; },
|
||||||
|
SCR_OCPO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max)),
|
||||||
|
diveCeiling(createItem<DiveCalculatedCeiling>(*profileYAxis,
|
||||||
|
[](const plot_data &item) { return (double)item.ceiling; },
|
||||||
|
1, dpr)),
|
||||||
decoModelParameters(new DiveTextItem(dpr, 1.0, Qt::AlignHCenter | Qt::AlignTop, nullptr)),
|
decoModelParameters(new DiveTextItem(dpr, 1.0, Qt::AlignHCenter | Qt::AlignTop, nullptr)),
|
||||||
heartBeatItem(createItem<DiveHeartrateItem>(*heartBeatAxis, DivePlotDataModel::HEARTBEAT, 1, dpr)),
|
heartBeatItem(createItem<DiveHeartrateItem>(*heartBeatAxis,
|
||||||
|
[](const plot_data &item) { return (double)item.heartbeat; },
|
||||||
|
1, dpr)),
|
||||||
percentageItem(new DivePercentageItem(*timeAxis, *percentageAxis, dpr)),
|
percentageItem(new DivePercentageItem(*timeAxis, *percentageAxis, dpr)),
|
||||||
tankItem(new TankItem(*timeAxis, dpr)),
|
tankItem(new TankItem(*timeAxis, dpr)),
|
||||||
pixmaps(getDivePixmaps(dpr))
|
pixmaps(getDivePixmaps(dpr))
|
||||||
|
@ -122,10 +163,7 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
|
||||||
heartBeatAxis->setTransform(1.0);
|
heartBeatAxis->setTransform(1.0);
|
||||||
gasYAxis->setTransform(1.0); // Non-metric countries likewise use bar (disguised as "percentage") for partial pressure.
|
gasYAxis->setTransform(1.0); // Non-metric countries likewise use bar (disguised as "percentage") for partial pressure.
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
addTissueItems<0,16>(dpr);
|
||||||
DiveCalculatedTissue *tissueItem = createItem<DiveCalculatedTissue>(*profileYAxis, DivePlotDataModel::TISSUE_1 + i, i + 1, dpr);
|
|
||||||
allTissues.append(tissueItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
percentageItem->setZValue(1.0);
|
percentageItem->setZValue(1.0);
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,11 @@ public:
|
||||||
const struct dive *d;
|
const struct dive *d;
|
||||||
int dc;
|
int dc;
|
||||||
private:
|
private:
|
||||||
template<typename T, class... Args> T *createItem(const DiveCartesianAxis &vAxis, int vColumn, int z, Args&&... args);
|
using DataAccessor = double (*)(const plot_data &data);
|
||||||
PartialPressureGasItem *createPPGas(int column, color_index_t color, color_index_t colorAlert,
|
template<typename T, class... Args> T *createItem(const DiveCartesianAxis &vAxis, DataAccessor accessor, int z, Args&&... args);
|
||||||
|
PartialPressureGasItem *createPPGas(DataAccessor accessor, color_index_t color, color_index_t colorAlert,
|
||||||
const double *thresholdSettingsMin, const double *thresholdSettingsMax);
|
const double *thresholdSettingsMin, const double *thresholdSettingsMax);
|
||||||
|
template <int ACT, int MAX> void addTissueItems(double dpr);
|
||||||
void updateVisibility(bool diveHasHeartBeat, bool simplified); // Update visibility of non-interactive chart features according to preferences
|
void updateVisibility(bool diveHasHeartBeat, bool simplified); // Update visibility of non-interactive chart features according to preferences
|
||||||
void updateAxes(bool diveHasHeartBeat, bool simplified); // Update axes according to preferences
|
void updateAxes(bool diveHasHeartBeat, bool simplified); // Update axes according to preferences
|
||||||
|
|
||||||
|
@ -94,7 +96,7 @@ private:
|
||||||
PartialPressureGasItem *ocpo2GasItem;
|
PartialPressureGasItem *ocpo2GasItem;
|
||||||
DiveCalculatedCeiling *diveCeiling;
|
DiveCalculatedCeiling *diveCeiling;
|
||||||
DiveTextItem *decoModelParameters;
|
DiveTextItem *decoModelParameters;
|
||||||
QList<DiveCalculatedTissue *> allTissues;
|
std::vector<DiveCalculatedTissue *> allTissues;
|
||||||
DiveHeartrateItem *heartBeatItem;
|
DiveHeartrateItem *heartBeatItem;
|
||||||
DivePercentageItem *percentageItem;
|
DivePercentageItem *percentageItem;
|
||||||
TankItem *tankItem;
|
TankItem *tankItem;
|
||||||
|
|
Loading…
Add table
Reference in a new issue