Warning, /plasma/latte-dock/plasmoid/package/contents/ui/task/TaskIcon.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 import QtQuick 2.7
0007 import QtGraphicalEffects 1.0
0008 
0009 import org.kde.plasma.core 2.0 as PlasmaCore
0010 import org.kde.plasma.components 2.0 as PlasmaComponents
0011 import org.kde.plasma.plasmoid 2.0
0012 import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
0013 
0014 import org.kde.kirigami 2.0 as Kirigami
0015 
0016 import org.kde.latte.core 0.2 as LatteCore
0017 import org.kde.latte.components 1.0 as LatteComponents
0018 
0019 import "animations" as TaskAnimations
0020 
0021 Item {
0022     id: taskIconContainer
0023     anchors.fill: parent
0024     property bool toBeDestroyed: false
0025 
0026     readonly property color backgroundColor: iconColorsLoader.active ? iconColorsLoader.item.backgroundColor : theme.backgroundColor
0027     readonly property color glowColor: iconColorsLoader.active ? iconColorsLoader.item.glowColor : theme.textColor
0028 
0029     readonly property bool smartLauncherEnabled: (taskItem.isStartup === false) //! it needs to be enabled independent of user-set option because it is used from indicators
0030     readonly property bool progressVisible: smartLauncherItem && smartLauncherItem.progressVisible
0031     readonly property real progress: smartLauncherItem && smartLauncherItem.progress ? smartLauncherItem.progress : 0
0032     readonly property QtObject smartLauncherItem: smartLauncherLoader.active ? smartLauncherLoader.item : null
0033 
0034     readonly property Item monochromizedItem: badgesLoader.active ? badgesLoader.item : taskIconItem
0035 
0036     Rectangle{
0037         id: draggedRectangle
0038         width: parent.width + 2
0039         height: parent.height + 2
0040         anchors.centerIn: taskIconContainer
0041         opacity: 0
0042         radius: 3
0043         anchors.margins: 5
0044 
0045         property color tempColor: theme.highlightColor
0046         color: tempColor
0047         border.width: 1
0048         border.color: theme.highlightColor
0049 
0050         onTempColorChanged: tempColor.a = 0.35;
0051     }
0052 
0053     Loader {
0054         id: smartLauncherLoader
0055         active: taskIconContainer.smartLauncherEnabled
0056         sourceComponent: TaskManagerApplet.SmartLauncherItem {
0057             //! It creates issues with Valgrind and needs to be completely removed in that case
0058             launcherUrl: taskItem.launcherUrlWithIcon
0059         }
0060     }
0061 
0062     //! Provide icon background and glow colors
0063     Loader {
0064         id: iconColorsLoader
0065         active: taskItem.abilities.indicators.info.needsIconColors
0066         visible: false
0067 
0068         sourceComponent: LatteCore.IconItem{
0069             width:64
0070             height:64
0071             source: taskIconItem.source
0072             providesColors: true
0073         }
0074     }
0075 
0076     Kirigami.Icon {
0077         id: taskIconItem
0078         anchors.fill: parent
0079         //roundToIconSize: false
0080         source: decoration
0081         visible: !badgesLoader.active
0082 
0083         readonly property real size: Math.min(width,height)
0084 
0085         ///states for launcher animation
0086         states: [
0087             State{
0088                 name: "*"
0089                 //! since qt 5.14 default state can not use "when" property
0090                 //! it breaks restoring transitions otherwise
0091 
0092                 AnchorChanges{
0093                     target: taskIconItem;
0094                     anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined;
0095                     anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined;
0096                     anchors.right: root.location === PlasmaCore.Types.RightEdge ? parent.right : undefined;
0097                     anchors.left: root.location === PlasmaCore.Types.LeftEdge ? parent.left : undefined;
0098                     anchors.top: root.location === PlasmaCore.Types.TopEdge ? parent.top : undefined;
0099                     anchors.bottom: root.location === PlasmaCore.Types.BottomEdge ? parent.bottom : undefined;
0100                 }
0101             },
0102 
0103             State{
0104                 name: "animating"
0105                 when: !taskItem.inAddRemoveAnimation && (launcherAnimation.running || newWindowAnimation.running)
0106 
0107                 AnchorChanges{
0108                     target: taskIconItem;
0109                     anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined;
0110                     anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined;
0111                     anchors.right: root.location === PlasmaCore.Types.LeftEdge ? parent.right : undefined;
0112                     anchors.left: root.location === PlasmaCore.Types.RightEdge ? parent.left : undefined;
0113                     anchors.top: root.location === PlasmaCore.Types.BottomEdge ? parent.top : undefined;
0114                     anchors.bottom: root.location === PlasmaCore.Types.TopEdge ? parent.bottom : undefined;
0115                 }
0116             }
0117         ]
0118 
0119         ///transitions, basic for the anchor changes
0120         transitions: [
0121             Transition{
0122                 from: "animating"
0123                 to: "*"
0124                 AnchorAnimation { duration: 1.5 * taskItem.abilities.animations.speedFactor.current * taskItem.abilities.animations.duration.large }
0125             }
0126         ]
0127     }
0128 
0129     //! Combined Loader for Progress and Audio badges masks
0130     Loader{
0131         id: badgesLoader
0132         anchors.fill: taskIconContainer
0133         active: (activateProgress > 0) && taskItem.abilities.environment.isGraphicsSystemAccelerated
0134         asynchronous: true
0135         opacity: stateColorizer.opacity > 0 ? 0 : 1
0136 
0137         property real activateProgress: showInfo || showProgress || showAudio ? 1 : 0
0138 
0139         property bool showInfo: (root.showInfoBadge
0140                                  && taskIcon.smartLauncherItem
0141                                  && (taskIcon.smartLauncherItem.countVisible || taskItem.badgeIndicator > 0)
0142                                  && !showProgress)
0143 
0144         property bool showProgress: root.showProgressBadge
0145                                     && taskIcon.smartLauncherItem
0146                                     && taskIcon.smartLauncherItem.progressVisible
0147 
0148         property bool showAudio: (root.showAudioBadge && taskItem.hasAudioStream && taskItem.playingAudio)
0149 
0150         Behavior on activateProgress {
0151             NumberAnimation { duration: 2 * taskItem.abilities.animations.speedFactor.current * taskItem.abilities.animations.duration.large }
0152         }
0153 
0154         sourceComponent: Item{
0155             ShaderEffect {
0156                 id: iconOverlay
0157                 enabled: false
0158                 anchors.fill: parent
0159                 property var source: ShaderEffectSource {
0160                     sourceItem: Kirigami.Icon{
0161                         width: taskIconItem.width
0162                         height: taskIconItem.height
0163                         smooth: taskIconItem.smooth
0164                         source: taskIconItem.source
0165                         //roundToIconSize: taskIconItem.roundToIconSize
0166                         active: taskIconItem.active
0167 
0168                         Loader{
0169                             anchors.fill: parent
0170                             active: plasmoid.configuration.forceMonochromaticIcons
0171 
0172                             sourceComponent: ColorOverlay {
0173                                 anchors.fill: parent
0174                                 color: latteBridge ? latteBridge.palette.textColor : "transparent"
0175                                 source: taskIconItem
0176                             }
0177                         }
0178                     }
0179                 }
0180                 property var mask: ShaderEffectSource {
0181                     sourceItem: Item{
0182                         LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft && !root.vertical
0183                         LayoutMirroring.childrenInherit: true
0184 
0185                         width: taskIconContainer.width
0186                         height: taskIconContainer.height
0187 
0188                         Rectangle{
0189                             id: maskRect
0190                             width: Math.max(badgeVisualsLoader.infoBadgeWidth, parent.width / 2)
0191                             height: parent.height / 2
0192                             radius: parent.height
0193                             visible: badgesLoader.showInfo || badgesLoader.showProgress
0194 
0195                             //! Removes any remainings from the icon around the roundness at the corner
0196                             Rectangle{
0197                                 id: maskCorner
0198                                 width: parent.width/2
0199                                 height: parent.height/2
0200                             }
0201 
0202                             states: [
0203                                 State {
0204                                     name: "default"
0205                                     when: (root.location !== PlasmaCore.Types.RightEdge)
0206 
0207                                     AnchorChanges {
0208                                         target: maskRect
0209                                         anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right;}
0210                                     }
0211                                     AnchorChanges {
0212                                         target: maskCorner
0213                                         anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right;}
0214                                     }
0215                                 },
0216                                 State {
0217                                     name: "right"
0218                                     when: (root.location === PlasmaCore.Types.RightEdge)
0219 
0220                                     AnchorChanges {
0221                                         target: maskRect
0222                                         anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined;}
0223                                     }
0224                                     AnchorChanges {
0225                                         target: maskCorner
0226                                         anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined;}
0227                                     }
0228                                 }
0229                             ]
0230                         } // progressMask
0231 
0232                         Rectangle{
0233                             id: maskRect2
0234                             width: parent.width/2
0235                             height: width
0236                             radius: width
0237                             visible: badgesLoader.showAudio
0238 
0239                             Rectangle{
0240                                 id: maskCorner2
0241                                 width:parent.width/2
0242                                 height:parent.height/2
0243                             }
0244 
0245                             states: [
0246                                 State {
0247                                     name: "default"
0248                                     when: (root.location !== PlasmaCore.Types.RightEdge)
0249 
0250                                     AnchorChanges {
0251                                         target: maskRect2
0252                                         anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined;}
0253                                     }
0254                                     AnchorChanges {
0255                                         target: maskCorner2
0256                                         anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined;}
0257                                     }
0258                                 },
0259                                 State {
0260                                     name: "right"
0261                                     when: (root.location === PlasmaCore.Types.RightEdge)
0262 
0263                                     AnchorChanges {
0264                                         target: maskRect2
0265                                         anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right;}
0266                                     }
0267                                     AnchorChanges {
0268                                         target: maskCorner2
0269                                         anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right;}
0270                                     }
0271                                 }
0272                             ]
0273                         } // audio mask
0274                     }
0275                     hideSource: true
0276                     live: true
0277                 } //end of mask
0278 
0279                 supportsAtlasTextures: true
0280 
0281                 fragmentShader: "
0282         varying highp vec2 qt_TexCoord0;
0283         uniform highp float qt_Opacity;
0284         uniform lowp sampler2D source;
0285         uniform lowp sampler2D mask;
0286         void main() {
0287             gl_FragColor = texture2D(source, qt_TexCoord0.st) * (1.0 - (texture2D(mask, qt_TexCoord0.st).a)) * qt_Opacity;
0288         }
0289     "
0290             } //end of sourceComponent
0291         }
0292     }
0293     ////!
0294 
0295     //! START: Badges Visuals
0296     //! the badges visual get out from iconGraphic in order to be able to draw shadows that
0297     //! extend beyond the iconGraphic boundaries
0298     Loader {
0299         id: badgeVisualsLoader
0300         anchors.fill: taskIconContainer
0301         active: (badgesLoader.activateProgress > 0)
0302 
0303         readonly property int infoBadgeWidth: active ? publishedInfoBadgeWidth : 0
0304         property int publishedInfoBadgeWidth: 0
0305 
0306         sourceComponent: Item {
0307             ProgressOverlay{
0308                 id: infoBadge
0309                 anchors.right: parent.right
0310                 anchors.top: parent.top
0311                 width: Math.max(parent.width, contentWidth)
0312                 height: parent.height
0313 
0314                 opacity: badgesLoader.activateProgress
0315                 visible: badgesLoader.showInfo || badgesLoader.showProgress
0316             }
0317 
0318             AudioStream{
0319                 id: audioStreamBadge
0320                 anchors.fill: parent
0321                 opacity: badgesLoader.activateProgress
0322                 visible: badgesLoader.showAudio
0323             }
0324 
0325             Binding {
0326                 target: badgeVisualsLoader
0327                 property: "publishedInfoBadgeWidth"
0328                 value: infoBadge.contentWidth
0329             }
0330         }
0331     }
0332 
0333     //! GREY-ing the information badges when the task is dragged
0334     //! moved out of badgeVisualsLoader in order to avoid crashes
0335     //! when the latte view is removed
0336     Loader {
0337         anchors.fill: parent
0338         active: badgeVisualsLoader.active
0339                 && taskItem.abilities.environment.isGraphicsSystemAccelerated
0340         sourceComponent: Colorize{
0341             source: badgeVisualsLoader.item
0342 
0343             //! HACK TO AVOID PIXELIZATION
0344             //! WORKAROUND: When Effects are enabled e.g. BrightnessContrast, Colorize etc.
0345             //! the icon appears pixelated. It is even most notable when parabolic.factor.zoom === 1
0346             //! I don't know enabling cached=true helps, but it does.
0347             //! In Question?
0348             //cached: true
0349 
0350             opacity: stateColorizer.opacity
0351             hue: stateColorizer.hue
0352             saturation: stateColorizer.saturation
0353             lightness: stateColorizer.lightness
0354         }
0355     }
0356     //! END: Badges Visuals
0357 
0358     //! Effects
0359     Colorize{
0360         id: stateColorizer
0361         anchors.fill: parent
0362         source: badgesLoader.active ? badgesLoader : taskIconItem
0363 
0364         opacity:0
0365 
0366         hue:0
0367         saturation:0
0368         lightness:0
0369     }
0370 
0371     BrightnessContrast{
0372         id:hoveredImage
0373         anchors.fill: parent
0374 
0375         //! HACK TO AVOID PIXELIZATION
0376         //! WORKAROUND: When Effects are enabled e.g. BrightnessContrast, Colorize etc.
0377         //! the icon appears pixelated. It is even most notable when parabolic.factor.zoom === 1
0378         //! I don't know enabling cached=true helps, but it does.
0379         //! In Question?
0380         //cached: true
0381 
0382         source: badgesLoader.active ? badgesLoader : taskIconItem
0383 
0384         opacity: taskItem.containsMouse && !clickedAnimation.running && !taskItem.abilities.indicators.info.providesHoveredAnimation ? 1 : 0
0385         brightness: 0.30
0386         contrast: 0.1
0387 
0388         Behavior on opacity {
0389             NumberAnimation { duration: taskItem.abilities.animations.speedFactor.current * taskItem.abilities.animations.duration.large }
0390         }
0391     }
0392 
0393     BrightnessContrast {
0394         id: brightnessTaskEffect
0395         anchors.fill: parent
0396 
0397         //! HACK TO AVOID PIXELIZATION
0398         //! WORKAROUND: When Effects are enabled e.g. BrightnessContrast, Colorize etc.
0399         //! the icon appears pixelated. It is even most notable when parabolic.factor.zoom === 1
0400         //! I don't know enabling cached=true helps, but it does.
0401         //! In Question?
0402         //cached: true
0403 
0404         source: badgesLoader.active ? badgesLoader : taskIconItem
0405 
0406         visible: clickedAnimation.running
0407     }
0408     //! Effects
0409 
0410     Loader {
0411         id: dropFilesVisual
0412         active: applyOpacity>0
0413 
0414         width: !root.vertical ? length : thickness
0415         height: !root.vertical ? thickness : length
0416         anchors.centerIn: parent
0417 
0418         readonly property int length: taskItem.abilities.metrics.totals.length
0419         readonly property int thickness: taskItem.abilities.metrics.totals.thickness
0420 
0421         readonly property real applyOpacity: (mouseHandler.isDroppingSeparator || mouseHandler.isDroppingFiles)
0422                                              && (root.dragSource === null)
0423                                              && (mouseHandler.hoveredItem === taskItem) ? 0.7 : 0
0424 
0425         sourceComponent: LatteComponents.AddItem {
0426             anchors.fill: parent
0427             backgroundOpacity: dropFilesVisual.applyOpacity
0428         }
0429     }
0430 
0431     //! Animations
0432     TaskAnimations.ClickedAnimation { id: clickedAnimation }
0433 
0434     TaskAnimations.LauncherAnimation { id:launcherAnimation }
0435 
0436     TaskAnimations.NewWindowAnimation { id: newWindowAnimation }
0437 
0438     TaskAnimations.RemoveWindowFromGroupAnimation { id: removingAnimation }
0439     //! Animations
0440 
0441     Component.onDestruction: {
0442         taskIcon.toBeDestroyed = true;
0443 
0444         if(removingAnimation.removingItem)
0445             removingAnimation.removingItem.destroy();
0446     }
0447 
0448     //////////// States ////////////////////
0449     states: [
0450         State{
0451             name: "*"
0452             //! since qt 5.14 default state can not use "when" property
0453             //! it breaks restoring transitions otherwise
0454         },
0455 
0456         State{
0457             name: "isDragged"
0458             when: taskItem.isDragged
0459         }
0460     ]
0461 
0462     //////////// Transitions //////////////
0463 
0464     readonly property string draggingNeedThicknessEvent: taskIcon + "_dragging"
0465 
0466     transitions: [
0467         Transition{
0468             id: isDraggedTransition
0469             to: "isDragged"
0470             property int speed: taskItem.abilities.animations.speedFactor.current * taskItem.abilities.animations.duration.large
0471 
0472             SequentialAnimation{
0473                 ScriptAction{
0474                     script: {
0475                         taskItem.abilities.animations.needThickness.addEvent(draggingNeedThicknessEvent);
0476                         taskItem.inBlockingAnimation = true;
0477                         taskItem.abilities.parabolic.setDirectRenderingEnabled(false);
0478                     }
0479                 }
0480 
0481                 PropertyAnimation {
0482                     target: taskItem.parabolicItem
0483                     property: "zoom"
0484                     to: 1
0485                     duration: taskItem.abilities.parabolic.factor.zoom === 1 ? 0 : (isDraggedTransition.speed*1.2)
0486                     easing.type: Easing.OutQuad
0487                 }
0488 
0489                 ParallelAnimation{
0490                     PropertyAnimation {
0491                         target: draggedRectangle
0492                         property: "opacity"
0493                         to: 1
0494                         duration: isDraggedTransition.speed
0495                         easing.type: Easing.OutQuad
0496                     }
0497 
0498                     PropertyAnimation {
0499                         target: taskIconItem
0500                         property: "opacity"
0501                         to: 0
0502                         duration: isDraggedTransition.speed
0503                         easing.type: Easing.OutQuad
0504                     }
0505 
0506                     PropertyAnimation {
0507                         target: stateColorizer
0508                         property: "opacity"
0509                         to: taskItem.isSeparator ? 0 : 1
0510                         duration: isDraggedTransition.speed
0511                         easing.type: Easing.OutQuad
0512                     }
0513                 }
0514 
0515                 ScriptAction{
0516                     script: {
0517                         taskItem.abilities.animations.needThickness.removeEvent(draggingNeedThicknessEvent);
0518                     }
0519                 }
0520             }
0521 
0522             onRunningChanged: {
0523                 if(running){
0524                     taskItem.animationStarted();
0525                 } else {
0526                     taskItem.abilities.animations.needThickness.removeEvent(draggingNeedThicknessEvent);
0527                 }
0528             }
0529         },
0530         Transition{
0531             id: defaultTransition
0532             from: "isDragged"
0533             to: "*"
0534             property int speed: taskItem.abilities.animations.speedFactor.current * taskItem.abilities.animations.duration.large
0535 
0536             SequentialAnimation{
0537                 ScriptAction{
0538                     script: {
0539                         taskItem.abilities.parabolic.setDirectRenderingEnabled(false);
0540                     }
0541                 }
0542 
0543                 ParallelAnimation{
0544                     PropertyAnimation {
0545                         target: draggedRectangle
0546                         property: "opacity"
0547                         to: 0
0548                         duration: defaultTransition.speed
0549                         easing.type: Easing.OutQuad
0550                     }
0551 
0552                     PropertyAnimation {
0553                         target: taskIconItem
0554                         property: "opacity"
0555                         to: 1
0556                         duration: defaultTransition.speed
0557                         easing.type: Easing.OutQuad
0558                     }
0559 
0560                     PropertyAnimation {
0561                         target: stateColorizer
0562                         property: "opacity"
0563                         to: 0
0564                         duration: isDraggedTransition.speed
0565                         easing.type: Easing.OutQuad
0566                     }
0567                 }
0568 
0569                 ScriptAction{
0570                     script: {
0571                         taskItem.inBlockingAnimation = false;
0572                     }
0573                 }
0574             }
0575 
0576             onRunningChanged: {
0577                 if(!running){
0578                     taskItem.animationEnded();
0579                 }
0580             }
0581         }
0582     ]
0583 }