diff --git a/example/qml/page/T_Icons.qml b/example/qml/page/T_Icons.qml index 43d80442..8cf6a584 100644 --- a/example/qml/page/T_Icons.qml +++ b/example/qml/page/T_Icons.qml @@ -24,7 +24,7 @@ FluContentPage { leftMargin: 14 } onClicked: { - grid_view.model = FluTheme.awesomeList(text_box.text) + grid_view.model = FluApp.iconDatas(text_box.text) } } GridView{ diff --git a/src/FluFrameless.cpp b/src/FluFrameless.cpp index 753ce22a..d4f6117c 100644 --- a/src/FluFrameless.cpp +++ b/src/FluFrameless.cpp @@ -4,6 +4,7 @@ #include #include #include +#include "FluTools.h" #ifdef Q_OS_WIN #pragma comment (lib, "user32.lib") @@ -13,6 +14,7 @@ #include #include + static inline QByteArray qtNativeEventType() { static const auto result = "windows_generic_MSG"; return result; @@ -55,6 +57,7 @@ FluFrameless::FluFrameless(QQuickItem *parent) : QQuickItem{parent} { _closeButton = nullptr; _topmost = false; _disabled = false; + _isWindows11OrGreater = FluTools::getInstance()->isWindows11OrGreater(); } FluFrameless::~FluFrameless() = default; @@ -110,11 +113,11 @@ void FluFrameless::componentComplete() { }); #endif h = h + _appbar->height(); - if(_fixSize){ - window()->setMaximumSize(QSize(w,h)); - window()->setMinimumSize(QSize(w,h)); + if (_fixSize) { + window()->setMaximumSize(QSize(w, h)); + window()->setMinimumSize(QSize(w, h)); } - window()->resize(QSize(w,h)); + window()->resize(QSize(w, h)); connect(this, &FluFrameless::topmostChanged, this, [this] { _setWindowTopmost(topmost()); }); @@ -160,7 +163,10 @@ void FluFrameless::componentComplete() { } int offsetSize; bool isMaximum = ::IsZoomed(hwnd); - offsetXY = QPoint(abs(clientRect->left - originalLeft), abs(clientRect->top - originalTop)); + auto _offsetXY = QPoint(abs(clientRect->left - originalLeft), abs(clientRect->top - originalTop)); + if (_offsetXY.x() != 0) { + offsetXY = _offsetXY; + } if (isMaximum || _isFullScreen()) { offsetSize = 0; } else { @@ -179,15 +185,17 @@ void FluFrameless::componentComplete() { *result = WVR_REDRAW; return true; } else if (uMsg == WM_NCHITTEST) { - if (_hitMaximizeButton()) { - if (*result == HTNOWHERE) { - *result = HTZOOM; + if (_isWindows11OrGreater) { + if (_hitMaximizeButton()) { + if (*result == HTNOWHERE) { + *result = HTZOOM; + } + _setMaximizeHovered(true); + return true; } - _setMaximizeHovered(true); - return true; + _setMaximizeHovered(false); + _setMaximizePressed(false); } - _setMaximizeHovered(false); - _setMaximizePressed(false); *result = 0; POINT nativeGlobalPos{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; POINT nativeLocalPos = nativeGlobalPos; @@ -229,14 +237,14 @@ void FluFrameless::componentComplete() { } *result = HTCLIENT; return true; - } else if (uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN) { + } else if (_isWindows11OrGreater && (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); _setMaximizePressed(true); return true; } - } else if (uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP) { + } else if (_isWindows11OrGreater && (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); @@ -251,11 +259,12 @@ void FluFrameless::componentComplete() { return true; } else if (uMsg == WM_GETMINMAXINFO) { auto *minmaxInfo = reinterpret_cast(lParam); -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) +#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; + return false; #else auto pixelRatio = window()->devicePixelRatio(); auto geometry = window()->screen()->availableGeometry(); @@ -265,8 +274,8 @@ void FluFrameless::componentComplete() { minmaxInfo->ptMaxPosition.y = rect.top - offsetXY.x(); minmaxInfo->ptMaxSize.x = qRound(geometry.width() * pixelRatio) + offsetXY.x() * 2; minmaxInfo->ptMaxSize.y = qRound(geometry.height() * pixelRatio) + offsetXY.y() * 2; + return true; #endif - return false; } else if (uMsg == WM_NCRBUTTONDOWN) { if (wParam == HTCAPTION) { _showSystemMenu(QCursor::pos()); @@ -281,9 +290,11 @@ void FluFrameless::componentComplete() { } else if (uMsg == WM_SYSCOMMAND) { if (wParam == SC_MINIMIZE) { if (window()->transientParent()) { - window()->transientParent()->showMinimized(); + HWND hwnd = reinterpret_cast(window()->transientParent()->winId()); + ::ShowWindow(hwnd, 2); } else { - window()->showMinimized(); + HWND hwnd = reinterpret_cast(window()->winId()); + ::ShowWindow(hwnd, 2); } return true; } @@ -395,16 +406,21 @@ void FluFrameless::showMaximized() { HWND hwnd = reinterpret_cast(window()->winId()); ::ShowWindow(hwnd, 3); #else - window()->showMaximized(); + window()->setVisibility(QQuickWindow::Maximized); #endif } [[maybe_unused]] void FluFrameless::showMinimized() { - window()->showMinimized(); +#ifdef Q_OS_WIN + HWND hwnd = reinterpret_cast(window()->winId()); + ::ShowWindow(hwnd, 2); +#else + window()->setVisibility(QQuickWindow::Minimized); +#endif } void FluFrameless::showNormal() { - window()->showNormal(); + window()->setVisibility(QQuickWindow::Windowed); } void FluFrameless::setHitTestVisible(QQuickItem *val) { diff --git a/src/FluFrameless.h b/src/FluFrameless.h index 6ccf79fb..e57fc447 100644 --- a/src/FluFrameless.h +++ b/src/FluFrameless.h @@ -73,5 +73,6 @@ private: int _edges = 0; int _margins = 8; quint64 _clickTimer = 0; + bool _isWindows11OrGreater = false; QList> _hitTestList; }; diff --git a/src/Qt5/imports/FluentUI/Controls/FluAutoSuggestBox.qml b/src/Qt5/imports/FluentUI/Controls/FluAutoSuggestBox.qml index 3cd525fb..bfa5a147 100644 --- a/src/Qt5/imports/FluentUI/Controls/FluAutoSuggestBox.qml +++ b/src/Qt5/imports/FluentUI/Controls/FluAutoSuggestBox.qml @@ -59,12 +59,8 @@ FluTextBox{ duration: FluTheme.animationEnabled ? 83 : 0 } } - contentItem: FluRectangle{ - radius: [4,4,4,4] - FluShadow{ - radius: 4 - } - color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1) + contentItem: FluClip{ + radius: [5,5,5,5] ListView{ id:list_view anchors.fill: parent @@ -97,10 +93,13 @@ FluTextBox{ radius:4 } color: { - if(hovered){ - return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1) + if(pressed){ + return FluTheme.itemPressColor } - return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0) + if(hovered){ + return FluTheme.itemHoverColor + } + return FluTheme.itemNormalColor } } contentItem: FluText{ @@ -112,22 +111,28 @@ FluTextBox{ } } } - background: Item{ - id:container + background:Rectangle{ + id: rect_background implicitWidth: control.width implicitHeight: 38*Math.min(Math.max(list_view.count,1),8) + radius: 5 + color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1) + border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1) + FluShadow{ + radius: 5 + } } } onTextChanged: { d.loadData() if(d.flagVisible){ var pos = control.mapToItem(null, 0, 0) - if(d.window.height>pos.y+control.height+container.implicitHeight){ + if(d.window.height>pos.y+control.height+rect_background.implicitHeight){ control_popup.y = control.height - } else if(pos.y>container.implicitHeight){ - control_popup.y = -container.implicitHeight + } else if(pos.y>rect_background.implicitHeight){ + control_popup.y = -rect_background.implicitHeight } else { - control_popup.y = d.window.height-(pos.y+container.implicitHeight) + control_popup.y = d.window.height-(pos.y+rect_background.implicitHeight) - 1 } control_popup.visible = true } diff --git a/src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml b/src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml index 024ce7e2..ef82bd13 100644 --- a/src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml +++ b/src/Qt5/imports/FluentUI/Controls/FluTextBoxBackground.qml @@ -23,16 +23,27 @@ FluControlBackground{ GradientStop { position: 1 - d.offsetSize/control.height; color: d.startColor } GradientStop { position: 1.0; color: d.endColor } } - bottomMargin: inputItem && inputItem.activeFocus ? 2 : 1 + bottomMargin: 1 QtObject{ id:d - property int offsetSize : inputItem && inputItem.activeFocus ? 2 : 3 - property color startColor: FluTheme.dark ? Qt.rgba(66/255,66/255,66/255,1) : Qt.rgba(232/255,232/255,232/255,1) + property int offsetSize : 3 + property color startColor : FluTheme.dark ? Qt.rgba(66/255,66/255,66/255,1) : Qt.rgba(232/255,232/255,232/255,1) property color endColor: { if(!control.enabled){ return d.startColor } - return inputItem && inputItem.activeFocus ? FluTheme.primaryColor : FluTheme.dark ? Qt.rgba(123/255,123/255,123/255,1) : Qt.rgba(132/255,132/255,132/255,1) + return FluTheme.dark ? Qt.rgba(123/255,123/255,123/255,1) : Qt.rgba(132/255,132/255,132/255,1) + } + } + FluClip{ + anchors.fill: parent + radius: [control.radius,control.radius,control.radius,control.radius] + visible: inputItem && inputItem.activeFocus + Rectangle{ + width: parent.width + height: 2 + anchors.bottom: parent.bottom + color: FluTheme.primaryColor } } } diff --git a/src/Qt5/imports/FluentUI/Controls/FluWindow.qml b/src/Qt5/imports/FluentUI/Controls/FluWindow.qml index a56fec54..10a099d5 100644 --- a/src/Qt5/imports/FluentUI/Controls/FluWindow.qml +++ b/src/Qt5/imports/FluentUI/Controls/FluWindow.qml @@ -330,6 +330,12 @@ Window { function showMaximized(){ frameless.showMaximized() } + function showMinimized(){ + frameless.showMinimized() + } + function showNormal(){ + frameless.showNormal() + } function showLoading(text = "",cancel = true){ if(text===""){ text = qsTr("Loading...") diff --git a/src/Qt6/imports/FluentUI/Controls/FluAutoSuggestBox.qml b/src/Qt6/imports/FluentUI/Controls/FluAutoSuggestBox.qml index cb37c970..bd5c2d25 100644 --- a/src/Qt6/imports/FluentUI/Controls/FluAutoSuggestBox.qml +++ b/src/Qt6/imports/FluentUI/Controls/FluAutoSuggestBox.qml @@ -58,12 +58,8 @@ FluTextBox{ duration: FluTheme.animationEnabled ? 83 : 0 } } - contentItem: FluRectangle{ - radius: [4,4,4,4] - FluShadow{ - radius: 4 - } - color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1) + contentItem: FluClip{ + radius: [5,5,5,5] ListView{ id:list_view anchors.fill: parent @@ -96,10 +92,13 @@ FluTextBox{ radius:4 } color: { - if(hovered){ - return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1) + if(pressed){ + return FluTheme.itemPressColor } - return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0) + if(hovered){ + return FluTheme.itemHoverColor + } + return FluTheme.itemNormalColor } } contentItem: FluText{ @@ -111,22 +110,28 @@ FluTextBox{ } } } - background: Item{ - id:container + background:Rectangle{ + id: rect_background implicitWidth: control.width implicitHeight: 38*Math.min(Math.max(list_view.count,1),8) + radius: 5 + color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1) + border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1) + FluShadow{ + radius: 5 + } } } onTextChanged: { d.loadData() if(d.flagVisible){ var pos = control.mapToItem(null, 0, 0) - if(d.window.height>pos.y+control.height+container.implicitHeight){ + if(d.window.height>pos.y+control.height+rect_background.implicitHeight){ control_popup.y = control.height - } else if(pos.y>container.implicitHeight){ - control_popup.y = -container.implicitHeight + } else if(pos.y>rect_background.implicitHeight){ + control_popup.y = -rect_background.implicitHeight } else { - control_popup.y = d.window.height-(pos.y+container.implicitHeight) + control_popup.y = d.window.height-(pos.y+rect_background.implicitHeight) - 1 } control_popup.visible = true } diff --git a/src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml b/src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml index d2ce9955..a57cff5a 100644 --- a/src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml +++ b/src/Qt6/imports/FluentUI/Controls/FluTextBoxBackground.qml @@ -23,16 +23,27 @@ FluControlBackground{ GradientStop { position: 1 - d.offsetSize/control.height; color: d.startColor } GradientStop { position: 1.0; color: d.endColor } } - bottomMargin: inputItem && inputItem.activeFocus ? 2 : 1 + bottomMargin: 1 QtObject{ id:d - property int offsetSize : inputItem && inputItem.activeFocus ? 2 : 3 - property color startColor: FluTheme.dark ? Qt.rgba(66/255,66/255,66/255,1) : Qt.rgba(232/255,232/255,232/255,1) + property int offsetSize : 3 + property color startColor : FluTheme.dark ? Qt.rgba(66/255,66/255,66/255,1) : Qt.rgba(232/255,232/255,232/255,1) property color endColor: { if(!control.enabled){ return d.startColor } - return inputItem && inputItem.activeFocus ? FluTheme.primaryColor : FluTheme.dark ? Qt.rgba(123/255,123/255,123/255,1) : Qt.rgba(132/255,132/255,132/255,1) + return FluTheme.dark ? Qt.rgba(123/255,123/255,123/255,1) : Qt.rgba(132/255,132/255,132/255,1) + } + } + FluClip{ + anchors.fill: parent + radius: [control.radius,control.radius,control.radius,control.radius] + visible: inputItem && inputItem.activeFocus + Rectangle{ + width: parent.width + height: 2 + anchors.bottom: parent.bottom + color: FluTheme.primaryColor } } } diff --git a/src/Qt6/imports/FluentUI/Controls/FluWindow.qml b/src/Qt6/imports/FluentUI/Controls/FluWindow.qml index a9b6cc2a..16dd0a33 100644 --- a/src/Qt6/imports/FluentUI/Controls/FluWindow.qml +++ b/src/Qt6/imports/FluentUI/Controls/FluWindow.qml @@ -329,6 +329,12 @@ Window { function showMaximized(){ frameless.showMaximized() } + function showMinimized(){ + frameless.showMinimized() + } + function showNormal(){ + frameless.showNormal() + } function showLoading(text = "",cancel = true){ if(text===""){ text = qsTr("Loading...")