diff --git a/containments/homescreen2/package/contents/ui/launcher/Delegate.qml b/containments/homescreen2/package/contents/ui/launcher/Delegate.qml index 67d458e..385d02f 100644 --- a/containments/homescreen2/package/contents/ui/launcher/Delegate.qml +++ b/containments/homescreen2/package/contents/ui/launcher/Delegate.qml @@ -1,153 +1,154 @@ /* * Copyright 2019 Marco Martin * * 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 2.010-1301, USA. */ import QtQuick 2.4 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.3 as Controls import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.kquickcontrolsaddons 2.0 import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager ContainmentLayoutManager.ItemContainer { id: delegate z: dragging ? 1 : 0 property var modelData: typeof model !== "undefined" ? model : null property bool dragging property ContainmentLayoutManager.ItemContainer dragDelegate leftPadding: units.smallSpacing * 2 topPadding: units.smallSpacing * 2 rightPadding: units.smallSpacing * 2 bottomPadding: units.smallSpacing * 2 opacity: dragging ? 0.4 : 1 - editModeCondition: model.ApplicationOnDesktopRole ? ContainmentLayoutManager.ItemContainer.AfterPressAndHold: ContainmentLayoutManager.ItemContainer.Manual + editModeCondition: ContainmentLayoutManager.ItemContainer.AfterPressAndHold//model.ApplicationOnDesktopRole ? ContainmentLayoutManager.ItemContainer.AfterPressAndHold: ContainmentLayoutManager.ItemContainer.Manual + onEditModeChanged: {//FIXME: remove + plasmoid.editMode = editMode + } + onDragActiveChanged: { + if (dragActive) { + return; + } + + plasmoid.editMode = false; + editMode = false; + launcher.forceLayout(); + favoriteStrip.forceLayout(); + } onDraggingChanged: { if (dragging) { var pos = dragDelegate.parent.mapFromItem(delegate, 0, 0); dragDelegate.parent = delegate.parent.parent; dragDelegate.x = delegate.x dragDelegate.y = delegate.y dragDelegate.modelData = model; root.reorderingApps = true; } else { dragDelegate.modelData = null; root.reorderingApps = false; } } - contentItem: MouseArea { - drag.target: dragging ? dragDelegate : null + onUserDrag: { + // newPosition + var newRow = 0; + + // Put it in the favorites strip + if (favoriteStrip.contains(favoriteStrip.mapFromItem(delegate, dragCenter.x, dragCenter.y))) { + var pos = favoriteStrip.mapFromItem(delegate, 0, 0); + newRow = Math.floor((pos.x + dragCenter.x) / delegate.width); + + // Put it on desktop + } else if (appletsLayout.contains(appletsLayout.mapFromItem(delegate, dragCenter.x, dragCenter.y))) { + var pos = appletsLayout.mapFromItem(delegate, 0, 0); + plasmoid.nativeInterface.applicationListModel.setDesktopItem(index, true); + delegate.x = pos.x + delegate.y = pos.y + return; + + // Put it in the general view + } else { + newRow = Math.round(applicationsFlow.width / delegate.width) * Math.floor((delegate.y + dragCenter.y) / delegate.height) + Math.floor((delegate.x + dragCenter.x) / delegate.width) + favoriteStrip.count; + } + plasmoid.nativeInterface.applicationListModel.setDesktopItem(index, false); + + plasmoid.nativeInterface.applicationListModel.moveItem(modelData.index, newRow); + + //delegate.x = newPosition.x; + } + + contentItem: MouseArea { onClicked: { if (modelData.ApplicationStartupNotifyRole) { clickFedbackAnimation.target = delegate; clickFedbackAnimation.running = true; feedbackWindow.title = modelData.ApplicationNameRole; feedbackWindow.state = "open"; } plasmoid.nativeInterface.applicationListModel.runApplication(modelData.ApplicationStorageIdRole); } - - onPressAndHold: { - if (model.ApplicationOnDesktopRole) { - mouse.accepted = false - return - } - delegate.dragging = true; - } - - onReleased: { - delegate.dragging = false; - - } - - onCanceled: delegate.dragging = false; - - onPositionChanged: { - if (!dragging || !dragDelegate) { - return; - } - - var newRow = 0; - - // Put it in the favorites strip - if (favoriteStrip.contains(favoriteStrip.mapFromItem(dragDelegate, dragDelegate.width/2, dragDelegate.height/2))) { - newRow = Math.floor((dragDelegate.x + dragDelegate.width/2) / dragDelegate.width); - // Put it on desktop - } else if (appletsLayout.contains(appletsLayout.mapFromItem(dragDelegate, dragDelegate.width/2, dragDelegate.height/2))) { - plasmoid.nativeInterface.applicationListModel.setDesktopItem(index, true); - return; - // Put it in the general view - } else { - newRow = Math.round(applicationsFlow.width / dragDelegate.width) * Math.floor((dragDelegate.y + dragDelegate.height/2) / dragDelegate.height) + Math.floor((dragDelegate.x + dragDelegate.width/2) / dragDelegate.width) + favoriteStrip.count; - } - - plasmoid.nativeInterface.applicationListModel.setDesktopItem(index, false); - - plasmoid.nativeInterface.applicationListModel.moveItem(modelData.index, newRow); - } ColumnLayout { anchors.fill: parent spacing: 0 PlasmaCore.IconItem { id: icon Layout.alignment: Qt.AlignHCenter | Qt.AlignTop Layout.fillWidth: true Layout.preferredHeight: parent.height - root.reservedSpaceForLabel source: modelData ? modelData.ApplicationIconRole : "" scale: root.reorderingApps && dragDelegate && !dragging ? 0.6 : 1 Behavior on scale { NumberAnimation { duration: units.longDuration easing.type: Easing.InOutQuad } } } PlasmaComponents.Label { id: label visible: text.length > 0 Layout.fillWidth: true Layout.fillHeight: true wrapMode: Text.WordWrap horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignTop maximumLineCount: 2 elide: Text.ElideRight text: modelData ? modelData.ApplicationNameRole : "" font.pixelSize: theme.defaultFont.pixelSize color: PlasmaCore.ColorScope.textColor } } } } diff --git a/containments/homescreen2/package/contents/ui/launcher/LauncherGrid.qml b/containments/homescreen2/package/contents/ui/launcher/LauncherGrid.qml index 727af73..9d6c8f6 100644 --- a/containments/homescreen2/package/contents/ui/launcher/LauncherGrid.qml +++ b/containments/homescreen2/package/contents/ui/launcher/LauncherGrid.qml @@ -1,128 +1,131 @@ /* * Copyright 2019 Marco Martin * * 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 2.010-1301, USA. */ import QtQuick 2.4 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.3 as Controls import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.kquickcontrolsaddons 2.0 import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager Controls.Control { id: root + function forceLayout() { + applicationsFlow.forceLayout(); + } readonly property bool dragging: applicationsFlow.dragData property bool reorderingApps: false property int availableCellHeight: units.iconSizes.huge + reservedSpaceForLabel readonly property int reservedSpaceForLabel: metrics.height readonly property int cellWidth: applicationsFlow.width / Math.floor(applicationsFlow.width / ((availableCellHeight - reservedSpaceForLabel) + units.smallSpacing*4)) readonly property int cellHeight: availableCellHeight - topPadding property ContainmentLayoutManager.AppletsLayout appletsLayout property FavoriteStrip favoriteStrip signal externalDragStarted signal dragPositionChanged(point pos) implicitHeight: applicationsFlow.implicitHeight + frame.margins.top + frame.margins.bottom leftPadding: frame.margins.left topPadding: frame.margins.top rightPadding: frame.margins.right bottomPadding: frame.margins.bottom background: PlasmaCore.FrameSvgItem { id: frame imagePath: "widgets/background" anchors.fill: parent } contentItem: Item { //NOTE: TextMetrics can't handle multi line Controls.Label { id: metrics text: "M\nM" visible: false } //This Delegate is the placeholder for the "drag" //delegate (that is not actual drag and drop Delegate { id: dragDelegateItem z: 999 width: root.cellWidth height: root.cellHeight onYChanged: dragPositionChanged(Qt.point(x, y)) opacity: 1 visible: modelData !== null } Flow { id: applicationsFlow anchors.fill: parent spacing: 0 property var dragData property int startContentYDrag property bool viewHasBeenDragged NumberAnimation { id: scrollAnim target: applicationsFlow properties: "contentY" duration: units.longDuration easing.type: Easing.InOutQuad } move: Transition { NumberAnimation { duration: units.longDuration easing.type: Easing.InOutQuad properties: "x,y" } } Repeater { model: plasmoid.nativeInterface.applicationListModel delegate: Delegate { width: root.cellWidth height: root.cellHeight dragDelegate: dragDelegateItem parent: { if (model.ApplicationOnDesktopRole) { return appletsLayout; } if (index < favoriteStrip.count) { return favoriteStrip.contentItem; } return applicationsFlow; } } } } } } diff --git a/containments/homescreen2/package/contents/ui/main.qml b/containments/homescreen2/package/contents/ui/main.qml index 5ccdbd7..10bb864 100644 --- a/containments/homescreen2/package/contents/ui/main.qml +++ b/containments/homescreen2/package/contents/ui/main.qml @@ -1,172 +1,172 @@ /* * Copyright 2019 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 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 Library General Public License for more details * * You should have received a copy of the GNU Library 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.12 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.2 as Controls import QtGraphicalEffects 1.0 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.draganddrop 2.0 as DragDrop import "launcher" as Launcher import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager Item { id: root width: 640 height: 480 property Item toolBox Text { text:"Edit Mode" color: "white" visible: plasmoid.editMode } Connections { target: plasmoid onEditModeChanged: { appletsLayout.editMode = plasmoid.editMode } } Flickable { id: mainFlickable anchors { fill: parent // bottomMargin: favoriteStrip.height } bottomMargin: favoriteStrip.height contentWidth: width contentHeight: flickableContents.height - interactive: !plasmoid.editMode + interactive: !plasmoid.editMode && !launcher.dragging ColumnLayout { id: flickableContents width: parent.width DragDrop.DropArea { Layout.fillWidth: true Layout.preferredHeight: mainFlickable.height //TODO: multiple widgets pages onDragEnter: { event.accept(event.proposedAction); } onDragMove: { appletsLayout.showPlaceHolderAt( Qt.rect(event.x - appletsLayout.defaultItemWidth / 2, event.y - appletsLayout.defaultItemHeight / 2, appletsLayout.defaultItemWidth, appletsLayout.defaultItemHeight) ); } onDragLeave: { appletsLayout.hidePlaceHolder(); } preventStealing: true onDrop: { plasmoid.processMimeData(event.mimeData, event.x - appletsLayout.placeHolder.width / 2, event.y - appletsLayout.placeHolder.height / 2); event.accept(event.proposedAction); appletsLayout.hidePlaceHolder(); } PlasmaCore.Svg { id: arrowsSvg imagePath: "widgets/arrows" colorGroup: PlasmaCore.Theme.ComplementaryColorGroup } PlasmaCore.SvgItem { anchors { horizontalCenter: parent.horizontalCenter bottom: parent.bottom bottomMargin: favoriteStrip.height } z: 2 svg: arrowsSvg elementId: "up-arrow" width: units.iconSizes.large height: width } ContainmentLayoutManager.AppletsLayout { id: appletsLayout anchors.fill: parent configKey: width > height ? "ItemGeometriesHorizontal" : "ItemGeometriesVertical" containment: plasmoid editModeCondition: plasmoid.immutable ? ContainmentLayoutManager.AppletsLayout.Manual : ContainmentLayoutManager.AppletsLayout.AfterPressAndHold // Sets the containment in edit mode when we go in edit mode as well onEditModeChanged: plasmoid.editMode = editMode minimumItemWidth: units.gridUnit * 3 minimumItemHeight: minimumItemWidth defaultItemWidth: units.gridUnit * 6 defaultItemHeight: defaultItemWidth cellWidth: units.iconSizes.small cellHeight: cellWidth acceptsAppletCallback: function(applet, x, y) { print("Applet: "+applet+" "+x+" "+y) return true; } appletContainerComponent: ContainmentLayoutManager.BasicAppletContainer { id: appletContainer configOverlayComponent: ConfigOverlay {} onEditModeChanged: { if (editMode) { plasmoid.editMode = true; } } } placeHolder: ContainmentLayoutManager.PlaceHolder {} } } Launcher.LauncherGrid { id: launcher Layout.fillWidth: true favoriteStrip: favoriteStrip appletsLayout: appletsLayout } } } Launcher.FavoriteStrip { id: favoriteStrip anchors.horizontalCenter: parent.horizontalCenter width: Math.min(root.width, units.gridUnit * 30) launcherGrid: launcher y: Math.max(0, root.height - height - mainFlickable.contentY) } }