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