subsurface/profile-widget/tooltipitem.cpp

157 lines
4.8 KiB
C++
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0
#include "tooltipitem.h"
#include "profiletranslations.h"
#include "zvalues.h"
#include "core/color.h"
#include "core/membuffer.h"
#include "core/profile.h"
#include "core/qthelper.h" // for decoMode
#include "core/settings/qPrefDisplay.h"
#include <cmath>
#include <QApplication>
#include <QFontMetrics>
static const int tooltipBorder = 2;
static const double tooltipBorderRadius = 4.0; // Radius of rounded corners
static QColor tooltipBorderColor(Qt::white);
static QColor tooltipColor(0, 0, 0, 155);
static QColor tooltipFontColor(Qt::white);
static QFont makeFont(double dpr)
{
QFont font(qApp->font());
if (dpr != 1.0) {
int pixelSize = font.pixelSize();
if (pixelSize > 0) {
pixelSize = lrint(static_cast<double>(pixelSize) * dpr);
font.setPixelSize(pixelSize);
} else {
font.setPointSizeF(font.pointSizeF() * dpr);
}
}
return font;
}
ToolTipItem::ToolTipItem(ChartView &view, double dpr) :
ChartRectItem(view, ProfileZValue::ToolTipItem,
QPen(tooltipBorderColor, tooltipBorder),
QBrush(tooltipColor), tooltipBorderRadius,
true),
font(makeFont(dpr)),
fm(font),
fontHeight(fm.height())
{
title = stringToPixmap(ProfileTranslations::tr("Information"));
QPointF pos = qPrefDisplay::tooltip_position();
setPos(pos);
}
QPixmap ToolTipItem::stringToPixmap(const QString &str) const
{
QSize s = fm.size(Qt::TextSingleLine, str);
if (s.width() <= 0 || s.height() <= 0)
return QPixmap(1,1);
QPixmap res(s);
res.fill(Qt::transparent);
QPainter painter(&res);
painter.setFont(font);
painter.setPen(tooltipFontColor);
painter.drawText(QRect(QPoint(), s), str);
return res;
}
static QPixmap drawTissues(const plot_info &pInfo, double dpr, int idx, bool inPlanner)
{
QPixmap tissues(16,60);
QPainter painter(&tissues);
tissues.fill();
painter.setPen(QColor(0, 0, 0, 0));
painter.setBrush(QColor(LIMENADE1));
painter.drawRect(0, 10 + (100 - AMB_PERCENTAGE) / 2, 16, AMB_PERCENTAGE / 2);
painter.setBrush(QColor(SPRINGWOOD1));
painter.drawRect(0, 10, 16, (100 - AMB_PERCENTAGE) / 2);
painter.setBrush(QColor(Qt::red));
painter.drawRect(0,0,16,10);
if (!idx)
return tissues;
const struct plot_data *entry = &pInfo.entry[idx];
painter.setPen(QColor(0, 0, 0, 255));
if (decoMode(inPlanner) == BUEHLMANN)
painter.drawLine(0, lrint(60 - entry->gfline / 2), 16, lrint(60 - entry->gfline / 2));
painter.drawLine(0, lrint(60 - AMB_PERCENTAGE * (entry->pressures.n2 + entry->pressures.he) / entry->ambpressure / 2),
16, lrint(60 - AMB_PERCENTAGE * (entry->pressures.n2 + entry->pressures.he) / entry->ambpressure /2));
painter.setPen(QColor(0, 0, 0, 127));
for (int i = 0; i < 16; i++)
painter.drawLine(i, 60, i, 60 - entry->percentages[i] / 2);
if (dpr == 1.0)
return tissues;
// Scale according to DPR
int new_width = lrint(tissues.width() * dpr);
int new_height = lrint(tissues.width() * dpr);
return tissues.scaled(new_width, new_height);
}
void ToolTipItem::update(const dive *d, double dpr, int time, const plot_info &pInfo, bool inPlanner)
{
auto [idx, lines] = get_plot_details_new(d, pInfo, time);
QPixmap tissues = drawTissues(pInfo, dpr, idx, inPlanner);
//TODO: add event tool tips!
//const auto l = scene()->items(pos, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder,
//scene()->views().first()->transform());
//for (QGraphicsItem *item: l) {
//if (!item->toolTip().isEmpty())
//addToolTip(item->toolTip(), QPixmap());
//}
width = title.size().width();
// Turn strings into QString/width pairs and increase width if needed
std::vector<std::pair<QString, int>> strings;
strings.reserve(lines.size());
for (auto &s_std: lines) {
auto s = QString::fromStdString(s_std);
int w = fm.size(Qt::TextSingleLine, s).width();
width = std::max(width, static_cast<double>(w));
strings.push_back(std::make_pair(s, w));
}
width += tissues.width();
width += 6.0 * tooltipBorder;
height = 4.0 * tooltipBorder + title.height() +
std::max((static_cast<double>(strings.size()) + 1.0) * fontHeight,
static_cast<double>(tissues.height()));
ChartRectItem::resize(QSizeF(width, height));
painter->setFont(font);
painter->setPen(QPen(tooltipFontColor)); // QPainter uses QPen to set text color!
double x = 4.0 * tooltipBorder + tissues.width();
double y = 2.0 * tooltipBorder;
double titleOffset = (width - title.width()) / 2.0;
painter->drawPixmap(lrint(titleOffset), lrint(y), title, 0, 0, title.width(), title.height());
y += round(fontHeight);
painter->drawPixmap(lrint(2.0 * tooltipBorder), lrint(y), tissues, 0, 0, tissues.width(), tissues.height());
y += round(fontHeight);
for (auto &[s,w]: strings) {
QRectF rect(x, y, w, fontHeight);
painter->drawText(rect, s);
y += fontHeight;
}
setTextureDirty();
}
void ToolTipItem::stopDrag(QPointF pos)
{
qPrefDisplay::set_tooltip_position(pos);
}