diff options
Diffstat (limited to 'stats')
-rw-r--r-- | stats/barseries.cpp | 3 | ||||
-rw-r--r-- | stats/boxseries.cpp | 3 | ||||
-rw-r--r-- | stats/informationbox.cpp | 65 | ||||
-rw-r--r-- | stats/informationbox.h | 10 | ||||
-rw-r--r-- | stats/pieseries.cpp | 3 | ||||
-rw-r--r-- | stats/scatterseries.cpp | 3 | ||||
-rw-r--r-- | stats/statsview.cpp | 8 | ||||
-rw-r--r-- | stats/statsview.h | 16 |
8 files changed, 53 insertions, 58 deletions
diff --git a/stats/barseries.cpp b/stats/barseries.cpp index 91ab1c941..733549d3d 100644 --- a/stats/barseries.cpp +++ b/stats/barseries.cpp @@ -4,6 +4,7 @@ #include "statscolors.h" #include "statshelper.h" #include "statstranslations.h" +#include "statsview.h" #include "zvalues.h" #include <math.h> // for lrint() @@ -403,7 +404,7 @@ bool BarSeries::hover(QPointF pos) Item &item = items[highlighted.bar]; item.highlight(index.subitem, true, binCount()); if (!information) - information = createItemPtr<InformationBox>(scene); + information = view.createChartItem<InformationBox>(); information->setText(makeInfo(item, highlighted.subitem), pos); } else { information.reset(); diff --git a/stats/boxseries.cpp b/stats/boxseries.cpp index def20477e..b3dc2e5bd 100644 --- a/stats/boxseries.cpp +++ b/stats/boxseries.cpp @@ -4,6 +4,7 @@ #include "statscolors.h" #include "statshelper.h" #include "statstranslations.h" +#include "statsview.h" #include "zvalues.h" #include <QLocale> @@ -149,7 +150,7 @@ bool BoxSeries::hover(QPointF pos) Item &item = *items[highlighted]; item.highlight(true); if (!information) - information = createItemPtr<InformationBox>(scene); + information = view.createChartItem<InformationBox>(); information->setText(formatInformation(item), pos); } else { information.reset(); diff --git a/stats/informationbox.cpp b/stats/informationbox.cpp index 189fd1ab1..c768b77b3 100644 --- a/stats/informationbox.cpp +++ b/stats/informationbox.cpp @@ -1,9 +1,9 @@ #include "informationbox.h" #include "statscolors.h" +#include "statsview.h" #include "zvalues.h" #include <QFontMetrics> -#include <QGraphicsScene> static const QColor informationBorderColor(Qt::black); static const QColor informationColor(0xff, 0xff, 0x00, 192); // Note: fourth argument is opacity @@ -11,74 +11,65 @@ 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() : RoundRectItem(informationBorderRadius, nullptr) +InformationBox::InformationBox(StatsView &v) : + ChartRectItem(v, QPen(informationBorderColor, informationBorder), + QBrush(informationColor), informationBorderRadius) { - setPen(QPen(informationBorderColor, informationBorder)); - setBrush(informationColor); - setZValue(ZValues::informationBox); } void InformationBox::setText(const std::vector<QString> &text, QPointF pos) { - width = height = 0.0; - textItems.clear(); + QFontMetrics fm(font); + double fontHeight = fm.height(); + std::vector<double> widths; + widths.reserve(text.size()); + width = 0.0; for (const QString &s: text) { - if (!s.isEmpty()) - addLine(s); + widths.push_back(static_cast<double>(fm.size(Qt::TextSingleLine, s).width())); + width = std::max(width, widths.back()); } width += 4.0 * informationBorder; - height += 4.0 * informationBorder; + height = widths.size() * fontHeight + 4.0 * informationBorder; + + ChartRectItem::resize(QSizeF(width, height)); - // Setting the position will also set the proper size - setPos(pos); + 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) { - QRectF plotArea = scene()->sceneRect(); + QSizeF size = sceneSize(); double x = pos.x() + distanceFromPointer; - if (x + width >= plotArea.right()) { - if (pos.x() - width >= plotArea.x()) + 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 >= plotArea.bottom()) { - if (pos.y() - height >= plotArea.y()) + if (y + height >= size.height()) { + if (pos.y() - height >= 0.0) y = pos.y() - height; else y = pos.y() - height / 2.0; } - setRect(x, y, width, height); - double actY = y + 2.0 * informationBorder; - for (auto &item: textItems) { - item->setPos(QPointF(x + 2.0 * informationBorder, actY)); - actY += item->boundingRect().height(); - } -} - -void InformationBox::addLine(const QString &s) -{ - textItems.emplace_back(new QGraphicsSimpleTextItem(s, this)); - QGraphicsSimpleTextItem &item = *textItems.back(); - item.setBrush(QBrush(darkLabelColor)); - item.setPos(QPointF(0.0, height)); - item.setFont(font); - item.setZValue(ZValues::informationBox); - QRectF rect = item.boundingRect(); - width = std::max(width, rect.width()); - height += rect.height(); + 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>(scene()->sceneRect().height()); + int maxHeight = static_cast<int>(sceneSize().height()); return maxHeight * 2 / fm.height() / 3; } diff --git a/stats/informationbox.h b/stats/informationbox.h index 741df537f..6ff2bb43e 100644 --- a/stats/informationbox.h +++ b/stats/informationbox.h @@ -4,26 +4,24 @@ #ifndef INFORMATION_BOX_H #define INFORMATION_BOX_H -#include "backend-shared/roundrectitem.h" +#include "chartitem.h" #include <vector> #include <memory> #include <QFont> struct dive; -class QGraphicsScene; +class StatsView; // Information window showing data of highlighted dive -struct InformationBox : RoundRectItem { - InformationBox(); +struct InformationBox : ChartRectItem { + InformationBox(StatsView &); void setText(const std::vector<QString> &text, QPointF pos); void setPos(QPointF pos); int recommendedMaxLines() const; private: QFont font; // For future specialization. double width, height; - void addLine(const QString &s); - std::vector<std::unique_ptr<QGraphicsSimpleTextItem>> textItems; }; #endif diff --git a/stats/pieseries.cpp b/stats/pieseries.cpp index 85c42b93b..dc337aa8d 100644 --- a/stats/pieseries.cpp +++ b/stats/pieseries.cpp @@ -4,6 +4,7 @@ #include "statscolors.h" #include "statshelper.h" #include "statstranslations.h" +#include "statsview.h" #include "zvalues.h" #include <numeric> @@ -246,7 +247,7 @@ bool PieSeries::hover(QPointF pos) if (highlighted >= 0 && highlighted < (int)items.size()) { items[highlighted].highlight(highlighted, true, (int)items.size()); if (!information) - information = createItemPtr<InformationBox>(scene); + information = view.createChartItem<InformationBox>(); information->setText(makeInfo(highlighted), pos); } else { information.reset(); diff --git a/stats/scatterseries.cpp b/stats/scatterseries.cpp index 2c5cc7716..a073f6992 100644 --- a/stats/scatterseries.cpp +++ b/stats/scatterseries.cpp @@ -5,6 +5,7 @@ #include "statshelper.h" #include "statstranslations.h" #include "statsvariables.h" +#include "statsview.h" #include "zvalues.h" #include "core/dive.h" #include "core/divelist.h" @@ -173,7 +174,7 @@ bool ScatterSeries::hover(QPointF pos) return false; } else { if (!information) - information = createItemPtr<InformationBox>(scene); + information = view.createChartItem<InformationBox>(); std::vector<QString> text; text.reserve(highlighted.size() * 5); diff --git a/stats/statsview.cpp b/stats/statsview.cpp index e97510087..05693fd0b 100644 --- a/stats/statsview.cpp +++ b/stats/statsview.cpp @@ -279,14 +279,6 @@ T *StatsView::createAxis(const QString &title, Args&&... args) return res; } -template <typename T, class... Args> -std::unique_ptr<T> StatsView::createChartItem(Args&&... args) -{ - std::unique_ptr<T> res(new T(*this, std::forward<Args>(args)...)); - items.push_back(res.get()); - return res; -} - void StatsView::setAxes(StatsAxis *x, StatsAxis *y) { xAxis = x; diff --git a/stats/statsview.h b/stats/statsview.h index 8270c237f..62fb246cd 100644 --- a/stats/statsview.h +++ b/stats/statsview.h @@ -52,6 +52,9 @@ public: QSizeF size() const; void addQSGNode(QSGNode *node, int z); // Must only be called in render thread! void unregisterChartItem(const ChartItem *item); + template <typename T, class... Args> + std::unique_ptr<T> createChartItem(Args&&... args); + private slots: void replotIfVisible(); private: @@ -109,9 +112,6 @@ private: template <typename T, class... Args> T *createAxis(const QString &title, Args&&... args); - template <typename T, class... Args> - std::unique_ptr<T> createChartItem(Args&&... args); - template<typename T> CategoryAxis *createCategoryAxis(const QString &title, const StatsBinner &binner, const std::vector<T> &bins, bool isHorizontal); @@ -179,4 +179,14 @@ private: QSGImageNode *rootNode; }; +// This implementation detail must be known to users of the class. +// Perhaps move it into a statsview_impl.h file. +template <typename T, class... Args> +std::unique_ptr<T> StatsView::createChartItem(Args&&... args) +{ + std::unique_ptr<T> res(new T(*this, std::forward<Args>(args)...)); + items.push_back(res.get()); + return res; +} + #endif |