mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
This one is extremely obscure: TankItem::setData(), which is called on every replot, was passed the DivePlotDataModel, even though it doesn't access that model at all. Instead, it connect()s to the model to stay informed of changes to the data. First of all, this should obviously be done once in the constructor, not on every replot. But also, the setData() function is called on every replot one lines before sending the model-changed signal. Thus, the tankitem was always repainted twice. Just remove the whole connect() thing and go for a more deterministic model. Should the tankbar not be repainted anywhere, add the appropriate calls there. Accordingly rename the "modelDataChanged" slot to "replot". Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
116 lines
3.4 KiB
C++
116 lines
3.4 KiB
C++
// SPDX-License-Identifier: GPL-2.0
|
|
#include "profile-widget/tankitem.h"
|
|
#include "profile-widget/divetextitem.h"
|
|
#include "core/event.h"
|
|
#include "core/profile.h"
|
|
#include <QPen>
|
|
|
|
static const qreal height = 3.0;
|
|
|
|
TankItem::TankItem(QObject *parent) :
|
|
QObject(parent),
|
|
plotEndTime(-1)
|
|
{
|
|
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;
|
|
hAxis = nullptr;
|
|
}
|
|
|
|
void TankItem::setData(struct plot_info *plotInfo, struct dive *d)
|
|
{
|
|
// If there is nothing to plot, quit early.
|
|
if (plotInfo->nr <= 0) {
|
|
plotEndTime = -1;
|
|
return;
|
|
}
|
|
|
|
// Find correct end of the dive plot for correct end of the tankbar.
|
|
struct plot_data *last_entry = &plotInfo->entry[plotInfo->nr - 1];
|
|
plotEndTime = last_entry->sec;
|
|
|
|
replot();
|
|
}
|
|
|
|
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(rect);
|
|
label->setText(gasname(gas));
|
|
label->setBrush(Qt::black);
|
|
label->setPos(x + 1, 0);
|
|
label->setAlignment(Qt::AlignBottom | Qt::AlignRight);
|
|
#ifdef SUBSURFACE_MOBILE
|
|
label->setPos(x + 1, -2.5);
|
|
#endif
|
|
label->setZValue(101);
|
|
}
|
|
|
|
void TankItem::replot()
|
|
{
|
|
// We don't have enougth data to calculate things, quit.
|
|
if (plotEndTime < 0)
|
|
return;
|
|
|
|
// remove the old rectangles
|
|
qDeleteAll(rects);
|
|
rects.clear();
|
|
|
|
// Bail if there are no cylinders
|
|
if (displayed_dive.cylinders.nr <= 0)
|
|
return;
|
|
|
|
// get the information directly from the displayed_dive (the dc always exists)
|
|
struct divecomputer *dc = get_dive_dc(&displayed_dive, dc_number);
|
|
|
|
// start with the first gasmix and at the start of the dive
|
|
int cyl = explicit_first_cylinder(&displayed_dive, dc);
|
|
struct gasmix gasmix = get_cylinder(&displayed_dive, cyl)->gasmix;
|
|
int startTime = 0;
|
|
|
|
// work through all the gas changes and add the rectangle for each gas while it was used
|
|
const struct event *ev = get_next_event(dc->events, "gaschange");
|
|
while (ev && (int)ev->time.seconds < plotEndTime) {
|
|
createBar(startTime, ev->time.seconds, gasmix);
|
|
startTime = ev->time.seconds;
|
|
gasmix = get_gasmix_from_event(&displayed_dive, ev);
|
|
ev = get_next_event(ev->next, "gaschange");
|
|
}
|
|
createBar(startTime, plotEndTime, gasmix);
|
|
}
|
|
|
|
void TankItem::setHorizontalAxis(DiveCartesianAxis *horizontal)
|
|
{
|
|
hAxis = horizontal;
|
|
connect(hAxis, SIGNAL(sizeChanged()), this, SLOT(replot()));
|
|
replot();
|
|
}
|