diff --git a/applets/kickoff/package/contents/ui/ApplicationsView.qml b/applets/kickoff/package/contents/ui/ApplicationsView.qml index b9d71fa4d..2530fd163 100644 --- a/applets/kickoff/package/contents/ui/ApplicationsView.qml +++ b/applets/kickoff/package/contents/ui/ApplicationsView.qml @@ -1,283 +1,282 @@ /* Copyright (C) 2011 Martin Gräßlin Copyright (C) 2012 Gregor Taetzner Copyright 2014 Sebastian Kügler 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.listView function decrementCurrentIndex() { applicationsView.decrementCurrentIndex(); } function incrementCurrentIndex() { applicationsView.incrementCurrentIndex(); } function activateCurrentIndex(start) { if (!applicationsView.currentItem.modelChildren) { if (!start) { return; } } 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(); applicationsView.state = "OutgoingRight"; return true; } return false; } function reset() { applicationsView.model = rootModel; - 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 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 } } focus: true appView: true model: rootModel function moveLeft() { state = ""; // newModelIndex set by clicked breadcrumb var oldModel = applicationsView.model; applicationsView.model = applicationsView.newModel; listView.positionViewAtIndex(model.rowForModel(oldModel), ListView.Center) } function moveRight() { state = ""; activatedItem.activate() applicationsView.listView.positionViewAtBeginning() } function clearBreadcrumbs() { crumbModel.clear(); crumbModel.models = []; } onReset: appViewContainer.reset() onAddBreadcrumb: { crumbModel.append({"text": title, "depth": crumbModel.count+1}) crumbModel.models.push(model); } states: [ State { name: "OutgoingLeft" PropertyChanges { target: applicationsView x: -parent.width opacity: 0.0 } }, State { name: "OutgoingRight" PropertyChanges { 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: applicationsView.activatedItem = applicationsView.currentItem } NumberAnimation { properties: "x,opacity"; easing.type: Easing.InQuad; duration: units.longDuration } ScriptAction { script: applicationsView.moveRight() } } }, Transition { to: "OutgoingRight" SequentialAnimation { NumberAnimation { properties: "x,opacity"; easing.type: Easing.InQuad; duration: units.longDuration } ScriptAction { script: applicationsView.moveLeft() } } } ] } MouseArea { 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; applicationsView.scrollArea.opacity = 0.3; } } onTriggered: { updatedLabel.opacity = 0; crumbContainer.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/KickoffListView.qml b/applets/kickoff/package/contents/ui/KickoffListView.qml index 2f3e7df5f..b3343dde0 100644 --- a/applets/kickoff/package/contents/ui/KickoffListView.qml +++ b/applets/kickoff/package/contents/ui/KickoffListView.qml @@ -1,174 +1,183 @@ /* 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(); } - + Connections { + target: plasmoid + + onExpandedChanged: { + if (!expanded) { + listView.positionViewAtBeginning(); + } + } + } + PlasmaExtras.ScrollArea { id: scrollArea frameVisible: false 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.left: parent.left width: scrollArea.viewport.width height: parent.height 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); listView.currentItem.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; } } } }