From 37a17735196b3b734d4d2e29b5f08a7ee2aa03be Mon Sep 17 00:00:00 2001 From: qiqi49 Date: Fri, 23 Feb 2024 18:19:22 +0800 Subject: [PATCH] =?UTF-8?q?feat(qml):=E5=AE=9E=E7=8E=B0=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E6=A1=86=E9=BB=98=E8=AE=A4=E6=BF=80=E6=B4=BB=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E3=80=81=E5=8F=B3=E9=94=AE=E8=8F=9C=E5=8D=95=E5=92=8C=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E5=A4=B1=E7=84=A6=E6=97=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qml/AppUI/AppList.qml | 5 +- qml/AppUI/AppPageSearch.qml | 5 +- qml/AppUI/FullScreenAppList.qml | 9 +- qml/AppUI/FullScreenUI.qml | 410 ++++++++++++++------------- qml/AppUI/NormalUI.qml | 23 +- qml/AppUI/PluginSelectButton.qml | 9 - qml/AppUI/SearchInputBar.qml | 38 +-- qml/AppUI/WidgetPage.qml | 1 - qml/extensions/FavoriteDelegate.qml | 11 + qml/extensions/FavoriteExtension.qml | 1 + qml/main.qml | 5 +- 11 files changed, 259 insertions(+), 258 deletions(-) diff --git a/qml/AppUI/AppList.qml b/qml/AppUI/AppList.qml index f519a35..e192285 100644 --- a/qml/AppUI/AppList.qml +++ b/qml/AppUI/AppList.qml @@ -80,7 +80,10 @@ AppListView { return; } } - onPressed: grabImage(); + onPressed: { + normalUI.focus = false; + grabImage(); + } } function grabImage() { diff --git a/qml/AppUI/AppPageSearch.qml b/qml/AppUI/AppPageSearch.qml index 7bc80df..6572995 100644 --- a/qml/AppUI/AppPageSearch.qml +++ b/qml/AppUI/AppPageSearch.qml @@ -8,6 +8,7 @@ import org.ukui.menu.utils 1.0 Item { property Item focusToPageContent property bool inputStatus: false + property alias searchInputBar: searchInputBar SearchInputBar { id: searchInputBar @@ -32,9 +33,9 @@ Item { } function changeToSearch(keyEvent) { - if (header.content === null) { +// if (header.content === null) { searchInputBar.text = keyEvent; searchInputBar.textInputFocus(); - } +// } } } diff --git a/qml/AppUI/FullScreenAppList.qml b/qml/AppUI/FullScreenAppList.qml index 9e3c8fb..db056e2 100644 --- a/qml/AppUI/FullScreenAppList.qml +++ b/qml/AppUI/FullScreenAppList.qml @@ -99,9 +99,12 @@ ListView { } drag.target: appItem - onPressed: grabToImage(function(result) { - Drag.imageSource = result.url - }) + onPressed: { + fullScreenUI.focus = false; + grabToImage(function(result) { + Drag.imageSource = result.url + }) + } Drag.supportedActions: Qt.CopyAction Drag.dragType: Drag.Automatic Drag.active: appItem.drag.active diff --git a/qml/AppUI/FullScreenUI.qml b/qml/AppUI/FullScreenUI.qml index 7cc1fa3..191bbe5 100644 --- a/qml/AppUI/FullScreenUI.qml +++ b/qml/AppUI/FullScreenUI.qml @@ -9,240 +9,258 @@ import AppControls2 1.0 as AppControls2 import org.ukui.quick.items 1.0 as UkuiItems import org.ukui.quick.platform 1.0 as Platform -UkuiItems.StyleBackground { - paletteRole: Platform.Theme.Dark +FocusScope { + id: fullScreenUI - MouseArea { - anchors.fill: parent - onClicked: { - if (mainWindow.editMode) { - mainWindow.editMode = false; - } else { - if (mainContainer.visible) { - //执行全屏退出操作 - forceActiveFocus(); - mainWindow.hide(); - } else { - folderLoader.isFolderOpened = false; - } - } - } + Component.onCompleted: { + forceFocus(); + mainWindow.visibleChanged.connect(forceFocus); + } + Component.onDestruction: { + mainWindow.visibleChanged.disconnect(forceFocus); } - Extension.FullScreenFolder { - id: folderLoader - anchors.fill: parent - - folderModel: FolderModel - Component.onCompleted: fullScreenAppList.openFolderSignal.connect(initFolder) - Component.onDestruction: fullScreenAppList.openFolderSignal.disconnect(initFolder) + function forceFocus() { + fullScreenUI.focus = true; } - Item { - id: mainContainer + UkuiItems.StyleBackground { anchors.fill: parent - z: 10 + paletteRole: Platform.Theme.Dark - state: !fullScreenAppList.isContentShow ? "contentShow" : "contentHidden" - states: [ - State { - name: "contentHidden" - PropertyChanges { target: mainContainer; opacity: 0; scale: 0.95 } - }, - State { - name: "contentShow" - PropertyChanges { target: mainContainer; opacity: 1; scale: 1 } - } - ] - - transitions: [ - Transition { - to:"contentHidden" - SequentialAnimation { - PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic } - ScriptAction { script: mainContainer.visible = false } - } - }, - Transition { - to: "contentShow" - SequentialAnimation { - ScriptAction { script: mainContainer.visible = true } - PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic } - } - } - ] - - // 两行三列 - GridLayout { + MouseArea { anchors.fill: parent - // anchors.margins: 36 - anchors.leftMargin: 36 - anchors.topMargin: 36 - anchors.rightMargin: 36 - anchors.bottomMargin: 5 - - rowSpacing: 5 - columnSpacing: 5 - rows: 2 - columns: 3 - - // 应用列表模式选择按钮: [row: 0, column: 0] [rowspan: 2, columnSpan: 1] - Item { - Layout.row: 0 - Layout.column: 0 - Layout.preferredWidth: Math.max(actionsItem.width, labelsItem.width) - Layout.preferredHeight: 40 - - // TODO: 设计最小保持宽度 - AppListActions { - id: actionsItem - anchors.centerIn: parent - height: parent.height - actions: AppPageBackend.appModel.header.actions - visible: count > 0 - } - } - - // 搜索框: [row: 0, column: 1] - Item { - Layout.row: 0 - Layout.column: 1 - Layout.fillWidth: true - Layout.preferredHeight: 40 - - SearchInputBar { - id: searchInputBar - width: 372; height: 36 - anchors.centerIn: parent - radius: Platform.Theme.minRadius - visible: opacity - - onTextChanged: { - if (text === "") { - AppPageBackend.group = PluginGroup.Display; - } else { - AppPageBackend.group = PluginGroup.Search; - AppPageBackend.startSearch(text); - } + onClicked: { + if (mainWindow.editMode) { + mainWindow.editMode = false; + } else { + if (mainContainer.visible) { + //执行全屏退出操作 + mainWindow.hide(); + } else { + folderLoader.isFolderOpened = false; } } } + } - // 右侧按钮区域: [row: 0, column: 2] [rowspan: 2, columnSpan: 1] - Sidebar { - Layout.row: 0 - Layout.column: 2 - Layout.rowSpan: 2 - Layout.columnSpan: 1 - Layout.preferredWidth: 60 - Layout.fillHeight: true - } + Extension.FullScreenFolder { + id: folderLoader + anchors.fill: parent - // 左侧标签列表: [row: 1, column: 0] - Item { - Layout.row: 1 - Layout.column: 0 - Layout.preferredWidth: Math.max(actionsItem.width, labelsItem.width) - Layout.fillHeight: true + folderModel: FolderModel + Component.onCompleted: fullScreenAppList.openFolderSignal.connect(initFolder) + Component.onDestruction: fullScreenAppList.openFolderSignal.disconnect(initFolder) + } + Item { + id: mainContainer + anchors.fill: parent + z: 10 + + state: !fullScreenAppList.isContentShow ? "contentShow" : "contentHidden" + states: [ + State { + name: "contentHidden" + PropertyChanges { target: mainContainer; opacity: 0; scale: 0.95 } + }, + State { + name: "contentShow" + PropertyChanges { target: mainContainer; opacity: 1; scale: 1 } + } + ] + + transitions: [ + Transition { + to:"contentHidden" + SequentialAnimation { + PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic } + ScriptAction { script: mainContainer.visible = false } + } + }, + Transition { + to: "contentShow" + SequentialAnimation { + ScriptAction { script: mainContainer.visible = true } + PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic } + } + } + ] + + // 两行三列 + GridLayout { + anchors.fill: parent + // anchors.margins: 36 + anchors.leftMargin: 36 + anchors.topMargin: 36 + anchors.rightMargin: 36 + anchors.bottomMargin: 5 + + rowSpacing: 5 + columnSpacing: 5 + rows: 2 + columns: 3 + + // 应用列表模式选择按钮: [row: 0, column: 0] [rowspan: 2, columnSpan: 1] Item { - id: labelsItem - anchors.centerIn: parent - width: 120 - height: parent.height + Layout.row: 0 + Layout.column: 0 + Layout.preferredWidth: Math.max(actionsItem.width, labelsItem.width) + Layout.preferredHeight: 40 - AppLabelPage { - id: appLabelPage + // TODO: 设计最小保持宽度 + AppListActions { + id: actionsItem anchors.centerIn: parent + height: parent.height + actions: AppPageBackend.appModel.header.actions + visible: count > 0 + } + } - width: parent.width - labelBottle: AppPageBackend.appModel.labelBottle - labelColum: 1 - cellHeight: 34 + // 搜索框: [row: 0, column: 1] + Item { + Layout.row: 0 + Layout.column: 1 + Layout.fillWidth: true + Layout.preferredHeight: 40 - // TODO: 潜在的优化点,尝试组合widget的model和应用model - model: { - if (labelBottle !== null) { - let labelItems = [], i = 0, item = null; - let widgetInfos = fullScreenAppList.headerItem.widgetInfos; - for (i = 0; i < widgetInfos.length; ++i) { - item = widgetInfos[i]; - labelItems.push({label: item.label, type: item.type, display: item.display}); + SearchInputBar { + id: searchInputBar + width: 372; height: 36 + anchors.centerIn: parent + radius: Platform.Theme.minRadius + visible: opacity + + onTextChanged: { + if (text === "") { + AppPageBackend.group = PluginGroup.Display; + } else { + AppPageBackend.group = PluginGroup.Search; + AppPageBackend.startSearch(text); + } + } + } + } + + // 右侧按钮区域: [row: 0, column: 2] [rowspan: 2, columnSpan: 1] + Sidebar { + Layout.row: 0 + Layout.column: 2 + Layout.rowSpan: 2 + Layout.columnSpan: 1 + Layout.preferredWidth: 60 + Layout.fillHeight: true + } + + // 左侧标签列表: [row: 1, column: 0] + Item { + Layout.row: 1 + Layout.column: 0 + Layout.preferredWidth: Math.max(actionsItem.width, labelsItem.width) + Layout.fillHeight: true + + Item { + id: labelsItem + anchors.centerIn: parent + width: 120 + height: parent.height + + AppLabelPage { + id: appLabelPage + anchors.centerIn: parent + + width: parent.width + labelBottle: AppPageBackend.appModel.labelBottle + labelColum: 1 + cellHeight: 34 + + // TODO: 潜在的优化点,尝试组合widget的model和应用model + model: { + if (labelBottle !== null) { + let labelItems = [], i = 0, item = null; + let widgetInfos = fullScreenAppList.headerItem.widgetInfos; + for (i = 0; i < widgetInfos.length; ++i) { + item = widgetInfos[i]; + labelItems.push({label: item.label, type: item.type, display: item.display}); + } + + let labels = labelBottle.labels; + for (i = 0; i < labels.length; ++i) { + item = labels[i]; + labelItems.push({label: item.label, type: item.type, display: item.display}); + } + + return labelItems; } - let labels = labelBottle.labels; - for (i = 0; i < labels.length; ++i) { - item = labels[i]; - labelItems.push({label: item.label, type: item.type, display: item.display}); - } - - return labelItems; + return []; } - return []; - } + interactive: height > parent.height + highlightMoveDuration: 300 + highlight: UkuiItems.StyleBackground { + width: appLabelPage.cellWidth + height: appLabelPage.cellHeight + useStyleTransparency: false + radius: Platform.Theme.minRadius + paletteRole: Platform.Theme.Light + alpha: 0.15; borderAlpha: 0.5 + border.width: 1 + borderColor: Platform.Theme.Highlight + } - interactive: height > parent.height - highlightMoveDuration: 300 - highlight: UkuiItems.StyleBackground { - width: appLabelPage.cellWidth - height: appLabelPage.cellHeight - useStyleTransparency: false - radius: Platform.Theme.minRadius - paletteRole: Platform.Theme.Light - alpha: 0.15; borderAlpha: 0.5 - border.width: 1 - borderColor: Platform.Theme.Highlight - } - - onLabelSelected: (label) => { - fullScreenAppList.positionLabel(label); + onLabelSelected: (label) => { + fullScreenAppList.positionLabel(label); + } } } } - } - // 应用列表: [row: 1, column: 1] - FullScreenAppList { - id: fullScreenAppList - Layout.row: 1 - Layout.column: 1 - Layout.fillWidth: true - Layout.fillHeight: true + // 应用列表: [row: 1, column: 1] + FullScreenAppList { + id: fullScreenAppList + Layout.row: 1 + Layout.column: 1 + Layout.fillWidth: true + Layout.fillHeight: true - sourceModel: AppPageBackend.appModel - isContentShow: folderLoader.isFolderOpened + sourceModel: AppPageBackend.appModel + isContentShow: folderLoader.isFolderOpened - function positionLabel(label) { - // 如果是Widget那么直接滚动到最顶上 - // console.log("=positionLabel=", label) - if (headerItem.widgets.includes(label)) { - positionViewAtBeginning(); + function positionLabel(label) { + // 如果是Widget那么直接滚动到最顶上 + // console.log("=positionLabel=", label) + if (headerItem.widgets.includes(label)) { + positionViewAtBeginning(); - } else { - let index = model.findLabelIndex(label); + } else { + let index = model.findLabelIndex(label); + if (index >= 0) { + positionViewAtIndex(index, ListView.Beginning) + } + } + } + + onContentYChanged: { + // 向下偏移200, 计算偏移后在那个item里 + let index = indexAt(10, contentY + 200); if (index >= 0) { - positionViewAtIndex(index, ListView.Beginning) + appLabelPage.currentIndex = index + headerItem.widgetCount; + } else if (contentY < 0) { + appLabelPage.currentIndex = 0; } } - } - onContentYChanged: { - // 向下偏移200, 计算偏移后在那个item里 - let index = indexAt(10, contentY + 200); - if (index >= 0) { - appLabelPage.currentIndex = index + headerItem.widgetCount; - } else if (contentY < 0) { - appLabelPage.currentIndex = 0; + Component.onCompleted: { + positionViewAtBeginning(); + folderLoader.turnPageFinished.connect(contentShowFinished) } + Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished) } - - Component.onCompleted: { - positionViewAtBeginning(); - folderLoader.turnPageFinished.connect(contentShowFinished) - } - Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished) } } } + } + diff --git a/qml/AppUI/NormalUI.qml b/qml/AppUI/NormalUI.qml index c1b9658..9ccf95a 100644 --- a/qml/AppUI/NormalUI.qml +++ b/qml/AppUI/NormalUI.qml @@ -7,8 +7,16 @@ import org.ukui.quick.items 1.0 as UkuiItems FocusScope { id: normalUI - function focusToFalse() { - focus = false; + Component.onCompleted: { + forceFocus(); + mainWindow.visibleChanged.connect(forceFocus); + } + Component.onDestruction: { + mainWindow.visibleChanged.disconnect(forceFocus); + } + + function forceFocus() { + normalUI.focus = true; } function keyPressed(event) { // 任意字符键焦点切换到搜索(0-9 a-z) @@ -23,17 +31,6 @@ FocusScope { } } - Component.onCompleted: mainWindow.visibleChanged.connect(focusToFalse) - Component.onDestruction: mainWindow.visibleChanged.disconnect(focusToFalse) - - // 点击空白处失去焦点 - MouseArea { - anchors.fill: parent - onClicked: { - normalUI.focusToFalse(); - } - } - RowLayout { anchors.fill: parent spacing: 0 diff --git a/qml/AppUI/PluginSelectButton.qml b/qml/AppUI/PluginSelectButton.qml index 56b7017..c25ff6e 100644 --- a/qml/AppUI/PluginSelectButton.qml +++ b/qml/AppUI/PluginSelectButton.qml @@ -31,13 +31,6 @@ UkuiItems.StyleBackground { radius: childrenRect.width / 2 alpha: 0.06 - - function resetFocus() { - if(!mainWindow.isFullScreen) { - normalUI.focusToFalse(); - } - } - RowLayout { id: pluginSortButtonRoot property int currentId: 0 @@ -67,7 +60,6 @@ UkuiItems.StyleBackground { background.alpha: parent.currentId === 0 ? 0.7 : 0 onClicked: { - resetFocus(); pluginSortButtonRoot.model.changeProvider(0); } Keys.onPressed: { @@ -95,7 +87,6 @@ UkuiItems.StyleBackground { background.alpha: parent.currentId === 1 ? 0.7 : 0 onClicked: { - resetFocus(); pluginSortButtonRoot.model.changeProvider(1); } Keys.onPressed: { diff --git a/qml/AppUI/SearchInputBar.qml b/qml/AppUI/SearchInputBar.qml index ce1c306..b6a11c4 100644 --- a/qml/AppUI/SearchInputBar.qml +++ b/qml/AppUI/SearchInputBar.qml @@ -34,7 +34,6 @@ UkuiItems.StyleBackground { border.width: 1 borderAlpha: textInput.activeFocus ? 1 : 0.1 borderColor: textInput.activeFocus ? Platform.Theme.Highlight : Platform.Theme.Base - Component.onCompleted: mainWindow.visibleChanged.connect(clear) Component.onDestruction: mainWindow.visibleChanged.disconnect(clear) function textInputFocus() { @@ -46,8 +45,8 @@ UkuiItems.StyleBackground { Item { id: defaultSearch width: searchIcon.width + defaultText.contentWidth; height: parent.height - anchors.horizontalCenter: mainWindow.isFullScreen ? parent.horizontalCenter : undefined anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left Item { id: searchIcon @@ -75,19 +74,6 @@ UkuiItems.StyleBackground { verticalAlignment: TextInput.AlignVCenter alpha: 0.25 } - - states: State { - when: !mainWindow.isFullScreen || textInput.text !== "" || textInput.activeFocus - AnchorChanges { - target: defaultSearch - anchors.left: parent.left - anchors.horizontalCenter: undefined - } - } - - transitions: Transition { - AnchorAnimation { duration: 300; easing.type: Easing.InOutCubic } - } } TextInput { @@ -99,29 +85,21 @@ UkuiItems.StyleBackground { selectByMouse: true verticalAlignment: TextInput.AlignVCenter font.pointSize: defaultText.font.pointSize - focus: parent.visible || mainWindow.isFullScreen - + focus: true activeFocusOnTab: true + function changeFocusToListView() { if (!mainWindow.isFullScreen) { normalUI.focus = true; changeFocusTarget.focus = true; appPage.content.resetFocus(); - } else { - if (text !== "") { - fullScreenContent.viewFocusEnable(); - } } } Keys.onDownPressed: changeFocusToListView() Keys.onReturnPressed: changeFocusToListView() - //字体选中跟随主题高亮 - property bool isFullScreen: mainWindow.isFullScreen - onIsFullScreenChanged: updateTextInputColor() - function updateTextInputColor() { - color = isFullScreen ? Platform.Theme.highlightedText() : Platform.Theme.text(); + color = Platform.Theme.text(); selectionColor = Platform.Theme.highlight(); } @@ -138,18 +116,16 @@ UkuiItems.StyleBackground { anchors.right: parent.right anchors.rightMargin: (parent.height - height) / 2 anchors.verticalCenter: parent.verticalCenter - width: 18; height: width - visible: textInput.activeFocus + width: 32; height: width + background.radius: width / 2 + visible: textInput.length !== 0 activeFocusOnTab: false - background.radius: width/2 - background.border.width: 1 icon.source: "edit-clear-symbolic" icon.mode: UkuiItems.Icon.AutoHighlight onClicked: { textInput.clear(); - textInput.focus = false; } } } diff --git a/qml/AppUI/WidgetPage.qml b/qml/AppUI/WidgetPage.qml index 8f921d8..2898cb9 100644 --- a/qml/AppUI/WidgetPage.qml +++ b/qml/AppUI/WidgetPage.qml @@ -117,7 +117,6 @@ Item { MouseArea { anchors.fill: parent onClicked: { - normalUI.focusToFalse(); widgetList.currentIndex = model.index; EventTrack.sendClickEvent("switch_plugin", "Sidebar", {"plugin": model.name}); } diff --git a/qml/extensions/FavoriteDelegate.qml b/qml/extensions/FavoriteDelegate.qml index 53e58d0..05786f1 100644 --- a/qml/extensions/FavoriteDelegate.qml +++ b/qml/extensions/FavoriteDelegate.qml @@ -90,10 +90,21 @@ UkuiItems.StyleBackground { acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: { + if (mainWindow.isFullScreen) { + fullScreenUI.focus =false; + } else { + normalUI.focus = false; + } + itemLoader.item.itemClicked(mouse.button); } onPressAndHold: { if (mouse.button === Qt.LeftButton) { + if (mainWindow.isFullScreen) { + fullScreenUI.focus =false; + } else { + normalUI.focus = false; + } drag.target = itemLoader; iconItem.hold = true; favoriteView.exchangedStartIndex = itemLoader.visualIndex; diff --git a/qml/extensions/FavoriteExtension.qml b/qml/extensions/FavoriteExtension.qml index e04dd8b..4d1bb43 100644 --- a/qml/extensions/FavoriteExtension.qml +++ b/qml/extensions/FavoriteExtension.qml @@ -35,6 +35,7 @@ UkuiMenuExtension { onClicked: { if (mouse.button === Qt.RightButton) { + normalUI.focus = false; menu.open(); } else { if (mainWindow.editMode) { diff --git a/qml/main.qml b/qml/main.qml index c864220..30891f4 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -26,7 +26,6 @@ import org.ukui.quick.platform 1.0 as Platform Item { id: root clip: true - property int animationDuration: menuSetting.get("animationDuration") property double transparency: mainWindow.transparency property bool onComlpeted: false @@ -224,6 +223,7 @@ Item { Loader { id: normalScreenLoader focus: !mainWindow.isFullScreen + active: false height: normalScreenGeometry.normalGeometry.height; width: normalScreenGeometry.normalGeometry.width sourceComponent: normalComponent NumberAnimation { id: normalShow; target: normalScreenLoader; properties: "opacity"; from: 0; to: 1; duration: root.animationDuration; easing.type: Easing.InQuint } @@ -240,6 +240,7 @@ Item { Loader { id: fullScreenLoader anchors.fill: parent + focus: mainWindow.isFullScreen sourceComponent: fullSceenComponent NumberAnimation { id: fullShow; target: fullScreenLoader; properties: "opacity"; from: 0; to: 1; duration: root.animationDuration; easing.type: Easing.InQuint } NumberAnimation { id: fullHide; target: fullScreenLoader; properties: "opacity"; from: 1; to: 0; duration: root.animationDuration; easing.type: Easing.OutQuint } @@ -257,6 +258,6 @@ Item { Component { id: normalComponent - AppUI.NormalUI {} + AppUI.NormalUI { } } }