Mercurial > minori
view include/gui/widgets/graph.h @ 258:862d0d8619f6
*: HUUUGE changes
animia has been renamed to animone, so instead of thinking of a
health condition, you think of a beautiful flower :)
I've also edited some of the code for animone, but I have no idea
if it even works or not because I don't have a mac or windows
machine lying around. whoops!
... anyway, all of the changes divergent from Anisthesia are now
licensed under BSD. it's possible that I could even rewrite most
of the code to where I don't even have to keep the MIT license,
but that's thinking too far into the future
I've been slacking off on implementing the anime seasons page,
mostly out of laziness. I think I'd have to create another db file
specifically for the seasons
anyway, this code is being pushed *primarily* because the hard drive
it's on is failing! yay :)
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Mon, 01 Apr 2024 02:43:44 -0400 |
parents | 45a0967485f1 |
children | 0362f3c4534c |
line wrap: on
line source
#ifndef __gui__widgets__graph_h #define __gui__widgets__graph_h /* This class is defined as a template, so that means everything gets defined here as well :) */ #include <QDebug> #include <QPaintEvent> #include <QPainter> #include <QPainterPath> #include <QPen> #include <QRect> #include <QSize> #include <QWidget> #include <algorithm> #include <unordered_map> template<typename T> class Graph final : public QWidget { public: Graph(QWidget* parent = nullptr) : QWidget(parent){}; void AddItem(T key, unsigned long val) { map[key] = val; update(); updateGeometry(); }; void Clear() { map.clear(); update(); updateGeometry(); }; protected: std::unordered_map<T, unsigned long> map = {}; QSize minimumSizeHint() const override { QFontMetrics metric(font()); /* wtf?... */ return QSize(100, (metric.height() * map.size()) + (2 * map.size())); } /* helper functions */ inline unsigned long GetTotal() { unsigned long count = 0; for (const auto& item : map) count += item.second; return count; } inline unsigned long GetTextWidth() { unsigned long ret = 0; QFontMetrics metric(font()); for (const auto& item : map) { unsigned long width = metric.horizontalAdvance(QString::number(item.first), -1); if (width > ret) ret = width; } return ret; } void paintEvent(QPaintEvent* event) override { static constexpr int HORIZ_SPACING = 5; static constexpr int VERT_SPACING = 2; /* these are retrieved from the QPaintEvent */ const QRect rect = event->rect(); const int width = event->rect().width(); const int x = rect.x(); int y = rect.y(); /* these are calculated from font metrics and such */ const int total = GetTotal(); const int text_width = GetTextWidth(); const int each_height = QFontMetrics(font()).height(); /* now we do the actual painting */ QPainter painter(this); for (const auto& [key, value] : map) { painter.drawText(QRect(x, y, text_width, each_height), Qt::AlignVCenter | Qt::AlignRight, QString::number(key)); /* only draw this if we actually have any data */ if (total) { QPainterPath path; path.addRect(x + text_width + HORIZ_SPACING, y, (static_cast<double>(value) / total) * (width - text_width - HORIZ_SPACING), each_height); painter.fillPath(path, Qt::darkBlue); painter.drawPath(path); } y += each_height + VERT_SPACING; } } }; #endif // __gui__widgets__graph_h