add support for frameless window!
@@ -186,6 +186,7 @@ if (USE_SQL)
|
||||
endif()
|
||||
|
||||
add_subdirectory (src/external/qt-color-widgets)
|
||||
add_subdirectory (src/external/framelesshelper)
|
||||
|
||||
# Add the found include directories to our include list.
|
||||
include_directories (SYSTEM "${CMAKE_SOURCE_DIR}/include/")
|
||||
@@ -220,6 +221,7 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/src/external/PNG2BLP/libpng" )
|
||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/src/external/PNG2BLP/libtxc_dxtn" )
|
||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/src/external/PNG2BLP/pngpp" )
|
||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/src/external/PNG2BLP/zlib" )
|
||||
include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS})
|
||||
|
||||
COLLECT_FILES(false noggit_root_sources src/noggit .cpp)
|
||||
COLLECT_FILES(true noggit_ui_sources src/noggit/ui .cpp)
|
||||
@@ -315,6 +317,7 @@ TARGET_LINK_LIBRARIES (noggit
|
||||
Qt5::OpenGL
|
||||
Qt5::OpenGLExtensions
|
||||
ColorWidgets-qt5
|
||||
FramelessHelper
|
||||
)
|
||||
|
||||
set (_noggit_revision_output_dir "${CMAKE_BINARY_DIR}/revision_output")
|
||||
|
||||
71
src/external/framelesshelper/.gitignore
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
# C++ objects and libs
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.a
|
||||
*.la
|
||||
*.lai
|
||||
*.so
|
||||
*.dll
|
||||
*.dylib
|
||||
|
||||
# Qt-es
|
||||
object_script.*.Release
|
||||
object_script.*.Debug
|
||||
*_plugin_import.cpp
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
*.pro.user
|
||||
*.pro.user.*
|
||||
*.qbs.user
|
||||
*.qbs.user.*
|
||||
*.moc
|
||||
moc_*.cpp
|
||||
moc_*.h
|
||||
qrc_*.cpp
|
||||
ui_*.h
|
||||
*.qmlc
|
||||
*.jsc
|
||||
Makefile*
|
||||
*build-*
|
||||
|
||||
# Qt unit tests
|
||||
target_wrapper.*
|
||||
|
||||
# QtCreator
|
||||
*.autosave
|
||||
|
||||
# QtCreator Qml
|
||||
*.qmlproject.user
|
||||
*.qmlproject.user.*
|
||||
|
||||
# QtCreator CMake
|
||||
CMakeLists.txt.user*
|
||||
|
||||
# My
|
||||
[Bb]in/
|
||||
[Bb]in64/
|
||||
[Bb]uild*/
|
||||
*.7z
|
||||
*.zip
|
||||
*.rar
|
||||
*.tar
|
||||
*.gz
|
||||
*.xz
|
||||
*.exe
|
||||
*.lib
|
||||
*.pdb
|
||||
*.ilk
|
||||
*.exp
|
||||
*.obj
|
||||
build.user.bat
|
||||
build.user.sh
|
||||
user.conf
|
||||
[Dd]oc/
|
||||
[Dd]ocs/
|
||||
Thumbs.db
|
||||
*.rc
|
||||
*.qm
|
||||
*.bin
|
||||
*.run
|
||||
.qmake.conf
|
||||
92
src/external/framelesshelper/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(FramelessHelper LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_DEBUG_POSTFIX d)
|
||||
else()
|
||||
set(CMAKE_DEBUG_POSTFIX _debug)
|
||||
endif()
|
||||
|
||||
find_package(Qt5 COMPONENTS Gui REQUIRED)
|
||||
find_package(Qt5 COMPONENTS Widgets Quick)
|
||||
|
||||
set(SOURCES
|
||||
framelesshelper_global.h
|
||||
framelesswindowsmanager.h
|
||||
framelesswindowsmanager.cpp
|
||||
)
|
||||
|
||||
if(Qt5Quick_FOUND)
|
||||
list(APPEND SOURCES
|
||||
framelessquickhelper.h
|
||||
framelessquickhelper.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND SOURCES
|
||||
winnativeeventfilter.h
|
||||
winnativeeventfilter.cpp
|
||||
)
|
||||
else()
|
||||
list(APPEND SOURCES
|
||||
framelesshelper.h
|
||||
framelesshelper.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
enable_language(RC)
|
||||
list(APPEND SOURCES framelesshelper.rc)
|
||||
endif()
|
||||
|
||||
add_library(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC
|
||||
FRAMELESSHELPER_STATIC
|
||||
)
|
||||
endif()
|
||||
if(MSVC)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /utf-8)
|
||||
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /guard:cf)
|
||||
target_link_options(${PROJECT_NAME} PRIVATE /GUARD:CF)
|
||||
endif()
|
||||
endif()
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
QT_NO_CAST_FROM_ASCII
|
||||
QT_NO_CAST_TO_ASCII
|
||||
FRAMELESSHELPER_BUILD_LIBRARY
|
||||
)
|
||||
if(WIN32)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
WIN32_LEAN_AND_MEAN
|
||||
_CRT_SECURE_NO_WARNINGS
|
||||
WNEF_LINK_SYSLIB
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
user32 shell32 gdi32 dwmapi shcore uxtheme d2d1
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::GuiPrivate)
|
||||
if(Qt5Widgets_FOUND)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Widgets)
|
||||
endif()
|
||||
if(Qt5Quick_FOUND)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Quick)
|
||||
endif()
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
|
||||
)
|
||||
21
src/external/framelesshelper/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
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.
|
||||
149
src/external/framelesshelper/README.md
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
# FramelessHelper
|
||||
|
||||
If you are using part of or all the code from this repository in your own projects, it's my pleasure and I'm happy that it can help you. But I hope you can tell me the URL of the homepage or repository of your projects, whether your projects are close-sourced or commercial products do not matter. I'll link to your homepage or repository in this README file. It would be much better if you can provide me some screenshots of your software for demonstration.
|
||||
|
||||
如果您正在使用此项目的部分或全部代码,这是我的荣幸,我很高兴能帮到您,但我同时也希望,您能将您项目的首页或仓库的网址告诉我(闭源或收费都没关系),我将在这个自述文件中链接到您所提供的网址,以供展示。如果您能一并提供一些软件运行时的截图,那就更好了。
|
||||
|
||||
## Screenshots - Win32
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Screenshots - Cross platform
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- Support Windows, X11, Wayland and macOS.
|
||||
- Frameless but have frame shadow.
|
||||
- Draggable and resizable.
|
||||
- Automatically high DPI scaling.
|
||||
- Multi-monitor support (different resolution and DPI).
|
||||
- Have animations when minimizing, maximizing and restoring.
|
||||
- Support tiled and stack windows by DWM (Win32 only).
|
||||
- Won't cover the task bar when maximized (Win32 only).
|
||||
- Won't block the auto-hide task bar when maximized (Win32 only).
|
||||
- No flickers when resizing.
|
||||
- Load all native APIs at run-time, no need to link to any system libraries directly (Win32 only).
|
||||
|
||||
## Usage
|
||||
|
||||
```cpp
|
||||
#include "framelesswindowsmanager.h"
|
||||
#include <QWidget>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QWidget widget;
|
||||
// Do this before the widget is shown.
|
||||
FramelessWindowsManager::addWindow(&widget);
|
||||
widget.show();
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to [the QWidget example](/examples/QWidget/main.cpp) for more detailed information.
|
||||
|
||||
### Ignore areas and etc
|
||||
|
||||
```cpp
|
||||
// Only **TOP LEVEL** QWidgets and QWindows are supported.
|
||||
QMainWindow *mainWindow = new QMainWindow;
|
||||
// Disable resizing of the given window. Resizing is enabled by default.
|
||||
FramelessWindowsManager::setResizable(mainWindow, false);
|
||||
// All the following values should not be DPI-aware, just use the
|
||||
// original numbers, assuming the scale factor is 1.0, don't scale
|
||||
// them yourself, this code will do the scaling according to DPI
|
||||
// internally and automatically.
|
||||
// Maximum window size
|
||||
FramelessWindowsManager::setMaximumSize(mainWindow, {1280, 720});
|
||||
// Minimum window size
|
||||
FramelessWindowsManager::setMinimumSize(mainWindow, {800, 540});
|
||||
// How to set ignore areas:
|
||||
// The geometry of something you already know, in window coordinates
|
||||
FramelessWindowsManager::addIgnoreArea(mainWindow, {100, 0, 30, 30});
|
||||
// The geometry of a widget, in window coordinates.
|
||||
// It won't update automatically when the geometry of that widget has
|
||||
// changed, so if you want to add a widget, which is in a layout and
|
||||
// it's geometry will possibly change, to the ignore list, try the
|
||||
// next method (addIgnoreObject) instead.
|
||||
FramelessWindowsManager::addIgnoreArea(mainWindow, pushButton_close.geometry());
|
||||
// The **POINTER** of a QWidget or QQuickItem
|
||||
FramelessWindowsManager::addIgnoreObject(mainWindow, ui->pushButton_minimize);
|
||||
// Move a QWidget or QWindow to the center of its current desktop.
|
||||
FramelessWindowsManager::moveWindowToDesktopCenter(mainWindow);
|
||||
```
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
### Win32
|
||||
|
||||
Windows 7 ~ 10, 32 bit & 64 bit.
|
||||
|
||||
The code itself should be able to work on Windows Vista in theory, but Qt5 has dropped Vista support long time ago. And Qt6 will only support Win10.
|
||||
|
||||
### UNIX
|
||||
|
||||
A not too old version of Linux and macOS, 32 bit & 64 bit.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Win32
|
||||
|
||||
| Component | Requirement | Additional Information |
|
||||
| --- | --- | --- |
|
||||
| Qt | >= 5.6 | Only the `gui` module is required explicitly, but to make full use of this repository, you'd better install the `widgets` and `quick` modules as well |
|
||||
| Compiler | >= C++11 | MSVC, MinGW, Clang-CL, Intel-CL or cross compile from Linux/macOS are all supported |
|
||||
|
||||
### UNIX
|
||||
|
||||
| Component | Requirement | Additional Information |
|
||||
| --- | --- | --- |
|
||||
| Qt | >= 5.15 | This code uses two functions, [`startSystemMove`](https://doc.qt.io/qt-5/qwindow.html#startSystemMove) and [`startSystemResize`](https://doc.qt.io/qt-5/qwindow.html#startSystemResize), which are introduced in Qt 5.15 |
|
||||
| Compiler | >= C++11 | MSVC, MinGW, Clang-CL, Intel-CL / GCC, Clang, ICC are all supported |
|
||||
|
||||
## Known Bugs
|
||||
|
||||
Please refer to <https://github.com/wangwenx190/framelesshelper/issues> for more information.
|
||||
|
||||
## License
|
||||
|
||||
```text
|
||||
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.
|
||||
```
|
||||
69
src/external/framelesshelper/README_unix.md
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
# FramelessHelper (UNIX version)
|
||||
|
||||
## Screenshots
|
||||
|
||||
TODO
|
||||
|
||||
## Features
|
||||
|
||||
- Frameless (of course!).
|
||||
- Draggable.
|
||||
- Resizable.
|
||||
- Cross-platform: Windows, X11, Wayland, macOS (however, it doesn't look good on Windows, so you may want to try [`WinNativeEventFilter`](/winnativeeventfilter.h) instead).
|
||||
|
||||
As for the frame shadow and other window features, they mainly depend on your window manager.
|
||||
|
||||
## Usage
|
||||
|
||||
```cpp
|
||||
QWidget widget;
|
||||
FramelessHelper helper;
|
||||
helper.removeWindowFrame(&widget);
|
||||
widget.show();
|
||||
```
|
||||
|
||||
### Ignore areas and etc
|
||||
|
||||
```cpp
|
||||
helper.setIgnoreAreas(&widget, {{0, 0, 30, 40}, {40, 0, 30, 40}});
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
| Component | Requirement | Additional Information |
|
||||
| --- | --- | --- |
|
||||
| Qt | >= 5.15 | This code uses two functions, [`startSystemMove`](https://doc.qt.io/qt-5/qwindow.html#startSystemMove) and [`startSystemResize`](https://doc.qt.io/qt-5/qwindow.html#startSystemResize), which are introduced in Qt 5.15 |
|
||||
| Compiler | >= C++11 | MSVC, MinGW, Clang-CL, Intel-CL / GCC, Clang, ICC are all supported |
|
||||
|
||||
## References for developers
|
||||
|
||||
- <https://doc.qt.io/qt-5/qobject.html#installEventFilter>
|
||||
- <https://doc.qt.io/qt-5/qobject.html#removeEventFilter>
|
||||
- <https://doc.qt.io/qt-5/qwindow.html#startSystemMove>
|
||||
- <https://doc.qt.io/qt-5/qwindow.html#startSystemResize>
|
||||
|
||||
## License
|
||||
|
||||
```text
|
||||
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.
|
||||
```
|
||||
203
src/external/framelesshelper/README_win32.md
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
# FramelessHelper (Win32 version)
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- Frameless but have frame shadow.
|
||||
- Draggable and resizable.
|
||||
- Automatically high DPI scaling.
|
||||
- Multi-monitor support (different resolution and DPI).
|
||||
- Have animations when minimizing, maximizing and restoring.
|
||||
- Support tiled and stack windows by DWM.
|
||||
- Won't cover the task bar when maximized.
|
||||
- Won't block the auto-hide task bar when maximized.
|
||||
- No flickers when resizing.
|
||||
- Load all Win32 APIs at run-time, no need to link to any system libraries directly.
|
||||
|
||||
## Usage
|
||||
|
||||
```cpp
|
||||
QWidget widget;
|
||||
// Do this before the widget is shown.
|
||||
WinNativeEventFilter::addFramelessWindow(&widget);
|
||||
widget.show();
|
||||
```
|
||||
|
||||
Please refer to [the QWidget example](/examples/QWidget/main.cpp) for more detailed information.
|
||||
|
||||
### Ignore areas and etc
|
||||
|
||||
```cpp
|
||||
WinNativeEventFilter::WINDOWDATA data = {};
|
||||
// All the following values should not be DPI-aware, just use the
|
||||
// original numbers, assuming the scale factor is 1.0, don't scale
|
||||
// them yourself, this code will do the scaling according to DPI
|
||||
// internally and automatically.
|
||||
// Maximum window size
|
||||
data.maximumSize = {1280, 720};
|
||||
// Minimum window size
|
||||
data.minimumSize = {800, 540};
|
||||
// How to set ignore areas:
|
||||
// The geometry of something you already know, in window coordinates
|
||||
data.ignoreAreas.append({100, 0, 30, 30});
|
||||
// The geometry of a widget, in window coordinates.
|
||||
// It won't update automatically when the geometry of that widget has
|
||||
// changed, so if you want to add a widget, which is in a layout and
|
||||
// it's geometry will possibly change, to the ignore list, try the
|
||||
// next method (ignoreObjects) instead.
|
||||
data.ignoreAreas.append(pushButton_close.geometry());
|
||||
// The **POINTER** of a QWidget or QQuickItem
|
||||
data.ignoreObjects.append(ui->pushButton_minimize);
|
||||
// Pass data as the second parameter
|
||||
WinNativeEventFilter::addFramelessWindow(&widget, &data);
|
||||
// Or
|
||||
WinNativeEventFilter::setWindowData(&widget, &data);
|
||||
// Or modify the window data of a specific window directly:
|
||||
const auto data = WinNativeEventFilter::windowData(&widget);
|
||||
if (data) {
|
||||
data->borderWidth = 5;
|
||||
data->borderHeight = 5;
|
||||
data->titleBarHeight = 30;
|
||||
}
|
||||
// The frameless window is resizable by default.
|
||||
WinNativeEventFilter::setWindowResizable(reinterpret_cast<void *>(mainWindow->winId()), false);
|
||||
```
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
Windows 7 ~ 10, 32 bit & 64 bit.
|
||||
|
||||
The code itself should be able to work on Windows Vista in theory, but Qt5 has dropped Vista support long time ago. And Qt6 will only support Win10.
|
||||
|
||||
## Requirements
|
||||
|
||||
| Component | Requirement | Additional Information |
|
||||
| --- | --- | --- |
|
||||
| Qt | >= 5.6 | Only the `gui` module is required explicitly, but to make full use of this repository, you'd better install the `widgets` and `quick` modules as well |
|
||||
| Compiler | >= C++11 | MSVC, MinGW, Clang-CL, Intel-CL or cross compile from Linux are all supported |
|
||||
|
||||
## Known Bugs
|
||||
|
||||
Please refer to <https://github.com/wangwenx190/framelesshelper/issues> for more information.
|
||||
|
||||
## Notes for developers
|
||||
|
||||
- As you may have found, if you use this code, the resize areas will be inside the frameless window, however, a normal Win32 window can be resized outside of it. Here is the reason: the `WS_THICKFRAME` window style will cause a window has three transparent areas beside the window's left, right and bottom edge. Their width/height is 8px if the window is not scaled. In most cases, they are totally invisible. It's DWM's responsibility to draw and control them. They exist to let the user resize the window, visually outside of it. They are in the window area, but not the client area, so they are in the non-client area actually. But we have turned the whole window area into client area in `WM_NCCALCSIZE`, so the three transparent resize areas also become a part of the client area and thus they become visible. When we resize the window, it looks like we are resizing inside of it, however, that's because the transparent resize areas are visible now, we ARE resizing outside of the window actually. But I don't know how to make them become transparent again without breaking the frame shadow drawn by DWM. If you really want to solve it, you can try to embed your window into a larger transparent window and draw the frame shadow yourself. [See the discussions here](https://github.com/wangwenx190/framelesshelper/issues/3) for more detailed information.
|
||||
- Don't change the window flags (for example, enable the Qt::FramelessWindowHint flag) because it will break the functionality of this code. I'll get rid of the window frame (including the titlebar of course) in Win32 native events.
|
||||
- All traditional Win32 APIs are replaced by their DPI-aware ones, if there is one.
|
||||
- Starting from Windows 10, normal windows usually have a one pixel width border line. After many times of trying, I still can't preserve it if I want to remove the window frame. I don't know how to solve this currently. If you really need it, you have to draw one manually by yourself. [See the discussions here](https://github.com/wangwenx190/framelesshelper/issues/3) for more detailed information.
|
||||
- The frame shadow will get lost if the window is totally transparent. It can't be solved unless you draw the frame shadow manually.
|
||||
- On Windows 7, if you disabled the Windows Aero, the frame shadow will be disabled as well because it's DWM's resposibility to draw the frame shadow.
|
||||
- The border width (8 if not scaled), border height (8 if not scaled) and titlebar height (30 if not scaled) are acquired by Win32 APIs and are the same with other standard windows, and thus you should not modify them. Only modify them when you really have a good reason to do so.
|
||||
- You can also copy all the code to `[virtual protected] bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)` or `[virtual protected] bool QWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)`, it's the same with install a native event filter to the application.
|
||||
|
||||
## References for developers
|
||||
|
||||
### Microsoft Docs
|
||||
|
||||
- <https://docs.microsoft.com/en-us/archive/blogs/wpfsdk/custom-window-chrome-in-wpf>
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize>
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-nchittest>
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-ncactivate>
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd>
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-getminmaxinfo>
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/dwm/customframe>
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows>
|
||||
|
||||
### Windows Presentation Foundation (WPF)
|
||||
|
||||
- <https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Shell/WindowChromeWorker.cs>
|
||||
|
||||
### Chromium
|
||||
|
||||
- <https://github.com/chromium/chromium/blob/master/ui/base/win/hwnd_metrics.cc>
|
||||
- <https://github.com/chromium/chromium/blob/master/ui/display/win/screen_win.cc>
|
||||
- <https://github.com/chromium/chromium/blob/master/ui/views/win/hwnd_message_handler.cc>
|
||||
- <https://github.com/chromium/chromium/blob/master/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc>
|
||||
- <https://github.com/chromium/chromium/blob/master/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc>
|
||||
- <https://github.com/chromium/chromium/blob/master/ui/views/widget/native_widget_aura.cc>
|
||||
- <https://github.com/chromium/chromium/blob/master/ui/views/widget/widget.cc>
|
||||
|
||||
### Mozilla Firefox
|
||||
|
||||
- <https://github.com/mozilla/gecko-dev/blob/master/widget/windows/nsWindow.cpp>
|
||||
|
||||
### Windows Terminal
|
||||
|
||||
- <https://github.com/microsoft/terminal/blob/master/src/cascadia/WindowsTerminal/IslandWindow.cpp>
|
||||
- <https://github.com/microsoft/terminal/blob/master/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp>
|
||||
|
||||
### GitHub
|
||||
|
||||
- <https://github.com/rossy/borderless-window>
|
||||
- <https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window>
|
||||
- <https://github.com/dfct/TrueFramelessWindow>
|
||||
- <https://github.com/qtdevs/FramelessHelper>
|
||||
|
||||
### Qt
|
||||
|
||||
- <https://doc.qt.io/qt-5/qcoreapplication.html#installNativeEventFilter>
|
||||
- <https://doc.qt.io/qt-5/qcoreapplication.html#removeNativeEventFilter>
|
||||
- <https://doc.qt.io/qt-5/qobject.html#installEventFilter>
|
||||
- <https://doc.qt.io/qt-5/qobject.html#removeEventFilter>
|
||||
- <https://doc.qt.io/qt-5/qwindow.html#startSystemMove>
|
||||
- <https://doc.qt.io/qt-5/qwindow.html#startSystemResize>
|
||||
|
||||
### 窗口样式的作用
|
||||
|
||||
`WS_OVERLAPPEDWINDOW` = `WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX`
|
||||
|
||||
`WS_OVERLAPPEDWINDOW`代表了一个正常的Win32窗口,也就是说,它就是正常窗口默认的窗口样式(`Window style`)。
|
||||
|
||||
`WS_OVERLAPPED`:窗口有标题栏和边界(功能性,并不是真的要有可视化的东西);`WS_CAPTION`:窗口有标题栏功能(并不是真的要有个可视化的标题栏,而是拥有和DWM交互的能力);`WS_SYSMENU`:窗口可以弹出系统菜单(ALT+空格);`WS_THICKFRAME`:窗口有三个不可视的拖拽区域(前提是非客户区存在),并且拥有DWM绘制的边框阴影(没有这个样式,DWM一定不会绘制边框阴影,只要有,就一定是自绘的);`WS_MINIMIZEBOX`:窗口支持最小化(与`WS_THICKFRAME`一起使用时最小化有动画);`WS_MAXIMIZEBOX`:窗口支持最大化(与`WS_THICKFRAME`一起使用时最大化有动画)。
|
||||
|
||||
这些窗口样式,只有`WS_SYSMENU`是可以没有的(虽然这样会导致窗口无法弹出系统菜单,但如果非要做,也是能用其他API模拟的,比如火狐和Chrome浏览器的做法),如果缺少其他窗口样式,会导致窗口的正常功能产生残缺,比如最大化最小化时的动画丢失,缺少窗口阴影等。
|
||||
|
||||
参考资料:<https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles>
|
||||
|
||||
## Special Thanks
|
||||
|
||||
Thanks **Lucas** for testing this code in many various conditions.
|
||||
|
||||
Thanks [**Shujaat Ali Khan**](https://github.com/shujaatak) for searching so many useful articles and repositories for me.
|
||||
|
||||
Thanks [**Julien Maille**](https://github.com/JulienMaille) for adding the `QMainWindow` example.
|
||||
|
||||
## License
|
||||
|
||||
```text
|
||||
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.
|
||||
```
|
||||
106
src/external/framelesshelper/examples/QMainWindow/MainWindow.ui
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>497</width>
|
||||
<height>348</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset>
|
||||
<normaloff>../windows.ico</normaloff>../windows.ico</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget"/>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>497</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuItem_1">
|
||||
<property name="title">
|
||||
<string>Menu 1</string>
|
||||
</property>
|
||||
<addaction name="actionItem_1"/>
|
||||
<addaction name="actionItem_2"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuItem_2">
|
||||
<property name="title">
|
||||
<string>Menu 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuMenu_3">
|
||||
<property name="title">
|
||||
<string>Menu 3</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuItem_1"/>
|
||||
<addaction name="menuItem_2"/>
|
||||
<addaction name="menuMenu_3"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<widget class="QDockWidget" name="dockWidget">
|
||||
<property name="windowTitle">
|
||||
<string>Dock 1</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>1</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents"/>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dockWidget_2">
|
||||
<property name="windowTitle">
|
||||
<string>Dock 2</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>1</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_2"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="actionAction_1"/>
|
||||
<addaction name="actionAction_2"/>
|
||||
</widget>
|
||||
<action name="actionAction_1">
|
||||
<property name="text">
|
||||
<string>Action 1</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAction_2">
|
||||
<property name="text">
|
||||
<string>Action 2</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionItem_1">
|
||||
<property name="text">
|
||||
<string>Item 1</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionItem_2">
|
||||
<property name="text">
|
||||
<string>Item 2</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
6
src/external/framelesshelper/examples/QMainWindow/QMainWindow.pro
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
TARGET = QMainWindow
|
||||
TEMPLATE = app
|
||||
QT += widgets
|
||||
SOURCES += main.cpp
|
||||
FORMS += TitleBar.ui MainWindow.ui
|
||||
include($$PWD/../common.pri)
|
||||
253
src/external/framelesshelper/examples/QMainWindow/TitleBar.ui
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TitleBar</class>
|
||||
<widget class="QWidget" name="TitleBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>423</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">#iconButton, #minimizeButton, #maximizeButton, #closeButton {
|
||||
background-color: transparent;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
#minimizeButton:hover, #maximizeButton:hover {
|
||||
border-style: none;
|
||||
background-color: #80c7c7c7;
|
||||
}
|
||||
|
||||
#minimizeButton:pressed, #maximizeButton:pressed {
|
||||
border-style: none;
|
||||
background-color: #80808080;
|
||||
}
|
||||
|
||||
#closeButton:hover {
|
||||
border-style: none;
|
||||
background-color: #e81123;
|
||||
}
|
||||
|
||||
#closeButton:pressed {
|
||||
border-style: none;
|
||||
background-color: #8c0a15;
|
||||
}</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="iconButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>26</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>26</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="titleLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>262</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="minimizeButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Minimize</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/button_minimize_black.svg</normaloff>:/images/button_minimize_black.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="maximizeButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Maximize</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/button_maximize_black.svg</normaloff>
|
||||
<normalon>:/images/button_restore_black.svg</normalon>:/images/button_maximize_black.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/button_close_black.svg</normaloff>:/images/button_close_black.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
120
src/external/framelesshelper/examples/QMainWindow/main.cpp
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 "../../framelesswindowsmanager.h"
|
||||
#include "ui_MainWindow.h"
|
||||
#include "ui_TitleBar.h"
|
||||
#include <QApplication>
|
||||
#include <QStyleOption>
|
||||
#include <QWidget>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
// High DPI scaling is enabled by default from Qt 6
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
// Windows: we are using the manifest file to get maximum compatibility
|
||||
// because some APIs are not supprted on old systems such as Windows 7
|
||||
// and Windows 8. And once we have set the DPI awareness level in the
|
||||
// manifest file, any attemptation to try to change it through API will
|
||||
// fail. In other words, Qt won't be able to enable or disable high DPI
|
||||
// scaling or change the DPI awareness level once we have set it in the
|
||||
// manifest file. So the following two lines are uesless actually (However,
|
||||
// they are still useful on other platforms).
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
// Don't round the scale factor.
|
||||
// This will break QWidget applications because they can't render correctly.
|
||||
// Qt Quick applications won't have this issue.
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QApplication application(argc, argv);
|
||||
|
||||
QMainWindow *mainWindow = new QMainWindow;
|
||||
Ui::MainWindow appMainWindow;
|
||||
appMainWindow.setupUi(mainWindow);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
Ui::TitleBar titleBarWidget;
|
||||
titleBarWidget.setupUi(widget);
|
||||
|
||||
QMenuBar *menuBar = mainWindow->menuBar();
|
||||
titleBarWidget.horizontalLayout->insertWidget(1, menuBar);
|
||||
menuBar->setMaximumHeight(20);
|
||||
|
||||
mainWindow->setMenuWidget(widget);
|
||||
|
||||
QObject::connect(mainWindow,
|
||||
&QMainWindow::windowIconChanged,
|
||||
titleBarWidget.iconButton,
|
||||
&QPushButton::setIcon);
|
||||
QObject::connect(mainWindow,
|
||||
&QMainWindow::windowTitleChanged,
|
||||
titleBarWidget.titleLabel,
|
||||
&QLabel::setText);
|
||||
QObject::connect(titleBarWidget.closeButton,
|
||||
&QPushButton::clicked,
|
||||
mainWindow,
|
||||
&QMainWindow::close);
|
||||
QObject::connect(titleBarWidget.minimizeButton,
|
||||
&QPushButton::clicked,
|
||||
mainWindow,
|
||||
&QMainWindow::showMinimized);
|
||||
QObject::connect(titleBarWidget.maximizeButton,
|
||||
&QPushButton::clicked,
|
||||
[mainWindow, titleBarWidget]() {
|
||||
if (mainWindow->isMaximized()) {
|
||||
mainWindow->showNormal();
|
||||
titleBarWidget.maximizeButton->setToolTip(QObject::tr("Maximize"));
|
||||
} else {
|
||||
mainWindow->showMaximized();
|
||||
titleBarWidget.maximizeButton->setToolTip(QObject::tr("Restore"));
|
||||
}
|
||||
});
|
||||
|
||||
QStyleOption option;
|
||||
option.initFrom(mainWindow);
|
||||
const QIcon icon = mainWindow->style()->standardIcon(QStyle::SP_ComputerIcon, &option);
|
||||
mainWindow->setWindowIcon(icon);
|
||||
mainWindow->setWindowTitle(QObject::tr("Hello, World!"));
|
||||
|
||||
FramelessWindowsManager::addWindow(mainWindow);
|
||||
|
||||
FramelessWindowsManager::addIgnoreObject(mainWindow, titleBarWidget.minimizeButton);
|
||||
FramelessWindowsManager::addIgnoreObject(mainWindow, titleBarWidget.maximizeButton);
|
||||
FramelessWindowsManager::addIgnoreObject(mainWindow, titleBarWidget.closeButton);
|
||||
FramelessWindowsManager::addIgnoreObject(mainWindow, appMainWindow.menubar);
|
||||
|
||||
mainWindow->resize(800, 600);
|
||||
|
||||
FramelessWindowsManager::moveWindowToDesktopCenter(mainWindow);
|
||||
|
||||
mainWindow->show();
|
||||
|
||||
return QApplication::exec();
|
||||
}
|
||||
33
src/external/framelesshelper/examples/QQPlayer/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(QQPlayer LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
find_package(Qt5 COMPONENTS Quick REQUIRED)
|
||||
|
||||
set(source_files qml.qrc images.qrc main.cpp ../../framelessquickhelper.h ../../framelessquickhelper.cpp)
|
||||
|
||||
if(WIN32)
|
||||
enable_language(RC)
|
||||
list(APPEND source_files QQPlayer.exe.manifest QQPlayer.rc ../../winnativeeventfilter.h ../../winnativeeventfilter.cpp)
|
||||
else()
|
||||
list(APPEND source_files ../../framelesshelper.h ../../framelesshelper.cpp)
|
||||
endif()
|
||||
|
||||
add_executable(QQPlayer WIN32 ${source_files})
|
||||
|
||||
if(MSVC)
|
||||
# Silence a compiler warning caused by the Chinese comments in the source file.
|
||||
target_compile_options(QQPlayer PRIVATE -utf-8)
|
||||
endif()
|
||||
target_compile_definitions(QQPlayer PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
|
||||
target_link_libraries(QQPlayer PRIVATE Qt::Quick Qt::GuiPrivate)
|
||||
34
src/external/framelesshelper/examples/QQPlayer/QQPlayer.exe.manifest
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity type="win32" name="com.wangwenx190.demo.qqplayer" version="1.0.0.0"/>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 7 and Windows Server 2008 R2 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows 8 and Windows Server 2012 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 8.1 and Windows Server 2012 R2 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
BIN
src/external/framelesshelper/examples/QQPlayer/QQPlayer.ico
vendored
Normal file
|
After Width: | Height: | Size: 133 KiB |
68
src/external/framelesshelper/examples/QQPlayer/QQPlayer.rc
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 <windows.h>
|
||||
|
||||
IDI_ICON1 ICON "QQPlayer.ico"
|
||||
|
||||
// CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "QQPlayer.exe.manifest"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
PRODUCTVERSION 1,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "Built by the Qt Toolkit."
|
||||
VALUE "CompanyName", "wangwenx190"
|
||||
VALUE "FileDescription", "QQPlayer DEMO"
|
||||
VALUE "FileVersion", "1.0.0.0"
|
||||
VALUE "InternalName", "qqplayer-demo"
|
||||
VALUE "LegalCopyright", "MIT License"
|
||||
#ifdef _DEBUG
|
||||
VALUE "OriginalFilename", "QQPlayerd.exe"
|
||||
#else
|
||||
VALUE "OriginalFilename", "QQPlayer.exe"
|
||||
#endif
|
||||
VALUE "ProductName", "QQPlayer"
|
||||
VALUE "ProductVersion", "1.0.0.0"
|
||||
VALUE "LegalTrademarks", "Tencent"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
12
src/external/framelesshelper/examples/QQPlayer/README.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Qt Quick 模仿的 QQ播放器
|
||||
|
||||
只做了主界面,而且只有界面,没有功能,仅供展示
|
||||
|
||||
可以看出,只要有贴图,Qt Quick 做这种界面很容易的
|
||||
|
||||
按钮的图片有些糊,而且边缘呈锯齿状,是因为我是直接从截图里扣下来的
|
||||
,没有仔细处理。由于只是示例项目,因此不会再进行任何额外处理了。
|
||||
如果是公司的项目,肯定会有正规的高清贴图的。
|
||||
|
||||
所有来自QQ播放器的图片以及图标,版权均归腾讯所有。
|
||||
此仓库里提供的所有相关的素材文件,仅供学习交流,请勿传播甚至商用。
|
||||
13
src/external/framelesshelper/examples/QQPlayer/build.bat
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
@echo off
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
|
||||
call "%SystemDrive%\Qt\5.15.0\msvc2019_64\bin\qtenv2.bat"
|
||||
cd /d "%~dp0"
|
||||
if exist build rd /s /q build
|
||||
md build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=bin -GNinja ..
|
||||
cmake --build .
|
||||
windeployqt --force --no-translations --no-system-d3d-compiler --no-virtualkeyboard --no-compiler-runtime --no-angle --no-opengl-sw --dir "%~dp0build\bin\qml" --libdir "%~dp0build\bin" --plugindir "%~dp0build\bin\plugins" --qmldir "%~dp0resources\qml" "%~dp0build\bin\QQPlayer.exe"
|
||||
cd /d "%~dp0"
|
||||
start explorer /select,"%~dp0build\bin\QQPlayer.exe"
|
||||
exit /b
|
||||
28
src/external/framelesshelper/examples/QQPlayer/images.qrc
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<RCC>
|
||||
<qresource prefix="/images">
|
||||
<file alias="background.png">resources/images/background.png</file>
|
||||
<file alias="button_close_black.svg">../../resources/images/button_close_black.svg</file>
|
||||
<file alias="button_close_white.svg">../../resources/images/button_close_white.svg</file>
|
||||
<file alias="button_maximize_black.svg">../../resources/images/button_maximize_black.svg</file>
|
||||
<file alias="button_maximize_white.svg">../../resources/images/button_maximize_white.svg</file>
|
||||
<file alias="button_minimize_black.svg">../../resources/images/button_minimize_black.svg</file>
|
||||
<file alias="button_minimize_white.svg">../../resources/images/button_minimize_white.svg</file>
|
||||
<file alias="button_restore_black.svg">../../resources/images/button_restore_black.svg</file>
|
||||
<file alias="button_restore_white.svg">../../resources/images/button_restore_white.svg</file>
|
||||
<file alias="logo.png">resources/images/logo.png</file>
|
||||
<file alias="open_file_blue.png">resources/images/open_file_blue.png</file>
|
||||
<file alias="open_file_white.png">resources/images/open_file_white.png</file>
|
||||
<file alias="main_menu_blue.png">resources/images/main_menu_blue.png</file>
|
||||
<file alias="main_menu_white.png">resources/images/main_menu_white.png</file>
|
||||
<file alias="play_blue.png">resources/images/play_blue.png</file>
|
||||
<file alias="play_blue_light.png">resources/images/play_blue_light.png</file>
|
||||
<file alias="stop_blue.png">resources/images/stop_blue.png</file>
|
||||
<file alias="stop_blue_light.png">resources/images/stop_blue_light.png</file>
|
||||
<file alias="previous_blue.png">resources/images/previous_blue.png</file>
|
||||
<file alias="previous_blue_light.png">resources/images/previous_blue_light.png</file>
|
||||
<file alias="next_blue.png">resources/images/next_blue.png</file>
|
||||
<file alias="next_blue_light.png">resources/images/next_blue_light.png</file>
|
||||
<file alias="volume_blue.png">resources/images/volume_blue.png</file>
|
||||
<file alias="volume_blue_light.png">resources/images/volume_blue_light.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
71
src/external/framelesshelper/examples/QQPlayer/main.cpp
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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"
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Enable Qt RHI, the default backend on Windows is D3D 11.1
|
||||
qputenv("QSG_RHI", "1");
|
||||
qputenv("QSG_INFO", "1");
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(6, 0, 0))
|
||||
QGuiApplication::setAttribute(
|
||||
Qt::ApplicationAttribute::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(
|
||||
Qt::ApplicationAttribute::AA_UseHighDpiPixmaps);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#endif
|
||||
QGuiApplication::setApplicationName(QString::fromUtf8("QQPlayer"));
|
||||
QGuiApplication::setApplicationDisplayName(QString::fromUtf8("QQPlayer"));
|
||||
#ifndef Q_OS_WINDOWS
|
||||
QGuiApplication::setApplicationVersion(QString::fromUtf8("1.0.0"));
|
||||
#endif
|
||||
QGuiApplication::setOrganizationName(QString::fromUtf8("wangwenx190"));
|
||||
QGuiApplication::setOrganizationDomain(
|
||||
QString::fromUtf8("wangwenx190.github.io"));
|
||||
QGuiApplication application(argc, argv);
|
||||
QQmlApplicationEngine engine;
|
||||
qmlRegisterType<FramelessQuickHelper>("wangwenx190.Utils", 1, 0,
|
||||
"FramelessHelper");
|
||||
const QUrl mainQmlUrl(QString::fromUtf8("qrc:/qml/main.qml"));
|
||||
const QMetaObject::Connection connection = QObject::connect(
|
||||
&engine, &QQmlApplicationEngine::objectCreated, &application,
|
||||
[&mainQmlUrl, &connection](QObject *object, const QUrl &url) {
|
||||
if (url != mainQmlUrl) {
|
||||
return;
|
||||
}
|
||||
if (!object) {
|
||||
QGuiApplication::exit(-1);
|
||||
} else {
|
||||
QObject::disconnect(connection);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
engine.load(mainQmlUrl);
|
||||
return QGuiApplication::exec();
|
||||
}
|
||||
16
src/external/framelesshelper/examples/QQPlayer/qml.qrc
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<RCC>
|
||||
<qresource prefix="/qml">
|
||||
<file alias="main.qml">resources/qml/main.qml</file>
|
||||
<file alias="CloseButton.qml">resources/qml/CloseButton.qml</file>
|
||||
<file alias="MaximizeButton.qml">resources/qml/MaximizeButton.qml</file>
|
||||
<file alias="MinimizeButton.qml">resources/qml/MinimizeButton.qml</file>
|
||||
<file alias="OpenFileButton.qml">resources/qml/OpenFileButton.qml</file>
|
||||
<file alias="MainMenuButton.qml">resources/qml/MainMenuButton.qml</file>
|
||||
<file alias="PlayButton.qml">resources/qml/PlayButton.qml</file>
|
||||
<file alias="StopButton.qml">resources/qml/StopButton.qml</file>
|
||||
<file alias="PreviousButton.qml">resources/qml/PreviousButton.qml</file>
|
||||
<file alias="NextButton.qml">resources/qml/NextButton.qml</file>
|
||||
<file alias="VolumeButton.qml">resources/qml/VolumeButton.qml</file>
|
||||
<file alias="ProgressSlider.qml">resources/qml/ProgressSlider.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/background.png
vendored
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/logo.png
vendored
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/main_menu_blue.png
vendored
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/main_menu_white.png
vendored
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/next_blue.png
vendored
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/next_blue_light.png
vendored
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/open_file_blue.png
vendored
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/open_file_white.png
vendored
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/play_blue.png
vendored
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/play_blue_light.png
vendored
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/previous_blue.png
vendored
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/previous_blue_light.png
vendored
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/stop_blue.png
vendored
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/stop_blue_light.png
vendored
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/volume_blue.png
vendored
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/external/framelesshelper/examples/QQPlayer/resources/images/volume_blue_light.png
vendored
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
47
src/external/framelesshelper/examples/QQPlayer/resources/qml/CloseButton.qml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 45
|
||||
implicitHeight: 30
|
||||
|
||||
ToolTip.visible: hovered && !down
|
||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
ToolTip.text: qsTr("Close")
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: "qrc:/images/button_close_white.svg"
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
visible: control.down || control.hovered
|
||||
color: control.down ? "#8c0a15" : (control.hovered ? "#e81123" : "transparent")
|
||||
}
|
||||
}
|
||||
41
src/external/framelesshelper/examples/QQPlayer/resources/qml/MainMenuButton.qml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 75
|
||||
implicitHeight: 15
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: control.down
|
||||
|| control.hovered ? "qrc:/images/main_menu_blue.png" : "qrc:/images/main_menu_white.png"
|
||||
}
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
49
src/external/framelesshelper/examples/QQPlayer/resources/qml/MaximizeButton.qml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 45
|
||||
implicitHeight: 30
|
||||
|
||||
property bool maximized: false
|
||||
|
||||
ToolTip.visible: hovered && !down
|
||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
ToolTip.text: maximized ? qsTr("Restore") : qsTr("Maximize")
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: maximized ? "qrc:/images/button_restore_white.svg" : "qrc:/images/button_maximize_white.svg"
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
visible: control.down || control.hovered
|
||||
color: control.down ? "#808080" : (control.hovered ? "#c7c7c7" : "transparent")
|
||||
}
|
||||
}
|
||||
47
src/external/framelesshelper/examples/QQPlayer/resources/qml/MinimizeButton.qml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 45
|
||||
implicitHeight: 30
|
||||
|
||||
ToolTip.visible: hovered && !down
|
||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
ToolTip.text: qsTr("Minimize")
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: "qrc:/images/button_minimize_white.svg"
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
visible: control.down || control.hovered
|
||||
color: control.down ? "#808080" : (control.hovered ? "#c7c7c7" : "transparent")
|
||||
}
|
||||
}
|
||||
41
src/external/framelesshelper/examples/QQPlayer/resources/qml/NextButton.qml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 16
|
||||
implicitHeight: 14
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: control.down
|
||||
|| control.hovered ? "qrc:/images/next_blue_light.png" : "qrc:/images/next_blue.png"
|
||||
}
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
41
src/external/framelesshelper/examples/QQPlayer/resources/qml/OpenFileButton.qml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 187
|
||||
implicitHeight: 50
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: control.down
|
||||
|| control.hovered ? "qrc:/images/open_file_blue.png" : "qrc:/images/open_file_white.png"
|
||||
}
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
41
src/external/framelesshelper/examples/QQPlayer/resources/qml/PlayButton.qml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 45
|
||||
implicitHeight: 45
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: control.down
|
||||
|| control.hovered ? "qrc:/images/play_blue_light.png" : "qrc:/images/play_blue.png"
|
||||
}
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
41
src/external/framelesshelper/examples/QQPlayer/resources/qml/PreviousButton.qml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 16
|
||||
implicitHeight: 14
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: control.down
|
||||
|| control.hovered ? "qrc:/images/previous_blue_light.png" : "qrc:/images/previous_blue.png"
|
||||
}
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
92
src/external/framelesshelper/examples/QQPlayer/resources/qml/ProgressSlider.qml
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Slider {
|
||||
id: control
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
|
||||
property int progressDuration: 200
|
||||
property int heightDuration: 100
|
||||
property int hoveredHeight: 10
|
||||
property int normalHeight: 4
|
||||
property color backgroundColor: "#bdbebf"
|
||||
property color foregroundColor: "#21be2b"
|
||||
property color handleColor: "#f0f0f0"
|
||||
property int handleWidth: 14
|
||||
property int handleBorderWidth: 0
|
||||
property color handleBorderColor: "transparent"
|
||||
property bool handleVisibility: true
|
||||
|
||||
background: Rectangle {
|
||||
x: 0
|
||||
y: control.availableHeight / 2 - height / 2
|
||||
implicitWidth: 200
|
||||
implicitHeight: control.hovered ? control.hoveredHeight : control.normalHeight
|
||||
width: control.availableWidth
|
||||
height: implicitHeight
|
||||
color: control.backgroundColor
|
||||
|
||||
Behavior on implicitHeight {
|
||||
NumberAnimation {
|
||||
duration: control.heightDuration
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: control.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: control.foregroundColor
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: control.progressDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
visible: control.handleVisibility
|
||||
x: control.visualPosition * (control.availableWidth - width)
|
||||
y: control.availableHeight / 2 - height / 2
|
||||
implicitWidth: control.handleWidth
|
||||
implicitHeight: implicitWidth
|
||||
radius: implicitHeight / 2
|
||||
color: control.handleColor
|
||||
border.width: control.handleBorderWidth
|
||||
border.color: control.handleBorderColor
|
||||
|
||||
Behavior on x {
|
||||
NumberAnimation {
|
||||
duration: control.progressDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
src/external/framelesshelper/examples/QQPlayer/resources/qml/StopButton.qml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 14
|
||||
implicitHeight: 14
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: control.down
|
||||
|| control.hovered ? "qrc:/images/stop_blue_light.png" : "qrc:/images/stop_blue.png"
|
||||
}
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
41
src/external/framelesshelper/examples/QQPlayer/resources/qml/VolumeButton.qml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: 18
|
||||
implicitHeight: 14
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: control
|
||||
source: control.down
|
||||
|| control.hovered ? "qrc:/images/volume_blue_light.png" : "qrc:/images/volume_blue.png"
|
||||
}
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
170
src/external/framelesshelper/examples/QQPlayer/resources/qml/main.qml
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import wangwenx190.Utils 1.0
|
||||
|
||||
Window {
|
||||
id: window
|
||||
visible: true
|
||||
width: 800
|
||||
height: 540
|
||||
title: qsTr("QQ Player")
|
||||
|
||||
property color themeColor: "#111111"
|
||||
|
||||
FramelessHelper {
|
||||
id: framelessHelper
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: titleBar
|
||||
height: framelessHelper.titleBarHeight
|
||||
color: window.themeColor
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
MainMenuButton {
|
||||
id: mainMenuButton
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
mainMenuButton)
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
|
||||
MinimizeButton {
|
||||
id: minimizeButton
|
||||
onClicked: window.showMinimized()
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
minimizeButton)
|
||||
}
|
||||
|
||||
MaximizeButton {
|
||||
id: maximizeButton
|
||||
maximized: window.visibility === Window.Maximized
|
||||
onClicked: {
|
||||
if (maximized) {
|
||||
window.showNormal()
|
||||
} else {
|
||||
window.showMaximized()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
maximizeButton)
|
||||
}
|
||||
|
||||
CloseButton {
|
||||
id: closeButton
|
||||
onClicked: window.close()
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
closeButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: backgroundImage
|
||||
anchors.top: titleBar.bottom
|
||||
anchors.bottom: controlPanel.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
source: "qrc:/images/background.png"
|
||||
|
||||
Image {
|
||||
id: logoImage
|
||||
width: 123
|
||||
height: 99
|
||||
anchors.centerIn: parent
|
||||
source: "qrc:/images/logo.png"
|
||||
}
|
||||
|
||||
OpenFileButton {
|
||||
id: openFileButton
|
||||
anchors.top: logoImage.bottom
|
||||
anchors.topMargin: 25
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: controlPanel
|
||||
height: 63
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
color: window.themeColor
|
||||
|
||||
ProgressSlider {
|
||||
id: progressSlider
|
||||
anchors.bottom: parent.top
|
||||
anchors.bottomMargin: -2
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
foregroundColor: "#1ab7e4"
|
||||
handleColor: "#923cf2"
|
||||
}
|
||||
|
||||
StopButton {
|
||||
id: stopButton
|
||||
anchors.right: previousButton.left
|
||||
anchors.rightMargin: 30
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
PreviousButton {
|
||||
id: previousButton
|
||||
anchors.right: playButton.left
|
||||
anchors.rightMargin: 30
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
PlayButton {
|
||||
id: playButton
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
NextButton {
|
||||
id: nextButton
|
||||
anchors.left: playButton.right
|
||||
anchors.leftMargin: 30
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
VolumeButton {
|
||||
id: volumeButton
|
||||
anchors.left: nextButton.right
|
||||
anchors.leftMargin: 30
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: framelessHelper.removeWindowFrame()
|
||||
}
|
||||
5
src/external/framelesshelper/examples/QWidget/QWidget.pro
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
TARGET = QWidget
|
||||
TEMPLATE = app
|
||||
QT += widgets
|
||||
SOURCES += main.cpp
|
||||
include($$PWD/../common.pri)
|
||||
110
src/external/framelesshelper/examples/QWidget/main.cpp
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 "../../framelesswindowsmanager.h"
|
||||
#include <QApplication>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
// High DPI scaling is enabled by default from Qt 6
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
// Windows: we are using the manifest file to get maximum compatibility
|
||||
// because some APIs are not supprted on old systems such as Windows 7
|
||||
// and Windows 8. And once we have set the DPI awareness level in the
|
||||
// manifest file, any attemptation to try to change it through API will
|
||||
// fail. In other words, Qt won't be able to enable or disable high DPI
|
||||
// scaling or change the DPI awareness level once we have set it in the
|
||||
// manifest file. So the following two lines are uesless actually (However,
|
||||
// they are still useful on other platforms).
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
// Don't round the scale factor.
|
||||
// This will break QWidget applications because they can't render correctly.
|
||||
// Qt Quick applications won't have this issue.
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QApplication application(argc, argv);
|
||||
|
||||
QWidget widget;
|
||||
widget.setContentsMargins(2, 2, 2, 2);
|
||||
QLabel *label = new QLabel;
|
||||
QObject::connect(&widget, &QWidget::windowTitleChanged, label, &QLabel::setText);
|
||||
QPushButton *minimizeButton = new QPushButton;
|
||||
minimizeButton->setText(QObject::tr("Minimize"));
|
||||
QObject::connect(minimizeButton, &QPushButton::clicked, &widget, &QWidget::showMinimized);
|
||||
QPushButton *maximizeButton = new QPushButton;
|
||||
maximizeButton->setText(QObject::tr("Maximize"));
|
||||
QObject::connect(maximizeButton, &QPushButton::clicked, [&widget, &maximizeButton]() {
|
||||
if (widget.isMaximized()) {
|
||||
widget.showNormal();
|
||||
maximizeButton->setText(QObject::tr("Maximize"));
|
||||
} else {
|
||||
widget.showMaximized();
|
||||
maximizeButton->setText(QObject::tr("Restore"));
|
||||
}
|
||||
});
|
||||
QPushButton *closeButton = new QPushButton;
|
||||
closeButton->setText(QObject::tr("Close"));
|
||||
QObject::connect(closeButton, &QPushButton::clicked, &widget, &QWidget::close);
|
||||
QHBoxLayout *tbLayout = new QHBoxLayout;
|
||||
tbLayout->setContentsMargins(0, 0, 0, 0);
|
||||
tbLayout->setSpacing(0);
|
||||
tbLayout->addSpacing(15);
|
||||
tbLayout->addWidget(label);
|
||||
tbLayout->addStretch();
|
||||
tbLayout->addWidget(minimizeButton);
|
||||
tbLayout->addWidget(maximizeButton);
|
||||
tbLayout->addWidget(closeButton);
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
mainLayout->addLayout(tbLayout);
|
||||
mainLayout->addStretch();
|
||||
widget.setLayout(mainLayout);
|
||||
widget.setWindowTitle(QObject::tr("Hello, World!"));
|
||||
|
||||
FramelessWindowsManager::addWindow(&widget);
|
||||
|
||||
FramelessWindowsManager::addIgnoreObject(&widget, minimizeButton);
|
||||
FramelessWindowsManager::addIgnoreObject(&widget, maximizeButton);
|
||||
FramelessWindowsManager::addIgnoreObject(&widget, closeButton);
|
||||
|
||||
widget.resize(800, 600);
|
||||
|
||||
FramelessWindowsManager::moveWindowToDesktopCenter(&widget);
|
||||
|
||||
widget.show();
|
||||
|
||||
return QApplication::exec();
|
||||
}
|
||||
6
src/external/framelesshelper/examples/Quick/Quick.pro
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
TARGET = Quick
|
||||
TEMPLATE = app
|
||||
QT += quick
|
||||
SOURCES += main.cpp
|
||||
RESOURCES += qml.qrc
|
||||
include($$PWD/../common.pri)
|
||||
77
src/external/framelesshelper/examples/Quick/main.cpp
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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"
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
// High DPI scaling is enabled by default from Qt 6
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
// Windows: we are using the manifest file to get maximum compatibility
|
||||
// because some APIs are not supprted on old systems such as Windows 7
|
||||
// and Windows 8. And once we have set the DPI awareness level in the
|
||||
// manifest file, any attemptation to try to change it through API will
|
||||
// fail. In other words, Qt won't be able to enable or disable high DPI
|
||||
// scaling or change the DPI awareness level once we have set it in the
|
||||
// manifest file. So the following two lines are uesless actually (However,
|
||||
// they are still useful on other platforms).
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
// Don't round the scale factor.
|
||||
// This will break QWidget applications because they can't render correctly.
|
||||
// Qt Quick applications won't have this issue.
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QGuiApplication application(argc, argv);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
qmlRegisterType<FramelessQuickHelper>("wangwenx190.Utils", 1, 0, "FramelessHelper");
|
||||
const QUrl mainQmlUrl(QString::fromUtf8("qrc:///qml/main.qml"));
|
||||
const QMetaObject::Connection connection = QObject::connect(
|
||||
&engine,
|
||||
&QQmlApplicationEngine::objectCreated,
|
||||
&application,
|
||||
[&mainQmlUrl, &connection](QObject *object, const QUrl &url) {
|
||||
if (url != mainQmlUrl) {
|
||||
return;
|
||||
}
|
||||
if (!object) {
|
||||
QGuiApplication::exit(-1);
|
||||
} else {
|
||||
QObject::disconnect(connection);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
engine.load(mainQmlUrl);
|
||||
|
||||
return QGuiApplication::exec();
|
||||
}
|
||||
9
src/external/framelesshelper/examples/Quick/qml.qrc
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file alias="qml/+windows/main.qml">qml/main_windows.qml</file>
|
||||
<file alias="qml/+unix/main.qml">qml/main_unix.qml</file>
|
||||
<file>qml/MinimizeButton.qml</file>
|
||||
<file>qml/MaximizeButton.qml</file>
|
||||
<file>qml/CloseButton.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
48
src/external/framelesshelper/examples/Quick/qml/CloseButton.qml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: button
|
||||
|
||||
implicitWidth: 45
|
||||
implicitHeight: 30
|
||||
|
||||
ToolTip.visible: hovered && !down
|
||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
ToolTip.text: qsTr("Close")
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: parent
|
||||
source: button.down
|
||||
|| button.hovered ? "qrc:/images/button_close_white.svg" : "qrc:/images/button_close_black.svg"
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
visible: button.down || button.hovered
|
||||
color: button.down ? "#8c0a15" : (button.hovered ? "#e81123" : "transparent")
|
||||
}
|
||||
}
|
||||
49
src/external/framelesshelper/examples/Quick/qml/MaximizeButton.qml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: button
|
||||
|
||||
implicitWidth: 45
|
||||
implicitHeight: 30
|
||||
|
||||
property bool maximized: false
|
||||
|
||||
ToolTip.visible: hovered && !down
|
||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
ToolTip.text: maximized ? qsTr("Restore") : qsTr("Maximize")
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: parent
|
||||
source: maximized ? "qrc:/images/button_restore_black.svg" : "qrc:/images/button_maximize_black.svg"
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
visible: button.down || button.hovered
|
||||
color: button.down ? "#808080" : (button.hovered ? "#c7c7c7" : "transparent")
|
||||
}
|
||||
}
|
||||
47
src/external/framelesshelper/examples/Quick/qml/MinimizeButton.qml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: button
|
||||
|
||||
implicitWidth: 45
|
||||
implicitHeight: 30
|
||||
|
||||
ToolTip.visible: hovered && !down
|
||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
ToolTip.text: qsTr("Minimize")
|
||||
|
||||
contentItem: Image {
|
||||
anchors.fill: parent
|
||||
source: "qrc:/images/button_minimize_black.svg"
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
visible: button.down || button.hovered
|
||||
color: button.down ? "#808080" : (button.hovered ? "#c7c7c7" : "transparent")
|
||||
}
|
||||
}
|
||||
106
src/external/framelesshelper/examples/Quick/qml/main_unix.qml
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import wangwenx190.Utils 1.0
|
||||
|
||||
Window {
|
||||
id: window
|
||||
visible: true
|
||||
width: 800
|
||||
height: 600
|
||||
title: qsTr("Hello, World!")
|
||||
|
||||
FramelessHelper {
|
||||
id: framelessHelper
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: titleBar
|
||||
height: framelessHelper.titleBarHeight
|
||||
color: "white"
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
Text {
|
||||
id: titleBarText
|
||||
text: window.title
|
||||
font.pointSize: 13
|
||||
color: window.active ? "black" : "gray"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
|
||||
MinimizeButton {
|
||||
id: minimizeButton
|
||||
onClicked: window.showMinimized()
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
minimizeButton)
|
||||
}
|
||||
|
||||
MaximizeButton {
|
||||
id: maximizeButton
|
||||
maximized: window.visibility === Window.Maximized
|
||||
onClicked: {
|
||||
if (maximized) {
|
||||
window.showNormal()
|
||||
} else {
|
||||
window.showMaximized()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
maximizeButton)
|
||||
}
|
||||
|
||||
CloseButton {
|
||||
id: closeButton
|
||||
onClicked: window.close()
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
closeButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: content
|
||||
color: "#f0f0f0"
|
||||
anchors {
|
||||
top: titleBar.bottom
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: framelessHelper.removeWindowFrame(true)
|
||||
}
|
||||
177
src/external/framelesshelper/examples/Quick/qml/main_windows.qml
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import wangwenx190.Utils 1.0
|
||||
|
||||
Window {
|
||||
id: window
|
||||
visible: true
|
||||
width: 800
|
||||
height: 600
|
||||
title: qsTr("Hello, World!")
|
||||
color: blurEffectCheckBox.checked ? "transparent" : "#f0f0f0"
|
||||
|
||||
FramelessHelper {
|
||||
id: framelessHelper
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: titleBar
|
||||
height: framelessHelper.titleBarHeight
|
||||
color: extendToTitleBarCheckBox.checked ? "transparent" : ((window.active && framelessHelper.colorizationEnabled) ? framelessHelper.colorizationColor : "white")
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
Label {
|
||||
id: titleBarText
|
||||
text: window.title
|
||||
font.pointSize: 13
|
||||
color: window.active ? (framelessHelper.colorizationEnabled ? "white" : "black") : "gray"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
|
||||
MinimizeButton {
|
||||
id: minimizeButton
|
||||
onClicked: window.showMinimized()
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
minimizeButton)
|
||||
}
|
||||
|
||||
MaximizeButton {
|
||||
id: maximizeButton
|
||||
maximized: window.visibility === Window.Maximized
|
||||
onClicked: {
|
||||
if (maximized) {
|
||||
window.showNormal()
|
||||
} else {
|
||||
window.showMaximized()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
maximizeButton)
|
||||
}
|
||||
|
||||
CloseButton {
|
||||
id: closeButton
|
||||
onClicked: window.close()
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
closeButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: content
|
||||
color: "transparent"
|
||||
anchors {
|
||||
top: titleBar.bottom
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 25
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
font.pointSize: 15
|
||||
font.bold: true
|
||||
text: qsTr("Current system theme: %1").arg(framelessHelper.darkThemeEnabled ? "dark theme" : "light theme")
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
font.pointSize: 15
|
||||
font.bold: true
|
||||
text: qsTr("Transparency effect: %1").arg(framelessHelper.transparencyEffectEnabled ? "enabled" : "disabled")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: blurEffectCheckBox
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
font.pointSize: 15
|
||||
font.bold: true
|
||||
text: qsTr("Enable blur effect")
|
||||
onCheckedChanged: framelessHelper.setBlurEffectEnabled(checked, forceAcrylicCheckBox.checked)
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: forceAcrylicCheckBox
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
font.pointSize: 15
|
||||
font.bold: true
|
||||
text: qsTr("Force enabling Acrylic effect")
|
||||
enabled: framelessHelper.canHaveWindowFrame
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: extendToTitleBarCheckBox
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
font.pointSize: 15
|
||||
font.bold: true
|
||||
text: qsTr("Extend to title bar")
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
text: qsTr("Move to desktop center")
|
||||
font.pointSize: 15
|
||||
font.bold: true
|
||||
onClicked: framelessHelper.moveWindowToDesktopCenter(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: topFrame
|
||||
visible: framelessHelper.canHaveWindowFrame && (window.visibility === Window.Windowed)
|
||||
color: window.active ? (framelessHelper.colorizationEnabled ? framelessHelper.colorizationColor : "#707070") : "#aaaaaa"
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: 1
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
framelessHelper.setWindowFrameVisible(framelessHelper.canHaveWindowFrame)
|
||||
framelessHelper.removeWindowFrame(true)
|
||||
}
|
||||
}
|
||||
6
src/external/framelesshelper/examples/Win32Demo/Win32Demo.pro
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
TARGET = Win32Demo
|
||||
TEMPLATE = app
|
||||
QT += widgets
|
||||
HEADERS += widget.h
|
||||
SOURCES += widget.cpp main.cpp
|
||||
include($$PWD/../common.pri)
|
||||
67
src/external/framelesshelper/examples/Win32Demo/main.cpp
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 "widget.h"
|
||||
#include <QApplication>
|
||||
#include <QStyleOption>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
// High DPI scaling is enabled by default from Qt 6
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
// Windows: we are using the manifest file to get maximum compatibility
|
||||
// because some APIs are not supprted on old systems such as Windows 7
|
||||
// and Windows 8. And once we have set the DPI awareness level in the
|
||||
// manifest file, any attemptation to try to change it through API will
|
||||
// fail. In other words, Qt won't be able to enable or disable high DPI
|
||||
// scaling or change the DPI awareness level once we have set it in the
|
||||
// manifest file. So the following two lines are uesless actually (However,
|
||||
// they are still useful on other platforms).
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
// Don't round the scale factor.
|
||||
// This will break QWidget applications because they can't render correctly.
|
||||
// Qt Quick applications won't have this issue.
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QApplication application(argc, argv);
|
||||
|
||||
QApplication::setFont({QLatin1String("Microsoft YaHei")});
|
||||
|
||||
Widget widget;
|
||||
|
||||
QStyleOption option;
|
||||
option.initFrom(&widget);
|
||||
widget.setWindowIcon(widget.style()->standardIcon(QStyle::SP_ComputerIcon, &option));
|
||||
widget.setWindowTitle(QObject::tr("Hello, World!"));
|
||||
|
||||
widget.show();
|
||||
|
||||
return QApplication::exec();
|
||||
}
|
||||
641
src/external/framelesshelper/examples/Win32Demo/widget.cpp
vendored
Normal file
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* 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 "widget.h"
|
||||
#include "../../winnativeeventfilter.h"
|
||||
#include <QCheckBox>
|
||||
#include <QColorDialog>
|
||||
#include <QEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QOperatingSystemVersion>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QSpacerItem>
|
||||
#include <QVBoxLayout>
|
||||
#include <qt_windows.h>
|
||||
|
||||
// Some old SDK doesn't have this value.
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0
|
||||
#endif
|
||||
|
||||
// Copied from windowsx.h
|
||||
#define GET_X_LPARAM(lp) ((int) (short) LOWORD(lp))
|
||||
#define GET_Y_LPARAM(lp) ((int) (short) HIWORD(lp))
|
||||
|
||||
namespace {
|
||||
|
||||
const Widget::Win10Version g_vAcrylicEffectVersion = Widget::Win10Version::Win10_1803;
|
||||
|
||||
const QColor g_cDefaultActiveBorderColor = {"#707070"};
|
||||
const QColor g_cDefaultInactiveBorderColor = {"#aaaaaa"};
|
||||
QColor g_cColorizationColor = Qt::white;
|
||||
|
||||
const char g_sUseNativeTitleBar[] = "WNEF_USE_NATIVE_TITLE_BAR";
|
||||
const char g_sPreserveWindowFrame[] = "WNEF_FORCE_PRESERVE_WINDOW_FRAME";
|
||||
const char g_sForceUseAcrylicEffect[] = "WNEF_FORCE_ACRYLIC_ON_WIN10";
|
||||
const char g_sDontExtendFrame[] = "WNEF_DO_NOT_EXTEND_FRAME";
|
||||
|
||||
const QLatin1String g_sSystemButtonsStyleSheet(R"(
|
||||
#iconButton, #minimizeButton, #maximizeButton, #closeButton {
|
||||
background-color: transparent;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
#minimizeButton:hover, #maximizeButton:hover {
|
||||
border-style: none;
|
||||
background-color: #80c7c7c7;
|
||||
}
|
||||
|
||||
#minimizeButton:pressed, #maximizeButton:pressed {
|
||||
border-style: none;
|
||||
background-color: #80808080;
|
||||
}
|
||||
|
||||
#closeButton:hover {
|
||||
border-style: none;
|
||||
background-color: #e81123;
|
||||
}
|
||||
|
||||
#closeButton:pressed {
|
||||
border-style: none;
|
||||
background-color: #8c0a15;
|
||||
}
|
||||
)");
|
||||
const
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
QString
|
||||
#else
|
||||
QLatin1String
|
||||
#endif
|
||||
g_sTitleLabelStyleSheet(
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
QString::fromLatin1(
|
||||
#endif
|
||||
R"(
|
||||
#titleLabel {
|
||||
color: rgb(%1, %2, %3);
|
||||
}
|
||||
)"
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
)
|
||||
#endif
|
||||
);
|
||||
const
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
QString
|
||||
#else
|
||||
QLatin1String
|
||||
#endif
|
||||
g_sTitleBarStyleSheet(
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
QString::fromLatin1(
|
||||
#endif
|
||||
R"(
|
||||
#titleBarWidget {
|
||||
background-color: rgba(%1, %2, %3, %4);
|
||||
border-top: 1px solid rgba(%5, %6, %7, %8);
|
||||
}
|
||||
)"
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
)
|
||||
#endif
|
||||
);
|
||||
|
||||
const QLatin1String g_sMinimizeButtonImageDark(":/images/button_minimize_black.svg");
|
||||
const QLatin1String g_sMaximizeButtonImageDark(":/images/button_maximize_black.svg");
|
||||
const QLatin1String g_sRestoreButtonImageDark(":/images/button_restore_black.svg");
|
||||
const QLatin1String g_sCloseButtonImageDark(":/images/button_close_black.svg");
|
||||
const QLatin1String g_sMinimizeButtonImageLight(":/images/button_minimize_white.svg");
|
||||
const QLatin1String g_sMaximizeButtonImageLight(":/images/button_maximize_white.svg");
|
||||
const QLatin1String g_sRestoreButtonImageLight(":/images/button_restore_white.svg");
|
||||
const QLatin1String g_sCloseButtonImageLight(":/images/button_close_white.svg");
|
||||
|
||||
} // namespace
|
||||
|
||||
Widget::Widget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
initializeWindow();
|
||||
}
|
||||
|
||||
void Widget::retranslateUi()
|
||||
{
|
||||
setWindowTitle(tr("Widget"));
|
||||
iconButton->setText({});
|
||||
titleLabel->setText({});
|
||||
minimizeButton->setText({});
|
||||
maximizeButton->setText({});
|
||||
closeButton->setText({});
|
||||
customizeTitleBarCB->setText(tr("Enable customized title bar"));
|
||||
preserveWindowFrameCB->setText(tr("Preserve window frame"));
|
||||
blurEffectCB->setText(tr("Enable blur effect"));
|
||||
extendToTitleBarCB->setText(tr("Extend to title bar"));
|
||||
forceAcrylicCB->setText(tr("Force enabling Acrylic effect"));
|
||||
resizableCB->setText(tr("Resizable"));
|
||||
moveCenterButton->setText(tr("Move to desktop center"));
|
||||
}
|
||||
|
||||
void Widget::setupUi()
|
||||
{
|
||||
resize(1056, 600);
|
||||
verticalLayout_3 = new QVBoxLayout(this);
|
||||
titleBarWidget = new QWidget(this);
|
||||
titleBarWidget->setObjectName(QLatin1String("titleBarWidget"));
|
||||
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
sizePolicy.setHeightForWidth(titleBarWidget->sizePolicy().hasHeightForWidth());
|
||||
titleBarWidget->setSizePolicy(sizePolicy);
|
||||
const int titleBarHeight
|
||||
= WinNativeEventFilter::getSystemMetric(rawHandle(),
|
||||
WinNativeEventFilter::SystemMetric::TitleBarHeight);
|
||||
titleBarWidget->setMinimumSize(QSize(0, titleBarHeight));
|
||||
titleBarWidget->setMaximumSize(QSize(16777215, titleBarHeight));
|
||||
horizontalLayout = new QHBoxLayout(titleBarWidget);
|
||||
horizontalLayout->setSpacing(0);
|
||||
horizontalLayout->setContentsMargins(0, 0, 0, 0);
|
||||
horizontalSpacer_7 = new QSpacerItem(3, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
|
||||
horizontalLayout->addItem(horizontalSpacer_7);
|
||||
iconButton = new QPushButton(titleBarWidget);
|
||||
iconButton->setObjectName(QLatin1String("iconButton"));
|
||||
horizontalLayout->addWidget(iconButton);
|
||||
horizontalSpacer = new QSpacerItem(3, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
|
||||
horizontalLayout->addItem(horizontalSpacer);
|
||||
titleLabel = new QLabel(titleBarWidget);
|
||||
titleLabel->setObjectName(QLatin1String("titleLabel"));
|
||||
QFont font;
|
||||
font.setPointSize(10);
|
||||
titleLabel->setFont(font);
|
||||
horizontalLayout->addWidget(titleLabel);
|
||||
horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
horizontalLayout->addItem(horizontalSpacer_2);
|
||||
minimizeButton = new QPushButton(titleBarWidget);
|
||||
minimizeButton->setObjectName(QLatin1String("minimizeButton"));
|
||||
QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
sizePolicy1.setHorizontalStretch(0);
|
||||
sizePolicy1.setVerticalStretch(0);
|
||||
sizePolicy1.setHeightForWidth(minimizeButton->sizePolicy().hasHeightForWidth());
|
||||
minimizeButton->setSizePolicy(sizePolicy1);
|
||||
const QSize systemButtonSize = {45, 30};
|
||||
minimizeButton->setMinimumSize(systemButtonSize);
|
||||
minimizeButton->setMaximumSize(systemButtonSize);
|
||||
QIcon icon;
|
||||
icon.addFile(g_sMinimizeButtonImageDark, {}, QIcon::Normal, QIcon::Off);
|
||||
minimizeButton->setIcon(icon);
|
||||
minimizeButton->setIconSize(systemButtonSize);
|
||||
horizontalLayout->addWidget(minimizeButton);
|
||||
maximizeButton = new QPushButton(titleBarWidget);
|
||||
maximizeButton->setObjectName(QLatin1String("maximizeButton"));
|
||||
sizePolicy1.setHeightForWidth(maximizeButton->sizePolicy().hasHeightForWidth());
|
||||
maximizeButton->setSizePolicy(sizePolicy1);
|
||||
maximizeButton->setMinimumSize(systemButtonSize);
|
||||
maximizeButton->setMaximumSize(systemButtonSize);
|
||||
QIcon icon1;
|
||||
icon1.addFile(g_sMaximizeButtonImageDark, {}, QIcon::Normal, QIcon::Off);
|
||||
maximizeButton->setIcon(icon1);
|
||||
maximizeButton->setIconSize(systemButtonSize);
|
||||
horizontalLayout->addWidget(maximizeButton);
|
||||
closeButton = new QPushButton(titleBarWidget);
|
||||
closeButton->setObjectName(QLatin1String("closeButton"));
|
||||
sizePolicy1.setHeightForWidth(closeButton->sizePolicy().hasHeightForWidth());
|
||||
closeButton->setSizePolicy(sizePolicy1);
|
||||
closeButton->setMinimumSize(systemButtonSize);
|
||||
closeButton->setMaximumSize(systemButtonSize);
|
||||
QIcon icon2;
|
||||
icon2.addFile(g_sCloseButtonImageDark, {}, QIcon::Normal, QIcon::Off);
|
||||
closeButton->setIcon(icon2);
|
||||
closeButton->setIconSize(systemButtonSize);
|
||||
horizontalLayout->addWidget(closeButton);
|
||||
verticalLayout_3->addWidget(titleBarWidget);
|
||||
contentsWidget = new QWidget(this);
|
||||
QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
sizePolicy2.setHorizontalStretch(0);
|
||||
sizePolicy2.setVerticalStretch(0);
|
||||
sizePolicy2.setHeightForWidth(contentsWidget->sizePolicy().hasHeightForWidth());
|
||||
contentsWidget->setSizePolicy(sizePolicy2);
|
||||
verticalLayout_2 = new QVBoxLayout(contentsWidget);
|
||||
verticalSpacer_2 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
verticalLayout_2->addItem(verticalSpacer_2);
|
||||
horizontalLayout_2 = new QHBoxLayout();
|
||||
horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
horizontalLayout_2->addItem(horizontalSpacer_3);
|
||||
controlPanelWidget = new QWidget(contentsWidget);
|
||||
QSizePolicy sizePolicy3(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
sizePolicy3.setHorizontalStretch(0);
|
||||
sizePolicy3.setVerticalStretch(0);
|
||||
sizePolicy3.setHeightForWidth(controlPanelWidget->sizePolicy().hasHeightForWidth());
|
||||
controlPanelWidget->setSizePolicy(sizePolicy3);
|
||||
verticalLayout = new QVBoxLayout(controlPanelWidget);
|
||||
customizeTitleBarCB = new QCheckBox(controlPanelWidget);
|
||||
QFont font1;
|
||||
font1.setPointSize(15);
|
||||
font1.setBold(true);
|
||||
font1.setWeight(75);
|
||||
customizeTitleBarCB->setFont(font1);
|
||||
verticalLayout->addWidget(customizeTitleBarCB);
|
||||
preserveWindowFrameCB = new QCheckBox(controlPanelWidget);
|
||||
preserveWindowFrameCB->setFont(font1);
|
||||
verticalLayout->addWidget(preserveWindowFrameCB);
|
||||
blurEffectCB = new QCheckBox(controlPanelWidget);
|
||||
blurEffectCB->setFont(font1);
|
||||
verticalLayout->addWidget(blurEffectCB);
|
||||
extendToTitleBarCB = new QCheckBox(controlPanelWidget);
|
||||
extendToTitleBarCB->setFont(font1);
|
||||
verticalLayout->addWidget(extendToTitleBarCB);
|
||||
forceAcrylicCB = new QCheckBox(controlPanelWidget);
|
||||
forceAcrylicCB->setFont(font1);
|
||||
forceAcrylicCB->setEnabled(m_bCanAcrylicBeEnabled);
|
||||
verticalLayout->addWidget(forceAcrylicCB);
|
||||
resizableCB = new QCheckBox(controlPanelWidget);
|
||||
resizableCB->setFont(font1);
|
||||
verticalLayout->addWidget(resizableCB);
|
||||
horizontalLayout_2->addWidget(controlPanelWidget);
|
||||
horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
horizontalLayout_2->addItem(horizontalSpacer_4);
|
||||
verticalLayout_2->addLayout(horizontalLayout_2);
|
||||
verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
verticalLayout_2->addItem(verticalSpacer);
|
||||
horizontalLayout_3 = new QHBoxLayout();
|
||||
horizontalSpacer_5 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
horizontalLayout_3->addItem(horizontalSpacer_5);
|
||||
moveCenterButton = new QPushButton(contentsWidget);
|
||||
moveCenterButton->setFont(font1);
|
||||
horizontalLayout_3->addWidget(moveCenterButton);
|
||||
horizontalSpacer_6 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
horizontalLayout_3->addItem(horizontalSpacer_6);
|
||||
verticalLayout_2->addLayout(horizontalLayout_3);
|
||||
verticalLayout_3->addWidget(contentsWidget);
|
||||
if (shouldDrawBorder()) {
|
||||
layout()->setContentsMargins(1, 1, 1, 1);
|
||||
} else {
|
||||
layout()->setContentsMargins(0, 0, 0, 0);
|
||||
}
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
bool Widget::isNormaled() const
|
||||
{
|
||||
return !isMinimized() && !isMaximized() && !isFullScreen();
|
||||
}
|
||||
|
||||
bool Widget::shouldDrawBorder(const bool ignoreWindowState) const
|
||||
{
|
||||
return m_bIsWin10OrGreater && (ignoreWindowState ? true : isNormaled())
|
||||
&& !preserveWindowFrameCB->isChecked() && customizeTitleBarCB->isChecked();
|
||||
}
|
||||
|
||||
bool Widget::shouldDrawThemedBorder(const bool ignoreWindowState) const
|
||||
{
|
||||
return (shouldDrawBorder(ignoreWindowState) && WinNativeEventFilter::colorizationEnabled());
|
||||
}
|
||||
|
||||
bool Widget::shouldDrawThemedTitleBar() const
|
||||
{
|
||||
return m_bIsWin10OrGreater && WinNativeEventFilter::colorizationEnabled();
|
||||
}
|
||||
|
||||
QColor Widget::activeBorderColor()
|
||||
{
|
||||
return WinNativeEventFilter::colorizationEnabled() ? g_cColorizationColor
|
||||
: g_cDefaultActiveBorderColor;
|
||||
}
|
||||
|
||||
QColor Widget::inactiveBorderColor()
|
||||
{
|
||||
return g_cDefaultInactiveBorderColor;
|
||||
}
|
||||
|
||||
QColor Widget::borderColor() const
|
||||
{
|
||||
return isActiveWindow() ? activeBorderColor() : inactiveBorderColor();
|
||||
}
|
||||
|
||||
bool Widget::isWin10OrGreater(const Win10Version subVer)
|
||||
{
|
||||
return (QOperatingSystemVersion::current()
|
||||
>= ((subVer == Win10Version::Windows10)
|
||||
? QOperatingSystemVersion::Windows10
|
||||
: QOperatingSystemVersion(QOperatingSystemVersion::Windows,
|
||||
10,
|
||||
0,
|
||||
static_cast<int>(subVer))));
|
||||
}
|
||||
|
||||
void *Widget::rawHandle() const
|
||||
{
|
||||
return reinterpret_cast<void *>(winId());
|
||||
}
|
||||
|
||||
bool Widget::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
Q_ASSERT(object);
|
||||
Q_ASSERT(event);
|
||||
if (object == this) {
|
||||
switch (event->type()) {
|
||||
case QEvent::WindowStateChange: {
|
||||
if (shouldDrawBorder(true)) {
|
||||
if (isMaximized()) {
|
||||
layout()->setContentsMargins(0, 0, 0, 0);
|
||||
}
|
||||
if (isNormaled()) {
|
||||
layout()->setContentsMargins(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
updateTitleBar();
|
||||
moveCenterButton->setEnabled(isNormaled());
|
||||
break;
|
||||
}
|
||||
case QEvent::WinIdChange:
|
||||
WinNativeEventFilter::addFramelessWindow(this);
|
||||
break;
|
||||
case QEvent::WindowActivate:
|
||||
case QEvent::WindowDeactivate:
|
||||
updateTitleBar();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
bool Widget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
#else
|
||||
bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
{
|
||||
Q_ASSERT(eventType == "windows_generic_MSG");
|
||||
Q_ASSERT(message);
|
||||
Q_ASSERT(result);
|
||||
if (customizeTitleBarCB && customizeTitleBarCB->isChecked()) {
|
||||
const auto msg = static_cast<LPMSG>(message);
|
||||
switch (msg->message) {
|
||||
case WM_NCRBUTTONUP: {
|
||||
if (msg->wParam == HTCAPTION) {
|
||||
const int x = GET_X_LPARAM(msg->lParam);
|
||||
const int y = GET_Y_LPARAM(msg->lParam);
|
||||
if (WinNativeEventFilter::displaySystemMenu(msg->hwnd, false, x, y)) {
|
||||
*result = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_DWMCOLORIZATIONCOLORCHANGED: {
|
||||
g_cColorizationColor = QColor::fromRgba(msg->wParam);
|
||||
if (shouldDrawThemedBorder()) {
|
||||
updateWindow();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_DPICHANGED:
|
||||
updateWindow();
|
||||
break;
|
||||
case WM_NCPAINT:
|
||||
update();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QWidget::nativeEvent(eventType, message, result);
|
||||
}
|
||||
|
||||
void Widget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QWidget::paintEvent(event);
|
||||
if (shouldDrawBorder()) {
|
||||
QPainter painter(this);
|
||||
painter.save();
|
||||
painter.setPen({borderColor(), 2.0});
|
||||
painter.drawLine(0, 0, width(), 0);
|
||||
painter.drawLine(0, height(), width(), height());
|
||||
painter.drawLine(0, 0, 0, height());
|
||||
painter.drawLine(width(), 0, width(), height());
|
||||
painter.restore();
|
||||
}
|
||||
}
|
||||
|
||||
void Widget::updateWindow()
|
||||
{
|
||||
WinNativeEventFilter::updateFrameMargins(rawHandle());
|
||||
WinNativeEventFilter::updateWindow(rawHandle(), true, true);
|
||||
update();
|
||||
}
|
||||
|
||||
void Widget::updateTitleBar()
|
||||
{
|
||||
const bool themedTitleBar = shouldDrawThemedTitleBar() && isActiveWindow();
|
||||
if (themedTitleBar && !m_bExtendToTitleBar) {
|
||||
minimizeButton->setIcon(QIcon(g_sMinimizeButtonImageLight));
|
||||
closeButton->setIcon(QIcon(g_sCloseButtonImageLight));
|
||||
if (isMaximized()) {
|
||||
maximizeButton->setIcon(QIcon(g_sRestoreButtonImageLight));
|
||||
}
|
||||
if (isNormaled()) {
|
||||
maximizeButton->setIcon(QIcon(g_sMaximizeButtonImageLight));
|
||||
}
|
||||
} else {
|
||||
minimizeButton->setIcon(QIcon(g_sMinimizeButtonImageDark));
|
||||
closeButton->setIcon(QIcon(g_sCloseButtonImageDark));
|
||||
if (isMaximized()) {
|
||||
maximizeButton->setIcon(QIcon(g_sRestoreButtonImageDark));
|
||||
}
|
||||
if (isNormaled()) {
|
||||
maximizeButton->setIcon(QIcon(g_sMaximizeButtonImageDark));
|
||||
}
|
||||
}
|
||||
const QColor titleBarBackgroundColor = m_bExtendToTitleBar
|
||||
? Qt::transparent
|
||||
: (themedTitleBar ? g_cColorizationColor : Qt::white);
|
||||
const QColor titleBarTextColor = isActiveWindow()
|
||||
? ((!themedTitleBar || m_bExtendToTitleBar) ? Qt::black
|
||||
: Qt::white)
|
||||
: QColor("#999999");
|
||||
const QColor titleBarBorderColor = (!m_bIsWin10OrGreater || shouldDrawBorder() || isMaximized()
|
||||
|| isFullScreen())
|
||||
? Qt::transparent
|
||||
: borderColor();
|
||||
titleBarWidget->setStyleSheet(
|
||||
g_sSystemButtonsStyleSheet
|
||||
+ g_sTitleLabelStyleSheet.arg(QString::number(titleBarTextColor.red()),
|
||||
QString::number(titleBarTextColor.green()),
|
||||
QString::number(titleBarTextColor.blue()))
|
||||
+ g_sTitleBarStyleSheet.arg(QString::number(titleBarBackgroundColor.red()),
|
||||
QString::number(titleBarBackgroundColor.green()),
|
||||
QString::number(titleBarBackgroundColor.blue()),
|
||||
QString::number(titleBarBackgroundColor.alpha()),
|
||||
QString::number(titleBarBorderColor.red()),
|
||||
QString::number(titleBarBorderColor.green()),
|
||||
QString::number(titleBarBorderColor.blue()),
|
||||
QString::number(titleBarBorderColor.alpha())));
|
||||
}
|
||||
|
||||
void Widget::initializeOptions()
|
||||
{
|
||||
if (m_bIsWin10OrGreater) {
|
||||
//preserveWindowFrameCB->click();
|
||||
if (m_bCanAcrylicBeEnabled) {
|
||||
forceAcrylicCB->click();
|
||||
}
|
||||
}
|
||||
customizeTitleBarCB->click();
|
||||
extendToTitleBarCB->click();
|
||||
blurEffectCB->click();
|
||||
resizableCB->click();
|
||||
m_bCanShowColorDialog = true;
|
||||
}
|
||||
|
||||
void Widget::setupConnections()
|
||||
{
|
||||
connect(iconButton, &QPushButton::clicked, this, [this]() {
|
||||
POINT pos = {};
|
||||
GetCursorPos(&pos);
|
||||
const auto hwnd = reinterpret_cast<HWND>(rawHandle());
|
||||
SendMessageW(hwnd, WM_CONTEXTMENU, reinterpret_cast<WPARAM>(hwnd), MAKELPARAM(pos.x, pos.y));
|
||||
});
|
||||
connect(minimizeButton, &QPushButton::clicked, this, &Widget::showMinimized);
|
||||
connect(maximizeButton, &QPushButton::clicked, this, [this]() {
|
||||
if (isMaximized()) {
|
||||
showNormal();
|
||||
} else {
|
||||
showMaximized();
|
||||
}
|
||||
});
|
||||
connect(closeButton, &QPushButton::clicked, this, &Widget::close);
|
||||
connect(moveCenterButton, &QPushButton::clicked, this, [this]() {
|
||||
WinNativeEventFilter::moveWindowToDesktopCenter(rawHandle());
|
||||
});
|
||||
connect(this, &Widget::windowTitleChanged, titleLabel, &QLabel::setText);
|
||||
connect(this, &Widget::windowIconChanged, iconButton, &QPushButton::setIcon);
|
||||
connect(customizeTitleBarCB, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
const bool enable = state == Qt::Checked;
|
||||
preserveWindowFrameCB->setEnabled(enable);
|
||||
WinNativeEventFilter::updateQtFrame(windowHandle(),
|
||||
enable ? WinNativeEventFilter::getSystemMetric(
|
||||
rawHandle(),
|
||||
WinNativeEventFilter::SystemMetric::TitleBarHeight)
|
||||
: 0);
|
||||
titleBarWidget->setVisible(enable);
|
||||
if (enable) {
|
||||
qunsetenv(g_sUseNativeTitleBar);
|
||||
} else {
|
||||
qputenv(g_sUseNativeTitleBar, "1");
|
||||
}
|
||||
updateWindow();
|
||||
});
|
||||
connect(preserveWindowFrameCB, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
const bool enable = state == Qt::Checked;
|
||||
if (enable) {
|
||||
qputenv(g_sPreserveWindowFrame, "1");
|
||||
qputenv(g_sDontExtendFrame, "1");
|
||||
} else {
|
||||
qunsetenv(g_sPreserveWindowFrame);
|
||||
qunsetenv(g_sDontExtendFrame);
|
||||
}
|
||||
if (!enable && shouldDrawBorder()) {
|
||||
layout()->setContentsMargins(1, 1, 1, 1);
|
||||
} else {
|
||||
layout()->setContentsMargins(0, 0, 0, 0);
|
||||
}
|
||||
updateTitleBar();
|
||||
updateWindow();
|
||||
});
|
||||
connect(blurEffectCB, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
const bool enable = state == Qt::Checked;
|
||||
QColor color = {0, 0, 0, 127};
|
||||
const bool useAcrylicEffect = m_bCanAcrylicBeEnabled && forceAcrylicCB->isChecked();
|
||||
if (useAcrylicEffect) {
|
||||
if (enable && m_bCanShowColorDialog) {
|
||||
color = QColorDialog::getColor(color,
|
||||
this,
|
||||
tr("Please select a gradient color"),
|
||||
QColorDialog::ShowAlphaChannel);
|
||||
}
|
||||
}
|
||||
WinNativeEventFilter::setBlurEffectEnabled(rawHandle(), enable, color);
|
||||
updateWindow();
|
||||
if (useAcrylicEffect && enable && WinNativeEventFilter::transparencyEffectEnabled()) {
|
||||
QMessageBox::warning(this,
|
||||
tr("BUG Warning!"),
|
||||
tr("You have enabled the transparency effect in the personalize "
|
||||
"settings.\nDragging will be very laggy when the Acrylic "
|
||||
"effect is enabled.\nDisabling the transparency effect can "
|
||||
"solve this issue temporarily."));
|
||||
}
|
||||
});
|
||||
connect(extendToTitleBarCB, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
m_bExtendToTitleBar = state == Qt::Checked;
|
||||
updateTitleBar();
|
||||
});
|
||||
connect(forceAcrylicCB, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
if (!m_bCanAcrylicBeEnabled) {
|
||||
return;
|
||||
}
|
||||
if (state == Qt::Checked) {
|
||||
qputenv(g_sForceUseAcrylicEffect, "1");
|
||||
} else {
|
||||
qunsetenv(g_sForceUseAcrylicEffect);
|
||||
}
|
||||
if (blurEffectCB->isChecked()) {
|
||||
blurEffectCB->click();
|
||||
blurEffectCB->click();
|
||||
}
|
||||
});
|
||||
connect(resizableCB, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
const bool enable = state == Qt::Checked;
|
||||
maximizeButton->setEnabled(enable);
|
||||
WinNativeEventFilter::setWindowResizable(rawHandle(), enable);
|
||||
});
|
||||
}
|
||||
|
||||
void Widget::initializeFramelessFunctions()
|
||||
{
|
||||
WinNativeEventFilter::WINDOWDATA data = {};
|
||||
data.ignoreObjects << iconButton << minimizeButton << maximizeButton << closeButton;
|
||||
WinNativeEventFilter::addFramelessWindow(this, &data);
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
void Widget::initializeVariables()
|
||||
{
|
||||
m_bIsWin10OrGreater = isWin10OrGreater();
|
||||
if (m_bIsWin10OrGreater) {
|
||||
m_bCanAcrylicBeEnabled = isWin10OrGreater(g_vAcrylicEffectVersion);
|
||||
g_cColorizationColor = WinNativeEventFilter::colorizationColor();
|
||||
}
|
||||
}
|
||||
|
||||
void Widget::initializeWindow()
|
||||
{
|
||||
initializeVariables();
|
||||
setupUi();
|
||||
updateTitleBar();
|
||||
initializeFramelessFunctions();
|
||||
setupConnections();
|
||||
initializeOptions();
|
||||
}
|
||||
125
src/external/framelesshelper/examples/Win32Demo/widget.h
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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 <QWidget>
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
|
||||
#define Q_DISABLE_MOVE(Class) \
|
||||
Class(Class &&) = delete; \
|
||||
Class &operator=(Class &&) = delete;
|
||||
|
||||
#define Q_DISABLE_COPY_MOVE(Class) \
|
||||
Q_DISABLE_COPY(Class) \
|
||||
Q_DISABLE_MOVE(Class)
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QHBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QSpacerItem)
|
||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||
QT_FORWARD_DECLARE_CLASS(QLabel)
|
||||
QT_FORWARD_DECLARE_CLASS(QCheckBox)
|
||||
|
||||
class Widget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY_MOVE(Widget)
|
||||
|
||||
public:
|
||||
enum class Win10Version : int {
|
||||
Win10_1507 = 10240,
|
||||
Win10_1511 = 10586,
|
||||
Win10_1607 = 14393,
|
||||
Win10_1703 = 15063,
|
||||
Win10_1709 = 16299,
|
||||
Win10_1803 = 17134,
|
||||
Win10_1809 = 17763,
|
||||
Win10_1903 = 18362,
|
||||
Win10_1909 = 18363,
|
||||
Win10_2004 = 19041,
|
||||
Win10_20H2 = 19042,
|
||||
Windows10 = Win10_1507
|
||||
};
|
||||
Q_ENUM(Win10Version)
|
||||
|
||||
explicit Widget(QWidget *parent = nullptr);
|
||||
~Widget() override = default;
|
||||
|
||||
void *rawHandle() const;
|
||||
|
||||
bool isNormaled() const;
|
||||
|
||||
bool shouldDrawBorder(const bool ignoreWindowState = false) const;
|
||||
bool shouldDrawThemedBorder(const bool ignoreWindowState = false) const;
|
||||
bool shouldDrawThemedTitleBar() const;
|
||||
|
||||
static QColor activeBorderColor();
|
||||
static QColor inactiveBorderColor();
|
||||
QColor borderColor() const;
|
||||
|
||||
static bool isWin10OrGreater(const Win10Version subVer = Win10Version::Windows10);
|
||||
|
||||
public Q_SLOTS:
|
||||
void retranslateUi();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
#else
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||
#endif
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
void setupUi();
|
||||
void updateWindow();
|
||||
void updateTitleBar();
|
||||
void initializeOptions();
|
||||
void setupConnections();
|
||||
void initializeFramelessFunctions();
|
||||
void initializeVariables();
|
||||
void initializeWindow();
|
||||
|
||||
private:
|
||||
bool m_bIsWin10OrGreater = false, m_bCanAcrylicBeEnabled = false, m_bExtendToTitleBar = false,
|
||||
m_bCanShowColorDialog = false;
|
||||
QVBoxLayout *verticalLayout_3 = nullptr, *verticalLayout_2 = nullptr, *verticalLayout = nullptr;
|
||||
QWidget *titleBarWidget = nullptr, *contentsWidget = nullptr, *controlPanelWidget = nullptr;
|
||||
QHBoxLayout *horizontalLayout = nullptr, *horizontalLayout_2 = nullptr,
|
||||
*horizontalLayout_3 = nullptr;
|
||||
QSpacerItem *horizontalSpacer_7 = nullptr, *horizontalSpacer = nullptr,
|
||||
*horizontalSpacer_2 = nullptr, *verticalSpacer_2 = nullptr,
|
||||
*horizontalSpacer_3 = nullptr, *horizontalSpacer_4 = nullptr,
|
||||
*verticalSpacer = nullptr, *horizontalSpacer_5 = nullptr,
|
||||
*horizontalSpacer_6 = nullptr;
|
||||
QPushButton *iconButton = nullptr, *minimizeButton = nullptr, *maximizeButton = nullptr,
|
||||
*closeButton = nullptr, *moveCenterButton = nullptr;
|
||||
QLabel *titleLabel = nullptr;
|
||||
QCheckBox *customizeTitleBarCB = nullptr, *preserveWindowFrameCB = nullptr,
|
||||
*blurEffectCB = nullptr, *extendToTitleBarCB = nullptr, *forceAcrylicCB = nullptr,
|
||||
*resizableCB = nullptr;
|
||||
};
|
||||
23
src/external/framelesshelper/examples/common.pri
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
DESTDIR = $$OUT_PWD/../../bin
|
||||
CONFIG += c++17 strict_c++ utf8_source warn_on
|
||||
DEFINES += \
|
||||
QT_NO_CAST_FROM_ASCII \
|
||||
QT_NO_CAST_TO_ASCII
|
||||
RESOURCES += $$PWD/images.qrc
|
||||
win32 {
|
||||
DEFINES += \
|
||||
WIN32_LEAN_AND_MEAN \
|
||||
_CRT_SECURE_NO_WARNINGS
|
||||
CONFIG += windeployqt
|
||||
CONFIG -= embed_manifest_exe
|
||||
LIBS += -luser32 -lshell32 -lgdi32 -ldwmapi -lshcore -ld2d1 -luxtheme
|
||||
RC_FILE = $$PWD/windows.rc
|
||||
OTHER_FILES += $$PWD/windows.manifest
|
||||
}
|
||||
CONFIG(debug, debug|release) {
|
||||
LIBS += -L$$OUT_PWD/../../debug
|
||||
win32: LIBS += -lFramelessHelperd
|
||||
else: unix: LIBS += -lFramelessHelper_debug
|
||||
} else: CONFIG(release, debug|release) {
|
||||
LIBS += -L$$OUT_PWD/../../release -lFramelessHelper
|
||||
}
|
||||
5
src/external/framelesshelper/examples/examples.pro
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
TEMPLATE = subdirs
|
||||
CONFIG -= ordered
|
||||
qtHaveModule(widgets): SUBDIRS += QWidget QMainWindow
|
||||
qtHaveModule(quick): SUBDIRS += Quick
|
||||
win32: qtHaveModule(widgets): SUBDIRS += Win32Demo
|
||||
12
src/external/framelesshelper/examples/images.qrc
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>images/button_minimize_black.svg</file>
|
||||
<file>images/button_minimize_white.svg</file>
|
||||
<file>images/button_maximize_black.svg</file>
|
||||
<file>images/button_maximize_white.svg</file>
|
||||
<file>images/button_restore_black.svg</file>
|
||||
<file>images/button_restore_white.svg</file>
|
||||
<file>images/button_close_black.svg</file>
|
||||
<file>images/button_close_white.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
5
src/external/framelesshelper/examples/images/README.txt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
All the SVG images in this folder are created by me, using Inkscape. No images are downloaded from the Internet, not even one pixel.
|
||||
|
||||
Since I copied the screenshot (when the scale factor is 1.0) pixel by pixel, they should be exactly the same with the real system buttons, in theory.
|
||||
|
||||
Anyone can use them freely.
|
||||
6
src/external/framelesshelper/examples/images/button_close_black.svg
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="45pt" height="30pt" version="1.1" viewBox="0 0 15.875 10.583" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="#000" stroke-width=".35278">
|
||||
<path d="m6.1295 3.6601 3.2632 3.2632z"/>
|
||||
<path d="m9.3927 3.6601-3.2632 3.2632z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 264 B |
6
src/external/framelesshelper/examples/images/button_close_white.svg
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="45pt" height="30pt" version="1.1" viewBox="0 0 15.875 10.583" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="#fff" stroke-width=".35278">
|
||||
<path d="m6.1295 3.6601 3.2632 3.2632z"/>
|
||||
<path d="m9.3927 3.6601-3.2632 3.2632z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 264 B |
3
src/external/framelesshelper/examples/images/button_maximize_black.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="45pt" height="30pt" version="1.1" viewBox="0 0 15.875 10.583" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="6.1736" y="3.7042" width="3.175" height="3.175" fill="none" stroke="#000" stroke-width=".35278"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 225 B |
3
src/external/framelesshelper/examples/images/button_maximize_white.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="45pt" height="30pt" version="1.1" viewBox="0 0 15.875 10.583" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="6.1736" y="3.7042" width="3.175" height="3.175" fill="none" stroke="#fff" stroke-width=".35278"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 225 B |
3
src/external/framelesshelper/examples/images/button_minimize_black.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="45pt" height="30pt" version="1.1" viewBox="0 0 15.875 10.583" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m6.35 5.4681h3.5278z" fill="none" stroke="#000" stroke-width=".35278"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 199 B |
3
src/external/framelesshelper/examples/images/button_minimize_white.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="45pt" height="30pt" version="1.1" viewBox="0 0 15.875 10.583" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m6.35 5.4681h3.5278z" fill="none" stroke="#fff" stroke-width=".35278"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 199 B |
11
src/external/framelesshelper/examples/images/button_restore_black.svg
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="45pt" height="30pt" version="1.1" viewBox="0 0 15.875 10.583" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="#000">
|
||||
<rect x="6.1736" y="4.4097" width="2.4694" height="2.4694" stroke-width=".35278"/>
|
||||
<g stroke-width=".35278">
|
||||
<path d="m6.8792 4.2333v-0.70556z"/>
|
||||
<path d="m7.0556 3.7042h2.4694z"/>
|
||||
<path d="m9.3486 3.8806v2.4694z"/>
|
||||
<path d="m9.1722 6.1736h-0.35278z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 430 B |
11
src/external/framelesshelper/examples/images/button_restore_white.svg
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="45pt" height="30pt" version="1.1" viewBox="0 0 15.875 10.583" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="#fff">
|
||||
<rect x="6.1736" y="4.4097" width="2.4694" height="2.4694" stroke-width=".35278"/>
|
||||
<g stroke-width=".35278">
|
||||
<path d="m6.8792 4.2333v-0.70556z"/>
|
||||
<path d="m7.0556 3.7042h2.4694z"/>
|
||||
<path d="m9.3486 3.8806v2.4694z"/>
|
||||
<path d="m9.1722 6.1736h-0.35278z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 430 B |
BIN
src/external/framelesshelper/examples/windows.ico
vendored
Normal file
|
After Width: | Height: | Size: 45 KiB |
34
src/external/framelesshelper/examples/windows.manifest
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity type="win32" name="com.wangwenx190.framelessapplication" version="1.0.0.0"/>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 7 and Windows Server 2008 R2 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows 8 and Windows Server 2012 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 8.1 and Windows Server 2012 R2 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
63
src/external/framelesshelper/examples/windows.rc
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 <windows.h>
|
||||
|
||||
IDI_ICON1 ICON "windows.ico"
|
||||
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "windows.manifest"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
PRODUCTVERSION 1,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "Built by the Qt Toolkit."
|
||||
VALUE "CompanyName", "wangwenx190"
|
||||
VALUE "FileDescription", "A FramelessHelper based Qt application."
|
||||
VALUE "FileVersion", "1.0.0.0"
|
||||
VALUE "InternalName", ""
|
||||
VALUE "LegalCopyright", "MIT License"
|
||||
VALUE "OriginalFilename", ""
|
||||
VALUE "ProductName", "Test Application"
|
||||
VALUE "ProductVersion", "1.0.0.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
604
src/external/framelesshelper/framelesshelper.cpp
vendored
Normal file
@@ -0,0 +1,604 @@
|
||||
/*
|
||||
* 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 "framelesshelper.h"
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||
#include <QDebug>
|
||||
#include <QGuiApplication>
|
||||
#include <QMargins>
|
||||
#include <QScreen>
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
#include <QWidget>
|
||||
#endif
|
||||
#ifdef QT_QUICK_LIB
|
||||
#include <QQuickItem>
|
||||
#endif
|
||||
#include <QEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QTouchEvent>
|
||||
#include <QWindow>
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#else
|
||||
#include <qpa/qplatformwindow.h>
|
||||
#include <qpa/qplatformwindow_p.h>
|
||||
#endif
|
||||
|
||||
Q_DECLARE_METATYPE(QMargins)
|
||||
|
||||
namespace {
|
||||
|
||||
QWindow *getWindowHandle(QObject *val)
|
||||
{
|
||||
Q_ASSERT(val);
|
||||
const auto validWindow = [](QWindow *window) -> QWindow * {
|
||||
Q_ASSERT(window);
|
||||
return window->handle() ? window : nullptr;
|
||||
};
|
||||
if (val->isWindowType()) {
|
||||
return validWindow(qobject_cast<QWindow *>(val));
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (val->isWidgetType()) {
|
||||
const auto widget = qobject_cast<QWidget *>(val);
|
||||
if (widget && widget->isTopLevel()) {
|
||||
return validWindow(widget->windowHandle());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
qFatal("Can't acquire the window handle: only top level QWidget and QWindow are accepted.");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FramelessHelper::FramelessHelper(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void FramelessHelper::updateQtFrame(QWindow *window, const int titleBarHeight)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
if (titleBarHeight >= 0) {
|
||||
// Reduce top frame to zero since we paint it ourselves. Use
|
||||
// device pixel to avoid rounding errors.
|
||||
const QMargins margins = {0, -titleBarHeight, 0, 0};
|
||||
const QVariant marginsVar = QVariant::fromValue(margins);
|
||||
// The dynamic property takes effect when creating the platform
|
||||
// window.
|
||||
window->setProperty("_q_windowsCustomMargins", marginsVar);
|
||||
// If a platform window exists, change via native interface.
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
QPlatformWindow *platformWindow = window->handle();
|
||||
if (platformWindow) {
|
||||
QGuiApplication::platformNativeInterface()
|
||||
->setWindowProperty(platformWindow,
|
||||
QString::fromUtf8("WindowsCustomMargins"),
|
||||
marginsVar);
|
||||
}
|
||||
#else
|
||||
auto *platformWindow = dynamic_cast<QNativeInterface::Private::QWindowsWindow *>(
|
||||
window->handle());
|
||||
if (platformWindow) {
|
||||
platformWindow->setCustomMargins(margins);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessHelper::moveWindowToDesktopCenter(QObject *obj)
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
if (obj->isWindowType()) {
|
||||
const auto window = qobject_cast<QWindow *>(obj);
|
||||
if (window) {
|
||||
const QSize ss = window->screen()->size();
|
||||
const int sw = ss.width();
|
||||
const int sh = ss.height();
|
||||
const int ww = window->width();
|
||||
const int wh = window->height();
|
||||
window->setX(qRound(static_cast<qreal>(sw - ww) / 2.0));
|
||||
window->setY(qRound(static_cast<qreal>(sh - wh) / 2.0));
|
||||
}
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (obj->isWidgetType()) {
|
||||
const auto widget = qobject_cast<QWidget *>(obj);
|
||||
if (widget && widget->isTopLevel()) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
const QSize ss = widget->screen()->size();
|
||||
#else
|
||||
QSize ss = {};
|
||||
QWindow *window = widget->windowHandle();
|
||||
if (window) {
|
||||
ss = window->screen()->size();
|
||||
}
|
||||
#endif
|
||||
const int sw = ss.width();
|
||||
const int sh = ss.height();
|
||||
const int ww = widget->width();
|
||||
const int wh = widget->height();
|
||||
widget->move(qRound(static_cast<qreal>(sw - ww) / 2.0),
|
||||
qRound(static_cast<qreal>(sh - wh) / 2.0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
qFatal("The given QObject is not a top level QWidget or QWindow.");
|
||||
}
|
||||
}
|
||||
|
||||
int FramelessHelper::getBorderWidth() const
|
||||
{
|
||||
return m_borderWidth;
|
||||
}
|
||||
|
||||
void FramelessHelper::setBorderWidth(const int val)
|
||||
{
|
||||
m_borderWidth = val;
|
||||
}
|
||||
|
||||
int FramelessHelper::getBorderHeight() const
|
||||
{
|
||||
return m_borderHeight;
|
||||
}
|
||||
|
||||
void FramelessHelper::setBorderHeight(const int val)
|
||||
{
|
||||
m_borderHeight = val;
|
||||
}
|
||||
|
||||
int FramelessHelper::getTitleBarHeight() const
|
||||
{
|
||||
return m_titleBarHeight;
|
||||
}
|
||||
|
||||
void FramelessHelper::setTitleBarHeight(const int val)
|
||||
{
|
||||
m_titleBarHeight = val;
|
||||
}
|
||||
|
||||
QList<QRect> FramelessHelper::getIgnoreAreas(QObject *obj) const
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
return m_ignoreAreas.value(obj);
|
||||
}
|
||||
|
||||
void FramelessHelper::addIgnoreArea(QObject *obj, const QRect &val)
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
QList<QRect> areas = m_ignoreAreas[obj];
|
||||
areas.append(val);
|
||||
m_ignoreAreas[obj] = areas;
|
||||
}
|
||||
|
||||
QList<QRect> FramelessHelper::getDraggableAreas(QObject *obj) const
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
return m_draggableAreas.value(obj);
|
||||
}
|
||||
|
||||
void FramelessHelper::addDraggableArea(QObject *obj, const QRect &val)
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
QList<QRect> areas = m_draggableAreas[obj];
|
||||
areas.append(val);
|
||||
m_draggableAreas[obj] = areas;
|
||||
}
|
||||
|
||||
QList<QObject *> FramelessHelper::getIgnoreObjects(QObject *obj) const
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
QList<QObject *> ret{};
|
||||
const QList<QObject *> objs = m_ignoreObjects.value(obj);
|
||||
if (!objs.isEmpty()) {
|
||||
for (auto &&_obj : qAsConst(objs)) {
|
||||
if (_obj) {
|
||||
ret.append(_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FramelessHelper::addIgnoreObject(QObject *obj, QObject *val)
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
QList<QObject *> objs = m_ignoreObjects[obj];
|
||||
objs.append(val);
|
||||
m_ignoreObjects[obj] = objs;
|
||||
}
|
||||
|
||||
QList<QObject *> FramelessHelper::getDraggableObjects(QObject *obj) const
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
QList<QObject *> ret{};
|
||||
const QList<QObject *> objs = m_draggableObjects.value(obj);
|
||||
if (!objs.isEmpty()) {
|
||||
for (auto &&_obj : qAsConst(objs)) {
|
||||
if (_obj) {
|
||||
ret.append(_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FramelessHelper::addDraggableObject(QObject *obj, QObject *val)
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
QList<QObject *> objs = m_draggableObjects[obj];
|
||||
objs.append(val);
|
||||
m_draggableObjects[obj] = objs;
|
||||
}
|
||||
|
||||
bool FramelessHelper::getResizable(QObject *obj) const
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
return !m_fixedSize.value(obj);
|
||||
}
|
||||
|
||||
void FramelessHelper::setResizable(QObject *obj, const bool val)
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
m_fixedSize[obj] = !val;
|
||||
}
|
||||
|
||||
bool FramelessHelper::getTitleBarEnabled(QObject *obj) const
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
return !m_disableTitleBar.value(obj);
|
||||
}
|
||||
|
||||
void FramelessHelper::setTitleBarEnabled(QObject *obj, const bool val)
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
m_disableTitleBar[obj] = !val;
|
||||
}
|
||||
|
||||
void FramelessHelper::removeWindowFrame(QObject *obj, const bool center)
|
||||
{
|
||||
Q_ASSERT(obj);
|
||||
// Don't miss the Qt::Window flag.
|
||||
const Qt::WindowFlags flags = Qt::Window | Qt::FramelessWindowHint;
|
||||
if (obj->isWindowType()) {
|
||||
const auto window = qobject_cast<QWindow *>(obj);
|
||||
if (window) {
|
||||
window->setFlags(flags);
|
||||
// MouseTracking is always enabled for QWindow.
|
||||
window->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (obj->isWidgetType()) {
|
||||
const auto widget = qobject_cast<QWidget *>(obj);
|
||||
if (widget && widget->isTopLevel()) {
|
||||
widget->setWindowFlags(flags);
|
||||
// We can't get MouseMove events if MouseTracking is
|
||||
// disabled.
|
||||
widget->setMouseTracking(true);
|
||||
widget->installEventFilter(this);
|
||||
QWindow *window = widget->windowHandle();
|
||||
if (window) {
|
||||
updateQtFrame(window, m_titleBarHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
qFatal("The given QObject is not a top level QWidget or QWindow.");
|
||||
}
|
||||
if (center) {
|
||||
moveWindowToDesktopCenter(obj);
|
||||
}
|
||||
}
|
||||
|
||||
bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
Q_ASSERT(object);
|
||||
Q_ASSERT(event);
|
||||
const auto isWindowTopLevel = [](QObject *window) -> bool {
|
||||
Q_ASSERT(window);
|
||||
if (window->isWindowType()) {
|
||||
const auto win = qobject_cast<QWindow *>(window);
|
||||
if (win) {
|
||||
return win->isTopLevel();
|
||||
}
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
const auto widget = qobject_cast<QWidget *>(window);
|
||||
if (widget) {
|
||||
return widget->isTopLevel();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
};
|
||||
if (!isWindowTopLevel(object)) {
|
||||
return false;
|
||||
}
|
||||
const auto getWindowEdges =
|
||||
[this](const QPointF &point, const int ww, const int wh) -> Qt::Edges {
|
||||
if (point.y() <= m_borderHeight) {
|
||||
if (point.x() <= m_borderWidth) {
|
||||
return Qt::Edge::TopEdge | Qt::Edge::LeftEdge;
|
||||
}
|
||||
if (point.x() >= (ww - m_borderWidth)) {
|
||||
return Qt::Edge::TopEdge | Qt::Edge::RightEdge;
|
||||
}
|
||||
return Qt::Edge::TopEdge;
|
||||
}
|
||||
if (point.y() >= (wh - m_borderHeight)) {
|
||||
if (point.x() <= m_borderWidth) {
|
||||
return Qt::Edge::BottomEdge | Qt::Edge::LeftEdge;
|
||||
}
|
||||
if (point.x() >= (ww - m_borderWidth)) {
|
||||
return Qt::Edge::BottomEdge | Qt::Edge::RightEdge;
|
||||
}
|
||||
return Qt::Edge::BottomEdge;
|
||||
}
|
||||
if (point.x() <= m_borderWidth) {
|
||||
return Qt::Edge::LeftEdge;
|
||||
}
|
||||
if (point.x() >= (ww - m_borderWidth)) {
|
||||
return Qt::Edge::RightEdge;
|
||||
}
|
||||
return {};
|
||||
};
|
||||
const auto getCursorShape = [](const Qt::Edges edges) -> Qt::CursorShape {
|
||||
if ((edges.testFlag(Qt::Edge::TopEdge) && edges.testFlag(Qt::Edge::LeftEdge))
|
||||
|| (edges.testFlag(Qt::Edge::BottomEdge) && edges.testFlag(Qt::Edge::RightEdge))) {
|
||||
return Qt::CursorShape::SizeFDiagCursor;
|
||||
}
|
||||
if ((edges.testFlag(Qt::Edge::TopEdge) && edges.testFlag(Qt::Edge::RightEdge))
|
||||
|| (edges.testFlag(Qt::Edge::BottomEdge) && edges.testFlag(Qt::Edge::LeftEdge))) {
|
||||
return Qt::CursorShape::SizeBDiagCursor;
|
||||
}
|
||||
if (edges.testFlag(Qt::Edge::TopEdge) || edges.testFlag(Qt::Edge::BottomEdge)) {
|
||||
return Qt::CursorShape::SizeVerCursor;
|
||||
}
|
||||
if (edges.testFlag(Qt::Edge::LeftEdge) || edges.testFlag(Qt::Edge::RightEdge)) {
|
||||
return Qt::CursorShape::SizeHorCursor;
|
||||
}
|
||||
return Qt::CursorShape::ArrowCursor;
|
||||
};
|
||||
const auto isInSpecificAreas = [](const int x, const int y, const QList<QRect> &areas) -> bool {
|
||||
if (!areas.isEmpty()) {
|
||||
for (auto &&area : qAsConst(areas)) {
|
||||
if (area.contains(x, y)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const auto isInSpecificObjects =
|
||||
[](const int x, const int y, const QList<QObject *> &objects) -> bool {
|
||||
if (!objects.isEmpty()) {
|
||||
for (auto &&obj : qAsConst(objects)) {
|
||||
if (!obj) {
|
||||
continue;
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
const auto widget = qobject_cast<QWidget *>(obj);
|
||||
if (widget) {
|
||||
const QPoint pos = widget->mapToGlobal({0, 0});
|
||||
if (QRect(pos.x(), pos.y(), widget->width(), widget->height()).contains(x, y)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef QT_QUICK_LIB
|
||||
const auto quickItem = qobject_cast<QQuickItem *>(obj);
|
||||
if (quickItem) {
|
||||
const QPointF pos = quickItem->mapToGlobal({0, 0});
|
||||
if (QRectF(pos.x(), pos.y(), quickItem->width(), quickItem->height())
|
||||
.contains(x, y)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const auto isInIgnoreAreas = [this, &isInSpecificAreas](const QPointF &point,
|
||||
QObject *window) -> bool {
|
||||
Q_ASSERT(window);
|
||||
return isInSpecificAreas(point.x(), point.y(), getIgnoreAreas(window));
|
||||
};
|
||||
const auto isInIgnoreObjects = [this, &isInSpecificObjects](const QPointF &point,
|
||||
QObject *window) -> bool {
|
||||
Q_ASSERT(window);
|
||||
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
|
||||
return isInSpecificObjects(point.x(), point.y(), getIgnoreObjects(window));
|
||||
#else
|
||||
Q_UNUSED(point)
|
||||
Q_UNUSED(window)
|
||||
return false;
|
||||
#endif
|
||||
};
|
||||
const auto isInDraggableAreas = [this, &isInSpecificAreas](const QPointF &point,
|
||||
QObject *window) -> bool {
|
||||
Q_ASSERT(window);
|
||||
const auto areas = getDraggableAreas(window);
|
||||
return (areas.isEmpty() ? true : isInSpecificAreas(point.x(), point.y(), areas));
|
||||
};
|
||||
const auto isInDraggableObjects = [this, &isInSpecificObjects](const QPointF &point,
|
||||
QObject *window) -> bool {
|
||||
Q_ASSERT(window);
|
||||
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
|
||||
const auto objs = getDraggableObjects(window);
|
||||
return (objs.isEmpty() ? true : isInSpecificObjects(point.x(), point.y(), objs));
|
||||
#else
|
||||
Q_UNUSED(point)
|
||||
Q_UNUSED(window)
|
||||
return true;
|
||||
#endif
|
||||
};
|
||||
const auto isResizePermitted = [&isInIgnoreAreas, &isInIgnoreObjects](const QPointF &globalPoint,
|
||||
const QPointF &point,
|
||||
QObject *window) -> bool {
|
||||
Q_ASSERT(window);
|
||||
return (!isInIgnoreAreas(point, window) && !isInIgnoreObjects(globalPoint, window));
|
||||
};
|
||||
const auto isInTitlebarArea = [this,
|
||||
&isInDraggableAreas,
|
||||
&isInDraggableObjects,
|
||||
&isResizePermitted](const QPointF &globalPoint,
|
||||
const QPointF &point,
|
||||
QObject *window) -> bool {
|
||||
Q_ASSERT(window);
|
||||
const bool customDragAreas = !getDraggableAreas(window).isEmpty();
|
||||
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
|
||||
const bool customDragObjects = !getDraggableObjects(window).isEmpty();
|
||||
#else
|
||||
const bool customDragObjects = false;
|
||||
#endif
|
||||
const bool customDrag = customDragAreas || customDragObjects;
|
||||
return ((customDrag ? (isInDraggableAreas(point, window)
|
||||
&& isInDraggableObjects(globalPoint, window))
|
||||
: (point.y() <= m_titleBarHeight))
|
||||
&& isResizePermitted(globalPoint, point, window) && getTitleBarEnabled(window));
|
||||
return false;
|
||||
};
|
||||
const auto moveOrResize =
|
||||
[this, &getWindowEdges, &isResizePermitted, &isInTitlebarArea](const QPointF &globalPoint,
|
||||
const QPointF &point,
|
||||
QObject *object) {
|
||||
Q_ASSERT(object);
|
||||
QWindow *window = getWindowHandle(object);
|
||||
if (window) {
|
||||
const Qt::Edges edges = getWindowEdges(point, window->width(), window->height());
|
||||
if (edges == Qt::Edges{}) {
|
||||
if (isInTitlebarArea(globalPoint, point, object)) {
|
||||
window->startSystemMove();
|
||||
}
|
||||
} else {
|
||||
if (window->windowStates().testFlag(Qt::WindowState::WindowNoState)
|
||||
&& isResizePermitted(globalPoint, point, object) && getResizable(object)) {
|
||||
window->startSystemResize(edges);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qWarning().noquote() << "Can't move or resize the window: failed "
|
||||
"to acquire the window handle.";
|
||||
}
|
||||
};
|
||||
switch (event->type()) {
|
||||
case QEvent::MouseButtonDblClick: {
|
||||
const auto mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent) {
|
||||
if (mouseEvent->button() != Qt::MouseButton::LeftButton) {
|
||||
break;
|
||||
}
|
||||
if (isInTitlebarArea(mouseEvent->screenPos(), mouseEvent->windowPos(), object)) {
|
||||
// ### FIXME: If the current object is a QWidget, we can use
|
||||
// getWindowHandle(object) to get the window handle, but if we
|
||||
// call showMaximized() of that window, it will not be
|
||||
// maximized, it will be moved to the top-left edge of the
|
||||
// screen without changing it's size instead. Why? Convert the
|
||||
// object to QWidget and call showMaximized() doesn't have this
|
||||
// issue.
|
||||
if (object->isWindowType()) {
|
||||
const auto window = qobject_cast<QWindow *>(object);
|
||||
if (window) {
|
||||
if (window->windowStates().testFlag(Qt::WindowState::WindowFullScreen)) {
|
||||
break;
|
||||
}
|
||||
if (window->windowStates().testFlag(Qt::WindowState::WindowMaximized)) {
|
||||
window->showNormal();
|
||||
} else {
|
||||
window->showMaximized();
|
||||
}
|
||||
window->setCursor(Qt::CursorShape::ArrowCursor);
|
||||
}
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (object->isWidgetType()) {
|
||||
const auto widget = qobject_cast<QWidget *>(object);
|
||||
if (widget) {
|
||||
if (widget->isFullScreen()) {
|
||||
break;
|
||||
}
|
||||
if (widget->isMaximized()) {
|
||||
widget->showNormal();
|
||||
} else {
|
||||
widget->showMaximized();
|
||||
}
|
||||
widget->setCursor(Qt::CursorShape::ArrowCursor);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case QEvent::MouseButtonPress: {
|
||||
const auto mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent) {
|
||||
if (mouseEvent->button() != Qt::MouseButton::LeftButton) {
|
||||
break;
|
||||
}
|
||||
moveOrResize(mouseEvent->screenPos(), mouseEvent->windowPos(), object);
|
||||
}
|
||||
} break;
|
||||
case QEvent::MouseMove: {
|
||||
const auto mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent) {
|
||||
QWindow *window = getWindowHandle(object);
|
||||
if (window) {
|
||||
if (window->windowStates().testFlag(Qt::WindowState::WindowNoState)
|
||||
&& getResizable(object)) {
|
||||
window->setCursor(getCursorShape(
|
||||
getWindowEdges(mouseEvent->windowPos(), window->width(), window->height())));
|
||||
}
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else {
|
||||
const auto widget = qobject_cast<QWidget *>(object);
|
||||
if (widget) {
|
||||
if (!widget->isMinimized() && !widget->isMaximized() && !widget->isFullScreen()
|
||||
&& getResizable(object)) {
|
||||
widget->setCursor(getCursorShape(getWindowEdges(mouseEvent->windowPos(),
|
||||
widget->width(),
|
||||
widget->height())));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
case QEvent::TouchBegin:
|
||||
case QEvent::TouchUpdate: {
|
||||
const auto point = static_cast<QTouchEvent *>(event)->touchPoints().first();
|
||||
moveOrResize(point.screenPos(), point.pos(), object);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
91
src/external/framelesshelper/framelesshelper.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 "framelesshelper_global.h"
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QRect>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
QT_FORWARD_DECLARE_CLASS(QWindow)
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class FRAMELESSHELPER_EXPORT FramelessHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY_MOVE(FramelessHelper)
|
||||
|
||||
public:
|
||||
explicit FramelessHelper(QObject *parent = nullptr);
|
||||
~FramelessHelper() override = default;
|
||||
|
||||
void removeWindowFrame(QObject *obj, const bool center = false);
|
||||
|
||||
static void updateQtFrame(QWindow *window, const int titleBarHeight);
|
||||
static void moveWindowToDesktopCenter(QObject *obj);
|
||||
|
||||
int getBorderWidth() const;
|
||||
void setBorderWidth(const int val);
|
||||
|
||||
int getBorderHeight() const;
|
||||
void setBorderHeight(const int val);
|
||||
|
||||
int getTitleBarHeight() const;
|
||||
void setTitleBarHeight(const int val);
|
||||
|
||||
void addIgnoreArea(QObject *obj, const QRect &val);
|
||||
QList<QRect> getIgnoreAreas(QObject *obj) const;
|
||||
|
||||
void addDraggableArea(QObject *obj, const QRect &val);
|
||||
QList<QRect> getDraggableAreas(QObject *obj) const;
|
||||
|
||||
void addIgnoreObject(QObject *obj, QObject *val);
|
||||
QList<QObject *> getIgnoreObjects(QObject *obj) const;
|
||||
|
||||
void addDraggableObject(QObject *obj, QObject *val);
|
||||
QList<QObject *> getDraggableObjects(QObject *obj) const;
|
||||
|
||||
bool getResizable(QObject *obj) const;
|
||||
void setResizable(QObject *obj, const bool val);
|
||||
|
||||
bool getTitleBarEnabled(QObject *obj) const;
|
||||
void setTitleBarEnabled(QObject *obj, const bool val);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
private:
|
||||
// ### TODO: The default border width and height on Windows is 8 pixels if
|
||||
// the scale factor is 1.0. Don't know how to acquire these values on UNIX
|
||||
// platforms through native API.
|
||||
int m_borderWidth = 8, m_borderHeight = 8, m_titleBarHeight = 30;
|
||||
QHash<QObject *, QList<QRect>> m_ignoreAreas = {}, m_draggableAreas = {};
|
||||
QHash<QObject *, QList<QObject *>> m_ignoreObjects = {}, m_draggableObjects = {};
|
||||
QHash<QObject *, bool> m_fixedSize = {}, m_disableTitleBar = {};
|
||||
};
|
||||
#endif
|
||||
5
src/external/framelesshelper/framelesshelper.pro
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
TEMPLATE = subdirs
|
||||
CONFIG -= ordered
|
||||
SUBDIRS += lib examples
|
||||
lib.file = lib.pro
|
||||
examples.depends += lib
|
||||
62
src/external/framelesshelper/framelesshelper.rc
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 <windows.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
PRODUCTVERSION 1,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "wangwenx190"
|
||||
VALUE "FileDescription", "Frameless Helper"
|
||||
VALUE "FileVersion", "1.0.0.0"
|
||||
VALUE "LegalCopyright", "MIT License"
|
||||
#ifdef _DEBUG
|
||||
VALUE "OriginalFilename", "FramelessHelperd.dll"
|
||||
#else
|
||||
VALUE "OriginalFilename", "FramelessHelper.dll"
|
||||
#endif
|
||||
VALUE "ProductName", "Frameless Helper"
|
||||
VALUE "ProductVersion", "1.0.0.0"
|
||||
VALUE "InternalName", "framelesshelper"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
39
src/external/framelesshelper/framelesshelper_global.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 <QtCore/qglobal.h>
|
||||
|
||||
#ifndef FRAMELESSHELPER_EXPORT
|
||||
#ifdef FRAMELESSHELPER_STATIC
|
||||
#define FRAMELESSHELPER_EXPORT
|
||||
#else
|
||||
#ifdef FRAMELESSHELPER_BUILD_LIBRARY
|
||||
#define FRAMELESSHELPER_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
#define FRAMELESSHELPER_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
266
src/external/framelesshelper/framelessquickhelper.cpp
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include "framelesswindowsmanager.h"
|
||||
#include <QtQuick/QQuickWindow>
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include "winnativeeventfilter.h"
|
||||
#include <QOperatingSystemVersion>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
namespace {
|
||||
|
||||
const char g_sPreserveWindowFrame[] = "WNEF_FORCE_PRESERVE_WINDOW_FRAME";
|
||||
const char g_sDontExtendFrame[] = "WNEF_DO_NOT_EXTEND_FRAME";
|
||||
const char g_sForceUseAcrylicEffect[] = "WNEF_FORCE_ACRYLIC_ON_WIN10";
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent) : QQuickItem(parent)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
startTimer(500);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FramelessQuickHelper::borderWidth() const
|
||||
{
|
||||
return FramelessWindowsManager::getBorderWidth(window());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setBorderWidth(const int val)
|
||||
{
|
||||
FramelessWindowsManager::setBorderWidth(window(), val);
|
||||
Q_EMIT borderWidthChanged(val);
|
||||
}
|
||||
|
||||
int FramelessQuickHelper::borderHeight() const
|
||||
{
|
||||
return FramelessWindowsManager::getBorderHeight(window());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setBorderHeight(const int val)
|
||||
{
|
||||
FramelessWindowsManager::setBorderHeight(window(), val);
|
||||
Q_EMIT borderHeightChanged(val);
|
||||
}
|
||||
|
||||
int FramelessQuickHelper::titleBarHeight() const
|
||||
{
|
||||
return FramelessWindowsManager::getTitleBarHeight(window());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setTitleBarHeight(const int val)
|
||||
{
|
||||
FramelessWindowsManager::setTitleBarHeight(window(), val);
|
||||
Q_EMIT titleBarHeightChanged(val);
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::resizable() const
|
||||
{
|
||||
return FramelessWindowsManager::getResizable(window());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setResizable(const bool val)
|
||||
{
|
||||
FramelessWindowsManager::setResizable(window(), val);
|
||||
Q_EMIT resizableChanged(val);
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::titleBarEnabled() const
|
||||
{
|
||||
return FramelessWindowsManager::getTitleBarEnabled(window());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setTitleBarEnabled(const bool val)
|
||||
{
|
||||
FramelessWindowsManager::setTitleBarEnabled(window(), val);
|
||||
Q_EMIT titleBarEnabledChanged(val);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
bool FramelessQuickHelper::canHaveWindowFrame() const
|
||||
{
|
||||
return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10;
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::colorizationEnabled() const
|
||||
{
|
||||
return WinNativeEventFilter::colorizationEnabled();
|
||||
}
|
||||
|
||||
QColor FramelessQuickHelper::colorizationColor() const
|
||||
{
|
||||
return WinNativeEventFilter::colorizationColor();
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::lightThemeEnabled() const
|
||||
{
|
||||
return WinNativeEventFilter::lightThemeEnabled();
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::darkThemeEnabled() const
|
||||
{
|
||||
return WinNativeEventFilter::darkThemeEnabled();
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::highContrastModeEnabled() const
|
||||
{
|
||||
return WinNativeEventFilter::highContrastModeEnabled();
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::darkFrameEnabled() const
|
||||
{
|
||||
return WinNativeEventFilter::darkFrameEnabled(rawHandle());
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::transparencyEffectEnabled() const
|
||||
{
|
||||
return WinNativeEventFilter::transparencyEffectEnabled();
|
||||
}
|
||||
#endif
|
||||
|
||||
QSize FramelessQuickHelper::minimumSize() const
|
||||
{
|
||||
return FramelessWindowsManager::getMinimumSize(window());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setMinimumSize(const QSize &val)
|
||||
{
|
||||
FramelessWindowsManager::setMinimumSize(window(), val);
|
||||
Q_EMIT minimumSizeChanged(val);
|
||||
}
|
||||
|
||||
QSize FramelessQuickHelper::maximumSize() const
|
||||
{
|
||||
return FramelessWindowsManager::getMaximumSize(window());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setMaximumSize(const QSize &val)
|
||||
{
|
||||
FramelessWindowsManager::setMaximumSize(window(), val);
|
||||
Q_EMIT maximumSizeChanged(val);
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::removeWindowFrame(const bool center)
|
||||
{
|
||||
FramelessWindowsManager::addWindow(window(), center);
|
||||
}
|
||||
|
||||
QSize FramelessQuickHelper::desktopSize() const
|
||||
{
|
||||
return FramelessWindowsManager::getDesktopSize(window());
|
||||
}
|
||||
|
||||
QRect FramelessQuickHelper::desktopAvailableGeometry() const
|
||||
{
|
||||
return FramelessWindowsManager::getDesktopAvailableGeometry(window());
|
||||
}
|
||||
|
||||
QSize FramelessQuickHelper::desktopAvailableSize() const
|
||||
{
|
||||
return FramelessWindowsManager::getDesktopAvailableSize(window());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::moveWindowToDesktopCenter(const bool realCenter)
|
||||
{
|
||||
FramelessWindowsManager::moveWindowToDesktopCenter(window(), realCenter);
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::addIgnoreArea(const QRect &val)
|
||||
{
|
||||
FramelessWindowsManager::addIgnoreArea(window(), val);
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::addDraggableArea(const QRect &val)
|
||||
{
|
||||
FramelessWindowsManager::addDraggableArea(window(), val);
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::addIgnoreObject(QQuickItem *val)
|
||||
{
|
||||
Q_ASSERT(val);
|
||||
FramelessWindowsManager::addIgnoreObject(window(), val);
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::addDraggableObject(QQuickItem *val)
|
||||
{
|
||||
Q_ASSERT(val);
|
||||
FramelessWindowsManager::addDraggableObject(window(), val);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
void FramelessQuickHelper::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
QQuickItem::timerEvent(event);
|
||||
Q_EMIT colorizationEnabledChanged(colorizationEnabled());
|
||||
Q_EMIT colorizationColorChanged(colorizationColor());
|
||||
Q_EMIT lightThemeEnabledChanged(lightThemeEnabled());
|
||||
Q_EMIT darkThemeEnabledChanged(darkThemeEnabled());
|
||||
Q_EMIT highContrastModeEnabledChanged(highContrastModeEnabled());
|
||||
Q_EMIT darkFrameEnabledChanged(darkFrameEnabled());
|
||||
Q_EMIT transparencyEffectEnabledChanged(transparencyEffectEnabled());
|
||||
}
|
||||
|
||||
void *FramelessQuickHelper::rawHandle() const
|
||||
{
|
||||
QWindow *win = window();
|
||||
if (win) {
|
||||
return reinterpret_cast<void *>(win->winId());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setWindowFrameVisible(const bool value)
|
||||
{
|
||||
if (value) {
|
||||
qputenv(g_sPreserveWindowFrame, "1");
|
||||
qputenv(g_sDontExtendFrame, "1");
|
||||
} else {
|
||||
qunsetenv(g_sPreserveWindowFrame);
|
||||
qunsetenv(g_sDontExtendFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::displaySystemMenu(const int x, const int y, const bool isRtl)
|
||||
{
|
||||
WinNativeEventFilter::displaySystemMenu(rawHandle(), isRtl, x, y);
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setBlurEffectEnabled(const bool enabled,
|
||||
const bool forceAcrylic,
|
||||
const QColor &gradientColor)
|
||||
{
|
||||
if (forceAcrylic) {
|
||||
qputenv(g_sForceUseAcrylicEffect, "1");
|
||||
} else {
|
||||
qunsetenv(g_sForceUseAcrylicEffect);
|
||||
}
|
||||
WinNativeEventFilter::setBlurEffectEnabled(rawHandle(), enabled, gradientColor);
|
||||
}
|
||||
#endif
|
||||
158
src/external/framelesshelper/framelessquickhelper.h
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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 "framelesshelper_global.h"
|
||||
#include <QtQuick/QQuickItem>
|
||||
|
||||
#if (defined(Q_OS_WIN) || defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)) \
|
||||
&& !defined(Q_OS_WINDOWS)
|
||||
#define Q_OS_WINDOWS
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
|
||||
#define Q_DISABLE_MOVE(Class) \
|
||||
Class(Class &&) = delete; \
|
||||
Class &operator=(Class &&) = delete;
|
||||
|
||||
#define Q_DISABLE_COPY_MOVE(Class) \
|
||||
Q_DISABLE_COPY(Class) \
|
||||
Q_DISABLE_MOVE(Class)
|
||||
#endif
|
||||
|
||||
class FRAMELESSHELPER_EXPORT FramelessQuickHelper : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY_MOVE(FramelessQuickHelper)
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||
QML_ELEMENT
|
||||
#endif
|
||||
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)
|
||||
Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize NOTIFY minimumSizeChanged)
|
||||
Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize NOTIFY maximumSizeChanged)
|
||||
Q_PROPERTY(bool titleBarEnabled READ titleBarEnabled WRITE setTitleBarEnabled NOTIFY
|
||||
titleBarEnabledChanged)
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_PROPERTY(bool canHaveWindowFrame READ canHaveWindowFrame CONSTANT)
|
||||
Q_PROPERTY(bool colorizationEnabled READ colorizationEnabled NOTIFY colorizationEnabledChanged)
|
||||
Q_PROPERTY(QColor colorizationColor READ colorizationColor NOTIFY colorizationColorChanged)
|
||||
Q_PROPERTY(bool lightThemeEnabled READ lightThemeEnabled NOTIFY lightThemeEnabledChanged)
|
||||
Q_PROPERTY(bool darkThemeEnabled READ darkThemeEnabled NOTIFY darkThemeEnabledChanged)
|
||||
Q_PROPERTY(bool highContrastModeEnabled READ highContrastModeEnabled NOTIFY
|
||||
highContrastModeEnabledChanged)
|
||||
Q_PROPERTY(bool darkFrameEnabled READ darkFrameEnabled NOTIFY darkFrameEnabledChanged)
|
||||
Q_PROPERTY(bool transparencyEffectEnabled READ transparencyEffectEnabled NOTIFY
|
||||
transparencyEffectEnabledChanged)
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
QSize minimumSize() const;
|
||||
void setMinimumSize(const QSize &val);
|
||||
|
||||
QSize maximumSize() const;
|
||||
void setMaximumSize(const QSize &val);
|
||||
|
||||
bool titleBarEnabled() const;
|
||||
void setTitleBarEnabled(const bool val);
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
bool canHaveWindowFrame() const;
|
||||
bool colorizationEnabled() const;
|
||||
QColor colorizationColor() const;
|
||||
bool lightThemeEnabled() const;
|
||||
bool darkThemeEnabled() const;
|
||||
bool highContrastModeEnabled() const;
|
||||
bool darkFrameEnabled() const;
|
||||
bool transparencyEffectEnabled() const;
|
||||
#endif
|
||||
|
||||
public Q_SLOTS:
|
||||
void removeWindowFrame(const bool center = false);
|
||||
|
||||
void moveWindowToDesktopCenter(const bool realCenter = true);
|
||||
|
||||
QSize desktopSize() const;
|
||||
QRect desktopAvailableGeometry() const;
|
||||
QSize desktopAvailableSize() const;
|
||||
|
||||
void addIgnoreArea(const QRect &val);
|
||||
void addDraggableArea(const QRect &val);
|
||||
|
||||
void addIgnoreObject(QQuickItem *val);
|
||||
void addDraggableObject(QQuickItem *val);
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
void setWindowFrameVisible(const bool value = true);
|
||||
void displaySystemMenu(const int x, const int y, const bool isRtl = false);
|
||||
void setBlurEffectEnabled(const bool enabled = true,
|
||||
const bool forceAcrylic = false,
|
||||
const QColor &gradientColor = Qt::white);
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
void *rawHandle() const;
|
||||
#endif
|
||||
|
||||
Q_SIGNALS:
|
||||
void borderWidthChanged(int);
|
||||
void borderHeightChanged(int);
|
||||
void titleBarHeightChanged(int);
|
||||
void resizableChanged(bool);
|
||||
void minimumSizeChanged(const QSize &);
|
||||
void maximumSizeChanged(const QSize &);
|
||||
void titleBarEnabledChanged(bool);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
void colorizationEnabledChanged(bool);
|
||||
void colorizationColorChanged(const QColor &);
|
||||
void lightThemeEnabledChanged(bool);
|
||||
void darkThemeEnabledChanged(bool);
|
||||
void highContrastModeEnabledChanged(bool);
|
||||
void darkFrameEnabledChanged(bool);
|
||||
void transparencyEffectEnabledChanged(bool);
|
||||
#endif
|
||||
};
|
||||
463
src/external/framelesshelper/framelesswindowsmanager.cpp
vendored
Normal file
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* 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 "framelesswindowsmanager.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
#include <QWidget>
|
||||
#endif
|
||||
|
||||
#if (defined(Q_OS_WIN) || defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)) \
|
||||
&& !defined(Q_OS_WINDOWS)
|
||||
#define Q_OS_WINDOWS
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include "winnativeeventfilter.h"
|
||||
#else
|
||||
#include "framelesshelper.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
void reportError()
|
||||
{
|
||||
qFatal("Only top level QWidgets and QWindows are accepted.");
|
||||
}
|
||||
|
||||
QScreen *getCurrentScreenFromWindow(QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
if (window->isWindowType()) {
|
||||
return qobject_cast<QWindow *>(window)->screen();
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
return qobject_cast<QWidget *>(window)->screen();
|
||||
#else
|
||||
QWindow *win = qobject_cast<QWidget *>(window)->windowHandle();
|
||||
return win ? win->screen() : nullptr;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
reportError();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
void *getRawHandleFromWindow(QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
if (window->isWindowType()) {
|
||||
return reinterpret_cast<void *>(qobject_cast<QWindow *>(window)->winId());
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
return reinterpret_cast<void *>(qobject_cast<QWidget *>(window)->winId());
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
reportError();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_WINDOWS
|
||||
using FLWM_CORE_DATA = struct _FLWM_CORE_DATA
|
||||
{
|
||||
FramelessHelper framelessHelper;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifndef Q_OS_WINDOWS
|
||||
Q_GLOBAL_STATIC(FLWM_CORE_DATA, coreData)
|
||||
#endif
|
||||
|
||||
FramelessWindowsManager::FramelessWindowsManager() {}
|
||||
|
||||
void FramelessWindowsManager::addWindow(QObject *window, const bool center)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
WinNativeEventFilter::addFramelessWindow(window);
|
||||
#else
|
||||
coreData()->framelessHelper.removeWindowFrame(window);
|
||||
#endif
|
||||
if (center) {
|
||||
moveWindowToDesktopCenter(window);
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::moveWindowToDesktopCenter(QObject *window, const bool realCenter)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
if (realCenter) {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
WinNativeEventFilter::moveWindowToDesktopCenter(getRawHandleFromWindow(window));
|
||||
#else
|
||||
FramelessHelper::moveWindowToDesktopCenter(window);
|
||||
#endif
|
||||
} else {
|
||||
QSize windowSize = {}, screenSize = {};
|
||||
QRect screenGeometry = {};
|
||||
if (window->isWindowType()) {
|
||||
const auto win = qobject_cast<QWindow *>(window);
|
||||
if (win) {
|
||||
windowSize = win->size();
|
||||
screenSize = getDesktopAvailableSize(win);
|
||||
screenGeometry = getDesktopAvailableGeometry(win);
|
||||
}
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
const auto widget = qobject_cast<QWidget *>(window);
|
||||
if (widget && widget->isTopLevel()) {
|
||||
windowSize = widget->size();
|
||||
screenSize = getDesktopAvailableSize(widget);
|
||||
screenGeometry = getDesktopAvailableGeometry(widget);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
reportError();
|
||||
}
|
||||
const int newX = qRound(static_cast<qreal>(screenSize.width() - windowSize.width()) / 2.0);
|
||||
const int newY = qRound(static_cast<qreal>(screenSize.height() - windowSize.height()) / 2.0);
|
||||
const int x = newX + screenGeometry.x();
|
||||
const int y = newY + screenGeometry.y();
|
||||
if (window->isWindowType()) {
|
||||
const auto win = qobject_cast<QWindow *>(window);
|
||||
if (win) {
|
||||
win->setX(x);
|
||||
win->setY(y);
|
||||
}
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
const auto widget = qobject_cast<QWidget *>(window);
|
||||
if (widget && widget->isTopLevel()) {
|
||||
widget->move(x, y);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
reportError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSize FramelessWindowsManager::getDesktopSize(QObject *window)
|
||||
{
|
||||
const QScreen *screen = window ? getCurrentScreenFromWindow(window)
|
||||
: QGuiApplication::primaryScreen();
|
||||
return screen ? screen->size() : QSize();
|
||||
}
|
||||
|
||||
QRect FramelessWindowsManager::getDesktopAvailableGeometry(QObject *window)
|
||||
{
|
||||
const QScreen *screen = window ? getCurrentScreenFromWindow(window)
|
||||
: QGuiApplication::primaryScreen();
|
||||
return screen ? screen->availableGeometry() : QRect();
|
||||
}
|
||||
|
||||
QSize FramelessWindowsManager::getDesktopAvailableSize(QObject *window)
|
||||
{
|
||||
const QScreen *screen = window ? getCurrentScreenFromWindow(window)
|
||||
: QGuiApplication::primaryScreen();
|
||||
return screen ? screen->availableSize() : QSize();
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::addIgnoreArea(QObject *window, const QRect &area)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->ignoreAreas.append(area);
|
||||
}
|
||||
#else
|
||||
coreData()->framelessHelper.addIgnoreArea(window, area);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::addDraggableArea(QObject *window, const QRect &area)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->draggableAreas.append(area);
|
||||
}
|
||||
#else
|
||||
coreData()->framelessHelper.addDraggableArea(window, area);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::addIgnoreObject(QObject *window, QObject *object)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->ignoreObjects.append(object);
|
||||
}
|
||||
#else
|
||||
coreData()->framelessHelper.addIgnoreObject(window, object);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::addDraggableObject(QObject *window, QObject *object)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->draggableObjects.append(object);
|
||||
}
|
||||
#else
|
||||
coreData()->framelessHelper.addDraggableObject(window, object);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FramelessWindowsManager::getBorderWidth(QObject *window)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_ASSERT(window);
|
||||
return WinNativeEventFilter::getSystemMetric(getRawHandleFromWindow(window),
|
||||
WinNativeEventFilter::SystemMetric::BorderWidth);
|
||||
#else
|
||||
Q_UNUSED(window)
|
||||
return coreData()->framelessHelper.getBorderWidth();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::setBorderWidth(QObject *window, const int value)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_ASSERT(window);
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->borderWidth = value;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(window)
|
||||
coreData()->framelessHelper.setBorderWidth(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FramelessWindowsManager::getBorderHeight(QObject *window)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_ASSERT(window);
|
||||
return WinNativeEventFilter::getSystemMetric(getRawHandleFromWindow(window),
|
||||
WinNativeEventFilter::SystemMetric::BorderHeight);
|
||||
#else
|
||||
Q_UNUSED(window)
|
||||
return coreData()->framelessHelper.getBorderHeight();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::setBorderHeight(QObject *window, const int value)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_ASSERT(window);
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->borderHeight = value;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(window)
|
||||
coreData()->framelessHelper.setBorderHeight(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FramelessWindowsManager::getTitleBarHeight(QObject *window)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_ASSERT(window);
|
||||
return WinNativeEventFilter::getSystemMetric(getRawHandleFromWindow(window),
|
||||
WinNativeEventFilter::SystemMetric::TitleBarHeight);
|
||||
#else
|
||||
Q_UNUSED(window)
|
||||
return coreData()->framelessHelper.getTitleBarHeight();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::setTitleBarHeight(QObject *window, const int value)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_ASSERT(window);
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->titleBarHeight = value;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(window)
|
||||
coreData()->framelessHelper.setTitleBarHeight(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessWindowsManager::getResizable(QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
return data ? !data->fixedSize : true;
|
||||
#else
|
||||
return coreData()->framelessHelper.getResizable(window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::setResizable(QObject *window, const bool value)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
WinNativeEventFilter::setWindowResizable(getRawHandleFromWindow(window), value);
|
||||
#else
|
||||
coreData()->framelessHelper.setResizable(window, value);
|
||||
#endif
|
||||
}
|
||||
|
||||
QSize FramelessWindowsManager::getMinimumSize(QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
return data ? data->minimumSize : QSize();
|
||||
#else
|
||||
if (window->isWindowType()) {
|
||||
return qobject_cast<QWindow *>(window)->minimumSize();
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
return qobject_cast<QWidget *>(window)->minimumSize();
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
reportError();
|
||||
}
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::setMinimumSize(QObject *window, const QSize &value)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->minimumSize = value;
|
||||
}
|
||||
#else
|
||||
if (window->isWindowType()) {
|
||||
qobject_cast<QWindow *>(window)->setMinimumSize(value);
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
qobject_cast<QWidget *>(window)->setMinimumSize(value);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
reportError();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QSize FramelessWindowsManager::getMaximumSize(QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
return data ? data->maximumSize : QSize();
|
||||
#else
|
||||
if (window->isWindowType()) {
|
||||
return qobject_cast<QWindow *>(window)->maximumSize();
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
return qobject_cast<QWidget *>(window)->maximumSize();
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
reportError();
|
||||
}
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::setMaximumSize(QObject *window, const QSize &value)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->maximumSize = value;
|
||||
}
|
||||
#else
|
||||
if (window->isWindowType()) {
|
||||
qobject_cast<QWindow *>(window)->setMaximumSize(value);
|
||||
}
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
else if (window->isWidgetType()) {
|
||||
qobject_cast<QWidget *>(window)->setMaximumSize(value);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
reportError();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessWindowsManager::getTitleBarEnabled(QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
return data ? !data->disableTitleBar : true;
|
||||
#else
|
||||
return coreData()->framelessHelper.getTitleBarEnabled(window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWindowsManager::setTitleBarEnabled(QObject *window, const bool value)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const auto data = WinNativeEventFilter::windowData(window);
|
||||
if (data) {
|
||||
data->disableTitleBar = !value;
|
||||
}
|
||||
#else
|
||||
coreData()->framelessHelper.setTitleBarEnabled(window, value);
|
||||
#endif
|
||||
}
|
||||
86
src/external/framelesshelper/framelesswindowsmanager.h
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 "framelesshelper_global.h"
|
||||
#include <QRect>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
QT_FORWARD_DECLARE_CLASS(QObject)
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
|
||||
#define Q_DISABLE_MOVE(Class) \
|
||||
Class(Class &&) = delete; \
|
||||
Class &operator=(Class &&) = delete;
|
||||
|
||||
#define Q_DISABLE_COPY_MOVE(Class) \
|
||||
Q_DISABLE_COPY(Class) \
|
||||
Q_DISABLE_MOVE(Class)
|
||||
#endif
|
||||
|
||||
class FRAMELESSHELPER_EXPORT FramelessWindowsManager
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(FramelessWindowsManager)
|
||||
|
||||
public:
|
||||
explicit FramelessWindowsManager();
|
||||
~FramelessWindowsManager() = default;
|
||||
|
||||
static void addWindow(QObject *window, const bool center = false);
|
||||
|
||||
static void moveWindowToDesktopCenter(QObject *window, const bool realCenter = true);
|
||||
|
||||
static QSize getDesktopSize(QObject *window = nullptr);
|
||||
static QRect getDesktopAvailableGeometry(QObject *window = nullptr);
|
||||
static QSize getDesktopAvailableSize(QObject *window = nullptr);
|
||||
|
||||
static void addIgnoreArea(QObject *window, const QRect &area);
|
||||
static void addDraggableArea(QObject *window, const QRect &area);
|
||||
|
||||
static void addIgnoreObject(QObject *window, QObject *object);
|
||||
static void addDraggableObject(QObject *window, QObject *object);
|
||||
|
||||
static int getBorderWidth(QObject *window);
|
||||
static void setBorderWidth(QObject *window, const int value);
|
||||
|
||||
static int getBorderHeight(QObject *window);
|
||||
static void setBorderHeight(QObject *window, const int value);
|
||||
|
||||
static int getTitleBarHeight(QObject *window);
|
||||
static void setTitleBarHeight(QObject *window, const int value);
|
||||
|
||||
static bool getResizable(QObject *window);
|
||||
static void setResizable(QObject *window, const bool value = true);
|
||||
|
||||
static QSize getMinimumSize(QObject *window);
|
||||
static void setMinimumSize(QObject *window, const QSize &value);
|
||||
|
||||
static QSize getMaximumSize(QObject *window);
|
||||
static void setMaximumSize(QObject *window, const QSize &value);
|
||||
|
||||
static bool getTitleBarEnabled(QObject *window);
|
||||
static void setTitleBarEnabled(QObject *window, const bool value = true);
|
||||
};
|
||||
34
src/external/framelesshelper/lib.pro
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
TARGET = $$qtLibraryTarget(FramelessHelper)
|
||||
TEMPLATE = lib
|
||||
win32: DLLDESTDIR = $$OUT_PWD/bin
|
||||
else: unix: DESTDIR = $$OUT_PWD/bin
|
||||
QT += gui-private
|
||||
qtHaveModule(widgets): QT += widgets
|
||||
qtHaveModule(quick): QT += quick
|
||||
CONFIG += c++17 strict_c++ utf8_source warn_on
|
||||
DEFINES += \
|
||||
QT_NO_CAST_FROM_ASCII \
|
||||
QT_NO_CAST_TO_ASCII \
|
||||
FRAMELESSHELPER_BUILD_LIBRARY
|
||||
HEADERS += \
|
||||
framelesshelper_global.h \
|
||||
framelesswindowsmanager.h
|
||||
SOURCES += framelesswindowsmanager.cpp
|
||||
qtHaveModule(quick) {
|
||||
HEADERS += framelessquickhelper.h
|
||||
SOURCES += framelessquickhelper.cpp
|
||||
}
|
||||
win32 {
|
||||
DEFINES += WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_WARNINGS
|
||||
CONFIG += LINK_TO_SYSTEM_DLL
|
||||
HEADERS += winnativeeventfilter.h
|
||||
SOURCES += winnativeeventfilter.cpp
|
||||
LINK_TO_SYSTEM_DLL {
|
||||
DEFINES += WNEF_LINK_SYSLIB
|
||||
LIBS += -luser32 -lshell32 -lgdi32 -ldwmapi -lshcore -ld2d1 -luxtheme
|
||||
}
|
||||
RC_FILE = framelesshelper.rc
|
||||
} else {
|
||||
HEADERS += framelesshelper.h
|
||||
SOURCES += framelesshelper.cpp
|
||||
}
|
||||
BIN
src/external/framelesshelper/screenshots/mainwindow.png
vendored
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
src/external/framelesshelper/screenshots/qqplayer.png
vendored
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
src/external/framelesshelper/screenshots/quick.png
vendored
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
src/external/framelesshelper/screenshots/widgets.png
vendored
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src/external/framelesshelper/screenshots/win32demo1.png
vendored
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
src/external/framelesshelper/screenshots/win32demo2.png
vendored
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/external/framelesshelper/screenshots/win32demo3.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
src/external/framelesshelper/screenshots/win32demo4.png
vendored
Normal file
|
After Width: | Height: | Size: 1006 KiB |
BIN
src/external/framelesshelper/screenshots/win32demo5.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
src/external/framelesshelper/screenshots/win32demo6.png
vendored
Normal file
|
After Width: | Height: | Size: 905 KiB |
BIN
src/external/framelesshelper/screenshots/zhihuiyanglao.png
vendored
Normal file
|
After Width: | Height: | Size: 145 KiB |
2609
src/external/framelesshelper/winnativeeventfilter.cpp
vendored
Normal file
185
src/external/framelesshelper/winnativeeventfilter.h
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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 "framelesshelper_global.h"
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QColor>
|
||||
#include <QList>
|
||||
#include <QRect>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
QT_FORWARD_DECLARE_CLASS(QWindow)
|
||||
QT_FORWARD_DECLARE_CLASS(QObject)
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
|
||||
#define Q_DISABLE_MOVE(Class) \
|
||||
Class(Class &&) = delete; \
|
||||
Class &operator=(Class &&) = delete;
|
||||
|
||||
#define Q_DISABLE_COPY_MOVE(Class) \
|
||||
Q_DISABLE_COPY(Class) \
|
||||
Q_DISABLE_MOVE(Class)
|
||||
#endif
|
||||
|
||||
class FRAMELESSHELPER_EXPORT WinNativeEventFilter : public QAbstractNativeEventFilter
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(WinNativeEventFilter)
|
||||
|
||||
public:
|
||||
using WINDOWDATA = struct _WINDOWDATA
|
||||
{
|
||||
bool initialized = false /* Internal use only, don't modify it from outside */,
|
||||
fixedSize = false, mouseTransparent = false, restoreDefaultWindowStyle = false,
|
||||
enableLayeredWindow = false, disableTitleBar = false, enableBlurBehindWindow = false;
|
||||
int borderWidth = -1, borderHeight = -1, titleBarHeight = -1;
|
||||
QList<QRect> ignoreAreas = {}, draggableAreas = {};
|
||||
QList<QObject *> ignoreObjects = {}, draggableObjects = {};
|
||||
QSize maximumSize = {}, minimumSize = {};
|
||||
QString currentScreen = {};
|
||||
};
|
||||
|
||||
enum class SystemMetric { BorderWidth, BorderHeight, TitleBarHeight };
|
||||
|
||||
explicit WinNativeEventFilter();
|
||||
~WinNativeEventFilter() override = default;
|
||||
|
||||
// Make the given window become frameless.
|
||||
// The width and height will be scaled automatically according to DPI. Don't
|
||||
// scale them yourself. Just pass the original value. If you don't want to
|
||||
// change them, pass negative values to the parameters.
|
||||
static void addFramelessWindow(void *window /* HWND */,
|
||||
const WINDOWDATA *data = nullptr,
|
||||
const bool center = false,
|
||||
const int x = -1,
|
||||
const int y = -1,
|
||||
const int width = -1,
|
||||
const int height = -1);
|
||||
static void addFramelessWindow(QObject *window,
|
||||
const WINDOWDATA *data = nullptr,
|
||||
const bool center = false,
|
||||
const int x = -1,
|
||||
const int y = -1,
|
||||
const int width = -1,
|
||||
const int height = -1);
|
||||
static void removeFramelessWindow(void *window /* HWND */);
|
||||
static void removeFramelessWindow(QObject *window);
|
||||
static void clearFramelessWindows();
|
||||
|
||||
// Set borderWidth, borderHeight or titleBarHeight to a negative value to
|
||||
// restore default behavior.
|
||||
// Note that it can only affect one specific window.
|
||||
// If you want to change these values globally, use setBorderWidth instead.
|
||||
static void setWindowData(void *window /* HWND */, const WINDOWDATA *data);
|
||||
static void setWindowData(QObject *window, const WINDOWDATA *data);
|
||||
// You can modify the given window's data directly, it's the same with using
|
||||
// setWindowData.
|
||||
static WINDOWDATA *windowData(void *window /* HWND */);
|
||||
static WINDOWDATA *windowData(QObject *window);
|
||||
|
||||
// Change settings globally, not a specific window.
|
||||
// These values will be scaled automatically according to DPI, don't scale
|
||||
// them yourself. Just pass the original value.
|
||||
static void setBorderWidth(const int bw);
|
||||
static void setBorderHeight(const int bh);
|
||||
static void setTitleBarHeight(const int tbh);
|
||||
|
||||
// System metric value of the given window (if the pointer is null,
|
||||
// return the system's standard value).
|
||||
static int getSystemMetric(void *handle /* HWND */,
|
||||
const SystemMetric metric,
|
||||
const bool dpiAware = false);
|
||||
|
||||
// Use this function to trigger a frame change event or redraw a
|
||||
// specific window. Useful when you want to let some changes
|
||||
// in effect immediately.
|
||||
static void updateWindow(void *handle /* HWND */,
|
||||
const bool triggerFrameChange = true,
|
||||
const bool redraw = true);
|
||||
|
||||
// Change the geometry of a window through Win32 API.
|
||||
// The width and height will be scaled automatically according to DPI. So
|
||||
// just pass the original value.
|
||||
static void setWindowGeometry(
|
||||
void *handle /* HWND */, const int x, const int y, const int width, const int height);
|
||||
|
||||
// Move the window to the center of the desktop.
|
||||
static void moveWindowToDesktopCenter(void *handle /* HWND */);
|
||||
|
||||
// Update Qt's internal data about the window frame, otherwise Qt will
|
||||
// take the size of the window frame into account when anyone is trying to
|
||||
// change the geometry of the window. That's not what we want.
|
||||
static void updateQtFrame(QWindow *window, const int titleBarHeight);
|
||||
|
||||
// Display the system context menu.
|
||||
static bool displaySystemMenu(void *handle /* HWND */,
|
||||
const bool isRtl,
|
||||
const int x,
|
||||
const int y);
|
||||
|
||||
// Enable or disable the blur effect for a specific window.
|
||||
// On Win10 it's the Acrylic effect.
|
||||
static bool setBlurEffectEnabled(void *handle /* HWND */,
|
||||
const bool enabled = true,
|
||||
const QColor &gradientColor = Qt::white);
|
||||
|
||||
// Thin wrapper of DwmExtendFrameIntoClientArea().
|
||||
static void updateFrameMargins(void *handle /* HWND */);
|
||||
|
||||
// A resizable window can be resized and maximized, however, a fixed size
|
||||
// window can only be moved and minimized, it can't be resized and maximized.
|
||||
static void setWindowResizable(void *handle /* HWND */, const bool resizable = true);
|
||||
|
||||
// Query whether colorization is enabled or not.
|
||||
static bool colorizationEnabled();
|
||||
|
||||
// Acquire the theme/colorization color set by the user.
|
||||
static QColor colorizationColor();
|
||||
|
||||
// Query whether the user is using the light theme or not.
|
||||
static bool lightThemeEnabled();
|
||||
|
||||
// Query whether the user is using the dark theme or not.
|
||||
static bool darkThemeEnabled();
|
||||
|
||||
// Query whether the high contrast mode is enabled or not.
|
||||
static bool highContrastModeEnabled();
|
||||
|
||||
// Query whether the given window is using dark frame or not.
|
||||
static bool darkFrameEnabled(void *handle /* HWND */);
|
||||
|
||||
// Query whether the transparency effect is enabled or not.
|
||||
static bool transparencyEffectEnabled();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
/// CORE FUNCTION - THE SOUL OF THIS CODE
|
||||
///////////////////////////////////////////////
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
#else
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override;
|
||||
#endif
|
||||
};
|
||||