profile: set alignment and scale of DiveTextItem at construction

Alignment and scale of DiveTextItems are never changed. Therefore,
pass them at construction time. This makes things much easier
if we want to cache the rendered text [currently the text is
rerendered at every paint() event].

This also removes the "parent=0" default parameter of the
constructor, because inadvertently leaving out the last argument
led to a subtle bug.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2021-08-12 22:57:57 +02:00 committed by Dirk Hohndel
parent 5540471ce4
commit 2ebe6e3684
7 changed files with 39 additions and 57 deletions

View file

@ -198,18 +198,17 @@ void DiveCartesianAxis::updateTicks(int animSpeed, color_index_t color)
} else {
childPos = begin - i * stepSize;
}
DiveTextItem *label = new DiveTextItem(dpr, this);
int alignFlags = orientation == RightToLeft || orientation == LeftToRight ? Qt::AlignBottom | Qt::AlignHCenter :
Qt::AlignVCenter | Qt::AlignLeft;
DiveTextItem *label = new DiveTextItem(dpr, labelScale, alignFlags, this);
label->setText(textForValue(currValueText));
label->setBrush(colorForValue(currValueText));
label->setScale(labelScale);
label->setZValue(1);
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, 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, animSpeed, m.x1() - tick_size, childPos);
}

View file

@ -142,10 +142,9 @@ void DiveProfileItem::replot(const dive *d, bool in_planner)
void DiveProfileItem::plot_depth_sample(struct plot_data *entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color)
{
DiveTextItem *item = new DiveTextItem(dpr, this);
DiveTextItem *item = new DiveTextItem(dpr, 1.0, flags, this);
item->setPos(hAxis.posAtValue(entry->sec), vAxis.posAtValue(entry->depth));
item->setText(get_depth_string(entry->depth, true));
item->setAlignment(flags);
item->setBrush(color);
texts.append(item);
}
@ -164,10 +163,11 @@ DiveHeartrateItem::DiveHeartrateItem(const DivePlotDataModel &model, const DiveC
void DiveHeartrateItem::replot(const dive *, bool)
{
int last = -300, last_printed_hr = 0, sec = 0;
struct {
struct sec_hr {
int sec;
int hr;
} hist[3] = {};
std::vector<sec_hr> textItems;
qDeleteAll(texts);
texts.clear();
@ -203,22 +203,24 @@ void DiveHeartrateItem::replot(const dive *, bool)
(abs(hr - last_printed_hr) < 10))
continue;
last = sec;
createTextItem(sec, hr);
textItems.push_back({ sec, hr });
last_printed_hr = hr;
}
setPolygon(poly);
if (texts.count())
texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
for (size_t i = 0; i < textItems.size(); ++i) {
auto [sec, hr] = textItems[i];
createTextItem(sec, hr, i == textItems.size() - 1);
}
}
void DiveHeartrateItem::createTextItem(int sec, int hr)
void DiveHeartrateItem::createTextItem(int sec, int hr, bool last)
{
DiveTextItem *text = new DiveTextItem(dpr, this);
text->setAlignment(Qt::AlignRight | Qt::AlignBottom);
int flags = last ? Qt::AlignLeft | Qt::AlignBottom :
Qt::AlignRight | Qt::AlignBottom;
DiveTextItem *text = new DiveTextItem(dpr, 0.7, flags, this);
text->setBrush(getColor(HR_TEXT));
text->setPos(QPointF(hAxis.posAtValue(sec), vAxis.posAtValue(hr)));
text->setScale(0.7); // need to call this BEFORE setText()
text->setText(QString("%1").arg(hr));
texts.append(text);
}
@ -315,6 +317,7 @@ DiveTemperatureItem::DiveTemperatureItem(const DivePlotDataModel &model, const D
void DiveTemperatureItem::replot(const dive *, bool)
{
int last = -300, last_printed_temp = 0, sec = 0, last_valid_temp = 0;
std::vector<std::pair<int, int>> textItems;
qDeleteAll(texts);
texts.clear();
@ -339,7 +342,7 @@ void DiveTemperatureItem::replot(const dive *, bool)
continue;
last = sec;
if (mkelvin > 200000)
createTextItem(sec, mkelvin);
textItems.push_back({ sec, mkelvin });
last_printed_temp = mkelvin;
}
setPolygon(poly);
@ -349,22 +352,25 @@ void DiveTemperatureItem::replot(const dive *, bool)
* than a quarter of the dive back */
if (last_valid_temp > 200000 &&
((abs(last_valid_temp - last_printed_temp) > 500) || ((double)last / (double)sec < 0.75))) {
createTextItem(sec, last_valid_temp);
textItems.push_back({ sec, last_valid_temp });
}
for (size_t i = 0; i < textItems.size(); ++i) {
auto [sec, mkelvin] = textItems[i];
createTextItem(sec, mkelvin, i == textItems.size() - 1);
}
if (texts.count())
texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
}
void DiveTemperatureItem::createTextItem(int sec, int mkelvin)
void DiveTemperatureItem::createTextItem(int sec, int mkelvin, bool last)
{
temperature_t temp;
temp.mkelvin = mkelvin;
DiveTextItem *text = new DiveTextItem(dpr, this);
text->setAlignment(Qt::AlignRight | Qt::AlignBottom);
int flags = last ? Qt::AlignLeft | Qt::AlignBottom :
Qt::AlignRight | Qt::AlignBottom;
DiveTextItem *text = new DiveTextItem(dpr, 0.8, flags, this);
text->setBrush(getColor(TEMP_TEXT));
text->setPos(QPointF(hAxis.posAtValue(sec), vAxis.posAtValue(mkelvin)));
text->setScale(0.8); // need to call this BEFORE setText()
text->setText(get_temperature_string(temp, true));
texts.append(text);
}
@ -428,11 +434,9 @@ void DiveMeanDepthItem::createTextItem()
int sec = entry[dataModel.rowCount()-1].sec;
qDeleteAll(texts);
texts.clear();
DiveTextItem *text = new DiveTextItem(dpr, this);
text->setAlignment(Qt::AlignRight | Qt::AlignTop);
DiveTextItem *text = new DiveTextItem(dpr, 0.8, Qt::AlignRight | Qt::AlignTop, this);
text->setBrush(getColor(TEMP_TEXT));
text->setPos(QPointF(hAxis.posAtValue(sec) + 1, vAxis.posAtValue(lastRunningSum)));
text->setScale(0.8); // need to call this BEFORE setText()
text->setText(get_depth_string(lrint(lastRunningSum), true));
texts.append(text);
}
@ -566,10 +570,9 @@ void DiveGasPressureItem::plotPressureValue(int mbar, int sec, QFlags<Qt::Alignm
{
const char *unit;
int pressure = get_pressure_units(mbar, &unit);
DiveTextItem *text = new DiveTextItem(dpr, this);
DiveTextItem *text = new DiveTextItem(dpr, 1.0, align, this);
text->setPos(hAxis.posAtValue(sec), vAxis.posAtValue(mbar) + pressure_offset );
text->setText(QString("%1%2").arg(pressure).arg(unit));
text->setAlignment(align);
text->setBrush(getColor(PRESSURE_TEXT));
texts.push_back(text);
}
@ -577,10 +580,9 @@ void DiveGasPressureItem::plotPressureValue(int mbar, int sec, QFlags<Qt::Alignm
void DiveGasPressureItem::plotGasValue(int mbar, int sec, struct gasmix gasmix, QFlags<Qt::AlignmentFlag> align, double gasname_offset)
{
QString gas = get_gas_string(gasmix);
DiveTextItem *text = new DiveTextItem(dpr, this);
DiveTextItem *text = new DiveTextItem(dpr, 1.0, align, this);
text->setPos(hAxis.posAtValue(sec), vAxis.posAtValue(mbar) + gasname_offset );
text->setText(gas);
text->setAlignment(align);
text->setBrush(getColor(PRESSURE_TEXT));
texts.push_back(text);
}

View file

@ -82,7 +82,7 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
private:
void createTextItem(int seconds, int mkelvin);
void createTextItem(int seconds, int mkelvin, bool last);
};
class DiveHeartrateItem : public AbstractProfilePolygonItem {
@ -93,7 +93,7 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
private:
void createTextItem(int seconds, int hr);
void createTextItem(int seconds, int hr, bool last);
QString visibilityKey;
};

View file

@ -8,12 +8,12 @@
#include <QDebug>
#include <QApplication>
DiveTextItem::DiveTextItem(double dpr, QGraphicsItem *parent) : QGraphicsItemGroup(parent),
internalAlignFlags(Qt::AlignHCenter | Qt::AlignVCenter),
DiveTextItem::DiveTextItem(double dpr, double scale, int alignFlags, QGraphicsItem *parent) : QGraphicsItemGroup(parent),
internalAlignFlags(alignFlags),
textBackgroundItem(new QGraphicsPathItem(this)),
textItem(new QGraphicsPathItem(this)),
dpr(dpr),
scale(1.0)
scale(scale)
{
setFlag(ItemIgnoresTransformations);
textBackgroundItem->setBrush(QBrush(getColor(TEXT_BACKGROUND)));
@ -27,25 +27,11 @@ void DiveTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
QGraphicsItemGroup::paint(painter, option, widget);
}
void DiveTextItem::setAlignment(int alignFlags)
{
if (alignFlags != internalAlignFlags) {
internalAlignFlags = alignFlags;
}
}
void DiveTextItem::setBrush(const QBrush &b)
{
textItem->setBrush(b);
}
void DiveTextItem::setScale(double newscale)
{
if (scale != newscale) {
scale = newscale;
}
}
void DiveTextItem::setText(const QString &t)
{
if (internalText != t) {

View file

@ -14,10 +14,8 @@ class DiveTextItem : public QObject, public QGraphicsItemGroup {
Q_PROPERTY(QPointF pos READ pos WRITE setPos)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
public:
DiveTextItem(double dpr, QGraphicsItem *parent = 0);
DiveTextItem(double dpr, double scale, int alignFlags, QGraphicsItem *parent);
void setText(const QString &text);
void setAlignment(int alignFlags);
void setScale(double newscale);
void setBrush(const QBrush &brush);
const QString &text();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

View file

@ -81,7 +81,7 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
temperatureItem(createItem<DiveTemperatureItem>(*temperatureAxis, DivePlotDataModel::TEMPERATURE, 1, dpr)),
meanDepthItem(createItem<DiveMeanDepthItem>(*profileYAxis, DivePlotDataModel::INSTANT_MEANDEPTH, 1, dpr)),
gasPressureItem(createItem<DiveGasPressureItem>(*cylinderPressureAxis, DivePlotDataModel::TEMPERATURE, 1, dpr)),
diveComputerText(new DiveTextItem(dpr)),
diveComputerText(new DiveTextItem(dpr, 1.0, Qt::AlignRight | Qt::AlignTop, nullptr)),
reportedCeiling(createItem<DiveReportedCeiling>(*profileYAxis, DivePlotDataModel::CEILING, 1, dpr)),
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)),
@ -92,7 +92,7 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
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<DiveCalculatedCeiling>(*profileYAxis, DivePlotDataModel::CEILING, 1, dpr)),
decoModelParameters(new DiveTextItem(dpr)),
decoModelParameters(new DiveTextItem(dpr, 1.0, Qt::AlignHCenter | Qt::AlignBottom, nullptr)),
heartBeatItem(createItem<DiveHeartrateItem>(*heartBeatAxis, DivePlotDataModel::HEARTBEAT, 1, dpr)),
tankItem(new TankItem(*timeAxis, dpr))
{
@ -158,9 +158,7 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
decoModelParameters->setY(0);
decoModelParameters->setX(50);
decoModelParameters->setBrush(getColor(PRESSURE_TEXT));
decoModelParameters->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
diveComputerText->setAlignment(Qt::AlignRight | Qt::AlignTop);
diveComputerText->setBrush(getColor(TIME_TEXT, isGrayscale));
diveComputerText->setPos(itemPos.dcLabel.on);

View file

@ -51,11 +51,10 @@ void TankItem::createBar(int startTime, int stopTime, struct gasmix gas)
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, rect);
DiveTextItem *label = new DiveTextItem(dpr, 1.0, Qt::AlignBottom | Qt::AlignRight, 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