/*SPDX-FileCopyrightText: 2013-2015 Eike Hein <hein@kde.org>SPDX-License-Identifier: GPL-2.0-or-later*/import QtQuickimport QtQuick.Layoutsimport org.kde.kirigami as Kirigamiimport org.kde.ksvg as KSvgimport org.kde.plasma.core as PlasmaCoreimport org.kde.plasma.extras as PlasmaExtrasimport org.kde.plasma.plasmoidFocusScope {id: rootfocus: trueLayout.minimumWidth: (sideBar.width + (sideBar.width ? mainRow.spacing : 0)+ Math.max(searchField.defaultWidth, runnerColumns.width))Layout.maximumWidth: Math.max(mainRow.width, Layout.minimumWidth); // mainRow.width is constrained by rootList.maximumWidthLayout.minimumHeight: Math.max(((rootModel.count - rootModel.separatorCount) * rootList.itemHeight)+ (rootModel.separatorCount * rootList.separatorHeight)+ searchField.height + (2 * Kirigami.Units.smallSpacing), sideBar.margins.top + sideBar.margins.bottom+ favoriteApps.contentHeight + favoriteSystemActions.contentHeight + sidebarSeparator.height+ (4 * Kirigami.Units.smallSpacing))Layout.maximumHeight: Layout.minimumHeightsignal appendSearchText(string text)function reset() {kicker.hideOnWindowDeactivate = true;rootList.currentIndex = -1;searchField.text = "";searchField.focus = true;}Row {id: mainRowheight: parent.heightspacing: Kirigami.Units.smallSpacingLayoutMirroring.enabled: ((Plasmoid.location === PlasmaCore.Types.RightEdge)|| (Qt.application.layoutDirection === Qt.RightToLeft && Plasmoid.location !== PlasmaCore.Types.LeftEdge))KSvg.FrameSvgItem {id: sideBarvisible: width > 0width: (globalFavorites && systemFavorites&& (globalFavorites.count + systemFavorites.count)? Kirigami.Units.iconSizes.medium + margins.left + margins.right : 0)height: parent.heightimagePath: "widgets/frame"prefix: "plain"SideBarSection {id: favoriteAppsanchors.top: parent.topanchors.topMargin: sideBar.margins.topheight: (sideBar.height - sideBar.margins.top - sideBar.margins.bottom- favoriteSystemActions.height - sidebarSeparator.height - (4 * Kirigami.Units.smallSpacing))model: globalFavoritesstates: State {name: "top"when: Plasmoid.location === PlasmaCore.Types.TopEdgeAnchorChanges {target: favoriteAppsanchors.top: undefinedanchors.bottom: parent.bottom}PropertyChanges {target: favoriteAppsanchors.topMargin: undefinedanchors.bottomMargin: sideBar.margins.bottom}}Binding {target: globalFavoritesproperty: "iconSize"value: Kirigami.Units.iconSizes.mediumrestoreMode: Binding.RestoreBinding}}KSvg.SvgItem {id: sidebarSeparatoranchors.bottom: favoriteSystemActions.topanchors.bottomMargin: (2 * Kirigami.Units.smallSpacing)anchors.horizontalCenter: parent.horizontalCenterwidth: Kirigami.Units.iconSizes.mediumheight: lineSvg.horLineHeightvisible: (favoriteApps.model && favoriteApps.model.count&& favoriteSystemActions.model && favoriteSystemActions.model.count)svg: lineSvgelementId: "horizontal-line"states: State {name: "top"when: Plasmoid.location === PlasmaCore.Types.TopEdgeAnchorChanges {target: sidebarSeparatoranchors.top: favoriteSystemActions.bottomanchors.bottom: undefined}PropertyChanges {target: sidebarSeparatoranchors.topMargin: (2 * Kirigami.Units.smallSpacing)anchors.bottomMargin: undefined}}}SideBarSection {id: favoriteSystemActionsanchors.bottom: parent.bottomanchors.bottomMargin: sideBar.margins.bottommodel: systemFavoritesstates: State {name: "top"when: Plasmoid.location === PlasmaCore.Types.TopEdgeAnchorChanges {target: favoriteSystemActionsanchors.top: parent.topanchors.bottom: undefined}PropertyChanges {target: favoriteSystemActionsanchors.topMargin: sideBar.margins.topanchors.bottomMargin: undefined}}}}ItemListView {id: rootListanchors.top: parent.topminimumWidth: root.Layout.minimumWidth - sideBar.width - mainRow.spacingheight: ((rootModel.count - rootModel.separatorCount) * itemHeight) + (rootModel.separatorCount * separatorHeight)visible: searchField.text === ""iconsEnabled: Plasmoid.configuration.showIconsRootLevelmodel: rootModelonKeyNavigationAtListEnd: {searchField.focus = true;}states: State {name: "top"when: Plasmoid.location === PlasmaCore.Types.TopEdgeAnchorChanges {target: rootListanchors.top: parent.top}}Component.onCompleted: {rootList.exited.connect(root.reset);}}Row {id: runnerColumnsheight: parent.heightvisible: searchField.text !== "" && runnerModel.count > 0Repeater {id: runnerColumnsRepeatermodel: runnerModeldelegate: RunnerResultsList {id: runnerMatchesvisible: runnerModel.modelForRow(index).count > 0onKeyNavigationAtListEnd: {searchField.focus = true;}onContainsMouseChanged: {if (containsMouse) {focus = true;}}onFocusChanged: {if (!focus) {currentIndex = -1;}}Keys.onPressed: event => {let target = null;const targets = [];switch (event.key) {case Qt.Key_Right:for (let i = index + 1; i < runnerModel.count; ++i) {targets.push(i);}for (let i = 0; i < index; ++i) {targets.push(i);}for (const i of targets) {if (runnerModel.modelForRow(i).count) {target = runnerColumnsRepeater.itemAt(i);break;}}break;case Qt.Key_Left:for (let i = index - 1; i >= 0; --i) {targets.push(i);}for (let i = runnerModel.count - 1; i > index; --i) {targets.push(i);}for (const i of targets) {if (runnerModel.modelForRow(i).count) {target = runnerColumnsRepeater.itemAt(i);break;}}break;}if (target) {event.accepted = true;currentIndex = -1;target.currentIndex = 0;target.focus = true;}}}}}}PlasmaExtras.SearchField {id: searchFieldanchors.bottom: mainRow.bottomanchors.left: parent.leftanchors.leftMargin: sideBar.width + (sideBar.width ? mainRow.spacing : Kirigami.Units.smallSpacing)readonly property real defaultWidth: Kirigami.Units.gridUnit * 14width: runnerColumns.visibleChildren.length > 1? runnerColumns.visibleChildren[0].width: (rootList.visible ? rootList.width : defaultWidth)focus: !Kirigami.InputMethod.willShowOnActiveonTextChanged: {runnerModel.query = text;}onFocusChanged: {if (focus) {// FIXME: Cleanup arbitration between rootList/runnerCols here and in Keys.if (rootList.visible) {rootList.currentIndex = -1;}if (runnerColumns.visible) {runnerColumnsRepeater.itemAt(0).currentIndex = -1;}}}states: [State {name: "top"when: Plasmoid.location === PlasmaCore.Types.TopEdgeAnchorChanges {target: searchFieldanchors.top: undefinedanchors.bottom: mainRow.bottomanchors.left: parent.leftanchors.right: undefined}PropertyChanges {target: searchFieldanchors.leftMargin: sideBar.width + mainRow.spacing + Kirigami.Units.smallSpacinganchors.rightMargin: undefined}},State {name: "right"when: (Plasmoid.location === PlasmaCore.Types.RightEdge && Qt.application.layoutDirection === Qt.LeftToRight)|| (Plasmoid.location === PlasmaCore.Types.LeftEdge && Qt.application.layoutDirection === Qt.RightToLeft)AnchorChanges {target: searchFieldanchors.top: undefinedanchors.bottom: mainRow.bottomanchors.left: undefinedanchors.right: parent.right}PropertyChanges {target: searchFieldanchors.leftMargin: undefinedanchors.rightMargin: sideBar.width + mainRow.spacing + Kirigami.Units.smallSpacing}}]Keys.onPressed: event => {if (event.key === Qt.Key_Up) {if (rootList.visible) {rootList.showChildDialogs = false;rootList.currentIndex = rootList.model.count - 1;rootList.forceActiveFocus();rootList.showChildDialogs = true;}if (runnerColumns.visible) {for (let i = 0; i < runnerModel.count; ++i) {if (runnerModel.modelForRow(i).count) {const targetList = runnerColumnsRepeater.itemAt(i);targetList.currentIndex = runnerModel.modelForRow(i).count - 1;targetList.forceActiveFocus();break;}}}} else if (event.key === Qt.Key_Down) {if (rootList.visible) {rootList.showChildDialogs = false;rootList.currentIndex = Math.min(1, rootList.count);rootList.forceActiveFocus();rootList.showChildDialogs = true;}if (runnerColumns.visible) {for (let i = 0; i < runnerModel.count; ++i) {if (runnerModel.modelForRow(i).count) {const targetList = runnerColumnsRepeater.itemAt(i);targetList.currentIndex = Math.min(1, targetList.count);targetList.forceActiveFocus();break;}}}} else if (event.key === Qt.Key_Left && cursorPosition === 0) {for (let i = runnerModel.count; i >= 0; --i) {if (runnerModel.modelForRow(i).count) {const targetList = runnerColumnsRepeater.itemAt(i);targetList.currentIndex = 0;targetList.forceActiveFocus();break;}}} else if (event.key === Qt.Key_Right && cursorPosition === length) {for (let i = 1; i < runnerModel.count; ++i) {if (runnerModel.modelForRow(i).count) {const targetList = runnerColumnsRepeater.itemAt(i);targetList.currentIndex = 0;targetList.forceActiveFocus();break;}}} else if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {if (runnerColumns.visible && runnerModel.modelForRow(0).count) {runnerModel.modelForRow(0).trigger(0, "", null);kicker.expanded = false;}}}function appendText(newText) {focus = true;text = text + newText;}}Keys.onPressed: event => {if (event.key === Qt.Key_Escape) {kicker.expanded = false;}}Component.onCompleted: {appendSearchText.connect(searchField.appendText);kicker.reset.connect(reset);windowSystem.hidden.connect(reset);rootModel.refresh();}}