map wizard: finish functionality

restructure framelesshelper
This commit is contained in:
Skarn
2020-11-05 17:21:12 +03:00
parent 15adddce89
commit 07bc9bc97a
102 changed files with 375 additions and 3318 deletions

View File

@@ -1,71 +0,0 @@
# 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

View File

@@ -1,106 +0,0 @@
<?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>

View File

@@ -1,6 +0,0 @@
TARGET = QMainWindow
TEMPLATE = app
QT += widgets
SOURCES += main.cpp
FORMS += TitleBar.ui MainWindow.ui
include($$PWD/../common.pri)

View File

@@ -1,229 +0,0 @@
<?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>
<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="icon">
<iconset resource="./resources/resources.qrc">
<normaloff>:icon</normaloff>:icon</iconset>
</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="./resources/resources.qrc">
<normaloff>:./media/button_minimize_black.svg</normaloff>:./media/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="./resources/resources.qrc">
<normaloff>:./media/button_maximize_black.svg</normaloff>
<normalon>:./media/button_restore_black.svg</normalon>:./media/button_maximize_black.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>45</width>
<height>30</height>
</size>
</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="./resources/resources.qrc">
<normaloff>:./media/button_close_black.svg</normaloff>:./media/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="./resources/resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -1,120 +0,0 @@
/*
* 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();
}

View File

@@ -1,33 +0,0 @@
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)

View File

@@ -1,34 +0,0 @@
<?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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

View File

@@ -1,68 +0,0 @@
/*
* 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

View File

@@ -1,12 +0,0 @@
Qt Quick 模仿的 QQ播放器
只做了主界面,而且只有界面,没有功能,仅供展示
可以看出只要有贴图Qt Quick 做这种界面很容易的
按钮的图片有些糊,而且边缘呈锯齿状,是因为我是直接从截图里扣下来的
,没有仔细处理。由于只是示例项目,因此不会再进行任何额外处理了。
如果是公司的项目,肯定会有正规的高清贴图的。
所有来自QQ播放器的图片以及图标版权均归腾讯所有。
此仓库里提供的所有相关的素材文件,仅供学习交流,请勿传播甚至商用。

View File

@@ -1,13 +0,0 @@
@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

View File

@@ -1,28 +0,0 @@
<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>

View File

@@ -1,71 +0,0 @@
/*
* 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();
}

View File

@@ -1,16 +0,0 @@
<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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,47 +0,0 @@
/*
* 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")
}
}

View File

@@ -1,41 +0,0 @@
/*
* 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 {}
}

View File

@@ -1,49 +0,0 @@
/*
* 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")
}
}

View File

@@ -1,47 +0,0 @@
/*
* 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")
}
}

View File

@@ -1,41 +0,0 @@
/*
* 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 {}
}

View File

@@ -1,41 +0,0 @@
/*
* 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 {}
}

View File

@@ -1,41 +0,0 @@
/*
* 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 {}
}

View File

@@ -1,41 +0,0 @@
/*
* 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 {}
}

View File

@@ -1,92 +0,0 @@
/*
* 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
}
}
}
}

View File

@@ -1,41 +0,0 @@
/*
* 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 {}
}

View File

@@ -1,41 +0,0 @@
/*
* 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 {}
}

View File

@@ -1,170 +0,0 @@
/*
* 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()
}

View File

@@ -1,5 +0,0 @@
TARGET = QWidget
TEMPLATE = app
QT += widgets
SOURCES += main.cpp
include($$PWD/../common.pri)

View File

@@ -1,110 +0,0 @@
/*
* 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();
}

View File

@@ -1,6 +0,0 @@
TARGET = Quick
TEMPLATE = app
QT += quick
SOURCES += main.cpp
RESOURCES += qml.qrc
include($$PWD/../common.pri)

View File

@@ -1,77 +0,0 @@
/*
* 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();
}

View File

@@ -1,9 +0,0 @@
<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>

View File

@@ -1,48 +0,0 @@
/*
* 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")
}
}

View File

@@ -1,49 +0,0 @@
/*
* 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")
}
}

View File

@@ -1,47 +0,0 @@
/*
* 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")
}
}

View File

@@ -1,106 +0,0 @@
/*
* 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)
}

View File

@@ -1,177 +0,0 @@
/*
* 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)
}
}

View File

@@ -1,6 +0,0 @@
TARGET = Win32Demo
TEMPLATE = app
QT += widgets
HEADERS += widget.h
SOURCES += widget.cpp main.cpp
include($$PWD/../common.pri)

View File

@@ -1,67 +0,0 @@
/*
* 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();
}

View File

@@ -1,641 +0,0 @@
/*
* 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();
}

View File

@@ -1,125 +0,0 @@
/*
* 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;
};

View File

@@ -1,23 +0,0 @@
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
}

View File

@@ -1,5 +0,0 @@
TEMPLATE = subdirs
CONFIG -= ordered
qtHaveModule(widgets): SUBDIRS += QWidget QMainWindow
qtHaveModule(quick): SUBDIRS += Quick
win32: qtHaveModule(widgets): SUBDIRS += Win32Demo

View File

@@ -1,12 +0,0 @@
<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>

View File

@@ -1,5 +0,0 @@
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.

View File

@@ -1,6 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 264 B

View File

@@ -1,6 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 264 B

View File

@@ -1,3 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 225 B

View File

@@ -1,3 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 225 B

View File

@@ -1,3 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 199 B

View File

@@ -1,3 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 199 B

View File

@@ -1,11 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 430 B

View File

@@ -1,11 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -1,34 +0,0 @@
<?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>

View File

@@ -1,63 +0,0 @@
/*
* 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

View File

@@ -319,6 +319,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
{
Q_ASSERT(object);
Q_ASSERT(event);
QPointF m_pCurMousePos = {};
const auto isWindowTopLevel = [](QObject *window) -> bool {
Q_ASSERT(window);
if (window->isWindowType()) {
@@ -486,21 +487,53 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
return false;
};
const auto moveOrResize =
[this, &getWindowEdges, &isResizePermitted, &isInTitlebarArea](const QPointF &globalPoint,
const QPointF &point,
QObject *object) {
[this,
&getWindowEdges,
&isResizePermitted,
&isInTitlebarArea,
&m_pCurMousePos](const QPointF &globalPoint, const QPointF &point, QObject *object) {
Q_ASSERT(object);
QWindow *window = getWindowHandle(object);
if (window) {
const int deltaX = m_pCurMousePos.x() - globalPoint.x();
const int deltaY = m_pCurMousePos.y() - globalPoint.y();
const Qt::Edges edges = getWindowEdges(point, window->width(), window->height());
if (edges == Qt::Edges{}) {
if (isInTitlebarArea(globalPoint, point, object)) {
window->startSystemMove();
if (!window->startSystemMove()) {
// Fallback to the traditional way.
window->setX(window->x() + deltaX);
window->setY(window->y() + deltaY);
}
}
} else {
if (window->windowStates().testFlag(Qt::WindowState::WindowNoState)
&& isResizePermitted(globalPoint, point, object) && getResizable(object)) {
window->startSystemResize(edges);
if (!window->startSystemResize(edges)) {
// Fallback to the traditional way.
bool leftHandled = false, topHandled = false;
int newX = window->x();
int newY = window->y();
int newWidth = window->width();
int newHeight = window->height();
if (edges.testFlag(Qt::Edge::LeftEdge)) {
newX += deltaX;
newWidth -= deltaX;
leftHandled = true;
}
if (edges.testFlag(Qt::Edge::TopEdge)) {
newY += deltaY;
newHeight -= deltaY;
topHandled = true;
}
if (!leftHandled) {
newWidth += deltaX;
}
if (!topHandled) {
newHeight += deltaY;
}
window->setGeometry(newX, newY, newWidth, newHeight);
}
}
}
} else {
@@ -568,6 +601,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
case QEvent::MouseMove: {
const auto mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent) {
m_pCurMousePos = mouseEvent->screenPos();
QWindow *window = getWindowHandle(object);
if (window) {
if (window->windowStates().testFlag(Qt::WindowState::WindowNoState)

View File

@@ -1,5 +0,0 @@
TEMPLATE = subdirs
CONFIG -= ordered
SUBDIRS += lib examples
lib.file = lib.pro
examples.depends += lib

View File

@@ -1,62 +0,0 @@
/*
* 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

View File

@@ -25,7 +25,7 @@
#include "framelessquickhelper.h"
#include "framelesswindowsmanager.h"
#include <QtQuick/QQuickWindow>
#include <QQuickWindow>
#ifdef Q_OS_WINDOWS
#include "winnativeeventfilter.h"
#include <QOperatingSystemVersion>

View File

@@ -25,7 +25,7 @@
#pragma once
#include "framelesshelper_global.h"
#include <QtQuick/QQuickItem>
#include <QQuickItem>
#if (defined(Q_OS_WIN) || defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)) \
&& !defined(Q_OS_WINDOWS)

View File

@@ -1,34 +0,0 @@
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
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 905 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

View File

@@ -29,7 +29,7 @@ protected:
AsyncObject(std::string filename) : filename(filename) {}
public:
std::string const filename;
std::string filename;
AsyncObject() = delete;
virtual ~AsyncObject() = default;

View File

@@ -106,6 +106,19 @@ std::string MapDB::getMapName(int pMapID)
return mapName;
}
int MapDB::findMapName(const std::string &map_name)
{
for (Iterator i = gMapDB.begin(); i != gMapDB.end(); ++i)
{
if (i->getString(MapDB::InternalName) == map_name)
{
return static_cast<int>(i->getUInt(MapDB::MapID));
}
}
return -1;
}
const char * getGroundEffectDoodad(unsigned int effectID, int DoodadNum)
{
try

View File

@@ -40,6 +40,7 @@ public:
static const size_t LoadingScreen = 57; // uint [LoadingScreen]
static std::string getMapName(int pMapID);
static int findMapName(const std::string& map_name);
};
class LoadingScreensDB : public DBCFile

View File

@@ -166,5 +166,18 @@ void DBCFile::removeRecord(size_t id, size_t id_field)
}
int DBCFile::getEmptyRecordID(size_t id_field)
{
unsigned int id = 0;
for (Iterator i = begin(); i != end(); ++i)
{
id = std::max(i->getUInt(id_field), id);
}
return static_cast<int>(++id);
}

View File

@@ -187,6 +187,7 @@ public:
Record addRecord(size_t id, size_t id_field = 0);
Record addRecordCopy(size_t id, size_t id_from, size_t id_field = 0);
void removeRecord(size_t id, size_t id_field = 0);
int getEmptyRecordID(size_t id_field = 0);
private:
std::string filename;

View File

@@ -127,6 +127,8 @@ public:
void initEmptyChunks();
void setFilename(const std::string& new_filename) {filename = new_filename;};
private:
tile_mode _mode;
bool _tile_is_being_reloaded;

View File

@@ -20,15 +20,15 @@
#include <QWheelEvent>
#include <QApplication>
#include <QComboBox>
#include <QCheckBox>
#include <QStackedWidget>
#include <QDir>
#include <QMessageBox>
using namespace noggit::Red::MapCreationWizard::Ui;
MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(parent)
{
setWindowTitle ("Map Creation Wizard");
setWindowIcon (QIcon (":/icon"));
setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint);
auto layout = new QHBoxLayout(this);
@@ -83,7 +83,7 @@ MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(paren
count++;
}
auto add_btn = new QPushButton("Add",this);
auto add_btn = new QPushButton("New",this);
add_btn->setIcon(noggit::ui::font_awesome_icon(noggit::ui::font_awesome::plus));
layout_selector->addWidget(add_btn);
@@ -104,6 +104,16 @@ MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(paren
_directory = new QLineEdit(_map_settings);
map_settings_layout->addRow("Map directory:", _directory);
_is_big_alpha = new QCheckBox(this);
map_settings_layout->addRow("Big alpha:", _is_big_alpha);
_is_big_alpha->setChecked(true);
_sort_by_size_cat = new QCheckBox(this);
map_settings_layout->addRow("Sort models", _sort_by_size_cat);
_sort_by_size_cat->setChecked(true);
_sort_by_size_cat->setToolTip("Sorts models based on their size on save. May help increase loading speed of the map.");
_instance_type = new QComboBox(_map_settings);
_instance_type->addItem("None");
_instance_type->setItemData(0, QVariant(0));
@@ -200,9 +210,21 @@ MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(paren
connect(discard_btn, &QPushButton::clicked
,[&] ()
{
discardChanges();
});
connect(add_btn, &QPushButton::clicked
,[&] ()
{
addNewMap();
});
connect(remove_btn, &QPushButton::clicked
,[&] ()
{
removeMap();
});
_connection = connect(reinterpret_cast<noggit::ui::main_window*>(parent),
QOverload<int>::of(&noggit::ui::main_window::map_selected)
, [&] (int index)
@@ -266,6 +288,7 @@ MapCreationWizard::MapCreationWizard(QWidget* parent) : noggit::ui::widget(paren
void MapCreationWizard::selectMap(int map_id)
{
_is_new_record = false;
DBCFile::Record record = gMapDB.getByID(map_id);
_cur_map_id = map_id;
@@ -279,6 +302,13 @@ void MapCreationWizard::selectMap(int map_id)
_minimap_widget->world(_world);
_directory->setText(record.getString(1));
_directory->setEnabled(false);
_is_big_alpha->setChecked(_world->mapIndex.hasBigAlpha());
_is_big_alpha->setEnabled(false);
_sort_by_size_cat->setChecked(_world->mapIndex.sort_models_by_size_class());
_instance_type->setCurrentIndex(record.getInt(2));
_map_name->fill(record, 5);
@@ -335,7 +365,51 @@ void MapCreationWizard::wheelEvent(QWheelEvent* event)
void MapCreationWizard::saveCurrentEntry()
{
// Save ADTs to disk
if (_is_new_record)
{
auto map_internal_name = _directory->text().toStdString();
// Check if map with that name already exists
int id = gMapDB.findMapName(map_internal_name);
if (id >= 0)
{
QMessageBox prompt;
prompt.setIcon (QMessageBox::Warning);
prompt.setWindowFlags(Qt::WindowStaysOnTopHint);
prompt.setText ("Warning!");
prompt.setInformativeText ("Saving failed. The map with this directory name already exists. Rename it to save.");
prompt.addButton ("Okay", QMessageBox::AcceptRole);
prompt.setWindowFlags (Qt::CustomizeWindowHint | Qt::WindowTitleHint);
prompt.exec();
return;
}
// Create WDT empty file for new map
std::stringstream filename;
filename << "World\\Maps\\" << map_internal_name << "\\" << map_internal_name << ".wdt";
QSettings settings;
auto project_path = boost::filesystem::path (settings.value ("project/path").toString().toStdString());
QDir dir((project_path / "/world/maps/" / map_internal_name).c_str());
if (!dir.exists())
dir.mkpath(".");
auto filepath = project_path / noggit::mpq::normalized_filename (filename.str());
QFile file(filepath.string().c_str());
file.open(QIODevice::WriteOnly);
file.close();
}
// Save ADTs and WDT to disk
_world->mapIndex.setBigAlpha(_is_big_alpha->isChecked());
_world->setBasename(_directory->text().toStdString());
_world->mapIndex.set_sort_models_by_size_class(_sort_by_size_cat->isChecked());
_world->mapIndex.saveChanged(_world, true);
_world->mapIndex.save();
@@ -343,6 +417,7 @@ void MapCreationWizard::saveCurrentEntry()
DBCFile::Record record = _is_new_record ? gMapDB.addRecord(_cur_map_id) : gMapDB.getByID(_cur_map_id);
record.writeString(1, _directory->text().toStdString());
record.write(2, _instance_type->itemData(_instance_type->currentIndex()).toInt());
_map_name->toRecord(record, 5);
@@ -361,10 +436,22 @@ void MapCreationWizard::saveCurrentEntry()
gMapDB.save();
emit map_dbc_updated();
_is_new_record = false;
}
void MapCreationWizard::discardChanges()
{
if (!_is_new_record)
{
selectMap(_cur_map_id);
}
else
{
addNewMap();
}
}
@@ -374,6 +461,62 @@ MapCreationWizard::~MapCreationWizard()
disconnect(_connection);
}
void MapCreationWizard::addNewMap()
{
_is_new_record = true;
_cur_map_id = gMapDB.getEmptyRecordID();
if (_world)
{
delete _world;
}
_world = new World("New_Map", _cur_map_id, true);
_minimap_widget->world(_world);
_directory->setText("New_Map");
_directory->setEnabled(true);
_is_big_alpha->setChecked(true);
_is_big_alpha->setEnabled(true);
_sort_by_size_cat->setChecked(true);
_instance_type->setCurrentIndex(0);
_map_name->clear();
_area_table_id->setValue(0);
_map_desc_alliance->clear();
_map_desc_horde->clear();
_loading_screen->setValue(0);
_minimap_icon_scale->setValue(0.0f);
_corpse_map_id->setCurrentIndex(0);
_corpse_x->setValue(0.0f);
_corpse_y->setValue(0.0f);
_time_of_day_override->setValue(0);
_expansion_id->setCurrentIndex(0);
_raid_offset->setValue(0);
_max_players->setValue(0);
}
void MapCreationWizard::removeMap()
{
if (!_is_new_record && _cur_map_id >= 0)
{
gMapDB.removeRecord(_cur_map_id);
gMapDB.save();
}
emit map_dbc_updated();
addNewMap();
}
LocaleDBCEntry::LocaleDBCEntry(QWidget* parent) : QWidget(parent)
{
@@ -486,5 +629,15 @@ void LocaleDBCEntry::toRecord(DBCFile::Record &record, size_t field)
record.write(field + 16, _flags->value());
}
void LocaleDBCEntry::clear()
{
for (int loc = 0; loc < 16; ++loc)
{
setValue("", loc);
}
_flags->setValue(0);
}

View File

@@ -11,6 +11,7 @@
#include <QComboBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QCheckBox>
#include <QDoubleSpinBox>
#include <QHBoxLayout>
#include <QStackedWidget>
@@ -44,6 +45,7 @@ namespace noggit
std::string getValue(int locale) { return _widget_map.at(_locale_names[locale])->text().toStdString(); };
void fill(DBCFile::Record& record, size_t field);
void clear();
void toRecord(DBCFile::Record& record, size_t field);
private:
@@ -76,6 +78,8 @@ namespace noggit
class MapCreationWizard : public ui::widget
{
Q_OBJECT
public:
MapCreationWizard(QWidget *parent = nullptr);
~MapCreationWizard();
@@ -83,6 +87,9 @@ namespace noggit
void wheelEvent(QWheelEvent *event) override;
void destroyFakeWorld() { if(_world) delete _world; _world = nullptr; _minimap_widget->world (nullptr); };
signals:
void map_dbc_updated();
private:
ui::minimap_widget* _minimap_widget;
int _selected_map;
@@ -90,6 +97,10 @@ namespace noggit
// Map settings
QLineEdit* _directory;
QCheckBox* _is_big_alpha;
QCheckBox* _sort_by_size_cat;
QComboBox* _instance_type;
LocaleDBCEntry* _map_name;
@@ -114,7 +125,7 @@ namespace noggit
World* _world = nullptr;
bool _is_new_record = false;
int _cur_map_id = 0;
int _cur_map_id = -1;
QMetaObject::Connection _connection;
@@ -123,6 +134,9 @@ namespace noggit
void saveCurrentEntry();
void discardChanges();
void addNewMap();
void removeMap();
};
}
}

View File

@@ -96,10 +96,10 @@ bool World::IsEditableWorld(int pMapId)
return false;
}
World::World(const std::string& name, int map_id)
World::World(const std::string& name, int map_id, bool create_empty)
: _model_instance_storage(this)
, _tile_update_queue(this)
, mapIndex (name, map_id, this)
, mapIndex (name, map_id, this, create_empty)
, horizon(name, &mapIndex)
, mWmoFilename("")
, mWmoEntry(ENTRY_MODF())
@@ -2857,3 +2857,9 @@ float World::getMaxTileHeight(const tile_index& tile)
return max_height;
}
void World::setBasename(const std::string &name)
{
basename = name;
mapIndex.set_basename(name);
}

View File

@@ -85,7 +85,9 @@ public:
OutdoorLightStats outdoorLightStats;
explicit World(const std::string& name, int map_id);
explicit World(const std::string& name, int map_id, bool create_empty = false);
void setBasename(const std::string& name);
void initDisplay();

View File

@@ -24,7 +24,7 @@
#include <forward_list>
#include <cstdlib>
MapIndex::MapIndex (const std::string &pBasename, int map_id, World* world)
MapIndex::MapIndex (const std::string &pBasename, int map_id, World* world, bool create_empty)
: basename(pBasename)
, _map_id (map_id)
, _last_unload_time((clock() / CLOCKS_PER_SEC)) // to not try to unload right away
@@ -41,6 +41,27 @@ MapIndex::MapIndex (const std::string &pBasename, int map_id, World* world)
_unload_interval = settings.value("unload_interval", 5).toInt();
_unload_dist = settings.value("unload_dist", 5).toInt();
if (create_empty)
{
mHasAGlobalWMO = false;
mBigAlpha = true;
_sort_models_by_size_class = true;
changed = false;
for (int j = 0; j < 64; ++j)
{
for (int i = 0; i < 64; ++i)
{
mTiles[j][i].tile = nullptr;
mTiles[j][i].onDisc = false;
mTiles[j][i].flags = 0;
}
}
return;
}
std::stringstream filename;
filename << "World\\Maps\\" << basename << "\\" << basename << ".wdt";
@@ -1131,3 +1152,24 @@ void MapIndex::removeTile(const tile_index &tile)
changed = true;
}
void MapIndex::set_basename(const std::string &pBasename)
{
basename = pBasename;
for (int z = 0; z < 64; ++z)
{
for (int x = 0; x < 64; ++x)
{
if (!mTiles[z][x].tile)
{
continue;
}
std::stringstream filename;
filename << "World\\Maps\\" << basename << "\\" << basename << "_" << x << "_" << z << ".adt";
mTiles[z][x].tile->setFilename(filename.str());
}
}
}

View File

@@ -149,7 +149,9 @@ public:
);
}
MapIndex(const std::string& pBasename, int map_id, World*);
MapIndex(const std::string& pBasename, int map_id, World*, bool create_empty = false);
void set_basename(const std::string& pBasename);
void enterTile(const tile_index& tile);
MapTile *loadTile(const tile_index& tile, bool reloading = false);
@@ -189,8 +191,10 @@ public:
void convert_alphamap(bool to_big_alpha);
bool hasBigAlpha() const { return mBigAlpha; }
void setBigAlpha(bool state) { mBigAlpha = state; };
bool sort_models_by_size_class() const { return _sort_models_by_size_class; }
void set_sort_models_by_size_class(bool state) { _sort_models_by_size_class = state; }
uint32_t newGUID();
@@ -221,7 +225,7 @@ private:
bool _uid_fix_all_in_progress = false;
const std::string basename;
std::string basename;
public:
int const _map_id;

Some files were not shown because too many files have changed in this diff Show More