/* * Copyright (C) 2023, KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ import QtQuick 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.5 import AppControls2 1.0 as AppControls2 import org.ukui.menu.core 1.0 import org.ukui.menu.utils 1.0 Item { id: appPageHeaderRoot property string title: "" property Item focusToPageContent property Component content: null clip: true function changeToSearch(keyEvent) { if (appPageHeaderRoot.content === null) { loader.item.changeToSearchState(keyEvent); } } Loader { id: loader anchors.fill: parent property string title: appPageHeaderRoot.title sourceComponent: { return appPageHeaderRoot.content === null ? defaultComponent : appPageHeaderRoot.content } } Component { id: defaultComponent Item { id: root function changeToSearchState(keyEvent) { state = "search"; searchInputBar.text = keyEvent; } state: "normal" states: [ State { name: "normal" PropertyChanges { target: searchBar; scale: 0.9; y: -pluginSelectionBar.height } PropertyChanges { target: pluginSelectionBar; scale: 1.0; y: 0 } StateChangeScript { script: pluginSelectMenu.model.reactivateProvider() } }, State { name: "search" PropertyChanges { target: searchBar; scale: 1.0; y: 0 } PropertyChanges { target: pluginSelectionBar; scale: 0.9; y: pluginSelectionBar.height } } ] transitions:[ Transition { to: "normal" SequentialAnimation { ScriptAction { script: { pluginSelectionBar.visible = true; pluginSelectMenu.visible = true; } } NumberAnimation { easing.type: Easing.InOutQuad; properties: "scale,y"; duration: 300 } ScriptAction { script: searchBar.visible = false } } }, Transition { to: "search" SequentialAnimation { ScriptAction { script: { searchBar.visible = true; searchInputBar.providerId = "search"; searchInputBar.textInputFocus(); } } NumberAnimation { easing.type: Easing.InOutQuad; properties: "scale,y"; duration: 300} ScriptAction { script: { pluginSelectionBar.visible = false; pluginSelectMenu.visible = false; } } } } ] Item { id: searchBar width: parent.width; height: 30 Component.onCompleted: { visible = false; mainWindow.visibleChanged.connect(searchBarHide); } Component.onDestruction: mainWindow.visibleChanged.disconnect(searchBarHide); function searchBarHide() { if (!mainWindow.visible) { root.state = "normal" } } RowLayout { anchors.fill: parent anchors.leftMargin: 15 anchors.rightMargin: 15 spacing: 10 SearchInputBar { id: searchInputBar property string providerId: "" Layout.fillWidth: true Layout.fillHeight: true radius: 16 changeFocusTarget: focusToPageContent onTextChanged: { if (text === "") { pluginSelectMenu.model.reactivateProvider(); } else { appPageHeaderUtils.activateProvider(providerId); appPageHeaderUtils.startSearch(text); } } } AppControls2.RoundButton { Layout.preferredWidth: parent.height; Layout.preferredHeight: parent.height buttonIcon: "image://appicon/edit-clear-symbolic" activeFocusOnTab: true onClicked: { normalUI.focusToFalse(); searchInputBar.clear(); root.state = "normal"; } Keys.onPressed: { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { searchInputBar.clear(); root.state = "normal"; } } } } } Item { id: pluginSelectionBar width: parent.width height: parent.height RowLayout { anchors.fill: parent anchors.leftMargin: 16 spacing: 12 AppControls2.StyleText { Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: Qt.AlignVCenter text: appPageHeaderRoot.title font.bold: true } ListView { id: searchListView Layout.preferredWidth: childrenRect.width Layout.preferredHeight: 32 Layout.minimumWidth: 32 Layout.maximumWidth: 68 Layout.alignment: Qt.AlignVCenter clip: true spacing: 4 orientation: ListView.Horizontal interactive: false activeFocusOnTab: true model: appPageHeaderUtils.model(PluginGroup.Button) delegate: AppControls2.RoundButton { width: height height: ListView.view ? ListView.view.height : 0 buttonIcon: model.icon ToolTip.text: qsTr("Search App") ToolTip.delay: 500 ToolTip.visible: containsMouse onClicked: { root.state = "search"; // 后续添加需求,可以用model数据设置 // searchInputBar.providerId = model.id; } Keys.onPressed: { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { root.state = "search"; } } } } PluginSelectMenu { id: pluginSelectMenu Layout.preferredWidth: childrenRect.width Layout.preferredHeight: 32 Layout.maximumHeight: 32 Layout.minimumWidth: 32 Layout.rightMargin: 8 Layout.alignment: Qt.AlignVCenter } } } function updateTitle(id) { appPageHeaderRoot.title = appPageHeaderUtils.getPluginTitle(id); } Component.onCompleted: { updateTitle(""); appPageHeaderUtils.pluginChanged.connect(updateTitle); } Component.onDestruction: { appPageHeaderUtils.pluginChanged.disconnect(updateTitle); } } } }