forked from github_mirror/framelesshelper
Add a Qt Quick helper class.
It's much easier to use it in Qt Quick now. Fixes: #11 Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
9a70ebaaa1
commit
2ca6a90ae2
|
@ -332,8 +332,9 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) {
|
||||||
#ifdef QT_QUICK_LIB
|
#ifdef QT_QUICK_LIB
|
||||||
const auto quickItem = qobject_cast<QQuickItem *>(obj);
|
const auto quickItem = qobject_cast<QQuickItem *>(obj);
|
||||||
if (quickItem) {
|
if (quickItem) {
|
||||||
if (QRect(quickItem->x(), quickItem->y(),
|
const auto pos = quickItem->mapToScene({0, 0});
|
||||||
quickItem->width(), quickItem->height())
|
if (QRect(pos.x(), pos.y(), quickItem->width(),
|
||||||
|
quickItem->height())
|
||||||
.contains(x, y)) {
|
.contains(x, y)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,11 @@ debug: TARGET = $$join(TARGET,,,_debug)
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
QT += gui-private
|
QT += gui-private
|
||||||
qtHaveModule(widgets): QT += widgets
|
qtHaveModule(widgets): QT += widgets
|
||||||
qtHaveModule(quick): QT += quick
|
qtHaveModule(quick) {
|
||||||
|
QT += quick
|
||||||
|
HEADERS += framelessquickhelper.h
|
||||||
|
SOURCES += framelessquickhelper.cpp
|
||||||
|
}
|
||||||
CONFIG += c++17 strict_c++ warn_on utf8_source
|
CONFIG += c++17 strict_c++ warn_on utf8_source
|
||||||
DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
|
DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
|
||||||
VERSION = 1.0.0
|
VERSION = 1.0.0
|
||||||
|
|
|
@ -3,7 +3,11 @@ debug: TARGET = $$join(TARGET,,,d)
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
QT += gui-private
|
QT += gui-private
|
||||||
qtHaveModule(widgets): QT += widgets
|
qtHaveModule(widgets): QT += widgets
|
||||||
qtHaveModule(quick): QT += quick
|
qtHaveModule(quick) {
|
||||||
|
QT += quick
|
||||||
|
HEADERS += framelessquickhelper.h
|
||||||
|
SOURCES += framelessquickhelper.cpp
|
||||||
|
}
|
||||||
CONFIG += c++17 strict_c++ utf8_source warn_on windeployqt
|
CONFIG += c++17 strict_c++ utf8_source warn_on windeployqt
|
||||||
DEFINES += WIN32_LEAN_AND_MEAN QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
|
DEFINES += WIN32_LEAN_AND_MEAN QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
|
||||||
CONFIG -= embed_manifest_exe
|
CONFIG -= embed_manifest_exe
|
||||||
|
|
|
@ -0,0 +1,442 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 by wangwenx190 (Yuhang Zhao)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "framelessquickhelper.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
#include "winnativeeventfilter.h"
|
||||||
|
#else
|
||||||
|
#include "framelesshelper.h"
|
||||||
|
#endif
|
||||||
|
#include <QQuickWindow>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8,
|
||||||
|
m_defaultTitleBarHeight = 30;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent)
|
||||||
|
: QQuickItem(parent) {}
|
||||||
|
|
||||||
|
int FramelessQuickHelper::borderWidth() const {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
return WinNativeEventFilter::getSystemMetric(
|
||||||
|
hWnd, WinNativeEventFilter::SystemMetric::BorderWidth, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_defaultBorderWidth;
|
||||||
|
#else
|
||||||
|
return m_framelessHelper.getBorderWidth();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::setBorderWidth(const int val) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->borderWidth = val;
|
||||||
|
Q_EMIT borderWidthChanged(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setBorderWidth(val);
|
||||||
|
Q_EMIT borderWidthChanged(val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int FramelessQuickHelper::borderHeight() const {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
return WinNativeEventFilter::getSystemMetric(
|
||||||
|
hWnd, WinNativeEventFilter::SystemMetric::BorderHeight, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_defaultBorderHeight;
|
||||||
|
#else
|
||||||
|
return m_framelessHelper.getBorderHeight();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::setBorderHeight(const int val) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->borderHeight = val;
|
||||||
|
Q_EMIT borderHeightChanged(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setBorderHeight(val);
|
||||||
|
Q_EMIT borderHeightChanged(val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int FramelessQuickHelper::titleBarHeight() const {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
return WinNativeEventFilter::getSystemMetric(
|
||||||
|
hWnd, WinNativeEventFilter::SystemMetric::TitleBarHeight,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_defaultTitleBarHeight;
|
||||||
|
#else
|
||||||
|
return m_framelessHelper.getTitleBarHeight();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::setTitleBarHeight(const int val) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->titleBarHeight = val;
|
||||||
|
Q_EMIT titleBarHeightChanged(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setTitleBarHeight(val);
|
||||||
|
Q_EMIT titleBarHeightChanged(val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FramelessQuickHelper::resizable() const {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
return !data->fixedSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
// ### TODO: impl
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::setResizable(const bool val) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->fixedSize = !val;
|
||||||
|
Q_EMIT resizableChanged(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// ### TODO: impl
|
||||||
|
Q_UNUSED(val)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::removeWindowFrame(const bool center) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
WinNativeEventFilter::addFramelessWindow(hWnd, nullptr, center);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.removeWindowFrame(win);
|
||||||
|
if (center) {
|
||||||
|
FramelessHelper::moveWindowToDesktopCenter(win);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::setIgnoreAreas(const QVector<QRect> &val) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->ignoreAreas = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setIgnoreAreas(win, val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::clearIgnoreAreas() {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->ignoreAreas.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setIgnoreAreas(win, {});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::addIgnoreArea(const QRect &val) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->ignoreAreas.append(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
QVector<QRect> areas = m_framelessHelper.getIgnoreAreas(win);
|
||||||
|
areas.append(val);
|
||||||
|
m_framelessHelper.setIgnoreAreas(win, areas);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::setDraggableAreas(const QVector<QRect> &val) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->draggableAreas = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setDraggableAreas(win, val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::clearDraggableAreas() {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->draggableAreas.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setDraggableAreas(win, {});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::addDraggableArea(const QRect &val) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->draggableAreas.append(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
QVector<QRect> areas = m_framelessHelper.getDraggableAreas(win);
|
||||||
|
areas.append(val);
|
||||||
|
m_framelessHelper.setDraggableAreas(win, areas);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::setIgnoreObjects(const QVector<QQuickItem *> &val) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->ignoreObjects.clear();
|
||||||
|
if (!val.isEmpty()) {
|
||||||
|
for (auto &&obj : qAsConst(val)) {
|
||||||
|
data->ignoreObjects.append(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
QVector<QPointer<QObject>> objs;
|
||||||
|
if (!val.isEmpty()) {
|
||||||
|
for (auto &&obj : qAsConst(val)) {
|
||||||
|
objs.append(obj);
|
||||||
|
}
|
||||||
|
m_framelessHelper.setIgnoreObjects(win, objs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::clearIgnoreObjects() {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->ignoreObjects.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setIgnoreObjects(win, {});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::addIgnoreObject(QQuickItem *val) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win && val) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->ignoreObjects.append(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
QVector<QPointer<QObject>> objs =
|
||||||
|
m_framelessHelper.getIgnoreObjects(win);
|
||||||
|
objs.append(val);
|
||||||
|
m_framelessHelper.setIgnoreObjects(win, objs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::setDraggableObjects(
|
||||||
|
const QVector<QQuickItem *> &val) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->draggableObjects.clear();
|
||||||
|
if (!val.isEmpty()) {
|
||||||
|
for (auto &&obj : qAsConst(val)) {
|
||||||
|
data->draggableObjects.append(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
QVector<QPointer<QObject>> objs;
|
||||||
|
if (!val.isEmpty()) {
|
||||||
|
for (auto &&obj : qAsConst(val)) {
|
||||||
|
objs.append(obj);
|
||||||
|
}
|
||||||
|
m_framelessHelper.setDraggableObjects(win, objs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::clearDraggableObjects() {
|
||||||
|
const auto win = window();
|
||||||
|
if (win) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->draggableObjects.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_framelessHelper.setDraggableObjects(win, {});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelper::addDraggableObject(QQuickItem *val) {
|
||||||
|
const auto win = window();
|
||||||
|
if (win && val) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const auto hWnd = reinterpret_cast<HWND>(win->winId());
|
||||||
|
if (hWnd) {
|
||||||
|
const auto data = WinNativeEventFilter::windowData(hWnd);
|
||||||
|
if (data) {
|
||||||
|
data->draggableObjects.append(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
QVector<QPointer<QObject>> objs =
|
||||||
|
m_framelessHelper.getDraggableObjects(win);
|
||||||
|
objs.append(val);
|
||||||
|
m_framelessHelper.setDraggableObjects(win, objs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 by wangwenx190 (Yuhang Zhao)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
#ifndef Q_OS_WINDOWS
|
||||||
|
#include "framelesshelper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class FramelessQuickHelper : public QQuickItem {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY_MOVE(FramelessQuickHelper)
|
||||||
|
Q_PROPERTY(int borderWidth READ borderWidth WRITE setBorderWidth NOTIFY
|
||||||
|
borderWidthChanged)
|
||||||
|
Q_PROPERTY(int borderHeight READ borderHeight WRITE setBorderHeight NOTIFY
|
||||||
|
borderHeightChanged)
|
||||||
|
Q_PROPERTY(int titleBarHeight READ titleBarHeight WRITE setTitleBarHeight
|
||||||
|
NOTIFY titleBarHeightChanged)
|
||||||
|
Q_PROPERTY(bool resizable READ resizable WRITE setResizable NOTIFY
|
||||||
|
resizableChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FramelessQuickHelper(QQuickItem *parent = nullptr);
|
||||||
|
~FramelessQuickHelper() override = default;
|
||||||
|
|
||||||
|
int borderWidth() const;
|
||||||
|
void setBorderWidth(const int val);
|
||||||
|
|
||||||
|
int borderHeight() const;
|
||||||
|
void setBorderHeight(const int val);
|
||||||
|
|
||||||
|
int titleBarHeight() const;
|
||||||
|
void setTitleBarHeight(const int val);
|
||||||
|
|
||||||
|
bool resizable() const;
|
||||||
|
void setResizable(const bool val);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void removeWindowFrame(const bool center = true);
|
||||||
|
|
||||||
|
void setIgnoreAreas(const QVector<QRect> &val);
|
||||||
|
void clearIgnoreAreas();
|
||||||
|
void addIgnoreArea(const QRect &val);
|
||||||
|
|
||||||
|
void setDraggableAreas(const QVector<QRect> &val);
|
||||||
|
void clearDraggableAreas();
|
||||||
|
void addDraggableArea(const QRect &val);
|
||||||
|
|
||||||
|
void setIgnoreObjects(const QVector<QQuickItem *> &val);
|
||||||
|
void clearIgnoreObjects();
|
||||||
|
void addIgnoreObject(QQuickItem *val);
|
||||||
|
|
||||||
|
void setDraggableObjects(const QVector<QQuickItem *> &val);
|
||||||
|
void clearDraggableObjects();
|
||||||
|
void addDraggableObject(QQuickItem *val);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void borderWidthChanged(int);
|
||||||
|
void borderHeightChanged(int);
|
||||||
|
void titleBarHeightChanged(int);
|
||||||
|
void resizableChanged(bool);
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifndef Q_OS_WINDOWS
|
||||||
|
FramelessHelper m_framelessHelper;
|
||||||
|
#endif
|
||||||
|
};
|
|
@ -4,8 +4,8 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#ifdef QT_QUICK_LIB
|
#ifdef QT_QUICK_LIB
|
||||||
|
#include "framelessquickhelper.h"
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QWindow>
|
|
||||||
#endif
|
#endif
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
@ -97,6 +97,8 @@ int main(int argc, char *argv[]) {
|
||||||
#ifdef QT_QUICK_LIB
|
#ifdef QT_QUICK_LIB
|
||||||
// Qt Quick example:
|
// Qt Quick example:
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
qmlRegisterType<FramelessQuickHelper>("wangwenx190.Utils", 1, 0,
|
||||||
|
"FramelessHelper");
|
||||||
const QUrl url(QString::fromUtf8("qrc:///qml/main.qml"));
|
const QUrl url(QString::fromUtf8("qrc:///qml/main.qml"));
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
&engine, &QQmlApplicationEngine::objectCreated, &application,
|
&engine, &QQmlApplicationEngine::objectCreated, &application,
|
||||||
|
@ -107,25 +109,6 @@ int main(int argc, char *argv[]) {
|
||||||
},
|
},
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
engine.load(url);
|
engine.load(url);
|
||||||
const auto window = qobject_cast<QWindow *>(engine.rootObjects().at(0));
|
|
||||||
Q_ASSERT(window);
|
|
||||||
const auto hWnd_qml = reinterpret_cast<HWND>(window->winId());
|
|
||||||
WinNativeEventFilter::addFramelessWindow(hWnd_qml, nullptr, true);
|
|
||||||
QObject::connect(
|
|
||||||
window, &QWindow::widthChanged, [window, hWnd_qml](const int arg) {
|
|
||||||
if (arg >= window->minimumWidth()) {
|
|
||||||
const auto data = WinNativeEventFilter::windowData(hWnd_qml);
|
|
||||||
if (data) {
|
|
||||||
const int tbh_qml = WinNativeEventFilter::getSystemMetric(
|
|
||||||
hWnd_qml,
|
|
||||||
WinNativeEventFilter::SystemMetric::TitleBarHeight,
|
|
||||||
false);
|
|
||||||
data->draggableAreas = {
|
|
||||||
{0, 0, (window->width() - (m_defaultButtonWidth * 3)),
|
|
||||||
tbh_qml}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return QApplication::exec();
|
return QApplication::exec();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Window 2.15
|
import QtQuick.Window 2.15
|
||||||
|
import wangwenx190.Utils 1.0
|
||||||
|
|
||||||
Window {
|
Window {
|
||||||
id: root
|
id: root
|
||||||
|
@ -8,6 +9,11 @@ Window {
|
||||||
height: 600
|
height: 600
|
||||||
title: qsTr("Hello, World!")
|
title: qsTr("Hello, World!")
|
||||||
|
|
||||||
|
FramelessHelper {
|
||||||
|
id: framelessHelper
|
||||||
|
Component.onCompleted: framelessHelper.removeWindowFrame()
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: titleBar
|
id: titleBar
|
||||||
height: 30
|
height: 30
|
||||||
|
@ -32,10 +38,15 @@ Window {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
MinimizeButton {
|
MinimizeButton {
|
||||||
|
id: minimizeButton
|
||||||
onClicked: root.showMinimized()
|
onClicked: root.showMinimized()
|
||||||
|
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||||
|
minimizeButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
MaximizeButton {
|
MaximizeButton {
|
||||||
|
id: maximizeButton
|
||||||
|
// QWindow::Visibility::Maximized
|
||||||
maximized: root.visibility === 4
|
maximized: root.visibility === 4
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (maximized) {
|
if (maximized) {
|
||||||
|
@ -44,10 +55,15 @@ Window {
|
||||||
root.showMaximized()
|
root.showMaximized()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||||
|
maximizeButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseButton {
|
CloseButton {
|
||||||
|
id: closeButton
|
||||||
onClicked: root.close()
|
onClicked: root.close()
|
||||||
|
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||||
|
closeButton)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1324,8 +1324,9 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
const auto quickItem =
|
const auto quickItem =
|
||||||
qobject_cast<QQuickItem *>(object);
|
qobject_cast<QQuickItem *>(object);
|
||||||
if (quickItem) {
|
if (quickItem) {
|
||||||
if (QRect(qRound(quickItem->x() * dpr),
|
const auto pos = quickItem->mapToScene({0, 0});
|
||||||
qRound(quickItem->y() * dpr),
|
if (QRect(qRound(pos.x() * dpr),
|
||||||
|
qRound(pos.y() * dpr),
|
||||||
qRound(quickItem->width() * dpr),
|
qRound(quickItem->width() * dpr),
|
||||||
qRound(quickItem->height() * dpr))
|
qRound(quickItem->height() * dpr))
|
||||||
.contains(x, y)) {
|
.contains(x, y)) {
|
||||||
|
|
Loading…
Reference in New Issue