diff --git a/containment/package/contents/ui/abilities/Indexer.qml b/containment/package/contents/ui/abilities/Indexer.qml index dac2c32e..1b32804f 100644 --- a/containment/package/contents/ui/abilities/Indexer.qml +++ b/containment/package/contents/ui/abilities/Indexer.qml @@ -1,45 +1,57 @@ /* * Copyright 2020 Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see . */ import QtQuick 2.7 import org.kde.plasma.plasmoid 2.0 import "./privates" as Ability Ability.IndexerPrivate { //! do not update during dragging/moving applets inConfigureAppletsMode updateIsBlocked: (root.dragOverlay && root.dragOverlay.pressed) || layouter.appletsInParentChange function getClientBridge(index) { if (clientsBridges.length<=0) { return false; } var ibl = clientsBridges.length; for(var i=0; i= 0) || (hidden.indexOf(actualIndex) >= 0)) { + return -1; + } + + var visibleItems = visibleItemsBeforeCount(layouts.startLayout, actualIndex) + + visibleItemsBeforeCount(layouts.mainLayout, actualIndex) + + visibleItemsBeforeCount(layouts.endLayout, actualIndex); + + return visibleItems; + } } diff --git a/containment/package/contents/ui/abilities/privates/IndexerPrivate.qml b/containment/package/contents/ui/abilities/privates/IndexerPrivate.qml index 95d2bf33..cc9d2dd4 100644 --- a/containment/package/contents/ui/abilities/privates/IndexerPrivate.qml +++ b/containment/package/contents/ui/abilities/privates/IndexerPrivate.qml @@ -1,198 +1,220 @@ /* * Copyright 2020 Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see . */ import QtQuick 2.7 import org.kde.plasma.plasmoid 2.0 import org.kde.latte.abilities.definitions 0.1 as AbilityDefinition AbilityDefinition.Indexer { id: indxr property Item layouts: null property bool updateIsBlocked: false property var clients: [] property var clientsBridges: [] Binding{ target: indxr property: "separators" when: !updateIsBlocked value: { var seps = []; var sLayout = layouts.startLayout; for (var i=0; i=0) { seps.push(appletItem.index); } } var mLayout = layouts.mainLayout; for (var i=0; i=0) { seps.push(appletItem.index); } } var eLayout = layouts.endLayout; for (var i=0; i=0) { seps.push(appletItem.index); } } return seps; } } Binding { target: indxr property: "hidden" when: !updateIsBlocked value: { var hdn = []; var sLayout = layouts.startLayout; for (var i=0; i=0) { hdn.push(appletItem.index); } } var mLayout = layouts.mainLayout; for (var i=0; i=0) { hdn.push(appletItem.index); } } var eLayout = layouts.endLayout; for (var i=0; i=0) { hdn.push(appletItem.index); } } return hdn; } } Binding { target: indxr property: "clients" when: !updateIsBlocked value: { var clns = []; var sLayout = layouts.startLayout; for (var i=0; i=0 && appletItem.communicator && appletItem.communicator.indexerIsSupported) { clns.push(appletItem.index); } } var mLayout = layouts.mainLayout; for (var i=0; i=0 && appletItem.communicator && appletItem.communicator.indexerIsSupported) { clns.push(appletItem.index); } } var eLayout = layouts.endLayout; for (var i=0; i=0 && appletItem.communicator && appletItem.communicator.indexerIsSupported) { clns.push(appletItem.index); } } return clns; } } Binding { target: indxr property: "clientsBridges" when: !updateIsBlocked value: { var bdgs = []; var sLayout = layouts.startLayout; for (var i=0; i=0 && appletItem.communicator && appletItem.communicator.indexerIsSupported && appletItem.communicator.bridge && appletItem.communicator.bridge.indexer) { bdgs.push(appletItem.communicator.bridge.indexer); } } var mLayout = layouts.mainLayout; for (var i=0; i=0 && appletItem.communicator && appletItem.communicator.indexerIsSupported && appletItem.communicator.bridge && appletItem.communicator.bridge.indexer) { bdgs.push(appletItem.communicator.bridge.indexer); } } var eLayout = layouts.endLayout; for (var i=0; i=0 && appletItem.communicator && appletItem.communicator.indexerIsSupported && appletItem.communicator.bridge && appletItem.communicator.bridge.indexer) { bdgs.push(appletItem.communicator.bridge.indexer); } } return bdgs; } } + + function visibleItemsBeforeCount(layout, actualIndex) { + var visibleItems = 0; + + for (var i=0; i= 0) || (hidden.indexOf(appletItem.index) >= 0)) { + //! ignore hidden and separators applets + continue; + } else if (!appletItem.communicator || !appletItem.communicator.indexerIsSupported) { + //! single item applet + visibleItems = visibleItems + 1; + } else if (appletItem.communicator && appletItem.communicator.indexerIsSupported) { + //! multi items applet + visibleItems = visibleItems + appletItem.communicator.bridge.indexer.client.visibleItemsCount; + } + } + } + + return visibleItems; + } } diff --git a/containment/package/contents/ui/applet/ShortcutBadge.qml b/containment/package/contents/ui/applet/ShortcutBadge.qml index 805360b9..8fde91dd 100644 --- a/containment/package/contents/ui/applet/ShortcutBadge.qml +++ b/containment/package/contents/ui/applet/ShortcutBadge.qml @@ -1,118 +1,118 @@ /* * Copyright 2019 Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see . */ import QtQuick 2.1 import QtGraphicalEffects 1.0 import org.kde.latte.components 1.0 as LatteComponents Loader{ id: appletNumberLoader active: appletItem.canShowAppletNumberBadge && (root.showLatteShortcutBadges || root.showAppletShortcutBadges || root.showMetaBadge && applet.id===applicationLauncherId) asynchronous: true visible: badgeString!=="" property int fixedIndex: -1 property string badgeString: "" onActiveChanged: { if (active && root.showLatteShortcutBadges && root.unifiedGlobalShortcuts) { - fixedIndex = parabolicManager.pseudoAppletIndex(index); + fixedIndex = appletItem.indexer.visibleIndex(index); } else { fixedIndex = -1; } } Component.onCompleted: { if (active && root.showLatteShortcutBadges && root.unifiedGlobalShortcuts) { - fixedIndex = parabolicManager.pseudoAppletIndex(index); + fixedIndex = appletItem.indexer.visibleIndex(index); } else { fixedIndex = -1; } } Binding{ target: appletNumberLoader property:"badgeString" when: root.showMetaBadge || root.showAppletShortcutBadges value: { if (root.showMetaBadge && applet && applet.id === applicationLauncherId) { return '\u2318'; } if (root.showAppletShortcutBadges) { var plasmaShortcut = applet ? shortcutsEngine.appletShortcutBadge(applet.id) : ""; if (plasmaShortcut !== "") { return plasmaShortcut; } } if (appletNumberLoader.fixedIndex>=1 && appletNumberLoader.fixedIndex<20) { return root.badgesForActivate[appletNumberLoader.fixedIndex-1]; } else { return ""; } } } sourceComponent: Item{ Loader{ anchors.fill: appletNumber active: root.enableShadows && graphicsSystem.isAccelerated sourceComponent: DropShadow{ color: root.appShadowColor fast: true samples: 2 * radius source: appletNumber radius: root.appShadowSize/2 verticalOffset: 2 } } LatteComponents.BadgeText { id: appletNumber // when iconSize < 48, height is always = 24, height / iconSize > 50% // we prefer center aligned badges to top-left aligned ones property bool centerInParent: appletItem.metrics.iconSize < 48 anchors.left: centerInParent? undefined : parent.left anchors.top: centerInParent? undefined : parent.top anchors.centerIn: centerInParent? parent : undefined minimumWidth: 0.4 * (wrapper.zoomScale * appletItem.metrics.iconSize) height: Math.max(24, 0.4 * (wrapper.zoomScale * appletItem.metrics.iconSize)) borderColor: colorizerManager.originalLightTextColor proportion: 0 radiusPerCentage: 100 showNumber: false showText: true textValue: appletNumberLoader.badgeString style3d: root.badges3DStyle } } } diff --git a/plasmoid/package/contents/ui/abilities/Indexer.qml b/plasmoid/package/contents/ui/abilities/Indexer.qml index b915854d..de3a4e33 100644 --- a/plasmoid/package/contents/ui/abilities/Indexer.qml +++ b/plasmoid/package/contents/ui/abilities/Indexer.qml @@ -1,141 +1,182 @@ /* * Copyright 2020 Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see . */ import QtQuick 2.0 import org.kde.plasma.plasmoid 2.0 import org.kde.latte.abilities.applets 0.1 as AppletAbility AppletAbility.Indexer { id: _indexer property Item layout: null readonly property bool tailAppletIsSeparator: isActive ? bridge.indexer.tailAppletIsSeparator : false readonly property bool headAppletIsSeparator: isActive ? bridge.indexer.headAppletIsSeparator : false - readonly property int visibleItemsCount: Math.max(0, layout.children.length - separators.length - hidden.length) - - readonly property int maxIndex: 99999 - + property int visibleItemsCount: 0 property int allItemsCount: 0 /*is needed to be set from consumer developer in order to avoid binding loops warnings*/ property int firstVisibleItemIndex: -1 property int lastVisibleItemIndex: -1 + readonly property int maxIndex: 99999 + Binding { target: _indexer property: "firstVisibleItemIndex" when: layout.children.length >= allItemsCount value: { var ind = maxIndex; for(var i=0; i=0 && hidden.indexOf(item.itemIndex)<0 && separators.indexOf(item.itemIndex)<0 && item.itemIndex < ind) { ind = item.itemIndex; } } return ind === maxIndex ? -1 : ind; } } Binding { target: _indexer property: "lastVisibleItemIndex" when: layout.children.length >= allItemsCount value: { var ind = -1; for(var i=0; i=0 && hidden.indexOf(item.itemIndex)<0 && separators.indexOf(item.itemIndex)<0 && item.itemIndex > ind) { //console.log("org.kde.latte SETTING UP ::: " + item.itemIndex + " / " + layout.children.length); ind = item.itemIndex; } } return ind; } } + Binding { + target: _indexer + property: "visibleItemsCount" + value: { + var count = 0; + for(var i=0; i=0 + && hidden.indexOf(item.itemIndex)<0 + && separators.indexOf(item.itemIndex)<0) { + count = count + 1; + } + } + return count; + } + } + readonly property bool firstTailItemIsSeparator: { if (visibleItemsCount === layout.children.length) { return false; } for(var i=0; i=0) { return true; } } return false; } readonly property bool lastHeadItemIsSeparator: { if (visibleItemsCount === layout.children.length) { return false; } var len = layout.children.length; for(var i=len-1; i>lastVisibleItemIndex; --i) { if (separators.indexOf(i)>=0) { return true; } } return false; } separators: { var seps = []; for (var i=0; i=0) { seps.push(item.itemIndex); } } return seps; } hidden: { var hdns = []; for (var i=0; i=0) { hdns.push(item.itemIndex); } } return hdns; } + function visibleIndex(taskIndex) { + if (taskIndex < firstVisibleItemIndex || taskIndex>lastVisibleItemIndex) { + return -1; + } + + var vindex = -1; + if (latteBridge) { + vindex = latteBridge.indexer.host.visibleIndex(latteBridge.indexer.appletIndex); + } + + for (var i=0; i=0 || separators.indexOf(item.itemIndex) >=0) { + continue; + } + + if (item.itemIndex * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see . */ import QtQuick 2.7 import QtGraphicalEffects 1.0 import org.kde.latte.components 1.0 as LatteComponents Loader{ id: shorcutBadge anchors.fill: iconImageBuffer active: root.showTaskShortcutBadges && !taskItem.isSeparator && fixedIndex>=0 && fixedIndex<20 asynchronous: true visible: badgeString !== "" property int fixedIndex:-1 property string badgeString: (shorcutBadge.fixedIndex>=1 && shorcutBadge.fixedIndex<20 && root.badgesForActivate.length===19) ? root.badgesForActivate[shorcutBadge.fixedIndex-1] : "" Connections { target: root - onShowTaskShortcutBadgesChanged: shorcutBadge.fixedIndex = parabolicManager.pseudoTaskIndex(index+1); + onShowTaskShortcutBadgesChanged: { + shorcutBadge.fixedIndex = taskItem.indexer.visibleIndex(taskItem.itemIndex); + } } - Component.onCompleted: fixedIndex = parabolicManager.pseudoTaskIndex(index+1); + Component.onCompleted: { + fixedIndex = taskItem.indexer.visibleIndex(taskItem.itemIndex); + } sourceComponent: Item{ Loader{ anchors.fill: taskNumber active: root.enableShadows && graphicsSystem.isAccelerated sourceComponent: DropShadow{ color: root.appShadowColor fast: true samples: 2 * radius source: taskNumber radius: root.appShadowSize/2 verticalOffset: 2 } } LatteComponents.BadgeText { id: taskNumber // when iconSize < 48, height is always = 24, height / iconSize > 50% // we prefer center aligned badges to top-left aligned ones property bool centerInParent: taskItem.metrics.iconSize < 48 anchors.left: centerInParent? undefined : parent.left anchors.top: centerInParent? undefined : parent.top anchors.centerIn: centerInParent? parent : undefined minimumWidth: 0.4 * (wrapper.mScale * taskItem.metrics.iconSize) height: Math.max(24, 0.4 * (wrapper.mScale * taskItem.metrics.iconSize)) style3d: root.badges3DStyle textValue: shorcutBadge.badgeString borderColor: root.lightTextColor showNumber: false showText: true proportion: 0 radiusPerCentage: 100 } } }