mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
This is a rather long commit, because it refactors lots of the event code from pointer to value semantics: pointers to entries in an std::vector<> are not stable, so better use indexes. To step through the event-list at diven time stamps, add *_loop classes, which encapsulate state that had to be manually handled before by the caller. I'm not happy about the interface, but it tries to mirror the one we had before. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
98 lines
3 KiB
C++
98 lines
3 KiB
C++
// SPDX-License-Identifier: GPL-2.0
|
|
#include "profile-widget/tankitem.h"
|
|
#include "profile-widget/divecartesianaxis.h"
|
|
#include "profile-widget/divetextitem.h"
|
|
#include "core/dive.h"
|
|
#include "core/event.h"
|
|
#include "core/profile.h"
|
|
#include <QPen>
|
|
#include <QFontMetrics>
|
|
|
|
static const double border = 1.0;
|
|
|
|
TankItem::TankItem(const DiveCartesianAxis &axis, double dpr) :
|
|
hAxis(axis),
|
|
dpr(dpr)
|
|
{
|
|
QColor red(PERSIANRED1);
|
|
QColor blue(AIR_BLUE);
|
|
QColor yellow(NITROX_YELLOW);
|
|
QColor green(NITROX_GREEN);
|
|
QLinearGradient nitroxGradient(QPointF(0, 0), QPointF(0, height()));
|
|
nitroxGradient.setColorAt(0.0, green);
|
|
nitroxGradient.setColorAt(0.49, green);
|
|
nitroxGradient.setColorAt(0.5, yellow);
|
|
nitroxGradient.setColorAt(1.0, yellow);
|
|
nitrox = nitroxGradient;
|
|
oxygen = green;
|
|
QLinearGradient trimixGradient(QPointF(0, 0), QPointF(0, height()));
|
|
trimixGradient.setColorAt(0.0, green);
|
|
trimixGradient.setColorAt(0.49, green);
|
|
trimixGradient.setColorAt(0.5, red);
|
|
trimixGradient.setColorAt(1.0, red);
|
|
trimix = trimixGradient;
|
|
air = blue;
|
|
}
|
|
|
|
double TankItem::height() const
|
|
{
|
|
return DiveTextItem::fontHeight(dpr, 1.0) + 2.0 * border * dpr;
|
|
}
|
|
|
|
void TankItem::createBar(int startTime, int stopTime, struct gasmix gas)
|
|
{
|
|
qreal x = hAxis.posAtValue(startTime);
|
|
qreal w = hAxis.posAtValue(stopTime) - hAxis.posAtValue(startTime);
|
|
|
|
// pick the right gradient, size, position and text
|
|
QGraphicsRectItem *rect = new QGraphicsRectItem(x, 0, w, height(), this);
|
|
if (gasmix_is_air(gas))
|
|
rect->setBrush(air);
|
|
else if (gas.he.permille)
|
|
rect->setBrush(trimix);
|
|
else if (gas.o2.permille == 1000)
|
|
rect->setBrush(oxygen);
|
|
else
|
|
rect->setBrush(nitrox);
|
|
rect->setPen(QPen(QBrush(), 0.0)); // get rid of the thick line around the rectangle
|
|
rects.push_back(rect);
|
|
DiveTextItem *label = new DiveTextItem(dpr, 1.0, Qt::AlignVCenter | Qt::AlignRight, rect);
|
|
label->set(gasname(gas), Qt::black);
|
|
label->setPos(x + 2.0 * dpr, height() / 2.0);
|
|
label->setZValue(101);
|
|
}
|
|
|
|
void TankItem::setData(const struct dive *d, const struct divecomputer *dc, int plotStartTime, int plotEndTime)
|
|
{
|
|
// remove the old rectangles
|
|
qDeleteAll(rects);
|
|
rects.clear();
|
|
|
|
if (!d || !dc)
|
|
return;
|
|
|
|
// We don't have enougth data to calculate things, quit.
|
|
if (plotEndTime < 0 || plotEndTime <= plotStartTime)
|
|
return;
|
|
|
|
// Bail if there are no cylinders
|
|
if (d->cylinders.nr <= 0)
|
|
return;
|
|
|
|
// start with the first gasmix and at the start of the plotted range
|
|
event_loop loop("gaschange");
|
|
struct gasmix gasmix = gasmix_invalid;
|
|
const struct event *ev;
|
|
while ((ev = loop.next(*dc)) != nullptr && ev->time.seconds <= plotStartTime)
|
|
gasmix = get_gasmix_from_event(d, *ev);
|
|
|
|
// work through all the gas changes and add the rectangle for each gas while it was used
|
|
int startTime = plotStartTime;
|
|
while (ev && (int)ev->time.seconds < plotEndTime) {
|
|
createBar(startTime, ev->time.seconds, gasmix);
|
|
startTime = ev->time.seconds;
|
|
gasmix = get_gasmix_from_event(d, *ev);
|
|
ev = loop.next(*dc);
|
|
}
|
|
createBar(startTime, plotEndTime, gasmix);
|
|
}
|