267 lines
7.3 KiB
C++
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);
|
|
|
|
}
|