diff --git a/containment/package/contents/ui/applet/ItemWrapper.qml b/containment/package/contents/ui/applet/ItemWrapper.qml index 3b63a05e..02f6ea99 100644 --- a/containment/package/contents/ui/applet/ItemWrapper.qml +++ b/containment/package/contents/ui/applet/ItemWrapper.qml @@ -1,720 +1,721 @@ /* * Copyright 2016 Smith AR * 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 QtQuick.Layouts 1.1 import QtGraphicalEffects 1.0 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.latte.core 0.2 as LatteCore import "../../code/MathTools.js" as MathTools Item{ id: wrapper width: root.isHorizontal ? length : thickness height: root.isHorizontal ? thickness : length readonly property int length: { if (appletItem.isInternalViewSplitter && !root.inConfigureAppletsMode) { return 0; } if (isSeparator && root.parabolicEffectEnabled) { return -1; } if (appletItem.isAutoFillApplet) { if (appletItem.layouter.maxMetricsInHigherPriority) { return appletItem.maxAutoFillLength; } return Math.max(appletItem.minAutoFillLength,Math.min(appletPreferredLength,appletItem.maxAutoFillLength)); } return root.inConfigureAppletsMode ? Math.max(Math.min(appletItem.metrics.iconSize, root.minAppletLengthInConfigure), scaledLength) : scaledLength; } readonly property int thickness: { if (appletItem.isInternalViewSplitter && !root.inConfigureAppletsMode) { return 0; } return screenEdgeMarginSupported ? layoutThickness : scaledThickness + appletItem.metrics.margin.screenEdge } opacity: appletColorizer.mustBeShown && graphicsSystem.isAccelerated ? 0 : 1 property bool disableLengthScale: false property bool disableThicknessScale: false property bool editMode: root.inConfigureAppletsMode property bool edgeLengthMarginsDisabled: isSeparator || !communicator.requires.lengthMarginsEnabled || !parabolicEffectIsSupported property int appletWidth: applet ? applet.width : -1 property int appletHeight: applet ? applet.height : -1 property int appletMinimumWidth: applet && applet.Layout ? applet.Layout.minimumWidth : -1 property int appletMinimumHeight: applet && applet.Layout ? applet.Layout.minimumHeight : -1 property int appletPreferredWidth: applet && applet.Layout ? applet.Layout.preferredWidth : -1 property int appletPreferredHeight: applet && applet.Layout ? applet.Layout.preferredHeight : -1 property int appletMaximumWidth: applet && applet.Layout ? applet.Layout.maximumWidth : -1 property int appletMaximumHeight: applet && applet.Layout ? applet.Layout.maximumHeight : -1 readonly property int appletLength: root.isHorizontal ? appletWidth : appletHeight readonly property int appletThickness: root.isHorizontal ? appletHeight : appletWidth readonly property int appletMinimumLength : root.isHorizontal ? appletMinimumWidth : appletMinimumHeight readonly property int appletMinimumThickness: root.isHorizontal ? appletMinimumHeight : appletMinimumWidth readonly property int appletPreferredLength: root.isHorizontal ? appletPreferredWidth : appletPreferredHeight readonly property int appletPreferredThickness: root.isHorizontal ? appletPreferredHeight : appletPreferredWidth readonly property int appletMaximumLength: root.isHorizontal ? appletMaximumWidth : appletMaximumHeight readonly property int appletMaximumThickness: root.isHorizontal ? appletMaximumHeight : appletMaximumWidth property int iconSize: appletItem.metrics.iconSize property int marginsThickness: appletItem.metrics.totals.thicknessEdges property int marginsLength: 0 //Fitt's Law, through Binding to avoid Binding loops property int localLengthMargins: isSeparator || !communicator.requires.lengthMarginsEnabled || isInternalViewSplitter ? 0 : appletItem.lengthAppletFullMargins property int edgeLengthMargins: edgeLengthMarginsDisabled ? 0 : appletItem.lengthAppletPadding * 2 property real scaledLength: zoomScaleLength * (layoutLength + marginsLength) property real scaledThickness: zoomScaleThickness * (layoutThickness + marginsThickness) property real zoomScaleLength: disableLengthScale ? 1 : zoomScale property real zoomScaleThickness: disableThicknessScale ? 1 : zoomScale property int layoutLength: 0 property int layoutThickness: 0 property real center:root.isHorizontal ? (width + hiddenSpacerLeft.separatorSpace + hiddenSpacerRight.separatorSpace) / 2 : (height + hiddenSpacerLeft.separatorSpace + hiddenSpacerRight.separatorSpace) / 2 property real zoomScale: 1 property int index: appletItem.index property Item wrapperContainer: _wrapperContainer property Item clickedEffect: _clickedEffect property Item containerForOverlayIcon: _containerForOverlayIcon property Item overlayIconLoader: _overlayIconLoader Behavior on opacity { NumberAnimation { duration: 0.8 * appletItem.animations.duration.proposed easing.type: Easing.OutCubic } } // property int pHeight: applet ? applet.Layout.preferredHeight : -10 /*function debugLayouts(){ if(applet){ console.log("---------- "+ applet.pluginName +" ----------"); console.log("MinW "+applet.Layout.minimumWidth); console.log("PW "+applet.Layout.preferredWidth); console.log("MaxW "+applet.Layout.maximumWidth); console.log("FillW "+applet.Layout.fillWidth); console.log("-----"); console.log("MinH "+applet.Layout.minimumHeight); console.log("PH "+applet.Layout.preferredHeight); console.log("MaxH "+applet.Layout.maximumHeight); console.log("FillH "+applet.Layout.fillHeight); console.log("-----"); console.log("Real Applet Width: "+applet.width); console.log("Real Applet Height: "+applet.height); console.log("-----"); console.log("Real Wrapper Width: "+wrapper.width); console.log("Real Wrapper Height: "+wrapper.height); console.log("-----"); console.log("Can be hovered: " + parabolicEffectIsSupported); console.log("Icon size: " + appletItem.metrics.iconSize); console.log("Thick Margins: " + appletItem.metrics.totals.thicknessEdges); console.log("Intern. Margins: " + (appletItem.metrics.padding.length * 2)); console.log("Intern. Margins: " + (appletItem.metrics.margin.length * 2)); console.log("Max hovered criteria: " + (appletItem.metrics.iconSize + metrics.totals.thicknessEdges)); console.log("-----"); console.log("LayoutW: " + layoutWidth); console.log("LayoutH: " + layoutHeight); } } onLayoutWidthChanged: { debugLayouts(); } onLayoutHeightChanged: { debugLayouts(); }*/ onAppletLengthChanged: { if(zoomScale === 1) { appletItem.updateParabolicEffectIsSupported(); } } onAppletThicknessChanged: { if(zoomScale === 1) { appletItem.updateParabolicEffectIsSupported(); } } onAppletMinimumLengthChanged: { if(zoomScale === 1) { appletItem.updateParabolicEffectIsSupported(); } updateAutoFillLength(); } onAppletMinimumThicknessChanged: { if(zoomScale === 1) { appletItem.updateParabolicEffectIsSupported(); } } onAppletPreferredLengthChanged: updateAutoFillLength(); onAppletMaximumLengthChanged: updateAutoFillLength(); onZoomScaleChanged: { if ((zoomScale === appletItem.parabolic.factor.zoom) && !appletItem.parabolic.directRenderingEnabled) { appletItem.parabolic.setDirectRenderingEnabled(true); } if ((zoomScale > 1) && !appletItem.isZoomed) { appletItem.isZoomed = true; appletItem.animations.needBothAxis.addEvent(appletItem); } else if (zoomScale == 1) { appletItem.isZoomed = false; appletItem.animations.needBothAxis.removeEvent(appletItem); } } Binding { target: wrapper property: "layoutThickness" when: latteView && (wrapper.zoomScale === 1 || communicator.parabolicEffectIsSupported) value: { if (appletItem.isInternalViewSplitter){ return !root.inConfigureAppletsMode ? 0 : appletItem.metrics.iconSize; } if (communicator.parabolicEffectIsSupported && !communicator.inStartup/*avoid binding loops on startup*/) { return appletPreferredThickness; } return appletItem.metrics.iconSize; } } Binding { target: wrapper property: "layoutLength" when: latteView && !appletItem.isAutoFillApplet && (wrapper.zoomScale === 1) value: { if (appletItem.isInternalViewSplitter){ return !root.inConfigureAppletsMode ? 0 : Math.min(appletItem.metrics.iconSize, root.maxJustifySplitterSize); } else if (applet && ( appletMaximumLength < appletItem.metrics.iconSize || appletPreferredLength > appletItem.metrics.iconSize || appletItem.originalAppletBehavior) && !communicator.overlayLatteIconIsActive) { //this way improves performance, probably because during animation the preferred sizes update a lot if (appletMaximumLength>0 && appletMaximumLength < appletItem.metrics.iconSize){ return appletMaximumLength; } else if (appletMinimumLength > appletItem.metrics.iconSize){ return appletMinimumLength; } else if ((appletPreferredLength > appletItem.metrics.iconSize) - || (appletItem.originalAppletBehavior && appletPreferredLength > 0 )){ + || (appletPreferredLength === 0)/*applet wants to hide itself*/ + || (appletItem.originalAppletBehavior && appletPreferredLength > 0)){ return appletPreferredLength; } } return appletItem.metrics.iconSize; } } Binding { target: wrapper property: "disableLengthScale" when: latteView && !(appletItem.isAutoFillApplet || appletItem.isLattePlasmoid) value: { var blockParabolicEffectInLength = false; if (communicator.parabolicEffectIsSupported) { return true; } if (appletItem.isInternalViewSplitter){ return false; } else { if(applet && (appletMinimumLength > appletItem.metrics.iconSize) && !appletItem.parabolicEffectIsSupported && !communicator.overlayLatteIconIsActive){ return (wrapper.zoomScale === 1); } //it is used for plasmoids that need to scale only one axis... e.g. the Weather Plasmoid else if(applet && ( appletMaximumLength < appletItem.metrics.iconSize || appletPreferredLength > appletItem.metrics.iconSize || appletItem.originalAppletBehavior) && !communicator.overlayLatteIconIsActive) { //this way improves performance, probably because during animation the preferred sizes update a lot if (appletMaximumLength>0 && appletMaximumLength < appletItem.metrics.iconSize){ return false; } else if (appletMinimumLength > appletItem.metrics.iconSize){ return (wrapper.zoomScale === 1); } else if ((appletPreferredLength > appletItem.metrics.iconSize) || (appletItem.originalAppletBehavior && appletPreferredLength > 0 )){ return (wrapper.zoomScale === 1); } } } return false; } } Binding { target: wrapper property: "marginsLength" when: latteView && (!root.inStartup || visibilityManager.inTempHiding) value: root.inFullJustify && atScreenEdge && !parabolicEffectMarginsEnabled ? edgeLengthMargins : localLengthMargins } function updateAutoFillLength() { if (appletItem.isAutoFillApplet) { appletItem.layouter.updateSizeForAppletsInFill(); } } Item{ id:_wrapperContainer width: root.isHorizontal ? _length : _thickness height: root.isHorizontal ? _thickness : _length opacity: appletShadow.active ? 0 : 1 property int _length:0 // through Binding to avoid binding loops property int _thickness:0 // through Binding to avoid binding loops readonly property int appliedEdgeMargin: { if (appletItem.isInternalViewSplitter) { return appletItem.metrics.margin.screenEdge + appletItem.metrics.margin.thickness; } return appletItem.screenEdgeMarginSupported ? 0 : appletItem.metrics.margin.screenEdge; } Binding { target: _wrapperContainer property: "_thickness" when: !visibilityManager.inTempHiding value: { if (appletItem.isInternalViewSplitter) { return wrapper.layoutThickness; } var wrapperContainerThickness = wrapper.zoomScaleThickness * (appletItem.metrics.totals.thickness); return appletItem.screenEdgeMarginSupported ? wrapperContainerThickness + appletItem.metrics.margin.screenEdge : wrapperContainerThickness; } } Binding { target: _wrapperContainer property: "_length" when: !visibilityManager.inTempHiding value: { if (appletItem.isAutoFillApplet && (appletItem.maxAutoFillLength>-1)){ return wrapper.length; } if (appletItem.isInternalViewSplitter) { return wrapper.layoutLength; } return wrapper.zoomScaleLength * wrapper.layoutLength; } } ///Secret MouseArea to be used by the folder widget Loader{ anchors.fill: parent active: communicator.overlayLatteIconIsActive && applet.pluginName === "org.kde.plasma.folder" && !appletItem.acceptMouseEvents sourceComponent: MouseArea{ onClicked: latteView.extendedInterface.toggleAppletExpanded(applet.id); } } Item{ id: _containerForOverlayIcon anchors.fill: parent } Loader{ id: _overlayIconLoader anchors.fill: parent active: communicator.overlayLatteIconIsActive property color backgroundColor: "black" property color glowColor: "white" sourceComponent: LatteCore.IconItem{ id: overlayIconItem anchors.fill: parent source: { if (communicator.appletIconItemIsShown()) return communicator.appletIconItem.source; else if (communicator.appletImageItemIsShown()) return communicator.appletImageItem.source; return ""; } providesColors: indicators.info.needsIconColors && source != "" usesPlasmaTheme: communicator.appletIconItemIsShown() ? communicator.appletIconItem.usesPlasmaTheme : false Binding{ target: _overlayIconLoader property: "backgroundColor" when: overlayIconItem.providesColors value: overlayIconItem.backgroundColor } Binding{ target: _overlayIconLoader property: "glowColor" when: overlayIconItem.providesColors value: overlayIconItem.glowColor } Loader{ anchors.centerIn: parent active: root.debugModeOverloadedIcons sourceComponent: Rectangle{ width: 30 height: 30 color: "green" opacity: 0.65 } } } } //! WrapperContainer States states:[ State{ name: "bottom" when: plasmoid.location === PlasmaCore.Types.BottomEdge AnchorChanges{ target: _wrapperContainer; anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: undefined; anchors.right: undefined; anchors.left: undefined; anchors.top: undefined; anchors.bottom: parent.bottom; } PropertyChanges{ target: _wrapperContainer; anchors.leftMargin: 0; anchors.rightMargin: 0; anchors.topMargin:0; anchors.bottomMargin: _wrapperContainer.appliedEdgeMargin; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, State{ name: "top" when: plasmoid.location === PlasmaCore.Types.TopEdge AnchorChanges{ target:_wrapperContainer; anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: undefined; anchors.right: undefined; anchors.left: undefined; anchors.top: parent.top; anchors.bottom: undefined; } PropertyChanges{ target: _wrapperContainer; anchors.leftMargin: 0; anchors.rightMargin: 0; anchors.topMargin: _wrapperContainer.appliedEdgeMargin; anchors.bottomMargin: 0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, State{ name: "left" when: plasmoid.location === PlasmaCore.Types.LeftEdge AnchorChanges{ target: _wrapperContainer; anchors.horizontalCenter: undefined; anchors.verticalCenter: parent.verticalCenter; anchors.right: undefined; anchors.left: parent.left; anchors.top: undefined; anchors.bottom: undefined; } PropertyChanges{ target: _wrapperContainer; anchors.leftMargin: _wrapperContainer.appliedEdgeMargin; anchors.rightMargin: 0; anchors.topMargin:0; anchors.bottomMargin: 0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, State{ name: "right" when: plasmoid.location === PlasmaCore.Types.RightEdge AnchorChanges{ target: _wrapperContainer; anchors.horizontalCenter: undefined; anchors.verticalCenter: parent.verticalCenter; anchors.right: parent.right; anchors.left: undefined; anchors.top: undefined; anchors.bottom: undefined; } PropertyChanges{ target: _wrapperContainer; anchors.leftMargin: 0; anchors.rightMargin: _wrapperContainer.appliedEdgeMargin; anchors.topMargin:0; anchors.bottomMargin: 0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } } ] } Loader{ anchors.fill: _wrapperContainer active: appletItem.isInternalViewSplitter && root.inConfigureAppletsMode sourceComponent: Item { anchors.fill: parent PlasmaCore.SvgItem{ id:splitterImage anchors.centerIn: parent width: Math.min(root.maxJustifySplitterSize, appletItem.metrics.iconSize) height: width rotation: root.isVertical ? 90 : 0 svg: PlasmaCore.Svg{ imagePath: root.universalSettings.splitterIconPath() } layer.enabled: graphicsSystem.isAccelerated layer.effect: DropShadow { radius: root.appShadowSize fast: true samples: 2 * radius color: root.appShadowColor verticalOffset: 2 } } } } ///Shadow in applets Loader{ id: appletShadow anchors.fill: appletItem.appletWrapper active: appletItem.applet && graphicsSystem.isAccelerated && !appletColorizer.mustBeShown && (root.enableShadows && applet.pluginName !== root.plasmoidName) onActiveChanged: { if (active && !isSeparator && graphicsSystem.isAccelerated) { wrapperContainer.opacity = 0; } else { wrapperContainer.opacity = 1; } } opacity: isSeparator ? 0.4 : 1 sourceComponent: DropShadow{ anchors.fill: parent color: root.appShadowColor //"#ff080808" fast: true samples: 2 * radius source: communicator.overlayLatteIconIsActive ? _wrapperContainer : appletItem.applet radius: shadowSize verticalOffset: root.forceTransparentPanel || root.forcePanelForBusyBackground ? 0 : 2 property int shadowSize : root.appShadowSize } } BrightnessContrast{ id:hoveredImage anchors.fill: _wrapperContainer source: _wrapperContainer enabled: appletItem.isSquare && !originalAppletBehavior && !indicators.info.providesHoveredAnimation && opacity != 0 ? true : false opacity: appletMouseArea.containsMouse ? 1 : 0 brightness: 0.25 contrast: 0.15 visible: !indicators.info.providesHoveredAnimation Behavior on opacity { NumberAnimation { duration: appletItem.animations.speedFactor.current*appletItem.animations.duration.large } } } BrightnessContrast { id: _clickedEffect anchors.fill: _wrapperContainer source: _wrapperContainer visible: clickedAnimation.running && !indicators.info.providesClickedAnimation } /* onHeightChanged: { if ((index == 1)|| (index==3)){ console.log("H: "+index+" ("+zoomScale+"). "+currentLayout.children[1].height+" - "+currentLayout.children[3].height+" - "+(currentLayout.children[1].height+currentLayout.children[3].height)); } } onZoomScaleChanged:{ if ((index == 1)|| (index==3)){ console.log(index+" ("+zoomScale+"). "+currentLayout.children[1].height+" - "+currentLayout.children[3].height+" - "+(currentLayout.children[1].height+currentLayout.children[3].height)); } }*/ Loader{ anchors.fill: parent active: root.debugMode sourceComponent: Rectangle{ anchors.fill: parent color: "transparent" //! red visualizer, in debug mode for the applets that use fillWidth or fillHeight //! green, for the rest border.color: (appletItem.isAutoFillApplet && (appletItem.maxAutoFillLength>-1) && root.isHorizontal) ? "red" : "green" border.width: 1 } } Behavior on zoomScale { id: animatedScaleBehavior enabled: !appletItem.parabolic.directRenderingEnabled || restoreAnimation.running NumberAnimation { duration: 3 * appletItem.animationTime easing.type: Easing.OutCubic } } Behavior on zoomScale { enabled: !animatedScaleBehavior.enabled NumberAnimation { duration: 0 } } function calculateParabolicScales( currentMousePosition ){ if (parabolic.factor.zoom===1 || parabolic.restoreZoomIsBlocked) { return; } //use the new parabolic effect manager in order to handle all parabolic effect messages var scales = parabolic.applyParabolicEffect(index, currentMousePosition, center); //Left hiddenSpacer if(appletItem.firstAppletInContainer){ hiddenSpacerLeft.nScale = scales.leftScale - 1; } //Right hiddenSpacer ///there is one more item in the currentLayout ???? if(appletItem.lastAppletInContainer){ hiddenSpacerRight.nScale = scales.rightScale - 1; } zoomScale = parabolic.factor.zoom; } //scale function updateScale(nIndex, nScale, step){ if(appletItem && !appletItem.containsMouse && (appletItem.index === nIndex)){ if ( ((parabolicEffectIsSupported && !appletItem.originalAppletBehavior) || appletItem.latteApplet) && (applet && applet.status !== PlasmaCore.Types.HiddenStatus) ){ if(!appletItem.latteApplet){ if(nScale >= 0) zoomScale = nScale + step; else zoomScale = zoomScale + step; } } } } function sltUpdateLowerItemScale(delegateIndex, newScale, step) { if (delegateIndex === appletItem.index) { if (communicator.parabolicEffectIsSupported) { communicator.bridge.parabolic.client.hostRequestUpdateLowerItemScale(newScale, step); return; } if (!appletItem.isSeparator && !appletItem.isHidden) { //! when accepted updateScale(delegateIndex, newScale, step); if (newScale > 1) { // clear lower items parabolic.sglUpdateLowerItemScale(delegateIndex-1, 1, 0); } } else { parabolic.sglUpdateLowerItemScale(delegateIndex-1, newScale, step); } } else if ((newScale === 1) && (appletItem.index < delegateIndex)) { //! apply zoom clearing if (communicator.parabolicEffectIsSupported) { communicator.bridge.parabolic.client.hostRequestUpdateLowerItemScale(1, step); } else { updateScale(appletItem.index, 1, 0); } } } function sltUpdateHigherItemScale(delegateIndex, newScale, step) { if (delegateIndex === appletItem.index) { if (communicator.parabolicEffectIsSupported) { communicator.bridge.parabolic.client.hostRequestUpdateHigherItemScale(newScale, step); return; } if (!appletItem.isSeparator && !appletItem.isHidden) { //! when accepted updateScale(delegateIndex, newScale, step); if (newScale > 1) { // clear higher items parabolic.sglUpdateHigherItemScale(delegateIndex+1, 1, 0); } } else { parabolic.sglUpdateHigherItemScale(delegateIndex+1, newScale, step); } } else if ((newScale === 1) && (appletItem.index > delegateIndex)) { //! apply zoom clearing if (communicator.parabolicEffectIsSupported) { communicator.bridge.parabolic.client.hostRequestUpdateHigherItemScale(1, step); } else { updateScale(appletItem.index, 1, 0); } } } Component.onCompleted: { parabolic.sglUpdateLowerItemScale.connect(sltUpdateLowerItemScale); parabolic.sglUpdateHigherItemScale.connect(sltUpdateHigherItemScale); } Component.onDestruction: { parabolic.sglUpdateLowerItemScale.disconnect(sltUpdateLowerItemScale); parabolic.sglUpdateHigherItemScale.disconnect(sltUpdateHigherItemScale); } }// Main task area // id:wrapper diff --git a/plasmoid/package/contents/ui/abilities/Indexer.qml b/plasmoid/package/contents/ui/abilities/Indexer.qml index 317b1978..d304240d 100644 --- a/plasmoid/package/contents/ui/abilities/Indexer.qml +++ b/plasmoid/package/contents/ui/abilities/Indexer.qml @@ -1,185 +1,188 @@ /* * 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.plasma.core 2.0 as PlasmaCore 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 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 bool isReady: layout.children.length >= allItemsCount readonly property int maxIndex: 99999 Binding { target: _indexer property: "firstVisibleItemIndex" - when: layout.children.length >= allItemsCount + when: isReady 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 + when: isReady 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 (taskIndexlastVisibleItemIndex || hidden.indexOf(taskIndex) >= 0 || separators.indexOf(taskIndex) >= 0) { 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 * 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.8 import QtQuick.Layouts 1.1 import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.plasmoid 2.0 import org.kde.taskmanager 0.1 as TaskManager import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet import org.kde.activities 0.1 as Activities import org.kde.latte.core 0.2 as LatteCore import org.kde.latte.components 1.0 as LatteComponents import org.kde.latte.abilities.applets 0.1 as AppletAbility import org.kde.latte.private.tasks 0.1 as LatteTasks import "abilities" as Ability import "previews" as Previews import "task" as Task import "taskslayout" as TasksLayout import "../code/tools.js" as TaskTools import "../code/activitiesTools.js" as ActivitiesTools import "../code/ColorizerTools.js" as ColorizerTools Item { id:root - Layout.fillWidth: scrollingEnabled && !root.vertical Layout.fillHeight: scrollingEnabled && root.vertical Layout.minimumWidth: -1 Layout.minimumHeight: -1 Layout.preferredWidth: tasksWidth Layout.preferredHeight: tasksHeight Layout.maximumWidth: -1 Layout.maximumHeight: -1 LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft && !root.vertical LayoutMirroring.childrenInherit: true property bool plasma515: latteView ? latteView.plasma515 : LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,15,0) property bool plasma518: latteView ? latteView.plasma518 : LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,18,0) property bool editMode: latteView ? latteView.editMode : plasmoid.userConfiguring property bool inConfigureAppletsMode: latteView ? latteView.inConfigureAppletsMode : true property bool disableRestoreZoom: false //blocks restore animation in rightClick property bool disableAllWindowsFunctionality: plasmoid.configuration.hideAllTasks property bool dropNewLauncher: false property bool inActivityChange: false property bool inDraggingPhase: false property bool initializationStep: false //true property bool isHovered: false property bool showBarLine: plasmoid.configuration.showBarLine property bool useThemePanel: plasmoid.configuration.useThemePanel property bool taskInAnimation: noTasksInAnimation > 0 ? true : false property bool transparentPanel: plasmoid.configuration.transparentPanel property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical ? true : false property int clearWidth property int clearHeight property int newDroppedPosition: -1 property int noInitCreatedBuffers: 0 property int noTasksInAnimation: 0 property int themePanelSize: plasmoid.configuration.panelSize property int location : { if (plasmoid.location === PlasmaCore.Types.LeftEdge || plasmoid.location === PlasmaCore.Types.RightEdge || plasmoid.location === PlasmaCore.Types.TopEdge) { return plasmoid.location; } return PlasmaCore.Types.BottomEdge; } property int tasksStarting: 0 ///Don't use Math.floor it adds one pixel in animations and creates glitches property int widthMargins: root.vertical ? metrics.totals.thicknessEdges : metrics.totals.lengthEdges property int heightMargins: !root.vertical ? metrics.totals.thicknessEdges : metrics.totals.lengthEdges property int internalWidthMargins: root.vertical ? metrics.totals.thicknessEdges : metrics.totals.lengthPaddings property int internalHeightMargins: !root.vertical ? metrics.totals.thicknessEdges : metrics.totals.lengthPaddings property real textColorBrightness: ColorizerTools.colorBrightness(themeTextColor) property color minimizedDotColor: { if (latteView) { return latteView.minimizedDotColor; } return textColorBrightness > 127.5 ? Qt.darker(themeTextColor, 1.7) : Qt.lighter(themeBackgroundColor, 7) } property color themeTextColor: theme.textColor property color themeBackgroundColor: theme.backgroundColor property color lightTextColor: textColorBrightness > 127.5 ? themeTextColor : themeBackgroundColor //a small badgers record (id,value) //in order to track badgers when there are changes //in launcher reference from libtaskmanager property variant badgers:[] property variant launchersOnActivities: [] //global plasmoid reference to the context menu property QtObject contextMenu: null property QtObject contextMenuComponent: Qt.createComponent("ContextMenu.qml"); property Item dragSource: null property Item tasksExtendedManager: _tasksExtendedManager readonly property alias animations: _animations readonly property alias indexer: _indexer readonly property alias launchers: _launchers readonly property alias metrics: _metrics readonly property alias parabolic: _parabolic readonly property alias shortcuts: _shortcuts readonly property alias containsDrag: mouseHandler.containsDrag readonly property bool dragAreaEnabled: latteView ? (root.dragSource !== null || latteView.dragInfo.isSeparator || latteView.dragInfo.isTask || !latteView.dragInfo.isPlasmoid) : true //! it is used to play the animation correct when the user removes a launcher property string launcherForRemoval: "" //BEGIN Latte Dock properties property bool badges3DStyle: latteView ? latteView.badges3DStyle : true property bool dockIsShownCompletely: latteView ? latteView.dockIsShownCompletely : true property bool enableShadows: latteView ? latteView.enableShadows > 0 : plasmoid.configuration.showShadows property bool forceHidePanel: false property bool disableLeftSpacer: false property bool disableRightSpacer: false property bool dockIsHidden: latteView ? latteView.dockIsHidden : false property bool groupTasksByDefault: plasmoid.configuration.groupTasksByDefault property bool highlightWindows: hoverAction === LatteTasks.Types.HighlightWindows || hoverAction === LatteTasks.Types.PreviewAndHighlightWindows property bool parabolicEffectEnabled: latteView ? latteView.parabolicEffectEnabled : parabolic.factor.zoom && !root.editMode property bool scrollingEnabled: plasmoid.configuration.scrollTasksEnabled property bool autoScrollTasksEnabled: scrollingEnabled && plasmoid.configuration.autoScrollTasksEnabled property bool manualScrollTasksEnabled: scrollingEnabled && manualScrollTasksType !== LatteTasks.Types.ManualScrollDisabled property int manualScrollTasksType: plasmoid.configuration.manualScrollTasksType property bool showInfoBadge: plasmoid.configuration.showInfoBadge property bool showProgressBadge: plasmoid.configuration.showInfoBadge property bool showAudioBadge: plasmoid.configuration.showAudioBadge property bool infoBadgeProminentColorEnabled: plasmoid.configuration.infoBadgeProminentColorEnabled property bool audioBadgeActionsEnabled: plasmoid.configuration.audioBadgeActionsEnabled property bool showOnlyCurrentScreen: plasmoid.configuration.showOnlyCurrentScreen property bool showOnlyCurrentDesktop: plasmoid.configuration.showOnlyCurrentDesktop property bool showOnlyCurrentActivity: plasmoid.configuration.showOnlyCurrentActivity property bool showPreviews: hoverAction === LatteTasks.Types.PreviewWindows || hoverAction === LatteTasks.Types.PreviewAndHighlightWindows property bool showWindowActions: plasmoid.configuration.showWindowActions && !disableAllWindowsFunctionality property bool showWindowsOnlyFromLaunchers: plasmoid.configuration.showWindowsOnlyFromLaunchers && !disableAllWindowsFunctionality property bool titleTooltips: latteView ? latteView.titleTooltips : false property alias windowPreviewIsShown: windowsPreviewDlg.visible property int launchersGroup: plasmoid.configuration.launchersGroup property int leftClickAction: plasmoid.configuration.leftClickAction property int middleClickAction: plasmoid.configuration.middleClickAction property int hoverAction: plasmoid.configuration.hoverAction property int modifier: plasmoid.configuration.modifier property int modifierClickAction: plasmoid.configuration.modifierClickAction property int modifierClick: plasmoid.configuration.modifierClick property int modifierQt:{ if (modifier === LatteTasks.Types.Shift) return Qt.ShiftModifier; else if (modifier === LatteTasks.Types.Ctrl) return Qt.ControlModifier; else if (modifier === LatteTasks.Types.Alt) return Qt.AltModifier; else if (modifier === LatteTasks.Types.Meta) return Qt.MetaModifier; else return -1; } property int taskScrollAction: plasmoid.configuration.taskScrollAction onTaskScrollActionChanged: { if (taskScrollAction > LatteTasks.Types.ScrollToggleMinimized) { //! migrating scroll action to LatteTasks.Types.ScrollAction plasmoid.configuration.taskScrollAction = plasmoid.configuration.taskScrollAction-LatteTasks.Types.ScrollToggleMinimized; } } //! Real properties are need in order for parabolic effect to be 1px precise perfect. //! This way moving from Tasks to Applets and vice versa is pretty stable when hovering with parabolic effect. property real tasksHeight: mouseHandler.height property real tasksWidth: mouseHandler.width //updated from Binding property int alignment readonly property real currentPanelOpacity: latteView ? latteView.currentPanelTransparency / 100 : 1 property int appShadowSize: latteView ? latteView.appShadowSize : Math.ceil(0.12*metrics.iconSize) property string appShadowColor: latteView ? latteView.appShadowColor : "#ff080808" property string appShadowColorSolid: latteView ? latteView.appShadowColorSolid : "#ff080808" property alias tasksCount: tasksModel.count readonly property rect screenGeometry: latteView ? latteView.screenGeometry : plasmoid.screenGeometry readonly property bool viewLayoutIsCurrent: latteView && viewLayout && latteView.layoutsManager && viewLayout.name === latteView.layoutsManager.currentLayoutName readonly property string viewLayoutName: viewLayout ? viewLayout.name : "" readonly property QtObject viewLayout : latteView && latteView.viewLayout ? latteView.viewLayout : null property Item latteView: null readonly property Item indicators: latteView ? latteView.indicatorsManager : indicatorsStandaloneLoader.item //END Latte Dock Panel properties + readonly property bool inEditMode: latteInEditMode || plasmoid.userConfiguring + //BEGIN Latte Dock Communicator property QtObject latteBridge: null readonly property bool enforceLattePalette: latteBridge && latteBridge.applyPalette && latteBridge.palette readonly property bool latteInEditMode: latteBridge && latteBridge.inEditMode //END Latte Dock Communicator Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground signal draggingFinished(); signal hiddenTasksUpdated(); signal launchersUpdatedFor(string launcher); signal presentWindows(variant winIds); signal requestLayout; signal signalPreviewsShown(); //signal signalDraggingState(bool value); signal showPreviewForTasks(QtObject group); //trigger updating scaling of neighbour delegates of zoomed delegate signal updateScale(int delegateIndex, real newScale, real step) signal mimicEnterForParabolic(); signal publishTasksGeometries(); signal windowsHovered(variant winIds, bool hovered) //onAnimationsChanged: console.log(animations); /* Rectangle{ anchors.fill: parent border.width: 1 border.color: "red" color: "white" } */ onLatteViewChanged: { if (latteView) { plasmoid.action("configure").visible = false; plasmoid.configuration.isInLatteDock = true; if (root.launchersGroup === LatteCore.Types.LayoutLaunchers || root.launchersGroup === LatteCore.Types.GlobalLaunchers) { tasksModel.updateLaunchersList(); } } else { plasmoid.configuration.isInLatteDock = false; } } onLaunchersGroupChanged:{ if(latteView) { tasksModel.updateLaunchersList(); } } Connections { target: plasmoid onLocationChanged: { iconGeometryTimer.start(); } } Connections { target: plasmoid.configuration // onLaunchersChanged: tasksModel.launcherList = plasmoid.configuration.launchers onGroupingAppIdBlacklistChanged: tasksModel.groupingAppIdBlacklist = plasmoid.configuration.groupingAppIdBlacklist; onGroupingLauncherUrlBlacklistChanged: tasksModel.groupingLauncherUrlBlacklist = plasmoid.configuration.groupingLauncherUrlBlacklist; } Connections{ target: latteView onDockIsHiddenChanged:{ if (latteView.dockIsHidden) { windowsPreviewDlg.hide("3.3"); } } } Connections{ target: latteView && latteView.layoutsManager ? latteView.layoutsManager : null onCurrentLayoutNameChanged: root.publishTasksGeometries(); } Binding { target: plasmoid property: "status" - value: (tasksModel.anyTaskDemandsAttentionInValidTime || root.dragSource ? - PlasmaCore.Types.NeedsAttentionStatus : PlasmaCore.Types.PassiveStatus); + value: { + if (tasksModel.anyTaskDemandsAttentionInValidTime || root.dragSource) { + return PlasmaCore.Types.NeedsAttentionStatus; + } + + return PlasmaCore.Types.PassiveStatus; + } } ///// PlasmaCore.ColorScope{ id: colorScopePalette } //! Item { id: graphicsSystem readonly property bool isAccelerated: (GraphicsInfo.api !== GraphicsInfo.Software) && (GraphicsInfo.api !== GraphicsInfo.Unknown) } Loader { id: indicatorsStandaloneLoader active: !latteView && !plasmoid.configuration.isInLatteDock source: "indicators/Manager.qml" } Binding { target: root property: "alignment" value: { if (latteView) { if (latteView.panelAlignment === -1) { return; } if (latteView.panelAlignment === LatteCore.Types.Justify) { if (latteView.latteAppletPos>=0 && latteView.latteAppletPos<100) { return plasmoid.formFactor === PlasmaCore.Types.Horizontal ? LatteCore.Types.Left : LatteCore.Types.Top; } else if (latteView.latteAppletPos>=100 && latteView.latteAppletPos<200) { return LatteCore.Types.Center; } else if (latteView.latteAppletPos>=200) { return plasmoid.formFactor === PlasmaCore.Types.Horizontal ? LatteCore.Types.Right : LatteCore.Types.Bottom; } return LatteCore.Types.Center; } return latteView.panelAlignment; } return LatteCore.Types.Center; } } ///// function launchersDropped(urls){ mouseHandler.urlsDropped(urls); } ///UPDATE function launcherExists(url) { return (ActivitiesTools.getIndex(url, tasksModel.launcherList)>=0); } function taskExists(url) { var tasks = icList.contentItem.children; for(var i=0; i -1) { launch.push(explicitLauncher); } } } return launch; } function currentListViewLauncherList() { var launch = []; var tasks = icList.contentItem.children; for(var i=0; i