mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
d0beae59f9
The chart items were laid out in relative terms with respect to a fixed scene size (100.0, 100.0). This simply does not cut it when resizing the chart. Why should the axes always occupy the same fraction of the chart independent of the size. Moreover, this led to basically unmaintainable code. Resize the scene according to the viewport and do absolute placement of the items. This breaks the layout, but at least now we have a chance to fix things somewhat reasonably. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
113 lines
3.4 KiB
C++
113 lines
3.4 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),
|
|
plotEndTime(-1),
|
|
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
|
|
{
|
|
QFont fnt = DiveTextItem::getFont(dpr, 1.0);
|
|
QFontMetrics fm(fnt);
|
|
return fm.height() + 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 plot_info *plotInfo, const struct dive *d)
|
|
{
|
|
if (!d)
|
|
return;
|
|
|
|
// 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.
|
|
const struct plot_data *last_entry = &plotInfo->entry[plotInfo->nr - 1];
|
|
plotEndTime = last_entry->sec;
|
|
|
|
// 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 (d->cylinders.nr <= 0)
|
|
return;
|
|
|
|
// get the information directly from the displayed dive
|
|
// (get_dive_dc() always returns a valid dive computer)
|
|
const struct divecomputer *dc = get_dive_dc_const(d, dc_number);
|
|
|
|
// start with the first gasmix and at the start of the dive
|
|
int cyl = explicit_first_cylinder(d, dc);
|
|
struct gasmix gasmix = get_cylinder(d, 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(d, ev);
|
|
ev = get_next_event(ev->next, "gaschange");
|
|
}
|
|
createBar(startTime, plotEndTime, gasmix);
|
|
}
|