Files
Renderive/YSGraphic_Core/component/frameless/FrameLessWidget.cpp
T
2026-06-16 13:33:27 +08:00

267 lines
7.3 KiB
C++

#include "FrameLessWidget.h"
#include <QMouseEvent>
#include <QPainter>
#include <qmath.h>
#include <QScreen>
using changeSize = std::function<void(void)>;
FrameLessWidget::FrameLessWidget(QWidget *parent) : QWidget(parent) {
setMouseTracking(true);
setAttribute(Qt::WA_Hover);
setAttribute(Qt::WA_TranslucentBackground);
//setAttribute(Qt::WA_Mapped);
setWindowFlags(
Qt::Window |
Qt::FramelessWindowHint |
Qt::WindowSystemMenuHint |
Qt::WindowMinimizeButtonHint |
Qt::WindowMaximizeButtonHint
);
space = 0;
radius = 16;
topMargin = 16;
bottomMargin = 16;
rightMargin = 16;
leftMargin = 16;
shapes.append
({
Qt::SizeFDiagCursor, Qt::SizeVerCursor, Qt::SizeBDiagCursor,
Qt::SizeHorCursor, Qt::ArrowCursor, Qt::SizeHorCursor,
Qt::SizeBDiagCursor, Qt::SizeVerCursor, Qt::SizeFDiagCursor,
Qt::ArrowCursor
});
changeSizes.append
({
[this]() { //R11
setGeometry(startX + dx, startY + dy, qMax(startW - dx, getMinWidth()), qMax(startH - dy, getMinHeight()));
},
[this]() { //R12
setGeometry(startX, startY + dy, qMax(startW, getMinWidth()), qMax(startH - dy, getMinHeight()));
},
[this]() { //R13
setGeometry(startX, startY + dy, qMax(startW + dx, getMinWidth()), qMax(startH - dy, getMinHeight()));
},
[this]() { //R21
setGeometry(startX + dx, startY, qMax(startW - dx, getMinWidth()), qMax(startH, getMinHeight()));
},
[]() {
//R22
},
[this]() { //R23
setGeometry(startX, startY, qMax(startW + dx, getMinWidth()), qMax(startH, getMinHeight()));
},
[this]() { //R31
setGeometry(startX + dx, startY, qMax(startW - dx, getMinWidth()), qMax(startH + dy, getMinHeight()));
},
[this]() { //R32
setGeometry(startX, startY, qMax(startW, getMinWidth()), qMax(startH + dy, getMinHeight()));
},
[this]() { //R33
setGeometry(startX, startY, qMax(startW + dx, getMinWidth()), qMax(startH + dy, getMinHeight()));
},
[]() {
//null
}
});
}
int FrameLessWidget::getMinWidth() {
return 0;
}
int FrameLessWidget::getMinHeight() {
return 0;
}
void FrameLessWidget::paintEvent(QPaintEvent* event) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.fillRect(rect(), QColor(255, 255, 255, 1)); //不能改 让他不是透明的 // painter.fillRect(r11, Qt::blue);
// painter.fillRect(r12, Qt::darkCyan);
// painter.fillRect(r13, Qt::green);
// painter.fillRect(r21, Qt::gray);
// painter.fillRect(r22, Qt::red);
// painter.fillRect(r23, Qt::darkGreen);
// painter.fillRect(r31, Qt::black);
// painter.fillRect(r32, Qt::darkRed);
// painter.fillRect(r33, Qt::darkBlue); 否则改变大小失效
// https://blog.csdn.net/liushuaitong/article/details/122117384
// https://www.cnblogs.com/linuxAndMcu/p/11057347.html
QRect rect = r22;
//painter.drawRoundedRect(rect, radius, radius);
//画阴影边框
auto color = background_color;
// int xRadius = r22.width();
// int yRadius = r22.height();
int xRadius = radius;
int yRadius = radius;
int mul = 2;
int n = topMargin/mul;
auto max = double(n*n*n);
double value = background_color.alpha();
for (int i = 0; i < n; i++) {
if (i == 0)
{
painter.setPen(Qt::NoPen);
QColor b = QColor::fromRgb(background_color.red(), background_color.green(), background_color.blue());
painter.setBrush(b);
painter.drawRoundedRect(rect, xRadius, yRadius);
painter.setBrush(Qt::NoBrush);
} else
{
double rate = (i*i*i)/max;
color.setAlpha(static_cast<int>(value * (1-rate)));
painter.setBrush(color);
painter.drawRoundedRect(rect.adjusted(-i * mul, -i * mul, i * mul, i * mul), xRadius, yRadius);
}
}
painter.end();
}
bool FrameLessWidget::event(QEvent *event) {
if (event->type() == QEvent::HoverMove) {
auto *hoverEvent = static_cast<QHoverEvent *>(event);
// qDebug() << hoverEvent->pos();
QMouseEvent mouseEvent(QEvent::MouseMove, hoverEvent->pos(),
Qt::NoButton, Qt::NoButton, Qt::NoModifier);
mouseMoveEvent(&mouseEvent);
}
return QWidget::event(event);
}
void FrameLessWidget::setPos() {
x1 = 0;
x2 = x1 + leftMargin + space;
x3 = width() - rightMargin - space;
y1 = 0;
y2 = y1 + topMargin + space;
y3 = height() - bottomMargin - space;
}
void FrameLessWidget::setRs() {
int w1 = x2 - x1, w2 = x3 - x2, w3 = width() - x3;
int h1 = y2 - y1, h2 = y3 - y2, h3 = height() - y3;
r11.setRect(x1, y1, w1, h1);
r12.setRect(x2, y1, w2, h1);
r13.setRect(x3, y1, w3, h1);
r21.setRect(x1, y2, w1, h2);
r22.setRect(x2, y2, w2, h2);
r23.setRect(x3, y2, w3, h2);
r31.setRect(x1, y3, w1, h3);
r32.setRect(x2, y3, w2, h3);
r33.setRect(x3, y3, w3, h3);
}
void FrameLessWidget::mousePressEvent(QMouseEvent *event) {
auto pos = event->pos();
if (event->button() != Qt::LeftButton) return;
if (changingSize) return;
if (drag_moving) return;
curR = getRectType(pos);
if (curR != Drag_R)
{
changingSize = true;
setCursor(shapes[curR]);
} else {
drag_moving = true;
setCursor(Qt::ClosedHandCursor);
}
if (changingSize || drag_moving)
{
startX = this->x();
startY = this->y();
startGlobalX = event->globalPos().x();
startGlobalY = event->globalPos().y();
startW = width();
startH = height();
}
}
void FrameLessWidget::mouseReleaseEvent(QMouseEvent *event) {
if (changingSize) {
changingSize = false;
}
if (drag_moving) {
drag_moving = false;
setCursor(Qt::OpenHandCursor);
}
}
void FrameLessWidget::mouseMoveEvent(QMouseEvent *event) {
RectType ret = getRectType(event->pos());
if (ret == Drag_R)
{
if (!drag_moving)
{
setCursor(Qt::OpenHandCursor);
}
} else
{
setCursor(shapes[ret]);
}
if (!changingSize && !drag_moving) {
return;
}
const QPoint &curGlobalPos = event->globalPos();
dx = curGlobalPos.x() - startGlobalX;
dy = curGlobalPos.y() - startGlobalY;
if (changingSize) {
changeSizes[curR]();
}
else if (drag_moving)
{
move(startX + dx, startY + dy);
}
}
RectType FrameLessWidget::getRectType(const QPoint &p) const {
if (p.y() < y2) {
if (p.x() < x2) return R11;
if (p.x() > x3) return R13;
if (p.x() < (x2 + x3)/4) return Drag_R;
return R12;
}
if (p.y() > y3) {
if (p.x() < x2) return R31;
if (p.x() > x3) return R33;
return R32;
}
if (p.x() < x2) return R21;
if (p.x() > x3) return R23;
return R22;
}
void FrameLessWidget::resizeEvent(QResizeEvent *event) {
if (isMaximized()) {
QRect screenSize = screen()->availableGeometry()
.adjusted(-leftMargin, -topMargin, rightMargin, bottomMargin);
setGeometry(screenSize);
}
setPos();
setRs();
}
void FrameLessWidget::showEvent(QShowEvent *event) {
QWidget::showEvent(event);
}