#pragma once #include #include #include #include #include #include #include #include #include #include "Delegate.h" #include "Layout.h" #include "../SVG.h" namespace Psc { class Border : public E { public: int width = 4; QPen pen = QPen(); QColor color = Qt::red; std::optional filled_color = QColor(200, 0, 0); Border() { } Border(int width, QPen pen, QColor color) : width(width), pen(pen), color(color) { } void paint(QPainter* painter, QRect r, QPaintEvent* event) override { pen.setColor(color); pen.setWidth(width); painter->setPen(pen); // if (filled_color.has_value()) { // painter->fillRect(r, filled_color.value()); // } painter->drawRect(r); } }; class Icon : public E { public: SVG_Image_Render svg; Icon() { svg.set_path(":/you_jian_tou.svg").set_color(Qt::red).create(); } void paint(QPainter* painter, QRect r, QPaintEvent* event) override { svg.render(painter, r); } [[nodiscard]] QSize sizeHint() const override { return {20, 20}; } }; class Icon2 : public E { public: QIcon icon; Icon2(QIcon icon) : icon(icon) { } Icon2() = default; void paint(QPainter* painter, QRect r, QPaintEvent* event) override { icon.paint(painter, r); } [[nodiscard]] QSize sizeHint() const override { return {20, 20}; } }; // https://runebook.dev/zh/docs/qt/qtextlayout/draw class Text : public E { public: QFont font; QFontMetrics font_metrics; QMargins margins; QString text; QPen pen = QPen(); Text() : font_metrics(font) { } [[nodiscard]] QSize sizeHint() const override { auto w = font_metrics.horizontalAdvance(text); auto h = font_metrics.height(); return {w + margins.left() + margins.right(), h + margins.top() + margins.bottom()}; } // TODO QTextLayout 研究一下 void paint(QPainter* painter, QRect r, QPaintEvent* event = nullptr) override { int x = r.left() + margins.left(); int y = r.top() + margins.top() + font_metrics.height(); painter->drawText(x, y, text); } }; class Button : public E { public: Border border; Text text; Icon icon; QMargins inter_margin; Delegate press_event; QRect rect; Layout layout = Layout(Qt::Horizontal); Button() { layout.space = 16; text.text = "123456"; icon.use_get_main_by_cros = true; icon.size_policy.setFlag(Cross_Expand); icon.size_policy.setFlag(Get_Main_By_Cross); layout.items.push_back(&icon); layout.items.push_back(&text); }; void paint(QPainter* painter, QRect r, QPaintEvent* event) override { border.paint(painter, r, event); auto r_icon = icon.rect(); auto r_text = text.rect(); painter->setPen(QPen(Qt::blue)); painter->drawRect(r_icon); painter->drawRect(r_text); icon.paint(painter, r_icon, event); text.paint(painter, r_text, event); } void event(QEvent::Type t, QEvent* e) override { if (t == QEvent::MouseButtonPress) { QMouseEvent* me = static_cast(e); if (rect.contains(me->pos())) { press_event.invoke(me); } } if (t == QEvent::Enter) { border.color = Qt::blue; update(); } if (t == QEvent::Leave) { border.color = Qt::black; update(); } if (t == QEvent::Resize) { QResizeEvent* resize = static_cast(e); layout.set_size(resize->size()); layout.layout(); auto r_icon = icon.rect(); auto r_text = text.rect(); // qDebug() << "resize" << r_icon << " " << r_text; } } }; template class W : public QWidget { public: E* inter; template W(Args&&... args) : inter(new T(std::forward(args)...)) { } bool event(QEvent* e) override { inter->event(e->type(), e); if (inter->need_update) { update(); inter->need_update = false; } return QWidget::event(e); } void paintEvent(QPaintEvent* event) override { QPainter painter(this); inter->paint(&painter, rect(), event); } }; } // namespace Psc