mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
e1c0cace95
The chart items were drawn in order of creation. To control this, add a notion of Z-value. In contrast to QGraphicsScene, make this a small integer value. To controll order of drawing, a plain QSGNode is created for every possible Z-Value and items are added to these nodes. Thus, items are rendered by Z-value and if the Z-value is equal by order of creation. Likewise split the list of chart-items into Z-values, so that items can be quickly unregistered: The items that will be removed individually will usuall be part of Z-levels with only few items (e.g. legend, infobox). Z-levels with many items (notably the series) will always be fully rebuilt. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
76 lines
2.2 KiB
C++
76 lines
2.2 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, ChartZValue::InformationBox,
|
|
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;
|
|
}
|