146 lines
4.3 KiB
C++
146 lines
4.3 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 shadowEffect;
|
||
Border *border{};
|
||
QMap<Mouse_State, QColor> map;
|
||
Qt::SizeMode mode = Qt::RelativeSize;
|
||
qreal radius = 0.1;
|
||
|
||
bool enter = false;
|
||
Mouse_State mouse_state = Mouse_State::Default;
|
||
QVector<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) {
|
||
shadowEffect.setBlurRadius(10); // 设置模糊半径
|
||
shadowEffect.setOffset(5, 5); // 设置阴影偏移量(x, y)
|
||
shadowEffect.setColor(Qt::black); // 设置阴影颜色
|
||
that->setGraphicsEffect(&shadowEffect);
|
||
}
|
||
|
||
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 halfPenWidth = 0;
|
||
QRect adjustedRect = rect.adjusted(halfPenWidth, halfPenWidth, -halfPenWidth, -halfPenWidth);
|
||
qreal xRadius, yRadius;
|
||
getRoundedRectRadius(adjustedRect, xRadius, yRadius);
|
||
QPainterPath borderPath;
|
||
borderPath.addRoundedRect(adjustedRect, xRadius, yRadius);
|
||
QRect innerRect = adjustedRect;
|
||
if(border) {
|
||
innerRect.adjust(border->len, border->len, -border->len, -border->len);
|
||
}
|
||
// 内部区域边距
|
||
QPainterPath innerPath;
|
||
innerPath.addRoundedRect(innerRect, xRadius, yRadius);
|
||
QColor c = map[mouse_state];
|
||
painter->setPen(Qt::NoPen);
|
||
if (c.isValid()) {
|
||
painter->save();
|
||
if (border) {
|
||
painter->setBrush(border->border_color);
|
||
painter->drawPath(borderPath);
|
||
}
|
||
painter->setBrush(c);
|
||
painter->drawPath(innerPath);
|
||
painter->restore();
|
||
} else
|
||
{
|
||
if (border) {
|
||
borderPath = borderPath.subtracted(innerPath);
|
||
painter->setBrush(border->border_color);
|
||
painter->drawPath(borderPath);
|
||
}
|
||
}
|
||
painter->restore();
|
||
}
|
||
|
||
void set_radius(Qt::SizeMode mode, qreal value) {
|
||
this->mode = mode;
|
||
this->radius = value;
|
||
}
|
||
|
||
|
||
protected:
|
||
|
||
void getRoundedRectRadius(const QRect& rect, qreal& xRadius, qreal& yRadius) const {
|
||
if (mode == Qt::RelativeSize) {
|
||
xRadius = rect.width() * radius;
|
||
yRadius = rect.height() * radius;
|
||
} else {
|
||
xRadius = radius;
|
||
yRadius = radius;
|
||
}
|
||
}
|
||
};
|
||
|