mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-01-22 20:04:32 +08:00
update
This commit is contained in:
parent
f616a2da6a
commit
41cbeef3fd
@ -535,104 +535,104 @@
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="315"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="307"/>
|
||||
<source>Dark Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="83"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="91"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="99"/>
|
||||
<source>Quit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="92"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="84"/>
|
||||
<source>Are you sure you want to exit the program?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="93"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="85"/>
|
||||
<source>Minimize</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="96"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="88"/>
|
||||
<source>Friendly Reminder</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="96"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="88"/>
|
||||
<source>FluentUI is hidden from the tray, click on the tray to activate the window again</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="100"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="344"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="92"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="336"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="111"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="103"/>
|
||||
<source>Open in Separate Window</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="208"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="200"/>
|
||||
<source>Click Time</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="218"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="210"/>
|
||||
<source>Search</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="301"/>
|
||||
<source>Finish</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="302"/>
|
||||
<source>Next</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="311"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="303"/>
|
||||
<source>Previous</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="315"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="307"/>
|
||||
<source>Here you can switch to night mode.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="317"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<source>Hide Easter eggs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="317"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<source>Try a few more clicks!!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="341"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="333"/>
|
||||
<source>Upgrade Tips</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="342"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>FluentUI is currently up to date </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="342"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source> -- The current app version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="342"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>
|
||||
Now go and download the new version?
|
||||
|
||||
@ -641,17 +641,17 @@ Updated content:
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="345"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="372"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="364"/>
|
||||
<source>The current version is already the latest</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="379"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="371"/>
|
||||
<source>The network is abnormal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -535,104 +535,104 @@
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="315"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="307"/>
|
||||
<source>Dark Mode</source>
|
||||
<translation type="unfinished">夜间模式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="83"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="91"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="99"/>
|
||||
<source>Quit</source>
|
||||
<translation type="unfinished">退出</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="92"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="84"/>
|
||||
<source>Are you sure you want to exit the program?</source>
|
||||
<translation type="unfinished">您确定要退出程序吗</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="93"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="85"/>
|
||||
<source>Minimize</source>
|
||||
<translation type="unfinished">最小化</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="96"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="88"/>
|
||||
<source>Friendly Reminder</source>
|
||||
<translation type="unfinished">友情提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="96"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="88"/>
|
||||
<source>FluentUI is hidden from the tray, click on the tray to activate the window again</source>
|
||||
<translation type="unfinished">FluentUI 在托盘中处于隐藏状态,单击托盘以再次激活窗口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="100"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="344"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="92"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="336"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="111"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="103"/>
|
||||
<source>Open in Separate Window</source>
|
||||
<translation type="unfinished">在独立窗口中打开</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="208"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="200"/>
|
||||
<source>Click Time</source>
|
||||
<translation type="unfinished">点击次数</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="218"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="210"/>
|
||||
<source>Search</source>
|
||||
<translation type="unfinished">搜索</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="301"/>
|
||||
<source>Finish</source>
|
||||
<translation type="unfinished">完成</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="302"/>
|
||||
<source>Next</source>
|
||||
<translation type="unfinished">下一步</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="311"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="303"/>
|
||||
<source>Previous</source>
|
||||
<translation type="unfinished">上一步</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="315"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="307"/>
|
||||
<source>Here you can switch to night mode.</source>
|
||||
<translation type="unfinished">在这里,您可以切换到夜间模式。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="317"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<source>Hide Easter eggs</source>
|
||||
<translation type="unfinished">隐藏彩蛋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="317"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="309"/>
|
||||
<source>Try a few more clicks!!</source>
|
||||
<translation type="unfinished">再试几下!!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="341"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="333"/>
|
||||
<source>Upgrade Tips</source>
|
||||
<translation type="unfinished">升级提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="342"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>FluentUI is currently up to date </source>
|
||||
<translation type="unfinished">FluentUI 目前最新版本 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="342"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source> -- The current app version</source>
|
||||
<translation type="unfinished"> -- 当前应用版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="342"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>
|
||||
Now go and download the new version?
|
||||
|
||||
@ -645,17 +645,17 @@ Updated content:
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="345"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished">确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="372"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="364"/>
|
||||
<source>The current version is already the latest</source>
|
||||
<translation type="unfinished">当前版本已经是最新版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="379"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="371"/>
|
||||
<source>The network is abnormal</source>
|
||||
<translation type="unfinished">网络异常</translation>
|
||||
</message>
|
||||
|
@ -35,17 +35,9 @@ FluWindow {
|
||||
}
|
||||
}
|
||||
|
||||
onFirstVisible: {
|
||||
timer_tour_delay.restart()
|
||||
}
|
||||
|
||||
Timer{
|
||||
id:timer_tour_delay
|
||||
interval: 200
|
||||
onTriggered: {
|
||||
onLazyLoad: {
|
||||
tour.open()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
checkUpdate(true)
|
||||
@ -168,7 +160,7 @@ FluWindow {
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
appBar.setHitTestVisible(layout_back_buttons)
|
||||
window.setHitTestVisible(layout_back_buttons)
|
||||
}
|
||||
}
|
||||
FluRemoteLoader{
|
||||
@ -226,9 +218,9 @@ FluWindow {
|
||||
ItemsOriginal.paneItemMenu = nav_item_right_menu
|
||||
ItemsFooter.navigationView = nav_view
|
||||
ItemsFooter.paneItemMenu = nav_item_right_menu
|
||||
appBar.setHitTestVisible(nav_view.buttonMenu)
|
||||
appBar.setHitTestVisible(nav_view.buttonBack)
|
||||
appBar.setHitTestVisible(nav_view.imageLogo)
|
||||
window.setHitTestVisible(nav_view.buttonMenu)
|
||||
window.setHitTestVisible(nav_view.buttonBack)
|
||||
window.setHitTestVisible(nav_view.imageLogo)
|
||||
setCurrentIndex(0)
|
||||
}
|
||||
}
|
||||
|
459
src/FluFrameless.cpp
Normal file
459
src/FluFrameless.cpp
Normal file
@ -0,0 +1,459 @@
|
||||
#include "FluFrameless.h"
|
||||
|
||||
#include <QQuickWindow>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#pragma comment (lib,"user32.lib")
|
||||
#pragma comment (lib,"dwmapi.lib")
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <dwmapi.h>
|
||||
static inline QByteArray qtNativeEventType()
|
||||
{
|
||||
static const auto result = "windows_generic_MSG";
|
||||
return result;
|
||||
}
|
||||
static inline bool isCompositionEnabled(){
|
||||
typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
|
||||
HMODULE module = ::LoadLibraryW(L"dwmapi.dll");
|
||||
if (module)
|
||||
{
|
||||
BOOL composition_enabled = false;
|
||||
DwmIsCompositionEnabledPtr dwm_is_composition_enabled;
|
||||
dwm_is_composition_enabled= reinterpret_cast<DwmIsCompositionEnabledPtr>(::GetProcAddress(module, "DwmIsCompositionEnabled"));
|
||||
if (dwm_is_composition_enabled)
|
||||
{
|
||||
dwm_is_composition_enabled(&composition_enabled);
|
||||
}
|
||||
return composition_enabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
FluFrameless::FluFrameless(QQuickItem *parent)
|
||||
: QQuickItem{parent}
|
||||
{
|
||||
appbar(nullptr);
|
||||
maximizeButton(nullptr);
|
||||
minimizedButton(nullptr);
|
||||
closeButton(nullptr);
|
||||
topmost(false);
|
||||
disabled(false);
|
||||
}
|
||||
|
||||
FluFrameless::~FluFrameless(){
|
||||
qApp->removeNativeEventFilter(this);
|
||||
}
|
||||
|
||||
void FluFrameless::componentComplete(){
|
||||
if(_disabled){
|
||||
return;
|
||||
}
|
||||
_current = window()->winId();
|
||||
window()->setFlags(( window()->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint);
|
||||
if(!_fixSize){
|
||||
window()->setFlag(Qt::WindowMaximizeButtonHint);
|
||||
}
|
||||
window()->installEventFilter(this);
|
||||
qApp->installNativeEventFilter(this);
|
||||
if(_appbar){
|
||||
_appbar->installEventFilter(this);
|
||||
}
|
||||
if(_maximizeButton){
|
||||
setHitTestVisible(_maximizeButton);
|
||||
}
|
||||
if(_minimizedButton){
|
||||
setHitTestVisible(_minimizedButton);
|
||||
}
|
||||
if(_closeButton){
|
||||
setHitTestVisible(_closeButton);
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
|
||||
if(_fixSize){
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME);
|
||||
for (int i = 0; i < qApp->screens().count(); ++i) {
|
||||
connect( qApp->screens().at(i),&QScreen::logicalDotsPerInchChanged,this,[=]{
|
||||
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
});
|
||||
}
|
||||
}else{
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME);
|
||||
}
|
||||
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
|
||||
connect(window(),&QQuickWindow::screenChanged,this,[hwnd]{
|
||||
::SetWindowPos(hwnd,0,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER);
|
||||
::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
||||
});
|
||||
#endif
|
||||
connect(this,&FluFrameless::topmostChanged,this,[this]{
|
||||
_setWindowTopmost(topmost());
|
||||
});
|
||||
_setWindowTopmost(topmost());
|
||||
}
|
||||
|
||||
bool FluFrameless::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result){
|
||||
#ifdef Q_OS_WIN
|
||||
if ((eventType != qtNativeEventType()) || !message) {
|
||||
return false;
|
||||
}
|
||||
const auto msg = static_cast<const MSG *>(message);
|
||||
const HWND hwnd = msg->hwnd;
|
||||
if (!hwnd || !msg) {
|
||||
return false;
|
||||
}
|
||||
const qint64 wid = reinterpret_cast<qint64>(hwnd);
|
||||
if(wid != _current){
|
||||
return false;
|
||||
}
|
||||
const UINT uMsg = msg->message;
|
||||
const WPARAM wParam = msg->wParam;
|
||||
const LPARAM lParam = msg->lParam;
|
||||
static QPoint offsetXY;
|
||||
if(uMsg == WM_WINDOWPOSCHANGING){
|
||||
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lParam);
|
||||
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
wp->flags |= SWP_NOCOPYBITS;
|
||||
*result = ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}else if(uMsg == WM_NCCALCSIZE){
|
||||
const auto clientRect = ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
||||
const LONG originalTop = clientRect->top;
|
||||
const LONG originalLeft = clientRect->left;
|
||||
const LONG originalRight = clientRect->right;
|
||||
const LONG originalBottom = clientRect->bottom;
|
||||
const LRESULT hitTestResult = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam);
|
||||
if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) {
|
||||
*result = hitTestResult;
|
||||
return true;
|
||||
}
|
||||
int offsetSize = 0;
|
||||
bool isMaximum = ::IsZoomed(hwnd);
|
||||
offsetXY = QPoint(abs(clientRect->left - originalLeft),abs(clientRect->top - originalTop));
|
||||
if(isMaximum || _isFullScreen()){
|
||||
offsetSize = 0;
|
||||
}else{
|
||||
offsetSize = 1;
|
||||
}
|
||||
if(!isCompositionEnabled()){
|
||||
offsetSize = 0;
|
||||
}
|
||||
if (!isMaximum || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) {
|
||||
clientRect->top = originalTop + offsetSize;
|
||||
clientRect->bottom = originalBottom - offsetSize;
|
||||
clientRect->left = originalLeft + offsetSize;
|
||||
clientRect->right = originalRight - offsetSize;
|
||||
}
|
||||
*result = WVR_REDRAW;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCHITTEST){
|
||||
if(_hitMaximizeButton()){
|
||||
if (*result == HTNOWHERE) {
|
||||
*result = HTZOOM;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*result = 0;
|
||||
POINT nativeGlobalPos{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
POINT nativeLocalPos = nativeGlobalPos;
|
||||
::ScreenToClient(hwnd, &nativeLocalPos);
|
||||
RECT clientRect{0, 0, 0, 0};
|
||||
::GetClientRect(hwnd, &clientRect);
|
||||
auto clientWidth = clientRect.right-clientRect.left;
|
||||
auto clientHeight = clientRect.bottom-clientRect.top;
|
||||
bool left = nativeLocalPos.x < _margins;
|
||||
bool right = nativeLocalPos.x > clientWidth - _margins;
|
||||
bool top = nativeLocalPos.y < _margins;
|
||||
bool bottom = nativeLocalPos.y > clientHeight - _margins;
|
||||
*result = 0;
|
||||
if (!_fixSize && !_isFullScreen() && !_isMaximized()) {
|
||||
if (left && top) {
|
||||
*result = HTTOPLEFT;
|
||||
} else if (left && bottom) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else if (right && top) {
|
||||
*result = HTTOPRIGHT;
|
||||
} else if (right && bottom) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
} else if (left) {
|
||||
*result = HTLEFT;
|
||||
} else if (right) {
|
||||
*result = HTRIGHT;
|
||||
} else if (top) {
|
||||
*result = HTTOP;
|
||||
} else if (bottom) {
|
||||
*result = HTBOTTOM;
|
||||
}
|
||||
}
|
||||
if (0 != *result) {
|
||||
return true;
|
||||
}
|
||||
auto aa = _hitAppBar();
|
||||
if(aa){
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
*result = HTCLIENT;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN){
|
||||
if(_hitMaximizeButton()){
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_maximizeButton,&event);
|
||||
return true;
|
||||
}
|
||||
}else if(uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP){
|
||||
if(_hitMaximizeButton()){
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_maximizeButton,&event);
|
||||
return true;
|
||||
}
|
||||
}else if(uMsg == WM_NCPAINT){
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCACTIVATE){
|
||||
*result = ::DefWindowProcW(hwnd, WM_NCACTIVATE, wParam, -1);
|
||||
return true;
|
||||
}else if(uMsg == WM_GETMINMAXINFO){
|
||||
MINMAXINFO* minmaxInfo = reinterpret_cast<MINMAXINFO *>(lParam);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
minmaxInfo->ptMaxPosition.x = 0;
|
||||
minmaxInfo->ptMaxPosition.y = 0;
|
||||
minmaxInfo->ptMaxSize.x = 0;
|
||||
minmaxInfo->ptMaxSize.y = 0;
|
||||
#else
|
||||
auto pixelRatio = window()->devicePixelRatio();
|
||||
auto geometry = window()->screen()->availableGeometry();
|
||||
RECT rect;
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
|
||||
minmaxInfo->ptMaxPosition.x = rect.left - offsetXY.x();
|
||||
minmaxInfo->ptMaxPosition.y = rect.top - offsetXY.x();
|
||||
minmaxInfo->ptMaxSize.x = geometry.width()*pixelRatio + offsetXY.x() * 2;
|
||||
minmaxInfo->ptMaxSize.y = geometry.height()*pixelRatio + offsetXY.y() * 2;
|
||||
#endif
|
||||
return false;
|
||||
}else if(uMsg == WM_NCRBUTTONDOWN){
|
||||
if (wParam == HTCAPTION) {
|
||||
_showSystemMenu(QCursor::pos());
|
||||
}
|
||||
}else if(uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN){
|
||||
const bool altPressed = ((wParam == VK_MENU) || (::GetKeyState(VK_MENU) < 0));
|
||||
const bool spacePressed = ((wParam == VK_SPACE) || (::GetKeyState(VK_SPACE) < 0));
|
||||
if (altPressed && spacePressed) {
|
||||
auto pos = window()->position();
|
||||
_showSystemMenu(QPoint(pos.x(),pos.y()+_appbar->height()));
|
||||
}
|
||||
}else if(uMsg == WM_SYSCOMMAND){
|
||||
if(wParam == SC_MINIMIZE){
|
||||
if(window()->transientParent()){
|
||||
window()->transientParent()->showMinimized();
|
||||
}else{
|
||||
window()->showMinimized();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FluFrameless::_isMaximized(){
|
||||
return window()->visibility() == QWindow::Maximized;
|
||||
}
|
||||
|
||||
bool FluFrameless::_isFullScreen(){
|
||||
return window()->visibility() == QWindow::FullScreen;
|
||||
}
|
||||
|
||||
void FluFrameless::_showSystemMenu(QPoint point){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
DWORD style = ::GetWindowLongPtr(hwnd,GWL_STYLE);
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_SYSMENU);
|
||||
const HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
|
||||
if(_isMaximized() || _isFullScreen()){
|
||||
::EnableMenuItem(hMenu,SC_MOVE,MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu,SC_RESTORE,MFS_ENABLED);
|
||||
}else{
|
||||
::EnableMenuItem(hMenu,SC_MOVE,MFS_ENABLED);
|
||||
::EnableMenuItem(hMenu,SC_RESTORE,MFS_DISABLED);
|
||||
}
|
||||
if(!_fixSize && !_isMaximized() && !_isFullScreen()){
|
||||
::EnableMenuItem(hMenu,SC_SIZE,MFS_ENABLED);
|
||||
::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_ENABLED);
|
||||
}else{
|
||||
::EnableMenuItem(hMenu,SC_SIZE,MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_DISABLED);
|
||||
}
|
||||
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), point.x()*window()->devicePixelRatio(), point.y()*window()->devicePixelRatio(), 0, hwnd, nullptr);
|
||||
if (result != FALSE) {
|
||||
::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0);
|
||||
}
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style &~ WS_SYSMENU);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FluFrameless::_containsCursorToItem(QQuickItem* item){
|
||||
if(!item || !item->isVisible()){
|
||||
return false;
|
||||
}
|
||||
auto point = QCursor::pos();
|
||||
auto rect = QRectF(item->mapToGlobal(QPoint(0,0)),item->size());
|
||||
if(point.x()>rect.x() && point.x()<(rect.x()+rect.width()) && point.y()>rect.y() && point.y()<(rect.y()+rect.height())){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FluFrameless::_hitAppBar(){
|
||||
foreach (auto item, _hitTestList) {
|
||||
if(_containsCursorToItem(item)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(_containsCursorToItem(_appbar)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FluFrameless::_hitMaximizeButton(){
|
||||
if(_containsCursorToItem(_maximizeButton)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FluFrameless::_updateCursor(int edges){
|
||||
switch (edges) {
|
||||
case 0:
|
||||
window()->setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case Qt::LeftEdge:
|
||||
case Qt::RightEdge:
|
||||
window()->setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case Qt::TopEdge:
|
||||
case Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case Qt::LeftEdge | Qt::TopEdge:
|
||||
case Qt::RightEdge | Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case Qt::RightEdge | Qt::TopEdge:
|
||||
case Qt::LeftEdge | Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FluFrameless::showFullScreen(){
|
||||
window()->showFullScreen();
|
||||
}
|
||||
|
||||
void FluFrameless::showMaximized(){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
::ShowWindow(hwnd,3);
|
||||
#else
|
||||
window()->showMaximized();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FluFrameless::showMinimized(){
|
||||
window()->showMinimized();
|
||||
}
|
||||
|
||||
void FluFrameless::showNormal(){
|
||||
window()->showNormal();
|
||||
}
|
||||
|
||||
void FluFrameless::setHitTestVisible(QQuickItem* val){
|
||||
_hitTestList.append(val);
|
||||
}
|
||||
|
||||
|
||||
void FluFrameless::_setWindowTopmost(bool topmost){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
if(topmost){
|
||||
::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}else{
|
||||
::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
#else
|
||||
window()->setFlag(Qt::WindowStaysOnTopHint,topmost);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FluFrameless::eventFilter(QObject *obj, QEvent *ev){
|
||||
#ifndef Q_OS_WIN
|
||||
switch (ev->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
if(_edges!=0){
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
if(event->button() == Qt::LeftButton){
|
||||
_updateCursor(_edges);
|
||||
window()->startSystemResize(Qt::Edges(_edges));
|
||||
}
|
||||
}else{
|
||||
if(_hitAppBar()){
|
||||
window()->startSystemMove();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
_edges = 0;
|
||||
break;
|
||||
case QEvent::MouseMove: {
|
||||
if(_isMaximized() || _isFullScreen()){
|
||||
break;
|
||||
}
|
||||
if(_fixSize){
|
||||
break;
|
||||
}
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
QPoint p =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
event->pos();
|
||||
#else
|
||||
event->position().toPoint();
|
||||
#endif
|
||||
if(p.x() >= _margins && p.x() <= (window()->width() - _margins) && p.y() >= _margins && p.y() <= (window()->height() - _margins)){
|
||||
if(_edges != 0){
|
||||
_edges = 0;
|
||||
_updateCursor(_edges);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_edges = 0;
|
||||
if ( p.x() < _margins ) {
|
||||
_edges |= Qt::LeftEdge;
|
||||
}
|
||||
if ( p.x() > (window()->width() - _margins) ) {
|
||||
_edges |= Qt::RightEdge;
|
||||
}
|
||||
if ( p.y() < _margins ) {
|
||||
_edges |= Qt::TopEdge;
|
||||
}
|
||||
if ( p.y() > (window()->height() - _margins) ) {
|
||||
_edges |= Qt::BottomEdge;
|
||||
}
|
||||
_updateCursor(_edges);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return QObject::eventFilter(obj, ev);
|
||||
}
|
58
src/FluFrameless.h
Normal file
58
src/FluFrameless.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef FLUFRAMELESS_H
|
||||
#define FLUFRAMELESS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include "stdafx.h"
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
|
||||
using QT_ENTER_EVENT_TYPE = QEnterEvent;
|
||||
#else
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = long;
|
||||
using QT_ENTER_EVENT_TYPE = QEvent;
|
||||
#endif
|
||||
|
||||
|
||||
class FluFrameless : public QQuickItem,QAbstractNativeEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QQuickItem*,appbar)
|
||||
Q_PROPERTY_AUTO(bool,topmost)
|
||||
Q_PROPERTY_AUTO(QQuickItem*,maximizeButton)
|
||||
Q_PROPERTY_AUTO(QQuickItem*,minimizedButton)
|
||||
Q_PROPERTY_AUTO(QQuickItem*,closeButton)
|
||||
Q_PROPERTY_AUTO(bool,disabled)
|
||||
Q_PROPERTY_AUTO(bool,fixSize)
|
||||
QML_NAMED_ELEMENT(FluFrameless)
|
||||
public:
|
||||
explicit FluFrameless(QQuickItem* parent = nullptr);
|
||||
~FluFrameless();
|
||||
void componentComplete() override;
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
|
||||
Q_INVOKABLE void showFullScreen();
|
||||
Q_INVOKABLE void showMaximized();
|
||||
Q_INVOKABLE void showMinimized();
|
||||
Q_INVOKABLE void showNormal();
|
||||
Q_INVOKABLE void setHitTestVisible(QQuickItem*);
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
private:
|
||||
bool _isFullScreen();
|
||||
bool _isMaximized();
|
||||
void _updateCursor(int edges);
|
||||
void _setWindowTopmost(bool topmost);
|
||||
void _showSystemMenu(QPoint point);
|
||||
bool _containsCursorToItem(QQuickItem* item);
|
||||
bool _hitAppBar();
|
||||
bool _hitMaximizeButton();
|
||||
qint64 _current;
|
||||
|
||||
private:
|
||||
int _edges = 0;
|
||||
int _margins = 8;
|
||||
QList<QPointer<QQuickItem>> _hitTestList;
|
||||
};
|
||||
|
||||
#endif // FLUFRAMELESS_H
|
@ -1,493 +0,0 @@
|
||||
#include "FluFramelessHelper.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QQuickItem>
|
||||
#include "FluTools.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#pragma comment (lib,"user32.lib")
|
||||
#pragma comment (lib,"dwmapi.lib")
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
static inline QByteArray qtNativeEventType()
|
||||
{
|
||||
static const auto result = "windows_generic_MSG";
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool isCompositionEnabled(){
|
||||
typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
|
||||
HMODULE module = ::LoadLibraryW(L"dwmapi.dll");
|
||||
if (module)
|
||||
{
|
||||
BOOL composition_enabled = false;
|
||||
DwmIsCompositionEnabledPtr dwm_is_composition_enabled;
|
||||
dwm_is_composition_enabled= reinterpret_cast<DwmIsCompositionEnabledPtr>(::GetProcAddress(module, "DwmIsCompositionEnabled"));
|
||||
if (dwm_is_composition_enabled)
|
||||
{
|
||||
dwm_is_composition_enabled(&composition_enabled);
|
||||
}
|
||||
return composition_enabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FramelessEventFilter::FramelessEventFilter(FluFramelessHelper* helper){
|
||||
_helper = helper;
|
||||
_current = _helper->window_->winId();
|
||||
}
|
||||
|
||||
bool FramelessEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result){
|
||||
#ifdef Q_OS_WIN
|
||||
if ((eventType != qtNativeEventType()) || !message || _helper.isNull() || _helper->window_.isNull()) {
|
||||
return false;
|
||||
}
|
||||
const auto msg = static_cast<const MSG *>(message);
|
||||
const HWND hwnd = msg->hwnd;
|
||||
if (!hwnd || !msg) {
|
||||
return false;
|
||||
}
|
||||
const qint64 wid = reinterpret_cast<qint64>(hwnd);
|
||||
if(wid != _current){
|
||||
return false;
|
||||
}
|
||||
const UINT uMsg = msg->message;
|
||||
const WPARAM wParam = msg->wParam;
|
||||
const LPARAM lParam = msg->lParam;
|
||||
static QPoint offsetXY;
|
||||
if(uMsg == WM_WINDOWPOSCHANGING){
|
||||
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lParam);
|
||||
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
wp->flags |= SWP_NOCOPYBITS;
|
||||
*result = ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}else if(uMsg == WM_NCCALCSIZE){
|
||||
const auto clientRect = ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
||||
const LONG originalTop = clientRect->top;
|
||||
const LONG originalLeft = clientRect->left;
|
||||
const LONG originalRight = clientRect->right;
|
||||
const LONG originalBottom = clientRect->bottom;
|
||||
const LRESULT hitTestResult = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam);
|
||||
if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) {
|
||||
*result = hitTestResult;
|
||||
return true;
|
||||
}
|
||||
int offsetSize = 0;
|
||||
bool isMaximum = ::IsZoomed(hwnd);
|
||||
offsetXY = QPoint(abs(clientRect->left - originalLeft),abs(clientRect->top - originalTop));
|
||||
if(isMaximum || _helper->fullScreen()){
|
||||
offsetSize = 0;
|
||||
}else{
|
||||
offsetSize = 1;
|
||||
}
|
||||
if(!isCompositionEnabled()){
|
||||
offsetSize = 0;
|
||||
}
|
||||
if (!isMaximum || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) {
|
||||
clientRect->top = originalTop + offsetSize;
|
||||
clientRect->bottom = originalBottom - offsetSize;
|
||||
clientRect->left = originalLeft + offsetSize;
|
||||
clientRect->right = originalRight - offsetSize;
|
||||
}
|
||||
*result = WVR_REDRAW;
|
||||
return true;
|
||||
}if(uMsg == WM_NCHITTEST){
|
||||
if(FluTools::getInstance()->isWindows11OrGreater() && _helper->hoverMaxBtn() && _helper->resizeable()){
|
||||
if (*result == HTNOWHERE) {
|
||||
*result = HTZOOM;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*result = 0;
|
||||
POINT nativeGlobalPos{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
POINT nativeLocalPos = nativeGlobalPos;
|
||||
::ScreenToClient(hwnd, &nativeLocalPos);
|
||||
RECT clientRect{0, 0, 0, 0};
|
||||
::GetClientRect(hwnd, &clientRect);
|
||||
auto clientWidth = clientRect.right-clientRect.left;
|
||||
auto clientHeight = clientRect.bottom-clientRect.top;
|
||||
int margins = _helper->getMargins();
|
||||
bool left = nativeLocalPos.x < margins;
|
||||
bool right = nativeLocalPos.x > clientWidth - margins;
|
||||
bool top = nativeLocalPos.y < margins;
|
||||
bool bottom = nativeLocalPos.y > clientHeight - margins;
|
||||
*result = 0;
|
||||
if (_helper->resizeable() && !_helper->fullScreen() && !_helper->maximized()) {
|
||||
if (left && top) {
|
||||
*result = HTTOPLEFT;
|
||||
} else if (left && bottom) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else if (right && top) {
|
||||
*result = HTTOPRIGHT;
|
||||
} else if (right && bottom) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
} else if (left) {
|
||||
*result = HTLEFT;
|
||||
} else if (right) {
|
||||
*result = HTRIGHT;
|
||||
} else if (top) {
|
||||
*result = HTTOP;
|
||||
} else if (bottom) {
|
||||
*result = HTBOTTOM;
|
||||
}
|
||||
}
|
||||
if (0 != *result) {
|
||||
return true;
|
||||
}
|
||||
QVariant appBar = _helper->getAppBar();
|
||||
if(!appBar.isNull()&& _helper->hoverAppBar()){
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
*result = HTCLIENT;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN){
|
||||
if(_helper->hoverMaxBtn()){
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_helper->maximizeButton(),&event);
|
||||
return true;
|
||||
}
|
||||
}else if(uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP){
|
||||
if(_helper->hoverMaxBtn()){
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_helper->maximizeButton(),&event);
|
||||
}
|
||||
}else if(uMsg == WM_NCPAINT){
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}else if(uMsg == WM_NCACTIVATE){
|
||||
*result = ::DefWindowProcW(hwnd, WM_NCACTIVATE, wParam, -1);
|
||||
return true;
|
||||
}else if(uMsg == WM_GETMINMAXINFO){
|
||||
MINMAXINFO* minmaxInfo = reinterpret_cast<MINMAXINFO *>(lParam);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
minmaxInfo->ptMaxPosition.x = 0;
|
||||
minmaxInfo->ptMaxPosition.y = 0;
|
||||
minmaxInfo->ptMaxSize.x = 0;
|
||||
minmaxInfo->ptMaxSize.y = 0;
|
||||
#else
|
||||
auto pixelRatio = _helper->window_->devicePixelRatio();
|
||||
auto geometry = _helper->window_->screen()->availableGeometry();
|
||||
RECT rect;
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
|
||||
minmaxInfo->ptMaxPosition.x = rect.left - offsetXY.x();
|
||||
minmaxInfo->ptMaxPosition.y = rect.top - offsetXY.x();
|
||||
minmaxInfo->ptMaxSize.x = geometry.width()*pixelRatio + offsetXY.x() * 2;
|
||||
minmaxInfo->ptMaxSize.y = geometry.height()*pixelRatio + offsetXY.y() * 2;
|
||||
#endif
|
||||
return false;
|
||||
}else if(uMsg == WM_NCRBUTTONDOWN){
|
||||
if (wParam == HTCAPTION) {
|
||||
_helper->showSystemMenu(QCursor::pos());
|
||||
}
|
||||
}else if(uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN){
|
||||
const bool altPressed = ((wParam == VK_MENU) || (::GetKeyState(VK_MENU) < 0));
|
||||
const bool spacePressed = ((wParam == VK_SPACE) || (::GetKeyState(VK_SPACE) < 0));
|
||||
if (altPressed && spacePressed) {
|
||||
auto pos = _helper->window_->position();
|
||||
_helper->showSystemMenu(QPoint(pos.x(),pos.y()+_helper->getAppBarHeight()));
|
||||
}
|
||||
}else if(uMsg == WM_SYSCOMMAND){
|
||||
if(wParam == SC_MINIMIZE){
|
||||
if(_helper->window_->transientParent()){
|
||||
_helper->window_->transientParent()->showMinimized();
|
||||
}else{
|
||||
_helper->window_->showMinimized();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FluFramelessHelper::FluFramelessHelper(QQuickItem *parent)
|
||||
: QQuickItem{parent}
|
||||
{
|
||||
}
|
||||
|
||||
void FluFramelessHelper::classBegin(){
|
||||
}
|
||||
|
||||
void FluFramelessHelper::_updateCursor(int edges){
|
||||
switch (edges) {
|
||||
case 0:
|
||||
window_->setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case Qt::LeftEdge:
|
||||
case Qt::RightEdge:
|
||||
window_->setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case Qt::TopEdge:
|
||||
case Qt::BottomEdge:
|
||||
window_->setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case Qt::LeftEdge | Qt::TopEdge:
|
||||
case Qt::RightEdge | Qt::BottomEdge:
|
||||
window_->setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case Qt::RightEdge | Qt::TopEdge:
|
||||
case Qt::LeftEdge | Qt::BottomEdge:
|
||||
window_->setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::eventFilter(QObject *obj, QEvent *ev){
|
||||
if (!window_.isNull() && window_->flags()) {
|
||||
switch (ev->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
if(_edges!=0){
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
if(event->button() == Qt::LeftButton){
|
||||
_updateCursor(_edges);
|
||||
window_->startSystemResize(Qt::Edges(_edges));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
_edges = 0;
|
||||
break;
|
||||
case QEvent::MouseMove: {
|
||||
if(maximized() || fullScreen()){
|
||||
break;
|
||||
}
|
||||
if(!resizeable()){
|
||||
break;
|
||||
}
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
QPoint p =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
event->pos();
|
||||
#else
|
||||
event->position().toPoint();
|
||||
#endif
|
||||
if(p.x() >= _margins && p.x() <= (window_->width() - _margins) && p.y() >= _margins && p.y() <= (window_->height() - _margins)){
|
||||
if(_edges != 0){
|
||||
_edges = 0;
|
||||
_updateCursor(_edges);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_edges = 0;
|
||||
if ( p.x() < _margins ) {
|
||||
_edges |= Qt::LeftEdge;
|
||||
}
|
||||
if ( p.x() > (window_->width() - _margins) ) {
|
||||
_edges |= Qt::RightEdge;
|
||||
}
|
||||
if ( p.y() < _margins ) {
|
||||
_edges |= Qt::TopEdge;
|
||||
}
|
||||
if ( p.y() > (window_->height() - _margins) ) {
|
||||
_edges |= Qt::BottomEdge;
|
||||
}
|
||||
_updateCursor(_edges);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, ev);
|
||||
}
|
||||
|
||||
void FluFramelessHelper::componentComplete(){
|
||||
this->window_ = window();
|
||||
if(!window_.isNull()){
|
||||
_stayTop = QQmlProperty(window_,"stayTop");
|
||||
_screen = QQmlProperty(window_,"screen");
|
||||
_fixSize = QQmlProperty(window_,"fixSize");
|
||||
_realHeight = QQmlProperty(window_,"_realHeight");
|
||||
_realWidth = QQmlProperty(window_,"_realWidth");
|
||||
_appBarHeight = QQmlProperty(window_,"_appBarHeight");
|
||||
_appBar = window_->property("appBar");
|
||||
#ifdef Q_OS_WIN
|
||||
if(!_appBar.isNull()){
|
||||
_appBar.value<QObject*>()->setProperty("systemMoveEnable",false);
|
||||
}
|
||||
window_->setFlags((window_->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
if(FluTools::getInstance()->isSoftware()){
|
||||
window_->setFlag(Qt::FramelessWindowHint,false);
|
||||
}
|
||||
#endif
|
||||
if(resizeable()){
|
||||
window_->setFlag(Qt::WindowMaximizeButtonHint);
|
||||
}
|
||||
_nativeEvent =new FramelessEventFilter(this);
|
||||
qApp->installNativeEventFilter(_nativeEvent);
|
||||
HWND hwnd = reinterpret_cast<HWND>(window_->winId());
|
||||
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
|
||||
if(resizeable()){
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME);
|
||||
}else{
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME);
|
||||
for (int i = 0; i < qApp->screens().count(); ++i) {
|
||||
connect( qApp->screens().at(i),&QScreen::logicalDotsPerInchChanged,this,[=]{
|
||||
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
});
|
||||
}
|
||||
}
|
||||
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
|
||||
#else
|
||||
window_->setFlags((window_->flags() & (~Qt::WindowMinMaxButtonsHint) & (~Qt::Dialog)) | Qt::FramelessWindowHint | Qt::Window);
|
||||
window_->installEventFilter(this);
|
||||
#endif
|
||||
int w = _realWidth.read().toInt();
|
||||
int h = _realHeight.read().toInt()+_appBarHeight.read().toInt();
|
||||
if(!resizeable()){
|
||||
window_->setMaximumSize(QSize(w,h));
|
||||
window_->setMinimumSize(QSize(w,h));
|
||||
}
|
||||
window_->resize(QSize(w,h));
|
||||
_onStayTopChange();
|
||||
_stayTop.connectNotifySignal(this,SLOT(_onStayTopChange()));
|
||||
_screen.connectNotifySignal(this,SLOT(_onScreenChanged()));
|
||||
Q_EMIT loadCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
void FluFramelessHelper::_onScreenChanged(){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window_->winId());
|
||||
::SetWindowPos(hwnd,0,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER);
|
||||
::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FluFramelessHelper::showSystemMenu(QPoint point){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window_->winId());
|
||||
DWORD style = ::GetWindowLongPtr(hwnd,GWL_STYLE);
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_SYSMENU);
|
||||
const HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
|
||||
if(maximized() || fullScreen()){
|
||||
::EnableMenuItem(hMenu,SC_MOVE,MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu,SC_RESTORE,MFS_ENABLED);
|
||||
}else{
|
||||
::EnableMenuItem(hMenu,SC_MOVE,MFS_ENABLED);
|
||||
::EnableMenuItem(hMenu,SC_RESTORE,MFS_DISABLED);
|
||||
}
|
||||
if(resizeable() && !maximized() && !fullScreen()){
|
||||
::EnableMenuItem(hMenu,SC_SIZE,MFS_ENABLED);
|
||||
::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_ENABLED);
|
||||
}else{
|
||||
::EnableMenuItem(hMenu,SC_SIZE,MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_DISABLED);
|
||||
}
|
||||
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), point.x()*window_->devicePixelRatio(), point.y()*window_->devicePixelRatio(), 0, hwnd, nullptr);
|
||||
if (result != FALSE) {
|
||||
::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0);
|
||||
}
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style &~ WS_SYSMENU);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FluFramelessHelper::showMaximized(){
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window_->winId());
|
||||
::ShowWindow(hwnd,3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FluFramelessHelper::_onStayTopChange(){
|
||||
bool isStayTop = _stayTop.read().toBool();
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window_->winId());
|
||||
if(isStayTop){
|
||||
::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}else{
|
||||
::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
#else
|
||||
window_->setFlag(Qt::WindowStaysOnTopHint,isStayTop);
|
||||
#endif
|
||||
}
|
||||
|
||||
FluFramelessHelper::~FluFramelessHelper(){
|
||||
if (!window_.isNull()) {
|
||||
window_->setFlags(Qt::Window);
|
||||
#ifdef Q_OS_WIN
|
||||
qApp->removeNativeEventFilter(_nativeEvent);
|
||||
delete _nativeEvent;
|
||||
#endif
|
||||
window_->removeEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::hoverMaxBtn(){
|
||||
if(_appBar.isNull()){
|
||||
return false;
|
||||
}
|
||||
QVariant var;
|
||||
QMetaObject::invokeMethod(_appBar.value<QObject*>(), "_maximizeButtonHover",Q_RETURN_ARG(QVariant, var));
|
||||
if(var.isNull()){
|
||||
return false;
|
||||
}
|
||||
return var.toBool();
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::hoverAppBar(){
|
||||
if(_appBar.isNull()){
|
||||
return false;
|
||||
}
|
||||
QVariant var;
|
||||
QMetaObject::invokeMethod(_appBar.value<QObject*>(), "_appBarHover",Q_RETURN_ARG(QVariant, var));
|
||||
if(var.isNull()){
|
||||
return false;
|
||||
}
|
||||
return var.toBool();
|
||||
}
|
||||
|
||||
QVariant FluFramelessHelper::getAppBar(){
|
||||
return _appBar;
|
||||
}
|
||||
|
||||
int FluFramelessHelper::getAppBarHeight(){
|
||||
if(_appBar.isNull()){
|
||||
return 0;
|
||||
}
|
||||
QVariant var = _appBar.value<QObject*>()->property("height");
|
||||
if(var.isNull()){
|
||||
return 0;
|
||||
}
|
||||
return var.toInt();
|
||||
}
|
||||
|
||||
QObject* FluFramelessHelper::maximizeButton(){
|
||||
if(_appBar.isNull()){
|
||||
return nullptr;
|
||||
}
|
||||
QVariant var = _appBar.value<QObject*>()->property("buttonMaximize");
|
||||
if(var.isNull()){
|
||||
return nullptr;
|
||||
}
|
||||
return var.value<QObject*>();
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::resizeable(){
|
||||
return !_fixSize.read().toBool();
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::maximized(){
|
||||
return window_->visibility() == QWindow::Maximized;
|
||||
}
|
||||
|
||||
bool FluFramelessHelper::fullScreen(){
|
||||
return window_->visibility() == QWindow::FullScreen;
|
||||
}
|
||||
|
||||
int FluFramelessHelper::getMargins(){
|
||||
return _margins;
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
#ifndef FLUFRAMELESSHELPER_H
|
||||
#define FLUFRAMELESSHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQuickWindow>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QQmlProperty>
|
||||
#include <QQuickItem>
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
|
||||
using QT_ENTER_EVENT_TYPE = QEnterEvent;
|
||||
#else
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = long;
|
||||
using QT_ENTER_EVENT_TYPE = QEvent;
|
||||
#endif
|
||||
|
||||
class FluFramelessHelper;
|
||||
|
||||
/**
|
||||
* @brief The FramelessEventFilter class
|
||||
*/
|
||||
class FramelessEventFilter : public QAbstractNativeEventFilter
|
||||
{
|
||||
public:
|
||||
FramelessEventFilter(FluFramelessHelper* helper);
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
|
||||
public:
|
||||
QPointer<FluFramelessHelper> _helper = nullptr;
|
||||
qint64 _current = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FluFramelessHelper class
|
||||
*/
|
||||
class FluFramelessHelper : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(FluFramelessHelper)
|
||||
public:
|
||||
explicit FluFramelessHelper(QQuickItem *parent = nullptr);
|
||||
~FluFramelessHelper();
|
||||
void classBegin() override;
|
||||
void componentComplete() override;
|
||||
bool hoverMaxBtn();
|
||||
bool hoverAppBar();
|
||||
bool resizeable();
|
||||
int getMargins();
|
||||
bool maximized();
|
||||
bool fullScreen();
|
||||
int getAppBarHeight();
|
||||
QVariant getAppBar();
|
||||
QObject* maximizeButton();
|
||||
Q_INVOKABLE void showSystemMenu(QPoint point);
|
||||
Q_INVOKABLE void showMaximized();
|
||||
Q_SIGNAL void loadCompleted();
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
private:
|
||||
void _updateCursor(int edges);
|
||||
Q_SLOT void _onStayTopChange();
|
||||
Q_SLOT void _onScreenChanged();
|
||||
public:
|
||||
QPointer<QQuickWindow> window_ = nullptr;
|
||||
private:
|
||||
FramelessEventFilter* _nativeEvent = nullptr;
|
||||
QQmlProperty _stayTop;
|
||||
QQmlProperty _screen;
|
||||
QQmlProperty _fixSize;
|
||||
QQmlProperty _realHeight;
|
||||
QQmlProperty _realWidth;
|
||||
QQmlProperty _appBarHeight;
|
||||
QVariant _appBar;
|
||||
int _edges = 0;
|
||||
int _margins = 8;
|
||||
};
|
||||
|
||||
#endif // FLUFRAMELESSHELPER_H
|
@ -11,9 +11,9 @@
|
||||
#include "FluCaptcha.h"
|
||||
#include "FluTreeModel.h"
|
||||
#include "FluRectangle.h"
|
||||
#include "FluFramelessHelper.h"
|
||||
#include "FluQrCodeItem.h"
|
||||
#include "FluTableSortProxyModel.h"
|
||||
#include "FluFrameless.h"
|
||||
|
||||
void FluentUI::registerTypes(QQmlEngine *engine){
|
||||
initializeEngine(engine,uri);
|
||||
@ -31,7 +31,7 @@ void FluentUI::registerTypes(const char *uri){
|
||||
qmlRegisterType<FluAccentColor>(uri,major,minor,"FluAccentColor");
|
||||
qmlRegisterType<FluTreeModel>(uri,major,minor,"FluTreeModel");
|
||||
qmlRegisterType<FluRectangle>(uri,major,minor,"FluRectangle");
|
||||
qmlRegisterType<FluFramelessHelper>(uri,major,minor,"FluFramelessHelper");
|
||||
qmlRegisterType<FluFrameless>(uri,major,minor,"FluFrameless");
|
||||
qmlRegisterType<FluTableSortProxyModel>(uri,major,minor,"FluTableSortProxyModel");
|
||||
|
||||
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluAcrylic.qml"),uri,major,minor,"FluAcrylic");
|
||||
|
@ -34,7 +34,13 @@ Rectangle{
|
||||
property int iconSize: 20
|
||||
property bool isMac: FluTools.isMacos()
|
||||
property color borerlessColor : FluTheme.primaryColor
|
||||
property bool systemMoveEnable: true
|
||||
property alias buttonStayTop: btn_stay_top
|
||||
property alias buttonMinimize: btn_minimize
|
||||
property alias buttonMaximize: btn_maximize
|
||||
property alias buttonClose: btn_close
|
||||
property alias buttonDark: btn_dark
|
||||
property alias layoutMacosButtons: layout_macos_buttons
|
||||
property alias layoutStandardbuttons: layout_standard_buttons
|
||||
property var maxClickListener : function(){
|
||||
if(FluTools.isMacos()){
|
||||
if (d.win.visibility === Window.FullScreen)
|
||||
@ -71,16 +77,6 @@ Rectangle{
|
||||
FluTheme.darkMode = FluThemeType.Dark
|
||||
}
|
||||
}
|
||||
property var systemMenuListener: function(){
|
||||
if(d.win instanceof FluWindow){
|
||||
d.win.showSystemMenu()
|
||||
}
|
||||
}
|
||||
property alias buttonStayTop: btn_stay_top
|
||||
property alias buttonMinimize: btn_minimize
|
||||
property alias buttonMaximize: btn_maximize
|
||||
property alias buttonClose: btn_close
|
||||
property alias buttonDark: btn_dark
|
||||
id:control
|
||||
color: Qt.rgba(0,0,0,0)
|
||||
height: visible ? 30 : 0
|
||||
@ -108,29 +104,6 @@ Rectangle{
|
||||
return false
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
id:mouse_app_bar
|
||||
anchors.fill: parent
|
||||
onPositionChanged:
|
||||
(mouse)=>{
|
||||
if(systemMoveEnable){
|
||||
d.win.startSystemMove()
|
||||
}
|
||||
}
|
||||
onDoubleClicked:
|
||||
(mouse)=>{
|
||||
if(systemMoveEnable && d.resizable && Qt.LeftButton){
|
||||
btn_maximize.clicked()
|
||||
}
|
||||
}
|
||||
acceptedButtons: Qt.LeftButton|Qt.RightButton
|
||||
onClicked:
|
||||
(mouse)=>{
|
||||
if (systemMoveEnable && mouse.button === Qt.RightButton){
|
||||
control.systemMenuListener()
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
@ -153,9 +126,8 @@ Rectangle{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_mac_buttons
|
||||
id:com_macos_buttons
|
||||
RowLayout{
|
||||
FluImageButton{
|
||||
Layout.preferredHeight: 12
|
||||
@ -186,24 +158,11 @@ Rectangle{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluLoader{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
sourceComponent: isMac ? com_mac_buttons : undefined
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
id:layout_row
|
||||
id:layout_standard_buttons
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
height: control.height
|
||||
spacing: 0
|
||||
Component.onCompleted: {
|
||||
setHitTestVisible(layout_row)
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_dark
|
||||
Layout.preferredWidth: 40
|
||||
@ -273,12 +232,9 @@ Rectangle{
|
||||
horizontalPadding: 0
|
||||
iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
|
||||
color: {
|
||||
if(down){
|
||||
if(pressed){
|
||||
return maximizePressColor
|
||||
}
|
||||
if(FluTools.isWindows11OrGreater()){
|
||||
return d.hoverMaxBtn ? maximizeHoverColor : maximizeNormalColor
|
||||
}
|
||||
return hovered ? maximizeHoverColor : maximizeNormalColor
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@ -312,36 +268,13 @@ Rectangle{
|
||||
onClicked: closeClickListener()
|
||||
}
|
||||
}
|
||||
function _maximizeButtonHover(){
|
||||
var hover = false
|
||||
if(btn_maximize.visible && FluTools.isWindows11OrGreater() && d.resizable){
|
||||
if(d.containsPointToItem(FluTools.cursorPos(),btn_maximize)){
|
||||
hover = true
|
||||
}else{
|
||||
if(btn_maximize.down){
|
||||
btn_maximize.down = false
|
||||
FluLoader{
|
||||
id:layout_macos_buttons
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
d.hoverMaxBtn = hover
|
||||
return hover;
|
||||
}
|
||||
function _appBarHover(){
|
||||
var cursorPos = FluTools.cursorPos()
|
||||
for(var i =0 ;i< d.hitTestList.length; i++){
|
||||
var item = d.hitTestList[i]
|
||||
if(item.visible){
|
||||
if(d.containsPointToItem(cursorPos,item)){
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if(d.containsPointToItem(cursorPos,control)){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
function setHitTestVisible(id){
|
||||
d.hitTestList.push(id)
|
||||
sourceComponent: isMac ? com_macos_buttons : undefined
|
||||
}
|
||||
}
|
||||
|
@ -56,29 +56,20 @@ Window {
|
||||
event.accepted = false
|
||||
}
|
||||
}
|
||||
signal showSystemMenu
|
||||
signal initArgument(var argument)
|
||||
signal firstVisible()
|
||||
property int _realHeight
|
||||
property int _realWidth
|
||||
property int _appBarHeight: appBar.height
|
||||
signal lazyLoad()
|
||||
property var _windowRegister
|
||||
property string _route
|
||||
id:window
|
||||
color:"transparent"
|
||||
Component.onCompleted: {
|
||||
FluRouter.addWindow(window)
|
||||
_realHeight = height
|
||||
_realWidth = width
|
||||
useSystemAppBar = FluApp.useSystemAppBar
|
||||
if(useSystemAppBar && autoCenter){
|
||||
moveWindowToDesktopCenter()
|
||||
}
|
||||
fixWindowSize()
|
||||
initArgument(argument)
|
||||
if(!useSystemAppBar){
|
||||
loader_frameless_helper.sourceComponent = com_frameless_helper
|
||||
}
|
||||
if(window.autoVisible){
|
||||
if(window.autoMaximize){
|
||||
window.showMaximized()
|
||||
@ -87,33 +78,30 @@ Window {
|
||||
}
|
||||
}
|
||||
}
|
||||
onShowSystemMenu: {
|
||||
if(loader_frameless_helper.item){
|
||||
loader_frameless_helper.item.showSystemMenu()
|
||||
}
|
||||
}
|
||||
onVisibleChanged: {
|
||||
if(visible && d.isFirstVisible){
|
||||
window.firstVisible()
|
||||
d.isFirstVisible = false
|
||||
if(visible && d.isLazyInit){
|
||||
window.lazyLoad()
|
||||
d.isLazyInit = false
|
||||
}
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property bool isFirstVisible: true
|
||||
property bool isLazyInit: true
|
||||
}
|
||||
Connections{
|
||||
target: window
|
||||
function onClosing(event){closeListener(event)}
|
||||
}
|
||||
Component{
|
||||
id:com_frameless_helper
|
||||
FluFramelessHelper{
|
||||
onLoadCompleted:{
|
||||
if(autoCenter){
|
||||
window.moveWindowToDesktopCenter()
|
||||
}
|
||||
}
|
||||
FluFrameless{
|
||||
id: frameless
|
||||
appbar: window.appBar
|
||||
maximizeButton: appBar.buttonMaximize
|
||||
fixSize: window.fixSize
|
||||
topmost: window.stayTop
|
||||
disabled: FluApp.useSystemAppBar
|
||||
Component.onCompleted: {
|
||||
frameless.setHitTestVisible(appBar.layoutMacosButtons)
|
||||
frameless.setHitTestVisible(appBar.layoutStandardbuttons)
|
||||
}
|
||||
}
|
||||
Component{
|
||||
@ -198,9 +186,6 @@ Window {
|
||||
border.color: window.resizeBorderColor
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
id:loader_frameless_helper
|
||||
}
|
||||
FluLoader{
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
@ -256,11 +241,6 @@ Window {
|
||||
return com_border
|
||||
}
|
||||
}
|
||||
function showLoading(text = qsTr("Loading..."),cancel = true){
|
||||
loader_loading.loadingText = text
|
||||
loader_loading.cancel = cancel
|
||||
loader_loading.sourceComponent = com_loading
|
||||
}
|
||||
function hideLoading(){
|
||||
loader_loading.sourceComponent = undefined
|
||||
}
|
||||
@ -298,12 +278,17 @@ Window {
|
||||
}
|
||||
}
|
||||
function showMaximized(){
|
||||
if(FluTools.isWin()){
|
||||
if(loader_frameless_helper.item){
|
||||
loader_frameless_helper.item.showMaximized()
|
||||
frameless.showMaximized()
|
||||
}
|
||||
}else{
|
||||
window.visibility = Window.Maximized
|
||||
function showLoading(text = "",cancel = true){
|
||||
if(text===""){
|
||||
text = qsTr("Loading...")
|
||||
}
|
||||
loader_loading.loadingText = text
|
||||
loader_loading.cancel = cancel
|
||||
loader_loading.sourceComponent = com_loading
|
||||
}
|
||||
function setHitTestVisible(val){
|
||||
frameless.setHitTestVisible(val)
|
||||
}
|
||||
}
|
||||
|
@ -65,17 +65,26 @@ Module {
|
||||
}
|
||||
}
|
||||
Component {
|
||||
name: "FluFramelessHelper"
|
||||
name: "FluFrameless"
|
||||
defaultProperty: "data"
|
||||
prototype: "QQuickItem"
|
||||
exports: ["FluentUI/FluFramelessHelper 1.0"]
|
||||
exports: ["FluentUI/FluFrameless 1.0"]
|
||||
exportMetaObjectRevisions: [0]
|
||||
Signal { name: "loadCompleted" }
|
||||
Method {
|
||||
name: "showSystemMenu"
|
||||
Parameter { name: "point"; type: "QPoint" }
|
||||
}
|
||||
Property { name: "appbar"; type: "QQuickItem"; isPointer: true }
|
||||
Property { name: "topmost"; type: "bool" }
|
||||
Property { name: "maximizeButton"; type: "QQuickItem"; isPointer: true }
|
||||
Property { name: "minimizedButton"; type: "QQuickItem"; isPointer: true }
|
||||
Property { name: "closeButton"; type: "QQuickItem"; isPointer: true }
|
||||
Property { name: "disabled"; type: "bool" }
|
||||
Property { name: "fixSize"; type: "bool" }
|
||||
Method { name: "showFullScreen" }
|
||||
Method { name: "showMaximized" }
|
||||
Method { name: "showMinimized" }
|
||||
Method { name: "showNormal" }
|
||||
Method {
|
||||
name: "setHitTestVisible"
|
||||
Parameter { type: "QQuickItem"; isPointer: true }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
name: "FluNavigationViewType"
|
||||
@ -2180,49 +2189,52 @@ Module {
|
||||
Property { name: "iconSize"; type: "int" }
|
||||
Property { name: "isMac"; type: "bool" }
|
||||
Property { name: "borerlessColor"; type: "QColor" }
|
||||
Property { name: "systemMoveEnable"; type: "bool" }
|
||||
Property { name: "maxClickListener"; type: "QVariant" }
|
||||
Property { name: "minClickListener"; type: "QVariant" }
|
||||
Property { name: "closeClickListener"; type: "QVariant" }
|
||||
Property { name: "stayTopClickListener"; type: "QVariant" }
|
||||
Property { name: "darkClickListener"; type: "QVariant" }
|
||||
Property { name: "systemMenuListener"; type: "QVariant" }
|
||||
Property {
|
||||
name: "buttonStayTop"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_20"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonMinimize"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_20"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonMaximize"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_20"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonClose"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_20"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonDark"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_20"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Method { name: "_maximizeButtonHover"; type: "QVariant" }
|
||||
Method { name: "_appBarHover"; type: "QVariant" }
|
||||
Method {
|
||||
name: "setHitTestVisible"
|
||||
type: "QVariant"
|
||||
Parameter { name: "id"; type: "QVariant" }
|
||||
Property {
|
||||
name: "layoutMacosButtons"
|
||||
type: "FluLoader_QMLTYPE_13"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "layoutStandardbuttons"
|
||||
type: "QQuickRowLayout"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
}
|
||||
Component {
|
||||
@ -2894,15 +2906,15 @@ Module {
|
||||
defaultProperty: "data"
|
||||
Property { name: "logo"; type: "QUrl" }
|
||||
Property { name: "title"; type: "string" }
|
||||
Property { name: "items"; type: "FluObject_QMLTYPE_128"; isPointer: true }
|
||||
Property { name: "footerItems"; type: "FluObject_QMLTYPE_128"; isPointer: true }
|
||||
Property { name: "items"; type: "FluObject_QMLTYPE_168"; isPointer: true }
|
||||
Property { name: "footerItems"; type: "FluObject_QMLTYPE_168"; isPointer: true }
|
||||
Property { name: "displayMode"; type: "int" }
|
||||
Property { name: "autoSuggestBox"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "topPadding"; type: "int" }
|
||||
Property { name: "pageMode"; type: "int" }
|
||||
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_34"; isPointer: true }
|
||||
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_34"; isPointer: true }
|
||||
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_32"; isPointer: true }
|
||||
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_32"; isPointer: true }
|
||||
Property { name: "navCompactWidth"; type: "int" }
|
||||
Property { name: "navTopMargin"; type: "int" }
|
||||
Property { name: "cellHeight"; type: "int" }
|
||||
@ -2910,13 +2922,13 @@ Module {
|
||||
Property { name: "hideNavAppBar"; type: "bool" }
|
||||
Property {
|
||||
name: "buttonMenu"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_20"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonBack"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_20"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
@ -3777,24 +3789,14 @@ Module {
|
||||
Property { name: "resizeBorderColor"; type: "QColor" }
|
||||
Property { name: "resizeBorderWidth"; type: "int" }
|
||||
Property { name: "closeListener"; type: "QVariant" }
|
||||
Property { name: "_realHeight"; type: "int" }
|
||||
Property { name: "_realWidth"; type: "int" }
|
||||
Property { name: "_appBarHeight"; type: "int" }
|
||||
Property { name: "_windowRegister"; type: "QVariant" }
|
||||
Property { name: "_route"; type: "string" }
|
||||
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
||||
Signal { name: "showSystemMenu" }
|
||||
Signal {
|
||||
name: "initArgument"
|
||||
Parameter { name: "argument"; type: "QVariant" }
|
||||
}
|
||||
Signal { name: "firstVisible" }
|
||||
Method {
|
||||
name: "showLoading"
|
||||
type: "QVariant"
|
||||
Parameter { name: "text"; type: "QVariant" }
|
||||
Parameter { name: "cancel"; type: "QVariant" }
|
||||
}
|
||||
Signal { name: "lazyLoad" }
|
||||
Method { name: "hideLoading"; type: "QVariant" }
|
||||
Method {
|
||||
name: "showSuccess"
|
||||
@ -3837,6 +3839,17 @@ Module {
|
||||
Parameter { name: "data"; type: "QVariant" }
|
||||
}
|
||||
Method { name: "showMaximized"; type: "QVariant" }
|
||||
Method {
|
||||
name: "showLoading"
|
||||
type: "QVariant"
|
||||
Parameter { name: "text"; type: "QVariant" }
|
||||
Parameter { name: "cancel"; type: "QVariant" }
|
||||
}
|
||||
Method {
|
||||
name: "setHitTestVisible"
|
||||
type: "QVariant"
|
||||
Parameter { name: "val"; type: "QVariant" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
prototype: "QQuickWindowQmlImpl"
|
||||
@ -3870,24 +3883,14 @@ Module {
|
||||
Property { name: "resizeBorderColor"; type: "QColor" }
|
||||
Property { name: "resizeBorderWidth"; type: "int" }
|
||||
Property { name: "closeListener"; type: "QVariant" }
|
||||
Property { name: "_realHeight"; type: "int" }
|
||||
Property { name: "_realWidth"; type: "int" }
|
||||
Property { name: "_appBarHeight"; type: "int" }
|
||||
Property { name: "_windowRegister"; type: "QVariant" }
|
||||
Property { name: "_route"; type: "string" }
|
||||
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
||||
Signal { name: "showSystemMenu" }
|
||||
Signal {
|
||||
name: "initArgument"
|
||||
Parameter { name: "argument"; type: "QVariant" }
|
||||
}
|
||||
Signal { name: "firstVisible" }
|
||||
Method {
|
||||
name: "showLoading"
|
||||
type: "QVariant"
|
||||
Parameter { name: "text"; type: "QVariant" }
|
||||
Parameter { name: "cancel"; type: "QVariant" }
|
||||
}
|
||||
Signal { name: "lazyLoad" }
|
||||
Method { name: "hideLoading"; type: "QVariant" }
|
||||
Method {
|
||||
name: "showSuccess"
|
||||
@ -3930,6 +3933,17 @@ Module {
|
||||
Parameter { name: "data"; type: "QVariant" }
|
||||
}
|
||||
Method { name: "showMaximized"; type: "QVariant" }
|
||||
Method {
|
||||
name: "showLoading"
|
||||
type: "QVariant"
|
||||
Parameter { name: "text"; type: "QVariant" }
|
||||
Parameter { name: "cancel"; type: "QVariant" }
|
||||
}
|
||||
Method {
|
||||
name: "setHitTestVisible"
|
||||
type: "QVariant"
|
||||
Parameter { name: "val"; type: "QVariant" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
prototype: "QQuickItem"
|
||||
|
@ -34,7 +34,13 @@ Rectangle{
|
||||
property int iconSize: 20
|
||||
property bool isMac: FluTools.isMacos()
|
||||
property color borerlessColor : FluTheme.primaryColor
|
||||
property bool systemMoveEnable: true
|
||||
property alias buttonStayTop: btn_stay_top
|
||||
property alias buttonMinimize: btn_minimize
|
||||
property alias buttonMaximize: btn_maximize
|
||||
property alias buttonClose: btn_close
|
||||
property alias buttonDark: btn_dark
|
||||
property alias layoutMacosButtons: layout_macos_buttons
|
||||
property alias layoutStandardbuttons: layout_standard_buttons
|
||||
property var maxClickListener : function(){
|
||||
if(FluTools.isMacos()){
|
||||
if (d.win.visibility === Window.FullScreen)
|
||||
@ -71,16 +77,6 @@ Rectangle{
|
||||
FluTheme.darkMode = FluThemeType.Dark
|
||||
}
|
||||
}
|
||||
property var systemMenuListener: function(){
|
||||
if(d.win instanceof FluWindow){
|
||||
d.win.showSystemMenu()
|
||||
}
|
||||
}
|
||||
property alias buttonStayTop: btn_stay_top
|
||||
property alias buttonMinimize: btn_minimize
|
||||
property alias buttonMaximize: btn_maximize
|
||||
property alias buttonClose: btn_close
|
||||
property alias buttonDark: btn_dark
|
||||
id:control
|
||||
color: Qt.rgba(0,0,0,0)
|
||||
height: visible ? 30 : 0
|
||||
@ -108,29 +104,6 @@ Rectangle{
|
||||
return false
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
id:mouse_app_bar
|
||||
anchors.fill: parent
|
||||
onPositionChanged:
|
||||
(mouse)=>{
|
||||
if(systemMoveEnable){
|
||||
d.win.startSystemMove()
|
||||
}
|
||||
}
|
||||
onDoubleClicked:
|
||||
(mouse)=>{
|
||||
if(systemMoveEnable && d.resizable && Qt.LeftButton){
|
||||
btn_maximize.clicked()
|
||||
}
|
||||
}
|
||||
acceptedButtons: Qt.LeftButton|Qt.RightButton
|
||||
onClicked:
|
||||
(mouse)=>{
|
||||
if (systemMoveEnable && mouse.button === Qt.RightButton){
|
||||
control.systemMenuListener()
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
@ -153,9 +126,8 @@ Rectangle{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_mac_buttons
|
||||
id:com_macos_buttons
|
||||
RowLayout{
|
||||
FluImageButton{
|
||||
Layout.preferredHeight: 12
|
||||
@ -186,24 +158,11 @@ Rectangle{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluLoader{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
sourceComponent: isMac ? com_mac_buttons : undefined
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
id:layout_row
|
||||
id:layout_standard_buttons
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
height: control.height
|
||||
spacing: 0
|
||||
Component.onCompleted: {
|
||||
setHitTestVisible(layout_row)
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_dark
|
||||
Layout.preferredWidth: 40
|
||||
@ -273,12 +232,9 @@ Rectangle{
|
||||
horizontalPadding: 0
|
||||
iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
|
||||
color: {
|
||||
if(down){
|
||||
if(pressed){
|
||||
return maximizePressColor
|
||||
}
|
||||
if(FluTools.isWindows11OrGreater()){
|
||||
return d.hoverMaxBtn ? maximizeHoverColor : maximizeNormalColor
|
||||
}
|
||||
return hovered ? maximizeHoverColor : maximizeNormalColor
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@ -312,36 +268,13 @@ Rectangle{
|
||||
onClicked: closeClickListener()
|
||||
}
|
||||
}
|
||||
function _maximizeButtonHover(){
|
||||
var hover = false
|
||||
if(btn_maximize.visible && FluTools.isWindows11OrGreater() && d.resizable){
|
||||
if(d.containsPointToItem(FluTools.cursorPos(),btn_maximize)){
|
||||
hover = true
|
||||
}else{
|
||||
if(btn_maximize.down){
|
||||
btn_maximize.down = false
|
||||
FluLoader{
|
||||
id:layout_macos_buttons
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
d.hoverMaxBtn = hover
|
||||
return hover;
|
||||
}
|
||||
function _appBarHover(){
|
||||
var cursorPos = FluTools.cursorPos()
|
||||
for(var i =0 ;i< d.hitTestList.length; i++){
|
||||
var item = d.hitTestList[i]
|
||||
if(item.visible){
|
||||
if(d.containsPointToItem(cursorPos,item)){
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if(d.containsPointToItem(cursorPos,control)){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
function setHitTestVisible(id){
|
||||
d.hitTestList.push(id)
|
||||
sourceComponent: isMac ? com_macos_buttons : undefined
|
||||
}
|
||||
}
|
||||
|
@ -55,29 +55,20 @@ Window {
|
||||
event.accepted = false
|
||||
}
|
||||
}
|
||||
signal showSystemMenu
|
||||
signal initArgument(var argument)
|
||||
signal firstVisible()
|
||||
property int _realHeight
|
||||
property int _realWidth
|
||||
property int _appBarHeight: appBar.height
|
||||
signal lazyLoad()
|
||||
property var _windowRegister
|
||||
property string _route
|
||||
id:window
|
||||
color:"transparent"
|
||||
Component.onCompleted: {
|
||||
FluRouter.addWindow(window)
|
||||
_realHeight = height
|
||||
_realWidth = width
|
||||
useSystemAppBar = FluApp.useSystemAppBar
|
||||
if(useSystemAppBar && autoCenter){
|
||||
moveWindowToDesktopCenter()
|
||||
}
|
||||
fixWindowSize()
|
||||
initArgument(argument)
|
||||
if(!useSystemAppBar){
|
||||
loader_frameless_helper.sourceComponent = com_frameless_helper
|
||||
}
|
||||
if(window.autoVisible){
|
||||
if(window.autoMaximize){
|
||||
window.showMaximized()
|
||||
@ -86,33 +77,30 @@ Window {
|
||||
}
|
||||
}
|
||||
}
|
||||
onShowSystemMenu: {
|
||||
if(loader_frameless_helper.item){
|
||||
loader_frameless_helper.item.showSystemMenu()
|
||||
}
|
||||
}
|
||||
onVisibleChanged: {
|
||||
if(visible && d.isFirstVisible){
|
||||
window.firstVisible()
|
||||
d.isFirstVisible = false
|
||||
if(visible && d.isLazyInit){
|
||||
window.lazyLoad()
|
||||
d.isLazyInit = false
|
||||
}
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property bool isFirstVisible: true
|
||||
property bool isLazyInit: true
|
||||
}
|
||||
Connections{
|
||||
target: window
|
||||
function onClosing(event){closeListener(event)}
|
||||
}
|
||||
Component{
|
||||
id:com_frameless_helper
|
||||
FluFramelessHelper{
|
||||
onLoadCompleted:{
|
||||
if(autoCenter){
|
||||
window.moveWindowToDesktopCenter()
|
||||
}
|
||||
}
|
||||
FluFrameless{
|
||||
id: frameless
|
||||
appbar: window.appBar
|
||||
maximizeButton: appBar.buttonMaximize
|
||||
fixSize: window.fixSize
|
||||
topmost: window.stayTop
|
||||
disabled: FluApp.useSystemAppBar
|
||||
Component.onCompleted: {
|
||||
frameless.setHitTestVisible(appBar.layoutMacosButtons)
|
||||
frameless.setHitTestVisible(appBar.layoutStandardbuttons)
|
||||
}
|
||||
}
|
||||
Component{
|
||||
@ -197,9 +185,6 @@ Window {
|
||||
border.color: window.resizeBorderColor
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
id:loader_frameless_helper
|
||||
}
|
||||
FluLoader{
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
@ -255,11 +240,6 @@ Window {
|
||||
return com_border
|
||||
}
|
||||
}
|
||||
function showLoading(text = qsTr("Loading..."),cancel = true){
|
||||
loader_loading.loadingText = text
|
||||
loader_loading.cancel = cancel
|
||||
loader_loading.sourceComponent = com_loading
|
||||
}
|
||||
function hideLoading(){
|
||||
loader_loading.sourceComponent = undefined
|
||||
}
|
||||
@ -297,12 +277,17 @@ Window {
|
||||
}
|
||||
}
|
||||
function showMaximized(){
|
||||
if(FluTools.isWin()){
|
||||
if(loader_frameless_helper.item){
|
||||
loader_frameless_helper.item.showMaximized()
|
||||
frameless.showMaximized()
|
||||
}
|
||||
}else{
|
||||
window.visibility = Window.Maximized
|
||||
function showLoading(text = "",cancel = true){
|
||||
if(text===""){
|
||||
text = qsTr("Loading...")
|
||||
}
|
||||
loader_loading.loadingText = text
|
||||
loader_loading.cancel = cancel
|
||||
loader_loading.sourceComponent = com_loading
|
||||
}
|
||||
function setHitTestVisible(val){
|
||||
frameless.setHitTestVisible(val)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user