diff --git a/applets/kickoff/package/contents/ui/ApplicationsView.qml b/applets/kickoff/package/contents/ui/ApplicationsView.qml index 7d4d71adf..b9d71fa4d 100644 --- a/applets/kickoff/package/contents/ui/ApplicationsView.qml +++ b/applets/kickoff/package/contents/ui/ApplicationsView.qml @@ -1,293 +1,283 @@ /* Copyright (C) 2011 Martin Gräßlin Copyright (C) 2012 Gregor Taetzner Copyright 2014 Sebastian Kügler - Copyright (C) 2015 Eike Hein + Copyright (C) 2015-2018 Eike Hein 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.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.components 2.0 as PlasmaComponents Item { id: appViewContainer anchors.fill: parent objectName: "ApplicationsView" - property ListView listView: applicationsView + property ListView listView: applicationsView.listView function decrementCurrentIndex() { applicationsView.decrementCurrentIndex(); } function incrementCurrentIndex() { applicationsView.incrementCurrentIndex(); } function activateCurrentIndex(start) { if (!applicationsView.currentItem.modelChildren) { if (!start) { return; } } - appViewScrollArea.state = "OutgoingLeft"; + applicationsView.state = "OutgoingLeft"; } function openContextMenu() { applicationsView.currentItem.openActionMenu(); } function deactivateCurrentIndex() { if (crumbModel.count > 0) { // this is not the case when switching from the "Applications" to the "Favorites" tab using the "Left" key breadcrumbsElement.children[crumbModel.count-1].clickCrumb(); - appViewScrollArea.state = "OutgoingRight"; + applicationsView.state = "OutgoingRight"; return true; } return false; } function reset() { applicationsView.model = rootModel; - applicationsView.positionViewAtBeginning(); + applicationsView.listView.positionViewAtBeginning(); applicationsView.clearBreadcrumbs(); } function refreshed() { reset(); updatedLabelTimer.running = true; } Connections { target: plasmoid onExpandedChanged: { if (!expanded) { reset(); } } } Item { id: crumbContainer anchors { top: parent.top left: parent.left right: parent.right } height: childrenRect.height Behavior on opacity { NumberAnimation { duration: units.longDuration } } Flickable { id: breadcrumbFlickable anchors { top: parent.top left: parent.left right: parent.right } height: breadcrumbsElement.height boundsBehavior: Flickable.StopAtBounds contentWidth: breadcrumbsElement.width pixelAligned: true //contentX: contentWidth - width // HACK: Align the content to right for RTL locales leftMargin: LayoutMirroring.enabled ? Math.max(0, width - contentWidth) : 0 PlasmaComponents.ButtonRow { id: breadcrumbsElement exclusive: false Breadcrumb { id: rootBreadcrumb root: true text: i18n("All Applications") depth: 0 } Repeater { model: ListModel { id: crumbModel // Array of the models property var models: [] } Breadcrumb { root: false text: model.text } } onWidthChanged: { if (LayoutMirroring.enabled) { breadcrumbFlickable.contentX = -Math.max(0, breadcrumbsElement.width - breadcrumbFlickable.width) } else { breadcrumbFlickable.contentX = Math.max(0, breadcrumbsElement.width - breadcrumbFlickable.width) } } } } // Flickable } // crumbContainer - PlasmaExtras.ScrollArea { - id: appViewScrollArea - - property Item activatedItem: null + KickoffListView { + id: applicationsView anchors { top: crumbContainer.bottom bottom: parent.bottom rightMargin: -units.largeSpacing leftMargin: -units.largeSpacing } + width: parent.width + + property Item activatedItem: null + property var newModel: null + Behavior on opacity { NumberAnimation { duration: units.longDuration } } - width: parent.width + focus: true - function moveRight() { - state = ""; - activatedItem.activate() - applicationsView.positionViewAtBeginning() - } + appView: true + + model: rootModel function moveLeft() { state = ""; // newModelIndex set by clicked breadcrumb var oldModel = applicationsView.model; applicationsView.model = applicationsView.newModel; - applicationsView.positionViewAtIndex(applicationsView.model.rowForModel(oldModel), ListView.Center) + listView.positionViewAtIndex(model.rowForModel(oldModel), ListView.Center) } - ListView { - id: applicationsView - - property variant newModel - - focus: true - keyNavigationWraps: true - boundsBehavior: Flickable.StopAtBounds - highlight: KickoffHighlight {} - highlightMoveDuration : 0 - highlightResizeDuration: 0 - - model: rootModel - - delegate: KickoffItem { - id: kickoffItem + function moveRight() { + state = ""; + activatedItem.activate() + applicationsView.listView.positionViewAtBeginning() + } - appView: true - } + function clearBreadcrumbs() { + crumbModel.clear(); + crumbModel.models = []; + } - function addBreadcrumb(model, title) { - crumbModel.append({"text": title, "depth": crumbModel.count+1}) - crumbModel.models.push(model); - } + onReset: appViewContainer.reset() - function clearBreadcrumbs() { - crumbModel.clear(); - crumbModel.models = []; - } - } // applicationsView + onAddBreadcrumb: { + crumbModel.append({"text": title, "depth": crumbModel.count+1}) + crumbModel.models.push(model); + } states: [ State { name: "OutgoingLeft" PropertyChanges { - target: appViewScrollArea + target: applicationsView x: -parent.width opacity: 0.0 } }, State { name: "OutgoingRight" PropertyChanges { - target: appViewScrollArea + target: applicationsView x: parent.width opacity: 0.0 } } ] transitions: [ Transition { to: "OutgoingLeft" SequentialAnimation { // We need to cache the currentItem since the selection can move during animation, // and we want the item that has been clicked on, not the one that is under the // mouse once the animation is done - ScriptAction { script: appViewScrollArea.activatedItem = applicationsView.currentItem } + ScriptAction { script: applicationsView.activatedItem = applicationsView.currentItem } NumberAnimation { properties: "x,opacity"; easing.type: Easing.InQuad; duration: units.longDuration } - ScriptAction { script: appViewScrollArea.moveRight() } + ScriptAction { script: applicationsView.moveRight() } } }, Transition { to: "OutgoingRight" SequentialAnimation { NumberAnimation { properties: "x,opacity"; easing.type: Easing.InQuad; duration: units.longDuration } - ScriptAction { script: appViewScrollArea.moveLeft() } + ScriptAction { script: applicationsView.moveLeft() } } } ] - } // appViewScrollArea + } MouseArea { - anchors.fill: appViewScrollArea + anchors.fill: parent + acceptedButtons: Qt.BackButton + onClicked: { deactivateCurrentIndex() } } Timer { id: updatedLabelTimer interval: 1500 running: false repeat: true onRunningChanged: { if (running) { updatedLabel.opacity = 1; crumbContainer.opacity = 0.3; - appViewScrollArea.opacity = 0.3; + applicationsView.scrollArea.opacity = 0.3; } } onTriggered: { updatedLabel.opacity = 0; crumbContainer.opacity = 1; - appViewScrollArea.opacity = 1; + applicationsView.scrollArea.opacity = 1; running = false; } } PlasmaComponents.Label { id: updatedLabel text: i18n("Applications updated.") opacity: 0 visible: opacity != 0 anchors.centerIn: parent Behavior on opacity { NumberAnimation { duration: units.shortDuration } } } Component.onCompleted: { rootModel.cleared.connect(refreshed); } } // appViewContainer diff --git a/applets/kickoff/package/contents/ui/BaseView.qml b/applets/kickoff/package/contents/ui/BaseView.qml index cf2e84efe..a9a14b4f8 100644 --- a/applets/kickoff/package/contents/ui/BaseView.qml +++ b/applets/kickoff/package/contents/ui/BaseView.qml @@ -1,80 +1,67 @@ /* Copyright (C) 2011 Martin Gräßlin Copyright (C) 2012 Marco Martin - Copyright (C) 2015 Eike Hein + Copyright (C) 2015-2018 Eike Hein 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.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.draganddrop 2.0 Item { - property alias model: kickoffListView.model - property alias delegate: kickoffListView.delegate + property alias model: baseView.model + property alias delegate: baseView.delegate - property ListView listView: kickoffListView + property ListView listView: baseView.listView function decrementCurrentIndex() { - kickoffListView.decrementCurrentIndex(); + baseView.decrementCurrentIndex(); } function incrementCurrentIndex() { - kickoffListView.incrementCurrentIndex(); + baseView.incrementCurrentIndex(); } function activateCurrentIndex() { - kickoffListView.currentItem.activate(); + baseView.currentItem.activate(); } function openContextMenu() { - kickoffListView.currentItem.openActionMenu(); + baseView.currentItem.openActionMenu(); } - PlasmaExtras.ScrollArea { - anchors.fill: parent + Connections { + target: plasmoid - ListView { - id: kickoffListView + onExpandedChanged: { + if (!expanded) { + baseView.currentIndex = -1; + } + } + } - interactive: contentHeight > height - boundsBehavior: Flickable.StopAtBounds - currentIndex: -1 - keyNavigationWraps: true - highlight: KickoffHighlight {} - highlightMoveDuration : 0 - highlightResizeDuration: 0 + KickoffListView { + id: baseView - delegate: KickoffItem {} + anchors.fill: parent - section { - property: "group" - criteria: ViewSection.FullString - delegate: SectionDelegate {} - } - Connections { - target: plasmoid - onExpandedChanged: { - if (!expanded) { - kickoffListView.currentIndex = -1; - } - } - } - } + currentIndex: -1 + interactive: contentHeight > height } } diff --git a/applets/kickoff/package/contents/ui/Breadcrumb.qml b/applets/kickoff/package/contents/ui/Breadcrumb.qml index 24ab36478..c5ecf3a42 100644 --- a/applets/kickoff/package/contents/ui/Breadcrumb.qml +++ b/applets/kickoff/package/contents/ui/Breadcrumb.qml @@ -1,74 +1,74 @@ /* Copyright (C) 2011 Martin Gräßlin 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.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents Item { id: crumbRoot height: crumb.implicitHeight width: crumb.implicitWidth + arrowSvg.width property string text property bool root: false property int depth: model.depth function clickCrumb() { crumb.clicked(); } PlasmaComponents.ToolButton { id: crumb anchors.left: arrowSvg.right text: crumbRoot.text enabled: crumbRoot.depth < crumbModel.count onClicked: { // Remove all the breadcrumbs in front of the clicked one while (crumbModel.count > 0 && crumbRoot.depth < crumbModel.get(crumbModel.count-1).depth) { crumbModel.remove(crumbModel.count-1) crumbModel.models.pop() } if (crumbRoot.root) { applicationsView.newModel = rootModel; } else { applicationsView.newModel = crumbModel.models[index]; } - appViewScrollArea.state = "OutgoingRight"; + applicationsView.state = "OutgoingRight"; } } PlasmaCore.SvgItem { id: arrowSvg anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter height: crumbRoot.height / 2 width: visible ? height : 0 svg: PlasmaCore.Svg { imagePath: "icons/go" } elementId: LayoutMirroring.enabled ? "go-previous" : "go-next" visible: !crumbRoot.root } } // crumbRoot diff --git a/applets/kickoff/package/contents/ui/FavoritesView.qml b/applets/kickoff/package/contents/ui/FavoritesView.qml index c4c2ee7ca..df3174b0e 100644 --- a/applets/kickoff/package/contents/ui/FavoritesView.qml +++ b/applets/kickoff/package/contents/ui/FavoritesView.qml @@ -1,171 +1,154 @@ /* Copyright (C) 2011 Martin Gräßlin Copyright (C) 2012 Marco Martin Copyright 2014 Sebastian Kügler - Copyright (C) 2015 Eike Hein + Copyright (C) 2015-2018 Eike Hein Copyright (C) 2016 Jonathan Liu Copyright (C) 2016 Kai Uwe Broulik 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.0 import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.draganddrop 2.0 import org.kde.plasma.private.kicker 0.1 as Kicker Item { anchors.fill: parent objectName: "FavoritesView" - property ListView listView: kickoffListView + property ListView listView: favoritesView.listView function decrementCurrentIndex() { - kickoffListView.decrementCurrentIndex(); + favoritesView.decrementCurrentIndex(); } function incrementCurrentIndex() { - kickoffListView.incrementCurrentIndex(); + favoritesView.incrementCurrentIndex(); } function activateCurrentIndex() { - kickoffListView.currentItem.activate(); + favoritesView.currentItem.activate(); } function openContextMenu() { - kickoffListView.currentItem.openActionMenu(); + favoritesView.currentItem.openActionMenu(); } // QQuickItem::isAncestorOf is not invokable... function isChildOf(item, parent) { if (!item || !parent) { return false; } if (item.parent === parent) { return true; } return isChildOf(item, item.parent); } DropArea { property int startRow: -1 - anchors.fill: scrollArea + anchors.fill: parent enabled: plasmoid.immutability !== PlasmaCore.Types.SystemImmutable function syncTarget(event) { - if (kickoffListView.animating) { + if (favoritesView.animating) { return; } - var pos = mapToItem(kickoffListView.contentItem, event.x, event.y); - var above = kickoffListView.itemAt(pos.x, pos.y); + var pos = mapToItem(listView.contentItem, event.x, event.y); + var above = listView.itemAt(pos.x, pos.y); var source = kickoff.dragSource; - if (above && above !== source && isChildOf(source, kickoffListView)) { - kickoffListView.model.moveRow(source.itemIndex, above.itemIndex); + if (above && above !== source && isChildOf(source, favoritesView)) { + favoritesView.model.moveRow(source.itemIndex, above.itemIndex); // itemIndex changes directly after moving, // we can just set the currentIndex to it then. - kickoffListView.currentIndex = source.itemIndex; + favoritesView.currentIndex = source.itemIndex; } } onDragEnter: { syncTarget(event); - startRow = kickoffListView.currentIndex; + startRow = favoritesView.currentIndex; } - onDragMove: syncTarget(event); + onDragMove: syncTarget(event) } Transition { id: moveTransition SequentialAnimation { - PropertyAction { target: kickoffListView; property: "animating"; value: true } + PropertyAction { target: favoritesView; property: "animating"; value: true } NumberAnimation { - duration: kickoffListView.animationDuration + duration: favoritesView.animationDuration properties: "x, y" easing.type: Easing.OutQuad } - PropertyAction { target: kickoffListView; property: "animating"; value: false } + PropertyAction { target: favoritesView; property: "animating"; value: false } } } - PlasmaExtras.ScrollArea { - id: scrollArea - - anchors.fill: parent - - ListView { - id: kickoffListView - - property bool animating: false - property int animationDuration: resetAnimationDurationTimer.interval + Connections { + target: plasmoid + onExpandedChanged: { + if (!expanded) { + favoritesView.currentIndex = -1; + } + } + } - currentIndex: -1 - boundsBehavior: Flickable.StopAtBounds - keyNavigationWraps: true - interactive: contentHeight > height + KickoffListView { + id: favoritesView - delegate: KickoffItem {} - highlight: KickoffHighlight {} - highlightMoveDuration : 0 - highlightResizeDuration: 0 + anchors.fill: parent - model: globalFavorites + property bool animating: false + property int animationDuration: resetAnimationDurationTimer.interval - onCountChanged: { - animationDuration = 0; - resetAnimationDurationTimer.start(); - } + interactive: contentHeight > height - section { - property: "group" - criteria: ViewSection.FullString - } + move: moveTransition + moveDisplaced: moveTransition - move: moveTransition - moveDisplaced: moveTransition + model: globalFavorites - Connections { - target: plasmoid - onExpandedChanged: { - if (!expanded) { - kickoffListView.currentIndex = -1; - } - } - } + onCountChanged: { + animationDuration = 0; + resetAnimationDurationTimer.start(); } } Timer { id: resetAnimationDurationTimer interval: 150 - onTriggered: kickoffListView.animationDuration = interval - 20 + onTriggered: favoritesView.animationDuration = interval - 20 } } diff --git a/applets/kickoff/package/contents/ui/KickoffItem.qml b/applets/kickoff/package/contents/ui/KickoffItem.qml index f90000736..3330f85c7 100644 --- a/applets/kickoff/package/contents/ui/KickoffItem.qml +++ b/applets/kickoff/package/contents/ui/KickoffItem.qml @@ -1,249 +1,180 @@ /* Copyright (C) 2011 Martin Gräßlin Copyright (C) 2012 Gregor Taetzner Copyright 2014 Sebastian Kügler - Copyright (C) 2015 Eike Hein + Copyright (C) 2015-2018 Eike Hein 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.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.draganddrop 2.0 import "code/tools.js" as Tools Item { id: listItem width: ListView.view.width height: (units.smallSpacing * 2) + Math.max(elementIcon.height, titleElement.height + subTitleElement.height) + signal reset signal actionTriggered(string actionId, variant actionArgument) signal aboutToShowActionMenu(variant actionMenu) + signal addBreadcrumb(var model, string title) readonly property int itemIndex: model.index + readonly property string url: model.url || "" + readonly property var decoration: model.decoration || "" property bool dropEnabled: false property bool appView: false property bool modelChildren: model.hasChildren || false property bool isCurrent: listItem.ListView.view.currentIndex === index; - property string url: model.url || "" property bool showAppsByName: plasmoid.configuration.showAppsByName property bool hasActionList: ((model.favoriteId != null) || (("hasActionList" in model) && (model.hasActionList == true))) property Item menu: actionMenu onAboutToShowActionMenu: { var actionList = hasActionList ? model.actionList : []; Tools.fillActionMenu(i18n, actionMenu, actionList, ListView.view.model.favoritesModel, model.favoriteId); } onActionTriggered: { if (Tools.triggerAction(ListView.view.model, model.index, actionId, actionArgument) === true) { plasmoid.expanded = false; } if (actionId.indexOf("_kicker_favorite_") === 0) { switchToInitial(); } } function activate() { var view = listItem.ListView.view; if (model.hasChildren) { var childModel = view.model.modelForRow(index); - view.addBreadcrumb(childModel, display); + listItem.addBreadcrumb(childModel, display); view.model = childModel; } else { view.model.trigger(index, "", null); plasmoid.expanded = false; - - if (view.reset) { - view.reset(); - } + listItem.reset(); } } - function openActionMenu(visualParent, x, y) { + function openActionMenu(x, y) { aboutToShowActionMenu(actionMenu); - actionMenu.visualParent = visualParent != undefined ? visualParent : mouseArea; + actionMenu.visualParent = listItem; actionMenu.open(x, y); } ActionMenu { id: actionMenu onActionClicked: { actionTriggered(actionId, actionArgument); } } - MouseArea { - id: mouseArea + PlasmaCore.IconItem { + id: elementIcon + anchors { left: parent.left - right: parent.right - top: parent.top - bottom: parent.bottom - } - - property bool pressed: false - property int pressX: -1 - property int pressY: -1 - - hoverEnabled: true - acceptedButtons: Qt.LeftButton | Qt.RightButton - - onEntered: { - listItem.ListView.view.currentIndex = index; + leftMargin: (units.gridUnit * 4) - units.iconSizes.medium + verticalCenter: parent.verticalCenter } + width: units.iconSizes.medium + height: width - onExited: { - listItem.ListView.view.currentIndex = -1; - } + animated: false + usesPlasmaTheme: false - onPressed: { - if (mouse.buttons & Qt.RightButton) { - if (hasActionList) { - openActionMenu(mouseArea, mouse.x, mouse.y); - } - } else { - pressed = true; - pressX = mouse.x; - pressY = mouse.y; - } - } - - onReleased: { - if (pressed) { - if (appView) { - appViewScrollArea.state = "OutgoingLeft"; - } else { - listItem.activate(); - } - - listItem.ListView.view.currentIndex = -1; - } - - pressed = false; - pressX = -1; - pressY = -1; - } - - onPositionChanged: { - if (pressX != -1 && model.url && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) { - kickoff.dragSource = listItem; - dragHelper.startDrag(root, model.url, model.decoration); - pressed = false; - pressX = -1; - pressY = -1; - } - } + source: model.decoration + } - onContainsMouseChanged: { - if (!containsMouse) { - pressed = false; - pressX = -1; - pressY = -1; - } - } + PlasmaComponents.Label { + id: titleElement - PlasmaCore.IconItem { - id: elementIcon + y: Math.round((parent.height - titleElement.height - ( (subTitleElement.text != "") ? subTitleElement.paintedHeight : 0) ) / 2) + anchors { + //bottom: elementIcon.verticalCenter + left: elementIcon.right + right: arrow.left + leftMargin: units.gridUnit + rightMargin: units.gridUnit * 2 + } + height: paintedHeight + // TODO: games should always show the by name! + text: model.display + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + } - anchors { - left: parent.left - leftMargin: (units.gridUnit * 4) - units.iconSizes.medium - verticalCenter: parent.verticalCenter - } - width: units.iconSizes.medium - height: width + PlasmaComponents.Label { + id: subTitleElement - animated: false - usesPlasmaTheme: false + anchors { + left: titleElement.left + right: arrow.left + rightMargin: units.gridUnit * 2 + top: titleElement.bottom + } + height: paintedHeight + + text: model.description + opacity: isCurrent ? 0.8 : 0.6 + font.pointSize: theme.smallestFont.pointSize + elide: Text.ElideMiddle + horizontalAlignment: Text.AlignLeft + } - source: model.decoration - } - PlasmaComponents.Label { - id: titleElement - - y: Math.round((parent.height - titleElement.height - ( (subTitleElement.text != "") ? subTitleElement.paintedHeight : 0) ) / 2) - anchors { - //bottom: elementIcon.verticalCenter - left: elementIcon.right - right: arrow.left - leftMargin: units.gridUnit - rightMargin: units.gridUnit * 2 - } - height: paintedHeight - // TODO: games should always show the by name! - text: model.display - elide: Text.ElideRight - horizontalAlignment: Text.AlignLeft - } - PlasmaComponents.Label { - id: subTitleElement - - anchors { - left: titleElement.left - right: arrow.left - rightMargin: units.gridUnit * 2 - top: titleElement.bottom - } - height: paintedHeight + PlasmaCore.SvgItem { + id: arrow - text: model.description - opacity: isCurrent ? 0.8 : 0.6 - font.pointSize: theme.smallestFont.pointSize - elide: Text.ElideMiddle - horizontalAlignment: Text.AlignLeft + anchors { + right: parent.right + rightMargin: units.gridUnit * 2 + verticalCenter: parent.verticalCenter } - PlasmaCore.SvgItem { - id: arrow + width: visible ? units.iconSizes.small : 0 + height: width - anchors { - right: parent.right - rightMargin: units.gridUnit * 2 - verticalCenter: parent.verticalCenter - } + visible: (model.hasChildren == true) + opacity: (listItem.ListView.view.currentIndex == index) ? 1.0 : 0.4 - width: visible ? units.iconSizes.small : 0 - height: width - - visible: (model.hasChildren == true) - opacity: (listItem.ListView.view.currentIndex == index) ? 1.0 : 0.4 - - svg: arrowsSvg - elementId: (Qt.application.layoutDirection == Qt.RightToLeft) ? "left-arrow" : "right-arrow" - } - } // listItemDelegate + svg: arrowsSvg + elementId: (Qt.application.layoutDirection == Qt.RightToLeft) ? "left-arrow" : "right-arrow" + } Keys.onPressed: { if (event.key == Qt.Key_Menu && hasActionList) { event.accepted = true; - openActionMenu(mouseArea); + openActionMenu(); } else if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return) && !modelChildren) { if (!modelChildren) { event.accepted = true; listItem.activate(); } } } } // listItem diff --git a/applets/kickoff/package/contents/ui/KickoffListView.qml b/applets/kickoff/package/contents/ui/KickoffListView.qml new file mode 100644 index 000000000..14ae9d71c --- /dev/null +++ b/applets/kickoff/package/contents/ui/KickoffListView.qml @@ -0,0 +1,170 @@ +/* + Copyright (C) 2011 Martin Gräßlin + Copyright (C) 2012 Gregor Taetzner + Copyright (C) 2015-2018 Eike Hein + + 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.0 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.plasma.components 2.0 as PlasmaComponents + + +FocusScope { + id: view + + signal reset + signal addBreadcrumb(var model, string title) + + readonly property Item listView: listView + readonly property Item scrollArea: scrollArea + + property bool showAppsByName: true + property bool appView: false + + property alias model: listView.model + property alias delegate: listView.delegate + property alias currentIndex: listView.currentIndex + property alias currentItem: listView.currentItem + property alias count: listView.count + property alias interactive: listView.interactive + property alias contentHeight: listView.contentHeight + + property alias move: listView.move + property alias moveDisplaced: listView.moveDisplaced + + function incrementCurrentIndex() { + listView.incrementCurrentIndex(); + } + + function decrementCurrentIndex() { + listView.decrementCurrentIndex(); + } + + PlasmaExtras.ScrollArea { + id: scrollArea + + anchors.fill: parent + + ListView { + id: listView + + focus: true + + keyNavigationWraps: true + boundsBehavior: Flickable.StopAtBounds + + highlight: KickoffHighlight {} + highlightMoveDuration : 0 + highlightResizeDuration: 0 + + delegate: KickoffItem { + id: delegateItem + + appView: view.appView + showAppsByName: view.showAppsByName + + onReset: view.reset() + onAddBreadcrumb: view.addBreadcrumb(model, title) + } + + section { + property: "group" + criteria: ViewSection.FullString + delegate: SectionDelegate {} + } + } + } + + MouseArea { + anchors.fill: parent + + id: mouseArea + + property Item pressed: null + property int pressX: -1 + property int pressY: -1 + + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onPressed: { + var mapped = listView.mapToItem(listView.contentItem, mouse.x, mouse.y); + var item = listView.itemAt(mapped.x, mapped.y); + + if (!item) { + return; + } + + if (mouse.buttons & Qt.RightButton) { + if (item.hasActionList) { + mapped = listView.contentItem.mapToItem(item, mapped.x, mapped.y); + openActionMenu(mapped.x, mapped.y); + } + } else { + pressed = item; + pressX = mouse.x; + pressY = mouse.y; + } + } + + onReleased: { + var mapped = listView.mapToItem(listView.contentItem, mouse.x, mouse.y); + var item = listView.itemAt(mapped.x, mapped.y); + + if (item && pressed === item) { + if (item.appView) { + view.state = "OutgoingLeft"; + } else { + item.activate(); + } + + listView.currentIndex = -1; + } + + pressed = null; + pressX = -1; + pressY = -1; + } + + onPositionChanged: { + var mapped = listView.mapToItem(listView.contentItem, mouse.x, mouse.y); + var item = listView.itemAt(mapped.x, mapped.y); + + if (item) { + listView.currentIndex = item.itemIndex; + } else { + listView.currentIndex = -1; + } + + if (pressed && pressX != -1 && pressed.url && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) { + kickoff.dragSource = item; + dragHelper.startDrag(root, pressed.url, pressed.decoration); + pressed = null; + pressX = -1; + pressY = -1; + } + } + + onContainsMouseChanged: { + if (!containsMouse) { + pressed = null; + pressX = -1; + pressY = -1; + } + } + } +} diff --git a/applets/kickoff/package/contents/ui/SearchView.qml b/applets/kickoff/package/contents/ui/SearchView.qml index cd739f98c..ded88bbac 100644 --- a/applets/kickoff/package/contents/ui/SearchView.qml +++ b/applets/kickoff/package/contents/ui/SearchView.qml @@ -1,109 +1,99 @@ /* Copyright (C) 2011 Martin Gräßlin Copyright (C) 2012 Gregor Taetzner - Copyright (C) 2015 Eike Hein + Copyright (C) 2015-2018 Eike Hein 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.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.private.kicker 0.1 as Kicker Item { id: searchViewContainer anchors.fill: parent objectName: "SearchView" function decrementCurrentIndex() { searchView.decrementCurrentIndex(); } function incrementCurrentIndex() { searchView.incrementCurrentIndex(); } function activateCurrentIndex() { searchView.currentItem.activate(); } function openContextMenu() { searchView.currentItem.openActionMenu(); } Kicker.RunnerModel { id: runnerModel appletInterface: plasmoid runners: { var runners = ["services", "places", "desktopsessions", "PowerDevil"]; if (plasmoid.configuration.useExtraRunners) { runners = runners.concat(plasmoid.configuration.runners); } return runners; } mergeResults: true favoritesModel: globalFavorites } - PlasmaExtras.ScrollArea { - anchors.fill: parent + Connections { + target: header - ListView { - id: searchView + onQueryChanged: { + runnerModel.query = header.query; + searchView.currentIndex = 0; - anchors.fill: parent - keyNavigationWraps: true - boundsBehavior: Flickable.StopAtBounds - delegate: KickoffItem { - showAppsByName: false //krunner results have the most relevant field in the "display" column, which is showAppsByName = false + if (!header.query) { + searchView.model = null; } - highlight: KickoffHighlight {} - highlightMoveDuration : 0 - highlightResizeDuration: 0 - - Connections { - target: header + } + } - onQueryChanged: { - runnerModel.query = header.query; + Connections { + target: runnerModel - if (!header.query) { - searchView.model = null; - } - } + onCountChanged: { + if (runnerModel.count && !searchView.model) { + searchView.model = runnerModel.modelForRow(0); } + } + } - Connections { - target: runnerModel + KickoffListView { + id: searchView - onCountChanged: { - if (runnerModel.count && !searchView.model) { - searchView.model = runnerModel.modelForRow(0); - searchView.currentIndex = 0; - } - } - } - } // searchView - } // ScrollArea + anchors.fill: parent + + showAppsByName: false //krunner results have the most relevant field in the "display" column, which is showAppsByName = false + } }