subsurface/stats/informationbox.cpp
Berthold Stoeger 785d5189f6 statistics: turn infobox into a QSGNode
A small step in converting from QGraphicsScene to QQuickItem.
This is the second item to be converted (after the legend)
and for now items are drawn in order of creation, which means
that the infobox is on top of the legend. This will have
to be made deterministic in follow-up commits.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20 08:47:18 +01:00

76 lines
2.1 KiB
C++

#include "informationbox.h"
#include "statscolors.h"
#include "statsview.h"
#include "zvalues.h"
#include <QFontMetrics>
static const QColor informationBorderColor(Qt::black);
static const QColor informationColor(0xff, 0xff, 0x00, 192); // Note: fourth argument is opacity
static const int informationBorder = 2;
static const double informationBorderRadius = 4.0; // Radius of rounded corners
static const int distanceFromPointer = 10; // Distance to place box from mouse pointer or scatter item
InformationBox::InformationBox(StatsView &v) :
ChartRectItem(v, QPen(informationBorderColor, informationBorder),
QBrush(informationColor), informationBorderRadius)
{
}
void InformationBox::setText(const std::vector<QString> &text, QPointF pos)
{
QFontMetrics fm(font);
double fontHeight = fm.height();
std::vector<double> widths;
widths.reserve(text.size());
width = 0.0;
for (const QString &s: text) {
widths.push_back(static_cast<double>(fm.size(Qt::TextSingleLine, s).width()));
width = std::max(width, widths.back());
}
width += 4.0 * informationBorder;
height = widths.size() * fontHeight + 4.0 * informationBorder;
ChartRectItem::resize(QSizeF(width, height));
painter->setPen(QPen(darkLabelColor)); // QPainter uses QPen to set text color!
double y = 2.0 * informationBorder;
for (size_t i = 0; i < widths.size(); ++i) {
QRectF rect(2.0 * informationBorder, y, widths[i], fontHeight);
painter->drawText(rect, text[i]);
y += fontHeight;
}
}
void InformationBox::setPos(QPointF pos)
{
QSizeF size = sceneSize();
double x = pos.x() + distanceFromPointer;
if (x + width >= size.width()) {
if (pos.x() - width >= 0.0)
x = pos.x() - width;
else
x = pos.x() - width / 2.0;
}
double y = pos.y() + distanceFromPointer;
if (y + height >= size.height()) {
if (pos.y() - height >= 0.0)
y = pos.y() - height;
else
y = pos.y() - height / 2.0;
}
ChartRectItem::setPos(QPointF(x, y));
}
// Try to stay within three-thirds of the chart height
int InformationBox::recommendedMaxLines() const
{
QFontMetrics fm(font);
int maxHeight = static_cast<int>(sceneSize().height());
return maxHeight * 2 / fm.height() / 3;
}