Mercurial > minori
comparison include/gui/widgets/graph.h @ 102:b315f3759c56
*: big patch
1. use a wrapper for mINI that enables case sensitivity
(personal preference)
2. rename dark_theme.cc to theme.cc and change it to be
a class
3. include the "dep" folder so we don't have stupidity in
json.h or ini.h
4. I think the graph was also tweaked a lot in this, nothing
is constexpr and size is found at runtime...
| author | Paper <mrpapersonic@gmail.com> |
|---|---|
| date | Fri, 03 Nov 2023 21:32:52 -0400 |
| parents | bd68e4393e6f |
| children | 03b444cbe55f |
comparison
equal
deleted
inserted
replaced
| 101:c537996cf67b | 102:b315f3759c56 |
|---|---|
| 2 #define __gui__widgets__graph_h | 2 #define __gui__widgets__graph_h |
| 3 | 3 |
| 4 /* This class is defined as a template, so that means everything gets defined here as well :) */ | 4 /* This class is defined as a template, so that means everything gets defined here as well :) */ |
| 5 | 5 |
| 6 #include <QWidget> | 6 #include <QWidget> |
| 7 #include <QDebug> | |
| 7 #include <QSize> | 8 #include <QSize> |
| 8 #include <QPaintEvent> | 9 #include <QPaintEvent> |
| 9 #include <QSize> | 10 #include <QSize> |
| 10 #include <QRect> | 11 #include <QRect> |
| 11 #include <QPainter> | 12 #include <QPainter> |
| 12 #include <QPainterPath> | 13 #include <QPainterPath> |
| 13 #include <QPen> | 14 #include <QPen> |
| 15 #include <algorithm> | |
| 14 #include <unordered_map> | 16 #include <unordered_map> |
| 15 | 17 |
| 16 template <typename T> | 18 template <typename T> |
| 17 class Graph final : public QWidget { | 19 class Graph final : public QWidget { |
| 18 public: | 20 public: |
| 19 Graph(QWidget* parent = nullptr) : QWidget(parent) {}; | 21 Graph(QWidget* parent = nullptr) : QWidget(parent) {}; |
| 20 void AddItem(T key, int val) { map[key] = val; update(); updateGeometry(); }; | 22 void AddItem(T key, unsigned long val) { map[key] = val; update(); updateGeometry(); }; |
| 21 void Clear() { map.clear(); update(); updateGeometry(); }; | 23 void Clear() { map.clear(); update(); updateGeometry(); }; |
| 22 | 24 |
| 23 protected: | 25 protected: |
| 24 static constexpr int ITEM_HEIGHT = 20; | 26 static constexpr int SPACING = 5; |
| 25 static constexpr int TEXT_WIDTH = 30; | 27 inline unsigned long GetTotal() { |
| 26 inline int GetTotal() { | 28 unsigned long count = 0; |
| 27 int count = 0; | |
| 28 for (const auto& item : map) | 29 for (const auto& item : map) |
| 29 count += item.second; | 30 count += item.second; |
| 30 return count; | 31 return count; |
| 31 } | 32 } |
| 32 QSize minimumSizeHint() const override { return QSize(100, ITEM_HEIGHT * map.size()); }; | 33 QSize minimumSizeHint() const override { |
| 34 QFontMetrics metric(font()); | |
| 35 return QSize(100, metric.height() * map.size() + 2 * (map.size() - 2)); | |
| 36 }; | |
| 37 inline unsigned long GetTextWidth() { | |
| 38 unsigned long ret = 0; | |
| 39 QFontMetrics metric(font()); | |
| 40 for (const auto& item : map) { | |
| 41 unsigned long width = metric.boundingRect(QString::number(item.first)).width(); | |
| 42 if (width > ret) | |
| 43 ret = width; | |
| 44 } | |
| 45 return ret; | |
| 46 } | |
| 33 void paintEvent(QPaintEvent* event) override { | 47 void paintEvent(QPaintEvent* event) override { |
| 34 const QRect rect = event->rect(); | 48 const QRect rect = event->rect(); |
| 35 const int height_of_each = rect.height() / map.size(); | 49 const int height_of_each = QFontMetrics(font()).height(); |
| 36 const int size = GetTotal(); | 50 const int size = GetTotal(); |
| 51 const int text_width = GetTextWidth(); | |
| 52 int current_y = rect.y(); | |
| 37 | 53 |
| 38 /* now we do the actual painting */ | 54 /* now we do the actual painting */ |
| 39 QPainter painter(this); | 55 QPainter painter(this); |
| 40 | 56 |
| 41 int i = 0; | |
| 42 for (const auto& item : map) { | 57 for (const auto& item : map) { |
| 43 painter.drawText(QRect(rect.x(), rect.y() + i * ITEM_HEIGHT, TEXT_WIDTH, ITEM_HEIGHT), Qt::AlignRight | Qt::AlignVCenter, QString::number(item.first)); | 58 painter.drawText(QRect(rect.x(), current_y, text_width, height_of_each), Qt::AlignRight | Qt::AlignVCenter, QString::number(item.first)); |
| 44 | 59 |
| 45 if (size) { | 60 if (size) { |
| 46 painter.save(); | 61 painter.save(); |
| 47 | 62 |
| 48 QPen pen(Qt::transparent, 0); | 63 QPen pen(Qt::transparent, 0); |
| 49 painter.setPen(pen); | 64 painter.setPen(pen); |
| 50 | 65 |
| 51 QPainterPath path; | 66 QPainterPath path; |
| 52 path.addRect(rect.x()+35, rect.y() + i * ITEM_HEIGHT, (static_cast<double>(item.second)/size)*(rect.width()-35), ITEM_HEIGHT); | 67 path.addRect(rect.x() + text_width + SPACING, current_y, (static_cast<double>(item.second)/size)*(rect.width() - text_width - SPACING), height_of_each); |
| 53 painter.fillPath(path, Qt::blue); | 68 painter.fillPath(path, Qt::darkBlue); |
| 54 painter.drawPath(path); | 69 painter.drawPath(path); |
| 55 | 70 |
| 56 painter.restore(); | 71 painter.restore(); |
| 57 } | 72 } |
| 58 i++; | 73 current_y += height_of_each + 2; |
| 59 } | 74 } |
| 60 }; | 75 }; |
| 61 std::unordered_map<T, int> map = {}; | 76 std::unordered_map<T, unsigned long> map = {}; |
| 62 }; | 77 }; |
| 63 | 78 |
| 64 #endif // __gui__widgets__graph_h | 79 #endif // __gui__widgets__graph_h |
