/*************************************************************************** * Copyright (C) 2014 by Weng Xuetian <wengxt@gmail.com> * Copyright (C) 2013-2017 by Eike Hein <hein@kde.org> * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.4 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.12 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 3.0 as PC3 import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.private.kicker 0.1 as Kicker import org.kde.kquickcontrolsaddons 2.0 import org.kde.plasma.private.quicklaunch 1.0 import org.kde.kirigami as Kirigami PlasmaCore.Dialog { id: root objectName: "popupWindow" //flags: Qt.Dialog | Qt.FramelessWindowHint flags: Qt.WindowStaysOnTopHint location:{ if (Plasmoid.configuration.displayPosition === 1) return PlasmaCore.Types.Floating else if (Plasmoid.configuration.displayPosition === 2) return PlasmaCore.Types.BottomEdge else return Plasmoid.location } hideOnWindowDeactivate: true property int iconSize:{ switch(Plasmoid.configuration.appsIconSize){ case 0: return Kirigami.Units.iconSizes.smallMedium; case 1: return Kirigami.Units.iconSizes.medium; case 2: return Kirigami.Units.iconSizes.large; case 3: return Kirigami.Units.iconSizes.huge; default: return 64 } } property int docsIconSize:{ switch(Plasmoid.configuration.docsIconSize){ case 0: return Kirigami.Units.iconSizes.smallMedium; case 1: return Kirigami.Units.iconSizes.medium; case 2: return Kirigami.Units.iconSizes.large; case 3: return Kirigami.Units.iconSizes.huge; default: return Kirigami.Units.iconSizes.medium; } } property int cellSizeHeight: iconSize + Kirigami.Units.gridUnit * 2 + (2 * Math.max(highlightItemSvg.margins.top + highlightItemSvg.margins.bottom, highlightItemSvg.margins.left + highlightItemSvg.margins.right)) property int cellSizeWidth: cellSizeHeight + Kirigami.Units.gridUnit property bool searching: (searchField.text != "") onSearchingChanged: { if(searching) view.currentIndex = 2 else view.currentIndex = 0 } onVisibleChanged: { if (visible) { var pos = popupPosition(width, height); x = pos.x; y = pos.y; reset(); }else{ view.currentIndex = 0 } } onHeightChanged: { var pos = popupPosition(width, height); x = pos.x; y = pos.y; } onWidthChanged: { var pos = popupPosition(width, height); x = pos.x; y = pos.y; } function toggle(){ root.visible = !root.visible } function reset() { searchField.text = ""; searchField.focus = true view.currentIndex = 0 globalFavoritesGrid.currentIndex = -1 documentsGrid.currentIndex = -1 allAppsGrid.currentIndex = -1 } function popupPosition(width, height) { var screenAvail = kicker.availableScreenRect; var screen = kicker.screenGeometry; var panelH = kicker.height var panelW = kicker.width var horizMidPoint = screen.x + (screen.width / 2); var vertMidPoint = screen.y + (screen.height / 2); var appletTopLeft = parent.mapToGlobal(0, 0); var offset = Kirigami.Units.smallSpacing * 2; if (Plasmoid.configuration.displayPosition === 1) { horizMidPoint = screen.x + (screen.width / 2); vertMidPoint = screen.y + (screen.height / 2); x = horizMidPoint - width / 2; y = vertMidPoint - height / 2; } else if (Plasmoid.configuration.displayPosition === 2) { horizMidPoint = screen.x + (screen.width / 2); vertMidPoint = screen.y + (screen.height / 2); x = horizMidPoint - width / 2; // y = screen.y + screen.height - height - offset - panelH - Kirigami.Units.gridUnit; // y = screen.y + screen.height - height - offset - panelH - Kirigami.Units.gridUnit / 2; y = screen.y + screen.height - height - offset - panelH - Kirigami.Units.largeSpacing * 1.5; } else { switch (plasmoid.location) { case PlasmaCore.Types.BottomEdge: var y = appletTopLeft.y - height - offset var x = appletTopLeft.x break; case PlasmaCore.Types.TopEdge: x = appletTopLeft.x < screen.width - width ? appletTopLeft.x + panelW - Kirigami.Units.gridUnit / 3 : screen.width - width; y = appletTopLeft.y + kicker.height + Kirigami.Units.gridUnit break; case PlasmaCore.Types.LeftEdge: x = appletTopLeft.x + panelW + Kirigami.Units.gridUnit / 2; y = appletTopLeft.y < screen.height - height ? appletTopLeft.y : appletTopLeft.y - height + iconUser.height / 2; break; case PlasmaCore.Types.RightEdge: x = appletTopLeft.x - width - Kirigami.Units.gridUnit / 2; y = appletTopLeft.y < screen.height - height ? appletTopLeft.y : screen.height - height - Kirigami.Units.gridUnit / 5; break; default: return; } } return Qt.point(x, y); } function colorWithAlpha(color: color, alpha: real): color { return Qt.rgba(color.r, color.g, color.b, alpha) } mainItem: FocusScope { id: rootItem property int widthComputed: root.cellSizeWidth * Plasmoid.configuration.numberColumns + Kirigami.Units.gridUnit*2 width: rootItem.widthComputed+ Kirigami.Units.gridUnit*2 Layout.minimumWidth: width Layout.maximumWidth: width Layout.minimumHeight: view.height + searchField.height + footer.height + Kirigami.Units.gridUnit * 3 Layout.maximumHeight: view.height + searchField.height + footer.height + Kirigami.Units.gridUnit * 3 focus: true onFocusChanged: searchField.focus = true Kirigami.Heading { id: dummyHeading visible: false width: 0 level: 5 } TextMetrics { id: headingMetrics font: dummyHeading.font } PC3.TextField { id: searchField anchors{ top: parent.top topMargin: Kirigami.Units.gridUnit left: parent.left leftMargin: Kirigami.Units.gridUnit right: parent.right rightMargin: Kirigami.Units.gridUnit } focus: true placeholderText: i18n("Type here to search ...") topPadding: 10 bottomPadding: 10 leftPadding: Kirigami.Units.gridUnit + Kirigami.Units.iconSizes.small text: "" font.pointSize: Kirigami.Theme.defaultFont.pointSize background: Rectangle { color: Kirigami.Theme.backgroundColor radius: 3 border.width: 1 border.color: colorWithAlpha(Kirigami.Theme.textColor,0.05) } onTextChanged: runnerModel.query = text; Keys.onPressed: (event)=> { if (event.key === Qt.Key_Escape) { event.accepted = true; if(root.searching){ searchField.clear() } else { root.toggle() } } if (event.key === Qt.Key_Down || event.key === Qt.Key_Tab || event.key === Qt.Key_Backtab) { event.accepted = true; view.currentItem.forceActiveFocus() view.currentItem.tryActivate(0,0) } } function backspace() { if (!root.visible) { return; } focus = true; text = text.slice(0, -1); } function appendText(newText) { if (!root.visible) { return; } focus = true; text = text + newText; } Kirigami.Icon { source: 'search' anchors { left: searchField.left verticalCenter: searchField.verticalCenter leftMargin: Kirigami.Units.smallSpacing * 2 } height: Kirigami.Units.iconSizes.small width: height } } Rectangle{ height: 2 width: searchField.width - 2 anchors.bottom: searchField.bottom anchors.horizontalCenter: parent.horizontalCenter color: Kirigami.Theme.highlightColor } // // // // // SwipeView { id: view interactive: false currentIndex: 0 clip: true anchors.top: searchField.bottom anchors.topMargin: Kirigami.Units.gridUnit anchors.left: parent.left anchors.leftMargin: Kirigami.Units.gridUnit onCurrentIndexChanged: { globalFavoritesGrid.currentIndex = -1 documentsGrid.currentIndex = -1 } width: rootItem.widthComputed height: (root.cellSizeHeight * Plasmoid.configuration.numberRows) + (topRow.height*2) + ((docsIconSize + Kirigami.Units.largeSpacing)*3) + (3*Kirigami.Units.largeSpacing) // // PAGE 1 // Column{ width: rootItem.widthComputed height: view.height spacing: Kirigami.Units.largeSpacing function tryActivate(row, col) { globalFavoritesGrid.tryActivate(row, col); } RowLayout{ id: topRow width: rootItem.widthComputed height: butttonActionAllApps.implicitHeight Kirigami.Icon { source: 'favorite' implicitHeight: Kirigami.Units.iconSizes.smallMedium implicitWidth: Kirigami.Units.iconSizes.smallMedium } PlasmaExtras.Heading { id: headLabelFavorites color: colorWithAlpha(Kirigami.Theme.textColor, 0.8) level: 5 text: i18n("Pinned") font.weight: Font.Bold } Item{ Layout.fillWidth: true } AToolButton { id: butttonActionAllApps flat: false iconName: "go-next" text: i18n("All apps") onClicked: { view.currentIndex = 1 } } } ItemGridView { id: globalFavoritesGrid width: rootItem.widthComputed height: root.cellSizeHeight * Plasmoid.configuration.numberRows itemColumns: 1 dragEnabled: true dropEnabled: true cellWidth: root.cellSizeWidth cellHeight: root.cellSizeHeight iconSize: root.iconSize onKeyNavUp: { globalFavoritesGrid.focus = false searchField.focus = true; } onKeyNavDown: { globalFavoritesGrid.focus = false documentsGrid.tryActivate(0,0) } Keys.onPressed:(event)=> { if (event.key === Qt.Key_Tab) { event.accepted = true; searchField.focus = true globalFavoritesGrid.focus = false } } } RowLayout{ width: rootItem.widthComputed height: butttonActionAllApps.implicitHeight Kirigami.Icon { source: 'tag-recents' implicitHeight: Kirigami.Units.iconSizes.smallMedium implicitWidth: Kirigami.Units.iconSizes.smallMedium } PlasmaExtras.Heading { color: colorWithAlpha(Kirigami.Theme.textColor, 0.8) level: 5 text: i18n("Recent documents") Layout.leftMargin: Kirigami.Units.smallSpacing font.weight: Font.Bold } Item{ Layout.fillWidth: true } //AToolButton { // flat: false // iconName: "list-add" // text: i18n("More") // onClicked: { // //view.currentIndex = 1 // // } //} } ItemGridView { id: documentsGrid width: rootItem.widthComputed height: cellHeight * 3 itemColumns: 2 dragEnabled: true dropEnabled: true cellWidth: rootItem.widthComputed * 0.48 cellHeight: docsIconSize + Kirigami.Units.largeSpacing iconSize: docsIconSize clip: true onKeyNavUp: {globalFavoritesGrid.tryActivate(0,0); documentsGrid.focus = false } Keys.onPressed:(event)=> { if (event.key === Qt.Key_Tab) { event.accepted = true; searchField.focus = true documentsGrid.focus = false } } } } // // PAGE 2 // Column{ width: rootItem.widthComputed height: view.height spacing: Kirigami.Units.largeSpacing function tryActivate(row, col) { allAppsGrid.tryActivate(row, col); } RowLayout{ width: rootItem.widthComputed height: butttonActionAllApps.implicitHeight Kirigami.Icon { source: 'application-menu' implicitHeight: Kirigami.Units.iconSizes.smallMedium implicitWidth: Kirigami.Units.iconSizes.smallMedium } PlasmaExtras.Heading { color: colorWithAlpha(Kirigami.Theme.textColor, 0.8) level: 5 text: i18n("All apps") Layout.leftMargin: Kirigami.Units.smallSpacing font.weight: Font.Bold } Item{ Layout.fillWidth: true } AToolButton { flat: false iconName: 'go-previous' text: i18n("Pinned") mirror: true onClicked: { view.currentIndex = 0 } } } ItemGridView { id: allAppsGrid width: rootItem.widthComputed height: Math.floor((view.height-topRow.height-Kirigami.Units.largeSpacing)/cellHeight)* cellHeight itemColumns: 3 dragEnabled: false dropEnabled: false cellWidth: rootItem.widthComputed - Kirigami.Units.gridUnit * 2 cellHeight: root.iconSize + Kirigami.Units.largeSpacing iconSize: root.iconSize clip: true onKeyNavUp: { searchField.focus = true allAppsGrid.focus = false } Keys.onPressed:(event)=> { if (event.key === Qt.Key_Tab) { event.accepted = true; searchField.focus = true allAppsGrid.focus = false } } } } // // PAGE 3 // ItemMultiGridView { id: runnerGrid width: rootItem.widthComputed height: view.height itemColumns: 3 cellWidth: rootItem.widthComputed - Kirigami.Units.gridUnit * 2 cellHeight: root.iconSize + Kirigami.Units.smallSpacing model: runnerModel grabFocus: false onKeyNavUp: { runnerGrid.focus = false searchField.focus = true } } } PlasmaExtras.PlasmoidHeading { id: footer contentWidth: parent.width contentHeight: Kirigami.Units.gridUnit * 3 anchors.bottom: parent.bottom position: PC3.ToolBar.Footer Footer{ anchors.fill: parent anchors.leftMargin: Kirigami.Units.gridUnit anchors.rightMargin: Kirigami.Units.gridUnit } } Keys.onPressed: (event)=> { if(event.modifiers & Qt.ControlModifier ||event.modifiers & Qt.ShiftModifier){ searchField.focus = true; return } if (event.key === Qt.Key_Escape) { event.accepted = true; if (root.searching) { reset(); } else { root.visible = false; } return; } if (searchField.focus) { return; } if (event.key === Qt.Key_Backspace) { event.accepted = true; searchField.backspace(); } else if (event.text !== "") { event.accepted = true; searchField.appendText(event.text); } searchField.focus = true } } function setModels(){ globalFavoritesGrid.model = globalFavorites allAppsGrid.model = rootModel.modelForRow(2); documentsGrid.model = rootModel.modelForRow(1) } Component.onCompleted: { rootModel.refreshed.connect(setModels) reset(); rootModel.refresh(); } }