diff --git a/plasmoid/package/contents/ui/ContextMenu.qml b/plasmoid/package/contents/ui/ContextMenu.qml index e44803c3a..31a7d56cc 100644 --- a/plasmoid/package/contents/ui/ContextMenu.qml +++ b/plasmoid/package/contents/ui/ContextMenu.qml @@ -653,7 +653,7 @@ PlasmaComponents.ContextMenu { text: i18n("&Pin") - visible: visualParent + visible: visualParent && !visualParent.isSeparator // && get(atm.IsLauncher) !== true && get(atm.IsStartup) !== true && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable @@ -743,7 +743,8 @@ PlasmaComponents.ContextMenu { } PlasmaComponents.MenuItem { - visible: (visualParent && get(atm.IsLauncher) === true) && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable + visible: (visualParent && !visualParent.isSeparator && get(atm.IsLauncher) === true) + && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable text: i18nc("Remove launcher button for application shown while it is not running", "Unpin") @@ -773,20 +774,28 @@ PlasmaComponents.ContextMenu { text: i18n("Add Internal Separator") onClicked: { - root.addSeparator(); + root.addSeparator(visualParent.itemIndex); } } PlasmaComponents.MenuItem { id: removeInternalSeparatorItem - visible: root.editMode + visible: root.editMode && visualParent.isSeparator icon: "remove" - text: i18n("Remove Last Internal Separator") + text: i18n("Remove Internal Separator") enabled: parabolicManager.hasInternalSeparator onClicked: { - root.removeLastSeparator(); + //root.removeLastSeparator(); + var launcher = get(atm.LauncherUrlWithoutIcon); + + if (latteDock && latteDock.launchersGroup >= Latte.Dock.LayoutLaunchers) { + latteDock.universalLayoutManager.launchersSignals.removeLauncher(latteDock.launchersGroup, launcher); + } else { + root.launcherForRemoval = launcher; + tasksModel.requestRemoveLauncher(launcher); + } } } @@ -853,7 +862,7 @@ PlasmaComponents.ContextMenu { PlasmaComponents.MenuItem { id: alternativesMenuItem - visible: root.editMode + visible: root.editMode && !visualParent.isSeparator text: plasmoid.action("alternatives").text icon: plasmoid.action("alternatives").icon diff --git a/plasmoid/package/contents/ui/ParabolicManager.qml b/plasmoid/package/contents/ui/ParabolicManager.qml index cf1c6d15b..142f799de 100644 --- a/plasmoid/package/contents/ui/ParabolicManager.qml +++ b/plasmoid/package/contents/ui/ParabolicManager.qml @@ -20,6 +20,10 @@ import QtQuick 2.0 +import org.kde.plasma.plasmoid 2.0 + +import org.kde.latte 0.1 as Latte + // holds all the logic around parabolic effect signals into one place. // ParabolicManager is responsible for triggering all the messages to tasks // that are neighbour to the hovered task. This will help a lot to catch cases @@ -42,6 +46,10 @@ Item { //(launcherUrl, index) property variant separators: [] + //new launchers in order to be moved in correct place + //(launcher, pos) + property variant launchersToBeMoved: [] + Connections{ target: root onTasksCountChanged:parManager.updateTasksEdgesIndexes(); @@ -461,4 +469,93 @@ Item { return ""; } + //! launchersToBeMoved, new launchers to have been added and must be repositioned + function addLauncherToBeMoved(launcherUrl, toPos) { + if (!hasLauncherToBeMoved(launcherUrl)) { + launchersToBeMoved.push({launcher: launcherUrl, pos: Math.max(0,toPos)}); + //console.log("-add launcher-"); + //printLaunchersToBeMoved() + } + } + + function printLaunchersToBeMoved(){ + for (var j=0; j<launchersToBeMoved.length; ++j){ + console.log(launchersToBeMoved[j].launcher+ " - "+launchersToBeMoved[j].pos); + } + } + + function moveLauncherToCorrectPos(launcherUrl, from) { + if (hasLauncherToBeMoved(launcherUrl)) { + launchersToBeMovedTimer.from = from; + launchersToBeMovedTimer.to = posOfLauncherToBeMoved(launcherUrl); + launchersToBeMovedTimer.launcherUrl = launcherUrl + + removeLauncherToBeMoved(launcherUrl); + launchersToBeMovedTimer.start(); + } + } + + function removeLauncherToBeMoved(launcherUrl) { + if (hasLauncherToBeMoved(launcherUrl)) { + var sLength = launchersToBeMoved.length; + var index = -1; + + for (var i=0; i<sLength; ++i) { + //!safety checker + if (i>=launchersToBeMoved.length) + return -1; + + if (launchersToBeMoved[i].launcher === launcherUrl) { + index = i; + break; + } + } + + if (index > -1) { + // console.log("removing launcher to be moved:: "+launcherUrl); + launchersToBeMoved.splice(index, 1); + } + } + } + + function posOfLauncherToBeMoved(launcherUrl) { + var sLength = launchersToBeMoved.length; + + for (var i=0; i<sLength; ++i) { + //!safety checker + if (i>=launchersToBeMoved.length) + return -1; + + if (launchersToBeMoved[i].launcher === launcherUrl) + return launchersToBeMoved[i].pos; + } + + return -1; + } + + function hasLauncherToBeMoved(launcher) { + return (posOfLauncherToBeMoved(launcher) >= 0); + } + + //!Trying to avoid a binding loop in TaskDelegate for modelLauncherUrl and + //!proper updating in separators indexes + Timer { + id: launchersToBeMovedTimer + interval: 50 + property int from: -1 + property int to: -1 + + property string launcherUrl: "" + + onTriggered: { + //console.log("to be moved: "+launcherUrl + " - " + from +" -> "+to) + + tasksModel.move(from, to); + if (latteDock && latteDock.launchersGroup >= Latte.Dock.LayoutLaunchers) { + latteDock.universalLayoutManager.launchersSignals.moveTask(plasmoid.id, latteDock.launchersGroup, from, to); + } + + tasksModel.syncLaunchers(); + } + } } diff --git a/plasmoid/package/contents/ui/main.qml b/plasmoid/package/contents/ui/main.qml index e3a0ccc07..44d4caa69 100644 --- a/plasmoid/package/contents/ui/main.qml +++ b/plasmoid/package/contents/ui/main.qml @@ -1433,18 +1433,31 @@ Item { //! it is used to add the fake desktop file which represents //! the separator (fake launcher) - function addSeparator(){ + function addSeparator(pos){ var separatorName = parabolicManager.freeAvailableSeparatorName(); - if (separatorName !== "") - tasksModel.requestAddLauncher(separatorName); + if (separatorName !== "") { + parabolicManager.addLauncherToBeMoved(separatorName, Math.max(0,pos)); + + if (latteDock && latteDock.launchersGroup >= Latte.Dock.LayoutLaunchers) { + latteDock.universalLayoutManager.launchersSignals.addLauncher(latteDock.launchersGroup, separatorName); + } else { + tasksModel.requestAddLauncher(separatorName); + } + } } function removeLastSeparator(){ var separatorName = parabolicManager.lastPresentSeparatorName(); - if (separatorName !== "") - tasksModel.requestRemoveLauncher(separatorName); + if (separatorName !== "") { + if (latteDock && latteDock.launchersGroup >= Latte.Dock.LayoutLaunchers) { + latteDock.universalLayoutManager.launchersSignals.removeLauncher(latteDock.launchersGroup, separatorName); + } else { + root.launcherForRemoval = separatorName; + tasksModel.requestRemoveLauncher(separatorName); + } + } } function setShowTasksNumbers(showNumbers){ diff --git a/plasmoid/package/contents/ui/task/TaskDelegate.qml b/plasmoid/package/contents/ui/task/TaskDelegate.qml index ea74bc1c3..15f68dc0e 100644 --- a/plasmoid/package/contents/ui/task/TaskDelegate.qml +++ b/plasmoid/package/contents/ui/task/TaskDelegate.qml @@ -225,6 +225,35 @@ MouseArea{ } } + Loader { + id: isSeparatorRectangle + active: (opacityN>0) + + width: mainItemContainer.width + height: mainItemContainer.height + anchors.centerIn: separatorItem + + property real opacityN: isSeparator && root.contextMenu && root.contextMenu.visualParent === mainItemContainer ? 1 : 0 + + Behavior on opacityN { + NumberAnimation { duration: root.durationTime*units.longDuration } + } + + sourceComponent: Rectangle{ + anchors.fill: parent + opacity: isSeparatorRectangle.opacityN + radius: 3 + + property color tempColor: theme.highlightColor + color: tempColor + border.width: 1 + border.color: theme.highlightColor + + onTempColorChanged: tempColor.a = 0.35; + + } + } + Item{ id:separatorItem anchors.rightMargin: root.position === PlasmaCore.Types.RightPositioned ? localThickMargin : 0 @@ -425,6 +454,10 @@ MouseArea{ onIsSeparatorChanged: { if (isSeparator) { parabolicManager.setSeparator(launcherUrl, itemIndex); + + if (parabolicManager.hasLauncherToBeMoved(launcherUrl) && itemIndex>=0) { + parabolicManager.moveLauncherToCorrectPos(launcherUrl, itemIndex); + } } else { parabolicManager.setSeparator(launcherUrl, -1); } @@ -602,7 +635,7 @@ MouseArea{ else if (mouse.button == Qt.RightButton && !modAccepted){ // When we're a launcher, there's no window controls, so we can show all // places without the menu getting super huge. - if (model.IsLauncher === true) { + if (model.IsLauncher === true && !isSeparator) { showContextMenu({showAllPlaces: true}) } else { showContextMenu(); @@ -941,7 +974,7 @@ MouseArea{ } function showContextMenu(args) { - if (isSeparator) + if (isSeparator && !root.editMode) return; contextMenu = root.createContextMenu(mainItemContainer, modelIndex(), args);