diff --git a/containment/package/contents/ui/applet/indicator/Bridge.qml b/containment/package/contents/ui/applet/indicator/Bridge.qml index eccf1fc4..48435d3d 100644 --- a/containment/package/contents/ui/applet/indicator/Bridge.qml +++ b/containment/package/contents/ui/applet/indicator/Bridge.qml @@ -1,94 +1,97 @@ /* * 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.7 import org.kde.latte 0.2 as Latte Item{ id: indicatorBridge anchors.fill: parent property bool appletIsValid: true readonly property bool active: appletIsValid && ((indicators.isEnabled && appletItem.communicatorAlias.activeIndicatorEnabled && indicators.enabledForApplets) || (!indicators.enabledForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive)) /* Indicators Properties in order use them*/ readonly property bool isTask: false readonly property bool isApplet: true readonly property bool isLauncher: false readonly property bool isStartup: false readonly property bool isWindow: false readonly property bool isActive: appletIsValid ? appletItem.isActive : false readonly property bool isGroup: false readonly property bool isHovered: appletIsValid ? appletMouseArea.containsMouse : false readonly property bool isMinimized: false readonly property bool isPressed: appletIsValid ? appletMouseArea.pressed : false readonly property bool inAttention: false readonly property bool inRemoving: false readonly property bool isSquare: appletIsValid ? appletItem.isSquare : true readonly property bool hasActive: isActive readonly property bool hasMinimized: false readonly property bool hasShown: false readonly property int windowsCount: 0 readonly property int windowsMinimizedCount: 0 readonly property int currentIconSize: root.iconSize readonly property int maxIconSize: root.maxIconSize readonly property real scaleFactor: appletIsValid ? appletItem.wrapperAlias.zoomScale : 1 readonly property real panelOpacity: root.currentPanelOpacity readonly property color shadowColor: root.appShadowColorSolid readonly property bool animationsEnabled: root.animationsEnabled readonly property real durationTime: root.durationTime + readonly property bool progressVisible: false /*since 0.9.2*/ + readonly property real progress: 0 /*since 0.9.2*/ + readonly property bool usePlasmaTabsStyle: !indicators.enabledForApplets readonly property QtObject palette: colorizerManager.applyTheme //!icon colors property color iconBackgroundColor: { if (appletIsValid) { return isSquare ? appletItem.wrapperAlias.overlayIconLoader.backgroundColor : colorizerManager.buttonFocusColor; } return "black"; } property color iconGlowColor:{ if (appletIsValid) { return isSquare ? appletItem.wrapperAlias.overlayIconLoader.glowColor : colorizerManager.focusGlowColor; } return "white"; } //! grouped options readonly property Item shared: indicators readonly property QtObject configuration: indicators.configuration readonly property QtObject resources: indicators.resources } diff --git a/indicators/org.kde.latte.plasma/package/ui/BackLayer.qml b/indicators/org.kde.latte.plasma/package/ui/BackLayer.qml index 0f61c834..e9596480 100644 --- a/indicators/org.kde.latte.plasma/package/ui/BackLayer.qml +++ b/indicators/org.kde.latte.plasma/package/ui/BackLayer.qml @@ -1,132 +1,110 @@ /* * 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.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.latte 0.2 as Latte PlasmaCore.FrameSvgItem { id: frame property string basePrefix: "normal" imagePath: indicator.usePlasmaTabsStyle ? "widgets/tabbar" : "widgets/tasks" rotation: root.reversedEnabled ? 180 : 0 opacity: 1 //state === "hovered" ? 0.9 : 1 prefix: { if (indicator.usePlasmaTabsStyle) { if (!indicator.isActive) { return ""; } if (plasmoid.location === PlasmaCore.Types.LeftEdge) { return "west-active-tab"; } if (plasmoid.location === PlasmaCore.Types.TopEdge) { return "north-active-tab"; } if (plasmoid.location === PlasmaCore.Types.RightEdge) { return "east-active-tab"; } if (plasmoid.location === PlasmaCore.Types.BottomEdge) { return "south-active-tab"; } return "south-active-tab"; } else { - return taskPrefix(basePrefix); + return root.taskPrefix(basePrefix); } } - function taskPrefix(prefix) { - var effectivePrefix; - - if (plasmoid.location === PlasmaCore.Types.LeftEdge) { - effectivePrefix = "west-" + prefix; - } - - if (plasmoid.location === PlasmaCore.Types.TopEdge) { - effectivePrefix = "north-" + prefix; - } - - if (plasmoid.location === PlasmaCore.Types.RightEdge) { - effectivePrefix = "east-" + prefix; - } - - if (plasmoid.location === PlasmaCore.Types.BottomEdge) { - effectivePrefix = "south-" + prefix; - } - - return [effectivePrefix, prefix]; - } - states: [ State { name: "launcher" when: indicator.isLauncher || (indicator.isApplet && !indicator.isActive) PropertyChanges { target: frame basePrefix: "" } }, State { name: "hovered" when: indicator.isHovered && frame.hasElementPrefix("hover") PropertyChanges { target: frame basePrefix: "hover" } }, State { name: "attention" when: indicator.inAttention PropertyChanges { target: frame basePrefix: "attention" } }, State { name: "minimized" when: indicator.isMinimized PropertyChanges { target: frame basePrefix: "minimized" } }, State { name: "active" when: indicator.isActive PropertyChanges { target: frame basePrefix: "focus" } } ] } diff --git a/indicators/org.kde.latte.plasma/package/ui/main.qml b/indicators/org.kde.latte.plasma/package/ui/main.qml index 54c70a7c..170619da 100644 --- a/indicators/org.kde.latte.plasma/package/ui/main.qml +++ b/indicators/org.kde.latte.plasma/package/ui/main.qml @@ -1,64 +1,117 @@ /* * 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.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.latte 0.2 as Latte import org.kde.latte.components 1.0 as LatteComponents LatteComponents.IndicatorItem { id: root needsMouseEventCoordinates: true providesClickedAnimation: clickedAnimationEnabled //providesHoveredAnimation: true providesFrontLayer: true svgImagePaths: ["widgets/tasks"] //! config options readonly property bool clickedAnimationEnabled: indicator && indicator.configuration && indicator.configuration.clickedAnimationEnabled !== undefined && indicator.configuration.clickedAnimationEnabled readonly property bool reversedEnabled: indicator && indicator.configuration && indicator.configuration.reversed !== undefined && indicator.configuration.reversed //! Background Layer Loader{ id: backLayer anchors.fill: parent active: level.isBackground sourceComponent: BackLayer{} } + /* progress overlay for BackLayer*/ + /* it is not added in the BackLayer because the BackLayer is rotated in some cases*/ + Loader { + anchors.fill: parent + asynchronous: true + active: level.isBackground && indicator.progressVisible + sourceComponent: Item { + id: background + + Item { + anchors { + top: parent.top + left: parent.left + bottom: parent.bottom + } + + width: parent.width * (Math.min(indicator.progress, 100) / 100) + clip: true + + PlasmaCore.FrameSvgItem { + id: progressFrame + width: background.width + height: background.height + + imagePath: "widgets/tasks" + prefix: root.taskPrefix("progress").concat(root.taskPrefix("hover")) + } + } + } + } + //! Foreground Layer to draw arrows Loader{ id: frontLayer anchors.fill: parent active: (level.isForeground && !indicator.isApplet && indicator.isGroup) || providesClickedAnimation sourceComponent: FrontLayer{} } + + function taskPrefix(prefix) { + var effectivePrefix; + + if (plasmoid.location === PlasmaCore.Types.LeftEdge) { + effectivePrefix = "west-" + prefix; + } + + if (plasmoid.location === PlasmaCore.Types.TopEdge) { + effectivePrefix = "north-" + prefix; + } + + if (plasmoid.location === PlasmaCore.Types.RightEdge) { + effectivePrefix = "east-" + prefix; + } + + if (plasmoid.location === PlasmaCore.Types.BottomEdge) { + effectivePrefix = "south-" + prefix; + } + + return [effectivePrefix, prefix]; + } } diff --git a/plasmoid/package/contents/ui/task/IconItem.qml b/plasmoid/package/contents/ui/task/IconItem.qml index 9b24856e..b6b64349 100644 --- a/plasmoid/package/contents/ui/task/IconItem.qml +++ b/plasmoid/package/contents/ui/task/IconItem.qml @@ -1,808 +1,810 @@ /* * 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.4 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.plasma.private.taskmanager 0.1 as TaskManagerApplet import org.kde.kquickcontrolsaddons 2.0 as KQuickControlAddons import org.kde.latte 0.2 as Latte import org.kde.latte.components 1.0 as LatteComponents import "animations" as TaskAnimations //I am using KQuickControlAddons.QIconItem even though onExit it triggers the following error //QObject::~QObject: Timers cannot be stopped from another thread //but it increases performance almost to double during animation Item{ id: taskIcon width: wrapper.regulatorWidth height: wrapper.regulatorHeight //big interval to show shadows only after all the crappy adds and removes of tasks //have happened property bool firstDrawed: true property bool toBeDestroyed: false // three intervals in order to create the necessary buffers from the // PlasmaCore.IconItem, one big interval for the first creation of the // plasmoid, a second one for the first creation of a task and a small one // for simple updates. // This is done before especially on initialization stage some visuals // are not ready and empty buffers are created //property int firstDrawedInterval: root.initializationStep ? 2000 : 1000 // property int shadowInterval: firstDrawed ? firstDrawedInterval : 250 property int shadowInterval: firstDrawed ? 1000 : 250 property int shadowSize : root.appShadowSize readonly property bool smartLauncherEnabled: ((taskItem.isStartup === false) && (root.showInfoBadge || root.showProgressBadge)) readonly property variant iconDecoration: decoration readonly property color backgroundColor: iconImageBuffer.backgroundColor readonly property color glowColor: iconImageBuffer.glowColor + readonly property bool progressVisible: smartLauncherItem && smartLauncherItem.progressVisible + readonly property real progress: smartLauncherItem && smartLauncherItem.progress property QtObject buffers: null property QtObject smartLauncherItem: null property Item visualIconItem: iconImageBuffer property Item titleTooltipVisualParent: titleTooltipParent property Item previewsTootipVisualParent: previewsTooltipParent /* Rectangle{ anchors.fill: parent border.width: 1 border.color: "green" color: "transparent" } */ onSmartLauncherEnabledChanged: { if (smartLauncherEnabled && !smartLauncherItem) { var smartLauncher = Qt.createQmlObject( " import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet; TaskManagerApplet.SmartLauncherItem { }", taskIcon); smartLauncher.launcherUrl = Qt.binding(function() { return taskItem.launcherUrlWithIcon; }); smartLauncherItem = smartLauncher; } else if (!smartLauncherEnabled && smartLauncherItem) { smartLauncherItem.destroy(); smartLauncherItem = null; } } Rectangle{ id: draggedRectangle width: taskItem.isSeparator ? parent.width + 1 : iconImageBuffer.width+1 height: taskItem.isSeparator ? parent.height + 1 : iconImageBuffer.height+1 anchors.centerIn: iconGraphic opacity: 0 radius: 3 anchors.margins: 5 property color tempColor: theme.highlightColor color: tempColor border.width: 1 border.color: theme.highlightColor onTempColorChanged: tempColor.a = 0.35; } TitleTooltipParent{ id: titleTooltipParent thickness: root.zoomFactor * (root.iconSize + root.thickMargins) } TitleTooltipParent{ id: previewsTooltipParent thickness: root.zoomFactor * (root.iconSize + root.thickMargins) + 1 } // KQuickControlAddons.QIconItem{ Item{ id: iconGraphic width: parent.width height: parent.height //fix bug #478, when changing form factor sometimes the tasks are not positioned //correctly, in such case we make a fast reinitialization for the sizes Connections { target: plasmoid onFormFactorChanged:{ taskItem.inAddRemoveAnimation = false; wrapper.mScale = 1.01; wrapper.tempScaleWidth = 1.01; wrapper.tempScaleHeight = 1.01; wrapper.mScale = 1; wrapper.tempScaleWidth = 1; wrapper.tempScaleHeight = 1; } } Latte.IconItem{ id: iconImageBuffer anchors.centerIn: parent width: Math.round(newTempSize) height: Math.round(width) source: decoration smooth: root.zoomFactor === 1 ? true : false providesColors: indicators ? indicators.info.needsIconColors : false opacity: root.enableShadows && taskWithShadow.active && (taskWithShadow.item.status === ShaderEffect.Compiled) ? 0 : 1 visible: !taskItem.isSeparator && !badgesLoader.active onValidChanged: { if (!valid && (source === decoration || source === "unknown")) { source = "application-x-executable"; } } //! try to show the correct icon when a window is removed... libtaskmanager when a window is removed //! sends an unknown pixmap as icon Connections { target: taskItem onInRemoveStageChanged: { if (taskItem.inRemoveStage && iconImageBuffer.lastValidSourceName !== "") { iconImageBuffer.source = iconImageBuffer.lastValidSourceName; } } } property int zoomedSize: root.zoomFactor * root.iconSize property real basicScalingWidth : wrapper.inTempScaling ? (root.iconSize * wrapper.scaleWidth) : root.iconSize * wrapper.mScale property real basicScalingHeight : wrapper.inTempScaling ? (root.iconSize * wrapper.scaleHeight) : root.iconSize * wrapper.mScale property real newTempSize: { if (wrapper.opacity == 1) return Math.min(basicScalingWidth, basicScalingHeight) else return Math.max(basicScalingWidth, basicScalingHeight) } //! Latte Side Painting-style if the user chose it Loader{ anchors.fill: iconImageBuffer active: plasmoid.configuration.forceMonochromaticIcons sourceComponent: ColorOverlay { anchors.fill: parent color: latteBridge ? latteBridge.palette.textColor : "transparent" source: iconImageBuffer } } //! Latte Side Painting-style if the user chose it ///states for launcher animation states: [ State{ name: "*" when: !launcherAnimation.running && !newWindowAnimation.running && !taskItem.inAddRemoveAnimation && !fastRestoreAnimation.running AnchorChanges{ target:iconImageBuffer; anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined; anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined; anchors.right: root.position === PlasmaCore.Types.RightPositioned ? parent.right : undefined; anchors.left: root.position === PlasmaCore.Types.LeftPositioned ? parent.left : undefined; anchors.top: root.position === PlasmaCore.Types.TopPositioned ? parent.top : undefined; anchors.bottom: root.position === PlasmaCore.Types.BottomPositioned ? parent.bottom : undefined; } }, State{ name: "inAddRemoveAnimation" when: taskItem.inAddRemoveAnimation AnchorChanges{ target:iconImageBuffer; anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined; anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined; anchors.right: root.position === PlasmaCore.Types.LeftPositioned ? parent.right : undefined; anchors.left: root.position === PlasmaCore.Types.RightPositioned ? parent.left : undefined; anchors.top: root.position === PlasmaCore.Types.BottomPositioned ? parent.top : undefined; anchors.bottom: root.position === PlasmaCore.Types.TopPositioned ? parent.bottom : undefined; } }, State{ name: "animating" when: (launcherAnimation.running || newWindowAnimation.running || fastRestoreAnimation.running) && !taskItem.inAddRemoveAnimation AnchorChanges{ target:iconImageBuffer; anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined; anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined; anchors.right: root.position === PlasmaCore.Types.LeftPositioned ? parent.right : undefined; anchors.left: root.position === PlasmaCore.Types.RightPositioned ? parent.left : undefined; anchors.top: root.position === PlasmaCore.Types.BottomPositioned ? parent.top : undefined; anchors.bottom: root.position === PlasmaCore.Types.TopPositioned ? parent.bottom : undefined; } } ] ///transitions, basic for the anchor changes transitions: [ Transition{ from: "animating" to: "*" enabled: !fastRestoreAnimation.running && !taskItem.inMimicParabolicAnimation AnchorAnimation { duration: 1.5*root.durationTime*units.longDuration } } ] } //IconImageBuffer //! Shadows Loader{ id: taskWithShadow anchors.fill: iconImageBuffer active: root.enableShadows && !taskItem.isSeparator sourceComponent: DropShadow{ anchors.fill: parent color: root.appShadowColor fast: true samples: 2 * radius source: badgesLoader.active ? badgesLoader.item : iconImageBuffer radius: root.appShadowSize verticalOffset: 2 } } //! Shadows //! Combined Loader for Progress and Audio badges masks Loader{ id: badgesLoader anchors.fill: iconImageBuffer active: activateProgress > 0 asynchronous: true opacity: stateColorizer.opacity > 0 ? 0 : 1 property real activateProgress: showInfo || showProgress || showAudio ? 1 : 0 property bool showInfo: (root.showInfoBadge && taskIcon.smartLauncherItem && !taskItem.isSeparator && (taskIcon.smartLauncherItem.countVisible || taskItem.badgeIndicator > 0)) property bool showProgress: root.showProgressBadge && taskIcon.smartLauncherItem && !taskItem.isSeparator && taskIcon.smartLauncherItem.progressVisible property bool showAudio: (root.showAudioBadge && taskItem.hasAudioStream && taskItem.playingAudio && !taskItem.isSeparator) && !shortcutBadge.active Behavior on activateProgress { NumberAnimation { duration: root.durationTime*2*units.longDuration } } sourceComponent: Item{ ShaderEffect { id: iconOverlay enabled: false anchors.fill: parent property var source: ShaderEffectSource { sourceItem: Latte.IconItem{ width: iconImageBuffer.width height: iconImageBuffer.height source: iconImageBuffer.source Loader{ anchors.fill: parent active: plasmoid.configuration.forceMonochromaticIcons sourceComponent: ColorOverlay { anchors.fill: parent color: latteBridge ? latteBridge.palette.textColor : "transparent" source: iconImageBuffer } } } } property var mask: ShaderEffectSource { sourceItem: Item{ LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft && !root.vertical LayoutMirroring.childrenInherit: true width: iconImageBuffer.width height: iconImageBuffer.height Rectangle{ id: maskRect width: Math.max(badgeVisualsLoader.infoBadgeWidth, parent.width / 2) height: parent.height / 2 radius: parent.height visible: badgesLoader.showInfo || badgesLoader.showProgress //! Removes any remainings from the icon around the roundness at the corner Rectangle{ id: maskCorner width: parent.width/2 height: parent.height/2 } states: [ State { name: "default" when: (plasmoid.location !== PlasmaCore.Types.RightEdge) AnchorChanges { target: maskRect anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right;} } AnchorChanges { target: maskCorner anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right;} } }, State { name: "right" when: (plasmoid.location === PlasmaCore.Types.RightEdge) AnchorChanges { target: maskRect anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined;} } AnchorChanges { target: maskCorner anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined;} } } ] } // progressMask Rectangle{ id: maskRect2 width: parent.width/2 height: width radius: width visible: badgesLoader.showAudio Rectangle{ id: maskCorner2 width:parent.width/2 height:parent.height/2 } states: [ State { name: "default" when: (plasmoid.location !== PlasmaCore.Types.RightEdge) AnchorChanges { target: maskRect2 anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined;} } AnchorChanges { target: maskCorner2 anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined;} } }, State { name: "right" when: (plasmoid.location === PlasmaCore.Types.RightEdge) AnchorChanges { target: maskRect2 anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right;} } AnchorChanges { target: maskCorner2 anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right;} } } ] } // audio mask } hideSource: true live: true } //end of mask supportsAtlasTextures: true fragmentShader: " varying highp vec2 qt_TexCoord0; uniform highp float qt_Opacity; uniform lowp sampler2D source; uniform lowp sampler2D mask; void main() { gl_FragColor = texture2D(source, qt_TexCoord0.st) * (1.0 - (texture2D(mask, qt_TexCoord0.st).a)) * qt_Opacity; } " } //end of sourceComponent } } ////! //! START: Badges Visuals //! the badges visual get out from iconGraphic in order to be able to draw shadows that //! extend beyond the iconGraphic boundaries Loader { id: badgeVisualsLoader anchors.fill: iconImageBuffer active: badgesLoader.active readonly property int infoBadgeWidth: active ? publishedInfoBadgeWidth : 0 property int publishedInfoBadgeWidth: 0 sourceComponent: Item { ProgressOverlay{ id: infoBadge anchors.right: parent.right anchors.top: parent.top width: Math.max(parent.width, contentWidth) height: parent.height opacity: badgesLoader.activateProgress visible: badgesLoader.showInfo || badgesLoader.showProgress layer.enabled: root.enableShadows layer.effect: DropShadow { color: root.appShadowColor fast: true samples: 2 * radius source: infoBadge radius: root.appShadowSize verticalOffset: 2 } } AudioStream{ id: audioStreamBadge anchors.fill: parent opacity: badgesLoader.activateProgress visible: badgesLoader.showAudio layer.enabled: root.enableShadows layer.effect: DropShadow { color: root.appShadowColor fast: true samples: 2 * radius source: audioStreamBadge radius: root.appShadowSize verticalOffset: 2 } } Binding { target: badgeVisualsLoader property: "publishedInfoBadgeWidth" value: infoBadge.contentWidth } } } //! GREY-ing the information badges when the task is dragged //! moved out of badgeVisualsLoader in order to avoid crashes //! when the latte view is removed Loader { width: iconImageBuffer.width height: iconImageBuffer.height anchors.centerIn: iconImageBuffer active: badgeVisualsLoader.active sourceComponent: Colorize{ source: badgeVisualsLoader.item //! HACK TO AVOID PIXELIZATION //! WORKAROUND: When Effects are enabled e.g. BrightnessContrast, Colorize etc. //! the icon appears pixelated. It is even most notable when zoomFactor === 1 //! I don't know enabling cached=true helps, but it does. cached: true opacity: stateColorizer.opacity hue: stateColorizer.hue saturation: stateColorizer.saturation lightness: stateColorizer.lightness } } //! END: Badges Visuals //! Effects Colorize{ id: stateColorizer anchors.centerIn: iconImageBuffer width: iconImageBuffer.width height: iconImageBuffer.height //! HACK TO AVOID PIXELIZATION //! WORKAROUND: When Effects are enabled e.g. BrightnessContrast, Colorize etc. //! the icon appears pixelated. It is even most notable when zoomFactor === 1 //! I don't know enabling cached=true helps, but it does. cached: true source: badgesLoader.active ? badgesLoader : iconImageBuffer visible: !isSeparator opacity:0 hue:0 saturation:0 lightness:0 } BrightnessContrast{ id:hoveredImage anchors.centerIn: iconImageBuffer width: iconImageBuffer.width height: iconImageBuffer.height //! HACK TO AVOID PIXELIZATION //! WORKAROUND: When Effects are enabled e.g. BrightnessContrast, Colorize etc. //! the icon appears pixelated. It is even most notable when zoomFactor === 1 //! I don't know enabling cached=true helps, but it does. cached: true source: badgesLoader.active ? badgesLoader : iconImageBuffer visible: !isSeparator opacity: taskItem.containsMouse && !clickedAnimation.running && !indicators.info.providesHoveredAnimation ? 1 : 0 brightness: 0.30 contrast: 0.1 Behavior on opacity { NumberAnimation { duration: root.durationTime*units.longDuration } } } BrightnessContrast { id: brightnessTaskEffect anchors.centerIn: iconImageBuffer width: iconImageBuffer.width height: iconImageBuffer.height //! HACK TO AVOID PIXELIZATION //! WORKAROUND: When Effects are enabled e.g. BrightnessContrast, Colorize etc. //! the icon appears pixelated. It is even most notable when zoomFactor === 1 //! I don't know enabling cached=true helps, but it does. cached: true source: badgesLoader.active ? badgesLoader : iconImageBuffer visible: clickedAnimation.running && !isSeparator } //! Effects ShortcutBadge{ id: shortcutBadge } } Loader { id: dropFilesVisual active: applyOpacity>0 width: !root.vertical ? length : thickness height: !root.vertical ? thickness : length anchors.centerIn: parent readonly property int length: root.iconSize + root.lengthMargins readonly property int thickness: root.iconSize + root.thickMargins readonly property real applyOpacity: root.dropNewLauncher && !mouseHandler.onlyLaunchers && (root.dragSource == null) && (mouseHandler.hoveredItem === taskItem) ? 0.7 : 0 sourceComponent: LatteComponents.AddItem { anchors.fill: parent backgroundOpacity: dropFilesVisual.applyOpacity } } Component.onDestruction: { taskIcon.toBeDestroyed = true; if(removingAnimation.removingItem) removingAnimation.removingItem.destroy(); } Connections{ target: taskItem onInAttentionChanged:{ if (!taskItem.inAttention && newWindowAnimation.running && taskItem.inAttentionAnimation) { newWindowAnimation.pause(); fastRestoreAnimation.start(); } } } ///// Animations ///// TaskAnimations.ClickedAnimation { id: clickedAnimation } TaskAnimations.LauncherAnimation { id:launcherAnimation } TaskAnimations.NewWindowAnimation { id: newWindowAnimation } TaskAnimations.RemoveWindowFromGroupAnimation { id: removingAnimation } TaskAnimations.FastRestoreAnimation { id: fastRestoreAnimation } //////////// States //////////////////// states: [ State{ name: "*" when: !taskItem.isDragged }, State{ name: "isDragged" when: ( (taskItem.isDragged) && (!root.inConfigureAppletsMode) ) } ] //////////// Transitions ////////////// transitions: [ Transition{ id: isDraggedTransition to: "isDragged" property int speed: root.durationTime*units.longDuration SequentialAnimation{ ScriptAction{ script: { icList.directRender = false; if(latteView) { latteView.globalDirectRender=false; } taskItem.inBlockingAnimation = true; root.clearZoom(); } } PropertyAnimation { target: wrapper property: "mScale" to: 1 + ((root.zoomFactor - 1) / 3) duration: isDraggedTransition.speed / 2 easing.type: Easing.OutQuad } ParallelAnimation{ PropertyAnimation { target: draggedRectangle property: "opacity" to: 1 duration: isDraggedTransition.speed easing.type: Easing.OutQuad } PropertyAnimation { target: iconImageBuffer property: "opacity" to: 0 duration: isDraggedTransition.speed easing.type: Easing.OutQuad } PropertyAnimation { target: stateColorizer property: "opacity" to: taskItem.isSeparator ? 0 : 1 duration: isDraggedTransition.speed easing.type: Easing.OutQuad } } } onRunningChanged: { if(running){ taskItem.animationStarted(); //root.animations++; parabolicManager.clearTasksGreaterThan(index); parabolicManager.clearTasksLowerThan(index); if (latteView){ latteView.parabolicManager.clearAppletsGreaterThan(latteView.latteAppletPos); latteView.parabolicManager.clearAppletsLowerThan(latteView.latteAppletPos); } } } }, Transition{ id: defaultTransition from: "isDragged" to: "*" property int speed: root.durationTime*units.longDuration SequentialAnimation{ ScriptAction{ script: { icList.directRender = false; if(latteView) { latteView.globalDirectRender=false; } } } ParallelAnimation{ PropertyAnimation { target: draggedRectangle property: "opacity" to: 0 duration: defaultTransition.speed easing.type: Easing.OutQuad } PropertyAnimation { target: iconImageBuffer property: "opacity" to: 1 duration: defaultTransition.speed easing.type: Easing.OutQuad } PropertyAnimation { target: stateColorizer property: "opacity" to: 0 duration: isDraggedTransition.speed easing.type: Easing.OutQuad } } /* PropertyAnimation { target: wrapper property: "mScale" to: 1; duration: isDraggedTransition.speed easing.type: Easing.OutQuad }*/ ScriptAction{ script: { taskItem.inBlockingAnimation = false; } } } onRunningChanged: { if(!running){ var halfZoom = 1 + ((root.zoomFactor - 1) / 2); wrapper.calculateScales((root.iconSize+root.thickMargins)/2); taskItem.animationEnded(); // root.animations--; } } } ] }// Icon Item diff --git a/plasmoid/package/contents/ui/task/Wrapper.qml b/plasmoid/package/contents/ui/task/Wrapper.qml index 02cca92b..e8593631 100644 --- a/plasmoid/package/contents/ui/task/Wrapper.qml +++ b/plasmoid/package/contents/ui/task/Wrapper.qml @@ -1,261 +1,264 @@ /* * 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.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.latte 0.2 as Latte Item{ id: wrapper opacity: 0 width: { if (!taskItem.visible) return 0; if (taskItem.isSeparator){ if (!root.vertical) return 0; else return (root.iconSize + root.widthMargins); } if (taskItem.isStartup && root.durationTime !==0 ) { return cleanScalingWidth; } else { return showDelegateWidth; } } height: { if (!taskItem.visible) return 0; if (taskItem.isSeparator){ if (root.vertical) return 0; else return (root.iconSize + root.heightMargins); } if (taskItem.isStartup && root.durationTime !==0){ return cleanScalingHeight; } else { return showDelegateheight; } } property int maxThickness: !root.vertical ? root.zoomFactor*(root.iconSize+root.heightMargins) : root.zoomFactor*(root.iconSize+root.widthMargins) property real showDelegateWidth: basicScalingWidth property real showDelegateheight: basicScalingHeight //scales which are used mainly for activating InLauncher ////Scalers/////// property bool inTempScaling: ((tempScaleWidth !== 1) || (tempScaleHeight !== 1) ) property real mScale: 1 property real tempScaleWidth: 1 property real tempScaleHeight: 1 property real scaleWidth: (inTempScaling == true) ? tempScaleWidth : mScale property real scaleHeight: (inTempScaling == true) ? tempScaleHeight : mScale property real cleanScalingWidth: (root.iconSize + root.widthMargins) * mScale property real cleanScalingHeight: (root.iconSize + root.heightMargins) * mScale property real basicScalingWidth : (inTempScaling == true) ? ((root.iconSize + root.widthMargins) * scaleWidth) : cleanScalingWidth property real basicScalingHeight : (inTempScaling == true) ? ((root.iconSize + root.heightMargins) * scaleHeight) : cleanScalingHeight property real regulatorWidth: taskItem.isSeparator ? width : basicScalingWidth; property real regulatorHeight: taskItem.isSeparator ? height : basicScalingHeight; property real visualScaledWidth: (root.iconSize + root.internalWidthMargins) * mScale property real visualScaledHeight: (root.iconSize + root.internalHeightMargins) * mScale /// end of Scalers/////// //property int curIndex: icList.hoveredIndex // property int index: taskItem.Positioner.index //property real center: (width + hiddenSpacerLeft.separatorSpace + hiddenSpacerRight.separatorSpace) / 2 property real center: !root.vertical ? (width + hiddenSpacerLeft.separatorSpace + hiddenSpacerRight.separatorSpace) / 2 : (height + hiddenSpacerLeft.separatorSpace + hiddenSpacerRight.separatorSpace) / 2 property color backgroundColor: taskIconItem.backgroundColor property color glowColor: taskIconItem.glowColor + property bool progressVisible: taskIconItem.progressVisible + property real progress: taskIconItem.progress + property Item visualIconItem: taskIconItem.visualIconItem property Item titleTooltipVisualParent: taskIconItem.titleTooltipVisualParent property Item previewsTooltipVisualParent: taskIconItem.previewsTootipVisualParent signal runLauncherAnimation(); /* Rectangle{ anchors.fill: parent border.width: 1 border.color: "green" color: "transparent" }*/ Behavior on mScale { enabled: !root.globalDirectRender || inMimicParabolicAnimation NumberAnimation{ duration: 3 * taskItem.animationTime easing.type: Easing.OutCubic } } Behavior on mScale { enabled: root.globalDirectRender && !inMimicParabolicAnimation && !restoreAnimation.running NumberAnimation { duration: root.directRenderAnimationTime } } IconItem{ id: taskIconItem anchors.bottom: (root.position === PlasmaCore.Types.BottomPositioned) ? parent.bottom : undefined anchors.top: (root.position === PlasmaCore.Types.TopPositioned) ? parent.top : undefined anchors.left: (root.position === PlasmaCore.Types.LeftPositioned) ? parent.left : undefined anchors.right: (root.position === PlasmaCore.Types.RightPositioned) ? parent.right : undefined anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined width: wrapper.width height:wrapper.height } function calculateScales( currentMousePosition ){ if (root.zoomFactor===1) { return; } var distanceFromHovered = Math.abs(index - icList.hoveredIndex); // A new algorithm trying to make the zoom calculation only once // and at the same time fixing glitches if ((distanceFromHovered === 0) && //! IMPORTANT: IS FIXING A BUG THAT NEGATIVE VALUES ARE SENT onEntered EVENT OF MOUSEAREA // (currentMousePosition>=0) && (root.dragSource === null) ){ //use the new parabolicManager in order to handle all parabolic effect messages var scales = parabolicManager.applyParabolicEffect(index, currentMousePosition, center); //Left hiddenSpacer for first task if(((index === parabolicManager.firstRealTaskIndex )&&(root.tasksCount>0)) && !root.disableLeftSpacer && !inMimicParabolicAnimation && !inFastRestoreAnimation && !inAttentionAnimation){ hiddenSpacerLeft.nScale = scales.leftScale - 1; } //Right hiddenSpacer for last task if(((index === parabolicManager.lastRealTaskIndex )&&(root.tasksCount>0)) && !root.disableRightSpacer && !inMimicParabolicAnimation && !inFastRestoreAnimation && !inAttentionAnimation){ hiddenSpacerRight.nScale = scales.rightScale - 1; } if (!taskItem.inAttentionAnimation) { mScale = root.zoomFactor; } else { var subSpacerScale = (root.zoomFactor-1)/2; hiddenSpacerLeft.nScale = subSpacerScale; hiddenSpacerRight.nScale = subSpacerScale; } taskItem.scalesUpdatedOnce = false; } } //nScale function signalUpdateScale(nIndex, nScale, step){ if (!taskItem.containsMouse && (index === nIndex) && (taskItem.hoverEnabled || inMimicParabolicAnimation)&&(tasksExtendedManager.waitingLaunchersLength()===0)){ if (taskItem.inAttentionAnimation) { var subSpacerScale = (nScale-1)/2; hiddenSpacerLeft.nScale = subSpacerScale; hiddenSpacerRight.nScale = subSpacerScale; } else if (!inBlockingAnimation || taskItem.inMimicParabolicAnimation) { var newScale = 1; if(nScale >= 0) { newScale = nScale + step; } else { newScale = mScale + step; } if (inMimicParabolicAnimation && mimicParabolicScale === -1) { mimicParabolicScale = newScale; } mScale = newScale; } } } function sendEndOfNeedBothAxisAnimation(){ if (taskItem.isZoomed) { taskItem.isZoomed = false; root.signalAnimationsNeedBothAxis(-1); } } onMScaleChanged: { if ((mScale === root.zoomFactor) && !root.directRenderTimerIsRunning && !root.globalDirectRender) { root.setGlobalDirectRender(true); } if (inMimicParabolicAnimation){ if (mScale >= mimicParabolicScale) { inMimicParabolicAnimation = false; inAnimation = false; inBlockingAnimation = false; mimicParabolicScale = -1; } else { var tempScale = (root.zoomFactor - mScale) / 2; hiddenSpacerLeft.nScale = tempScale; hiddenSpacerRight.nScale = tempScale; } } if ((mScale > 1) && !taskItem.isZoomed) { taskItem.isZoomed = true; root.signalAnimationsNeedBothAxis(1); } else if ((mScale == 1) && taskItem.isZoomed) { sendEndOfNeedBothAxisAnimation(); } } Component.onCompleted: { if (!Latte.WindowSystem.compositingActive) { opacity = 1; } root.updateScale.connect(signalUpdateScale); } Component.onDestruction: { root.updateScale.disconnect(signalUpdateScale); } }// Main task area // id:wrapper diff --git a/plasmoid/package/contents/ui/task/indicator/Bridge.qml b/plasmoid/package/contents/ui/task/indicator/Bridge.qml index f3993ee0..f92e11c6 100644 --- a/plasmoid/package/contents/ui/task/indicator/Bridge.qml +++ b/plasmoid/package/contents/ui/task/indicator/Bridge.qml @@ -1,88 +1,91 @@ /* * 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.7 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.latte 0.2 as Latte import "../../indicators/options" as TaskIndicator Item { id: indicatorBridge property bool taskIsValid: true readonly property bool active: indicators ? indicators.isEnabled : false readonly property bool locked: taskIsValid ? (inAttentionAnimation || inNewWindowAnimation) : false /* Indicators Properties in order for indicators to use them*/ readonly property bool isTask: true readonly property bool isApplet: false readonly property bool isLauncher: taskIsValid ? taskItem.isLauncher : true readonly property bool isStartup: taskIsValid ? taskItem.isStartup : false readonly property bool isWindow: taskIsValid ? taskItem.isWindow : false readonly property bool isActive: taskIsValid ? (taskItem.hasActive || (root.showPreviews && (taskItem.isWindow || taskItem.isGroupParent) && windowsPreviewDlg.activeItem && (windowsPreviewDlg.activeItem === taskItem)) ) : false readonly property bool isGroup: taskIsValid ? taskItem.isGroupParent : false readonly property bool isHovered: taskIsValid ? taskItem.containsMouse : false readonly property bool isMinimized: taskIsValid ? taskItem.isMinimized : false readonly property bool isPressed: taskIsValid ? taskItem.pressed : false readonly property bool inAttention: taskIsValid ? taskItem.inAttention : false readonly property bool inRemoving: taskIsValid ? taskItem.inRemoveStage : false readonly property bool isSquare: true readonly property bool hasActive: taskIsValid ? taskItem.hasActive : false readonly property bool hasMinimized: taskIsValid? taskItem.hasMinimized : false readonly property bool hasShown: taskIsValid ? taskItem.hasShown : false readonly property int windowsCount: taskIsValid ? taskItem.windowsCount : 0 readonly property int windowsMinimizedCount: taskIsValid ? taskItem.windowsMinimizedCount : 0 readonly property int currentIconSize: root.iconSize readonly property int maxIconSize: root.maxIconSize readonly property real scaleFactor: taskIsValid ? taskItem.wrapperAlias.mScale : 1 readonly property real panelOpacity: root.currentPanelOpacity readonly property color shadowColor: root.appShadowColorSolid readonly property bool animationsEnabled: root.animationsEnabled readonly property real durationTime: root.durationTime + readonly property bool progressVisible: wrapper.progressVisible /*since 0.9.2*/ + readonly property real progress: wrapper.progress /*since 0.9.2*/ + readonly property bool usePlasmaTabsStyle: false readonly property variant svgs: indicators ? indicators.svgs : [] readonly property QtObject palette: enforceLattePalette ? latteBridge.palette.applyTheme : theme //!icon colors property color iconBackgroundColor: taskIsValid ? taskItem.wrapperAlias.backgroundColor : "black" property color iconGlowColor: taskIsValid ? taskItem.wrapperAlias.glowColor : "white" //! grouped options readonly property Item shared: indicators ? indicators : emptyOptions readonly property QtObject configuration: indicators ? indicators.configuration : null readonly property QtObject resources: indicators ? indicators.resources : null Item{id: emptyOptions} }