Mercurial > minori
view include/gui/widgets/graph.h @ 115:c72b907b9bef
window: patch for Qt 5
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Tue, 07 Nov 2023 12:04:51 -0500 |
parents | b315f3759c56 |
children | 03b444cbe55f |
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 <QWidget> #include <QDebug> #include <QSize> #include <QPaintEvent> #include <QSize> #include <QRect> #include <QPainter> #include <QPainterPath> #include <QPen> #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: static constexpr int SPACING = 5; inline unsigned long GetTotal() { unsigned long count = 0; for (const auto& item : map) count += item.second; return count; } QSize minimumSizeHint() const override { QFontMetrics metric(font()); return QSize(100, metric.height() * map.size() + 2 * (map.size() - 2)); }; inline unsigned long GetTextWidth() { unsigned long ret = 0; QFontMetrics metric(font()); for (const auto& item : map) { unsigned long width = metric.boundingRect(QString::number(item.first)).width(); if (width > ret) ret = width; } return ret; } void paintEvent(QPaintEvent* event) override { const QRect rect = event->rect(); const int height_of_each = QFontMetrics(font()).height(); const int size = GetTotal(); const int text_width = GetTextWidth(); int current_y = rect.y(); /* now we do the actual painting */ QPainter painter(this); for (const auto& item : map) { painter.drawText(QRect(rect.x(), current_y, text_width, height_of_each), Qt::AlignRight | Qt::AlignVCenter, QString::number(item.first)); if (size) { painter.save(); QPen pen(Qt::transparent, 0); painter.setPen(pen); QPainterPath path; path.addRect(rect.x() + text_width + SPACING, current_y, (static_cast<double>(item.second)/size)*(rect.width() - text_width - SPACING), height_of_each); painter.fillPath(path, Qt::darkBlue); painter.drawPath(path); painter.restore(); } current_y += height_of_each + 2; } }; std::unordered_map<T, unsigned long> map = {}; }; #endif // __gui__widgets__graph_h