Warning, /plasma/latte-dock/declarativeimports/abilities/items/basicitem/ParabolicEventsArea.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 import QtQuick 2.7
0007 import org.kde.plasma.core 2.0 as PlasmaCore
0008 
0009 Item {
0010     id: _parabolicArea
0011     signal parabolicEntered(real mouseX, real mouseY);
0012     signal parabolicMove(real mouseX, real mouseY);
0013     signal parabolicExited();
0014 
0015     property int lastMouseX: 0
0016     property int lastMouseY: 0
0017     property int lastParabolicPos: 0
0018 
0019     readonly property bool containsMouse: (abilityItem.abilities.parabolic.currentParabolicItem === _parabolicArea) || parabolicMouseArea.containsMouse
0020 
0021     readonly property bool isParabolicEnabled: parabolicEventsAreaLoader.isParabolicEnabled
0022     readonly property bool isThinTooltipEnabled: parabolicEventsAreaLoader.isThinTooltipEnabled
0023     readonly property real length: abilityItem.isHorizontal ? abilityItem.width : abilityItem.height
0024 
0025     MouseArea {
0026         id: parabolicMouseArea
0027         anchors.fill: parent
0028         enabled: visible
0029         hoverEnabled: true
0030         visible: abilityItem.abilities.parabolic.currentParabolicItem !== _parabolicArea
0031 
0032         onEntered: {
0033             abilityItem.abilities.parabolic.setCurrentParabolicItem(_parabolicArea);
0034 
0035             if (isThinTooltipEnabled) {
0036                 abilityItem.abilities.thinTooltip.show(abilityItem.tooltipVisualParent, abilityItem.thinTooltipText);
0037             }
0038 
0039             if (isParabolicEnabled) {
0040                 var vIndex = abilityItem.abilities.shortcuts.shortcutIndex(abilityItem.itemIndex);
0041                 abilityItem.abilities.parabolic.setCurrentParabolicItemIndex(vIndex);
0042             }
0043 
0044             // mouseX/Y can not be trusted at this point
0045             //_parabolicArea.parabolicEntered(mouseX, mouseY);
0046         }
0047     }
0048 
0049     Connections {
0050         target: parabolicItem
0051         onIsParabolicEventBlockedChanged: {
0052             if (!parabolicItem.isParabolicEventBlocked && _parabolicArea.containsMouse) {
0053                 _parabolicArea.parabolicEntered(lastMouseX, lastMouseY);
0054             }
0055         }
0056     }
0057 
0058     Connections{
0059         target: abilityItem.abilities.myView
0060 
0061         //! During dock sliding-in because the parabolic effect isnt trigerred
0062         //! immediately but we wait first the dock to go to its final normal
0063         //! place we might miss the activation of the parabolic effect.
0064         //! By catching that signal we are trying to solve this.
0065         onIsShownFullyChanged: {
0066             if (abilityItem.abilities.myView.isShownFully && _parabolicArea.containsMouse) {
0067                 _parabolicArea.parabolicMove(lastMouseX, lastMouseY);
0068             }
0069         }
0070     }
0071 
0072     onParabolicEntered: {
0073         lastMouseX = mouseX;
0074         lastMouseY = mouseY;
0075 
0076         restoreAnimation.stop();
0077 
0078         if (isThinTooltipEnabled) {
0079             abilityItem.abilities.thinTooltip.show(abilityItem.tooltipVisualParent, abilityItem.thinTooltipText);
0080         }
0081 
0082         if (isParabolicEnabled) {
0083             //! mouseX/Y can NOW be trusted because ParabolicEnterd event is triggered from View::Parabolic class
0084             var current = abilityItem.isHorizontal ? mouseX : mouseY;
0085             lastParabolicPos = current;
0086             calculateParabolicScales(current);
0087         }
0088     }
0089 
0090     onParabolicMove: {
0091         lastMouseX = mouseX;
0092         lastMouseY = mouseY;
0093 
0094         if (isParabolicEnabled) {
0095             var mousePos = abilityItem.isHorizontal ? mouseX : mouseY;
0096 
0097             if (mousePos<0 || parabolicItem.isParabolicEventBlocked) {
0098                 return;
0099             }
0100 
0101             if (abilityItem.abilities.myView.isReady && !abilityItem.abilities.myView.isShownFully) {
0102                 return;
0103             }
0104 
0105             if( ((abilityItem.parabolicItem.zoom === 1 || abilityItem.parabolicItem.zoom === abilityItem.abilities.parabolic.factor.zoom)
0106                  && !abilityItem.abilities.parabolic.directRenderingEnabled)
0107                     || abilityItem.abilities.parabolic.directRenderingEnabled) {
0108 
0109                 var step = Math.abs(lastParabolicPos-mousePos);
0110                 if (step >= abilityItem.abilities.animations.hoverPixelSensitivity){
0111                     lastParabolicPos = mousePos;
0112                     calculateParabolicScales(mousePos);
0113                 }
0114             }
0115         }
0116     }
0117 
0118     onParabolicExited: {
0119         lastParabolicPos = 0;
0120 
0121         if (isThinTooltipEnabled) {
0122             abilityItem.abilities.thinTooltip.hide(abilityItem.tooltipVisualParent);
0123         }
0124     }
0125 
0126     function calculateParabolicScales( currentMousePosition ){
0127         if (abilityItem.abilities.parabolic.factor.zoom===1
0128                 || abilityItem.abilities.parabolic.restoreZoomIsBlocked
0129                 || parabolicItem.isParabolicEventBlocked) {
0130             return;
0131         }
0132 
0133         if (abilityItem.parabolicItem.zoom === 1 && (abilityItem.isFirstItemInContainer || abilityItem.isLastItemInContainer)) {
0134             //! first hover of first or last items in container
0135             //! this way we make sure that neighbour items will increase their zoom faster
0136             var substep = length/4;
0137             var center = length/2;
0138             currentMousePosition = Math.min(Math.max(currentMousePosition, center-substep), center+substep);
0139         }
0140 
0141         //use the new parabolic ability in order to handle all parabolic effect messages
0142         var scales = abilityItem.abilities.parabolic.applyParabolicEffect(index, currentMousePosition, length);
0143 
0144         if (!parabolicItem.isUpdatingOnlySpacers) {
0145             abilityItem.parabolicItem.zoom = abilityItem.abilities.parabolic.factor.zoom;
0146         } else {
0147             var subSpacerScale = (abilityItem.abilities.parabolic.factor.zoom-1)/2;
0148 
0149             hiddenSpacerLeft.nScale = subSpacerScale;
0150             hiddenSpacerRight.nScale = subSpacerScale;
0151         }
0152     } //zoom
0153 
0154     function updateScale(nIndex, nScale){
0155         if (index === nIndex /*&& !_parabolicArea.containsMouse*/ /*&& !parabolicItem.isParabolicEventBlocked*/){ //!disabled them in order to provide smoother parabolic effect during dock showing and first hovering
0156             if (parabolicItem.isUpdatingOnlySpacers) {
0157                 var subSpacerScale = (nScale-1)/2;
0158 
0159                 hiddenSpacerLeft.nScale = subSpacerScale;
0160                 hiddenSpacerRight.nScale = subSpacerScale;
0161             } else {
0162                 abilityItem.parabolicItem.zoom = Math.max(1, nScale);
0163             }
0164         }
0165     }
0166 
0167     function sltUpdateItemScale(delegateIndex, newScales, islower) {
0168         var ishigher = !islower;
0169         var clearrequestedfromlastacceptedsignal = (newScales.length===1) && (newScales[0]===1);
0170         var sideindex = islower ? index-1 : index+1;
0171 
0172         if (delegateIndex === index) {
0173             if (newScales.length <= 0) {
0174                 return
0175             }
0176 
0177             var nextscales = newScales.slice();                       //first copy scales in order to not touch referenced/same array to other slots
0178 
0179             if (!abilityItem.isSeparator && !abilityItem.isHidden) {  //accept signal and apply the first scale in the stack
0180                 updateScale(delegateIndex, nextscales[0]);            //apply scale
0181                 nextscales.splice(0,1);                               //remove accepted and previously applied scale
0182 
0183                 if ((nextscales.length===1) && (nextscales[0]===1)) { //send clearrequestedfromlastacceptedsignal to inform neighbours in that direction to release zoom
0184                     if (islower) {
0185                         abilityItem.abilities.parabolic.sglUpdateLowerItemScale(sideindex, nextscales);
0186                     } else {
0187                         abilityItem.abilities.parabolic.sglUpdateHigherItemScale(sideindex, nextscales);
0188                     }
0189                     return;
0190                 }
0191             }
0192 
0193             if (!clearrequestedfromlastacceptedsignal) {              //send remaining scales in the stack as long as this is not the clearrequestedfromlastacceptedsignal, in order to not send twice
0194                 if (islower) {
0195                     abilityItem.abilities.parabolic.sglUpdateLowerItemScale(sideindex, nextscales);
0196                 } else {
0197                     abilityItem.abilities.parabolic.sglUpdateHigherItemScale(sideindex, nextscales);
0198                 }
0199             }
0200         } else if ((islower && clearrequestedfromlastacceptedsignal && (index < delegateIndex))           //accept requestedfromlastacceptedsignal in lower direction if that is the case
0201                    || (ishigher && clearrequestedfromlastacceptedsignal && (index > delegateIndex))) {    //accept requestedfromlastacceptedsignal in higher direction if that is the case
0202             updateScale(index, 1);
0203         }
0204     }
0205 
0206     function sltUpdateLowerItemScale(delegateIndex, newScales) {
0207         var islower = true;
0208         sltUpdateItemScale(delegateIndex, newScales, islower);
0209     }
0210 
0211     function sltUpdateHigherItemScale(delegateIndex, newScales) {
0212         var ishigher = false;
0213         sltUpdateItemScale(delegateIndex, newScales, ishigher);
0214     }
0215 
0216     Component.onCompleted: {
0217         abilityItem.abilities.parabolic.sglUpdateLowerItemScale.connect(sltUpdateLowerItemScale);
0218         abilityItem.abilities.parabolic.sglUpdateHigherItemScale.connect(sltUpdateHigherItemScale);
0219     }
0220 
0221     Component.onDestruction: {
0222         abilityItem.abilities.parabolic.sglUpdateLowerItemScale.disconnect(sltUpdateLowerItemScale);
0223         abilityItem.abilities.parabolic.sglUpdateHigherItemScale.disconnect(sltUpdateHigherItemScale);
0224     }
0225 }