131 lines
4.4 KiB
C++
131 lines
4.4 KiB
C++
#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;
|
||
}
|
||
}
|
||
};
|