Files
Renderive/Widget/component/Background.h
T
2026-07-29 18:08:57 +08:00

131 lines
4.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "global.h"
enum class Mouse_State {
Default,
Pressed,
Entered
};
struct Border {
QColor border_color = Qt::red;
int len = 4;
};
using Handle_Mouse = std::function<void(QEvent::Type, QMouseEvent*)>;
struct Background : Paintable {
QGraphicsDropShadowEffect shadow_effect;
Border* border{};
std::map<Mouse_State, QColor> map;
Qt::SizeMode mode = Qt::RelativeSize;
qreal radius = 0.1;
bool enter = false;
Mouse_State mouse_state = Mouse_State::Default;
std::vector<Handle_Mouse> mouse_handlers;
void set_border(const QColor& border_color, int len = 1) {
if (!border)
border = new Border;
border->border_color = border_color;
border->len = len;
}
void set_effect(QWidget* that) {
shadow_effect.setBlurRadius(10); // 设置模糊半径
shadow_effect.setOffset(5, 5); // 设置阴影偏移量(x, y
shadow_effect.setColor(Qt::black); // 设置阴影颜色
that->setGraphicsEffect(&shadow_effect);
}
void set_color(const QColor& color) {
map[Mouse_State::Default] = color;
double r = color.red();
double g = color.green();
double b = color.blue();
// int alpha = color.alpha();
double upper = 1.6;
double lower = 0.4;
auto ur = qMin(255, (int)(r * upper));
auto ug = qMin(255, (int)(g * upper));
auto ub = qMin(255, (int)(b * upper));
int lr = (int)(r * lower);
int lg = (int)(g * lower);
int lb = (int)(b * lower);
map[Mouse_State::Pressed] = QColor(ur, ug, ub);
map[Mouse_State::Entered] = QColor(lr, lg, lb);
}
Event_Type mouse_event(QEvent::Type t, QMouseEvent* e) override {
if (t == QEvent::MouseButtonPress) {
mouse_state = Mouse_State::Pressed;
}
else if (t == QEvent::MouseButtonRelease) {
if (enter)
mouse_state = Mouse_State::Entered;
else
mouse_state = Mouse_State::Default;
}
for (auto& handler : mouse_handlers) {
handler(t, e);
}
return Event_Type::refresh;
}
Event_Type event(QEvent::Type t, QEvent* e) override {
if (t == QEvent::Enter) {
enter = true;
mouse_state = Mouse_State::Entered;
return Event_Type::refresh;
}
else if (t == QEvent::Leave) {
enter = false;
mouse_state = Mouse_State::Default;
return Event_Type::refresh;
}
return Paintable::event(t, e);
}
void paint(QPainter* painter, QRect rect) override {
painter->save();
int half_pen_width = 0;
QRect adjusted_rect = rect.adjusted(half_pen_width, half_pen_width, -half_pen_width, -half_pen_width);
qreal x_radius, y_radius;
get_rounded_rect_radius(adjusted_rect, x_radius, y_radius);
QPainterPath border_path;
border_path.addRoundedRect(adjusted_rect, x_radius, y_radius);
QRect inner_rect = adjusted_rect;
if (border) {
inner_rect.adjust(border->len, border->len, -border->len, -border->len);
}
// 内部区域边距
QPainterPath inner_path;
inner_path.addRoundedRect(inner_rect, x_radius, y_radius);
QColor c = map[mouse_state];
painter->setPen(Qt::NoPen);
if (c.isValid()) {
painter->save();
if (border) {
painter->setBrush(border->border_color);
painter->drawPath(border_path);
}
painter->setBrush(c);
painter->drawPath(inner_path);
painter->restore();
}
else {
if (border) {
border_path = border_path.subtracted(inner_path);
painter->setBrush(border->border_color);
painter->drawPath(border_path);
}
}
painter->restore();
}
void set_radius(Qt::SizeMode mode, qreal value) {
this->mode = mode;
this->radius = value;
}
protected:
void get_rounded_rect_radius(const QRect& rect, qreal& x_radius, qreal& y_radius) const {
if (mode == Qt::RelativeSize) {
x_radius = rect.width() * radius;
y_radius = rect.height() * radius;
}
else {
x_radius = radius;
y_radius = radius;
}
}
};