add hitTestVisible logic

This commit is contained in:
Altair Wei 2021-09-20 19:41:24 +08:00
parent 5ab2024f54
commit 5f58937588
5 changed files with 116 additions and 4 deletions

View File

@ -2,13 +2,15 @@
#include "../../framelesshelper.h"
#include <QScreen>
#include <QVBoxLayout>
#include <QPushButton>
FRAMELESSHELPER_USE_NAMESPACE
FLWindow::FLWindow(QWidget *parent) : QWidget(parent)
{
setWindowFlags(Qt::FramelessWindowHint);
setStyleSheet(QString::fromLatin1("background:blue"));
setupUi();
move(screen()->geometry().center() - frameGeometry().center());
}
@ -22,8 +24,11 @@ void FLWindow::initFramelessWindow()
{
FramelessHelper* helper = new FramelessHelper(windowHandle());
helper->setResizeBorderThickness(4);
helper->setTitleBarHeight(40);
helper->setTitleBarHeight(m_titleBarWidget->height());
helper->setResizable(true);
helper->setHitTestVisible(m_minimizeButton);
helper->setHitTestVisible(m_maximizeButton);
helper->setHitTestVisible(m_closeButton);
helper->install();
}
@ -37,3 +42,51 @@ void FLWindow::showEvent(QShowEvent *event)
initFramelessWindow();
}
}
void FLWindow::setupUi()
{
resize(800, 600);
m_titleBarWidget = new QWidget(this);
m_titleBarWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_titleBarWidget->setFixedHeight(40);
m_titleBarWidget->setStyleSheet(QString::fromLatin1("background:grey"));
m_minimizeButton = new QPushButton(m_titleBarWidget);
m_minimizeButton->setText(QStringLiteral("Min"));
m_minimizeButton->setObjectName(QStringLiteral("MinimizeButton"));
connect(m_minimizeButton, &QPushButton::clicked, this, &QWidget::showMinimized);
m_maximizeButton = new QPushButton(m_titleBarWidget);
m_maximizeButton->setText(QStringLiteral("Max"));
m_maximizeButton->setObjectName(QStringLiteral("MaximizeButton"));
connect(m_maximizeButton, &QPushButton::clicked, this, [this](){
if (isMaximized() || isFullScreen()) {
showNormal();
} else {
showMaximized();
}
});
m_closeButton = new QPushButton(m_titleBarWidget);
m_closeButton->setText(QStringLiteral("Close"));
m_closeButton->setObjectName(QStringLiteral("CloseButton"));
connect(m_closeButton, &QPushButton::clicked, this, &QWidget::close);
const auto titleBarLayout = new QHBoxLayout(m_titleBarWidget);
titleBarLayout->setContentsMargins(0, 0, 0, 0);
titleBarLayout->setSpacing(10);
titleBarLayout->addStretch();
titleBarLayout->addWidget(m_minimizeButton);
titleBarLayout->addWidget(m_maximizeButton);
titleBarLayout->addWidget(m_closeButton);
titleBarLayout->addStretch();
m_titleBarWidget->setLayout(titleBarLayout);
const auto mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(m_titleBarWidget);
mainLayout->addStretch();
setLayout(mainLayout);
}

View File

@ -2,6 +2,8 @@
#include <QWidget>
class QPushButton;
class FLWindow : public QWidget
{
Q_OBJECT
@ -14,4 +16,11 @@ protected:
private:
void initFramelessWindow();
void setupUi();
private:
QWidget *m_titleBarWidget = nullptr;
QPushButton *m_minimizeButton = nullptr;
QPushButton *m_maximizeButton = nullptr;
QPushButton *m_closeButton = nullptr;
};

View File

@ -31,6 +31,7 @@
#include <QtWidgets/qpushbutton.h>
#include "../../utilities.h"
#include "../../framelesswindowsmanager.h"
#include "../../framelesshelper.h"
FRAMELESSHELPER_USE_NAMESPACE

View File

@ -94,8 +94,20 @@ QRect FramelessHelper::titleBarRect()
QRegion FramelessHelper::titleBarRegion()
{
// TODO: consider HitTestVisibleObject
QRegion region(titleBarRect());
for (const auto obj : m_HTVObjects) {
if (!obj || !(obj->isWidgetType() || obj->inherits("QQuickItem"))) {
continue;
}
if (!obj->property("visible").toBool()) {
continue;
}
region -= getHTVObjectRect(obj);
}
return region;
}
@ -111,9 +123,21 @@ QRect FramelessHelper::clientRect()
QRegion FramelessHelper::nonClientRegion()
{
// TODO: consider HitTestVisibleObject
QRegion region(QRect(QPoint(0, 0), windowSize()));
region -= clientRect();
for (const auto obj : m_HTVObjects) {
if (!obj || !(obj->isWidgetType() || obj->inherits("QQuickItem"))) {
continue;
}
if (!obj->property("visible").toBool()) {
continue;
}
region -= getHTVObjectRect(obj);
}
return region;
}
@ -309,6 +333,26 @@ void FramelessHelper::startResize(QMouseEvent* event, Qt::WindowFrameSection fra
#endif
}
void FramelessHelper::setHitTestVisible(QObject *obj)
{
m_HTVObjects.push_back(obj);
}
bool FramelessHelper::isHitTestVisible(QObject *obj)
{
return m_HTVObjects.contains(obj);
}
QRect FramelessHelper::getHTVObjectRect(QObject *obj)
{
const QPoint originPoint = m_window->mapFromGlobal(
Utilities::mapOriginPointToWindow(obj).toPoint());
const int width = obj->property("width").toInt();
const int height = obj->property("height").toInt();
return QRect(originPoint, QSize(width, height));
}
bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
{
bool filterOut = false;

View File

@ -87,6 +87,10 @@ public:
void startMove(QMouseEvent* event);
void startResize(QMouseEvent* event, Qt::WindowFrameSection frameSection);
void setHitTestVisible(QObject *obj);
bool isHitTestVisible(QObject *obj);
QRect getHTVObjectRect(QObject *obj);
protected:
bool eventFilter(QObject *object, QEvent *event) override;
@ -100,6 +104,7 @@ private:
bool m_cursorChanged;
Qt::WindowFrameSection m_hoveredFrameSection;
Qt::WindowFrameSection m_clickedFrameSection;
QList<QObject*> m_HTVObjects;
};
FRAMELESSHELPER_END_NAMESPACE