Mercurial > minori
comparison include/gui/widgets/graph.h @ 171:03b444cbe55f
graph: improve? drawing the text
dark stylesheet: add borders on QMenu, taking inspiration from MPC-HC
media: fix warning about missing enums
| author | Paper <mrpapersonic@gmail.com> | 
|---|---|
| date | Mon, 27 Nov 2023 13:51:27 -0500 | 
| parents | b315f3759c56 | 
| children | 45a0967485f1 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 170:c8375765f0fc | 171:03b444cbe55f | 
|---|---|
| 13 #include <QPainterPath> | 13 #include <QPainterPath> | 
| 14 #include <QPen> | 14 #include <QPen> | 
| 15 #include <algorithm> | 15 #include <algorithm> | 
| 16 #include <unordered_map> | 16 #include <unordered_map> | 
| 17 | 17 | 
| 18 template <typename T> | 18 template<typename T> | 
| 19 class Graph final : public QWidget { | 19 class Graph final : public QWidget { | 
| 20 public: | 20 public: | 
| 21 Graph(QWidget* parent = nullptr) : QWidget(parent) {}; | 21 Graph(QWidget* parent = nullptr) : QWidget(parent) {}; | 
| 22 void AddItem(T key, unsigned long val) { map[key] = val; update(); updateGeometry(); }; | 22 void AddItem(T key, unsigned long val) { map[key] = val; update(); updateGeometry(); }; | 
| 23 void Clear() { map.clear(); update(); updateGeometry(); }; | 23 void Clear() { map.clear(); update(); updateGeometry(); }; | 
| 24 | 24 | 
| 25 protected: | 25 protected: | 
| 26 static constexpr int SPACING = 5; | 26 static constexpr int SPACING = 5; | 
| 27 | |
| 28 std::unordered_map<T, unsigned long> map = {}; | |
| 29 | |
| 30 QSize minimumSizeHint() const override { | |
| 31 QFontMetrics metric(font()); | |
| 32 /* wtf?... */ | |
| 33 return QSize(100, metric.height() * map.size() + (2 * (map.size() - 2))); | |
| 34 } | |
| 35 | |
| 36 /* helper functions */ | |
| 27 inline unsigned long GetTotal() { | 37 inline unsigned long GetTotal() { | 
| 28 unsigned long count = 0; | 38 unsigned long count = 0; | 
| 39 | |
| 29 for (const auto& item : map) | 40 for (const auto& item : map) | 
| 30 count += item.second; | 41 count += item.second; | 
| 42 | |
| 31 return count; | 43 return count; | 
| 32 } | 44 } | 
| 33 QSize minimumSizeHint() const override { | 45 | 
| 34 QFontMetrics metric(font()); | |
| 35 return QSize(100, metric.height() * map.size() + 2 * (map.size() - 2)); | |
| 36 }; | |
| 37 inline unsigned long GetTextWidth() { | 46 inline unsigned long GetTextWidth() { | 
| 38 unsigned long ret = 0; | 47 unsigned long ret = 0; | 
| 39 QFontMetrics metric(font()); | 48 QFontMetrics metric(font()); | 
| 49 | |
| 40 for (const auto& item : map) { | 50 for (const auto& item : map) { | 
| 41 unsigned long width = metric.boundingRect(QString::number(item.first)).width(); | 51 unsigned long width = metric.boundingRect(QString::number(item.first)).width(); | 
| 42 if (width > ret) | 52 if (width > ret) | 
| 43 ret = width; | 53 ret = width; | 
| 44 } | 54 } | 
| 55 | |
| 45 return ret; | 56 return ret; | 
| 46 } | 57 } | 
| 58 | |
| 47 void paintEvent(QPaintEvent* event) override { | 59 void paintEvent(QPaintEvent* event) override { | 
| 48 const QRect rect = event->rect(); | 60 const QRect rect = event->rect(); | 
| 49 const int height_of_each = QFontMetrics(font()).height(); | 61 const int height_of_each = QFontMetrics(font()).height(); | 
| 50 const int size = GetTotal(); | 62 const int size = GetTotal(); | 
| 51 const int text_width = GetTextWidth(); | 63 const int text_width = GetTextWidth(); | 
| 52 int current_y = rect.y(); | 64 const int x = rect.x(); | 
| 65 int y = rect.y(); | |
| 53 | 66 | 
| 54 /* now we do the actual painting */ | 67 /* now we do the actual painting */ | 
| 55 QPainter painter(this); | 68 QPainter painter(this); | 
| 56 | 69 | 
| 57 for (const auto& item : map) { | 70 for (const auto& item : map) { | 
| 58 painter.drawText(QRect(rect.x(), current_y, text_width, height_of_each), Qt::AlignRight | Qt::AlignVCenter, QString::number(item.first)); | 71 painter.drawText(QRect(x + 2, y, text_width - 2, height_of_each), Qt::AlignRight | Qt::AlignVCenter, QString::number(item.first)); | 
| 59 | 72 | 
| 60 if (size) { | 73 if (size) { | 
| 61 painter.save(); | 74 painter.save(); | 
| 62 | 75 | 
| 63 QPen pen(Qt::transparent, 0); | 76 QPen pen(Qt::transparent, 0); | 
| 64 painter.setPen(pen); | 77 painter.setPen(pen); | 
| 65 | 78 | 
| 66 QPainterPath path; | 79 QPainterPath path; | 
| 67 path.addRect(rect.x() + text_width + SPACING, current_y, (static_cast<double>(item.second)/size)*(rect.width() - text_width - SPACING), height_of_each); | 80 path.addRect(x + text_width + 2 + SPACING, y, (static_cast<double>(item.second)/size) * (rect.width() - text_width + 2 - SPACING), height_of_each); | 
| 68 painter.fillPath(path, Qt::darkBlue); | 81 painter.fillPath(path, Qt::darkBlue); | 
| 69 painter.drawPath(path); | 82 painter.drawPath(path); | 
| 70 | 83 | 
| 71 painter.restore(); | 84 painter.restore(); | 
| 72 } | 85 } | 
| 73 current_y += height_of_each + 2; | 86 | 
| 87 y += height_of_each + 2; | |
| 74 } | 88 } | 
| 75 }; | 89 } | 
| 76 std::unordered_map<T, unsigned long> map = {}; | |
| 77 }; | 90 }; | 
| 78 | 91 | 
| 79 #endif // __gui__widgets__graph_h | 92 #endif // __gui__widgets__graph_h | 
