refactor Task code in plasmoid

--refactore the previous enormous classes
TaskDelegate and TaskIconItem and in general
put anything relates to Task into its own
specific directory
pull/1/head
Michail Vourlakos 8 years ago
parent 50f8091601
commit c6a8ed09b5

@ -33,6 +33,7 @@ import org.kde.activities 0.1 as Activities
import org.kde.latte 0.1 as Latte
import "task" as Task
import "../code/tools.js" as TaskTools
import "../code/activitiesTools.js" as ActivitiesTools
@ -921,7 +922,7 @@ Item {
orientation: Qt.Horizontal
delegate: TaskDelegate{}
delegate: Task.TaskDelegate{}
/* Rectangle{
anchors.fill: parent

@ -30,6 +30,8 @@ import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
import org.kde.latte 0.1 as Latte
import "animations" as TaskAnimations
MouseArea{
id: mainItemContainer
@ -169,31 +171,6 @@ MouseArea{
signal groupWindowRemoved();
signal checkWindowsStates();
/* onHasMinimizedChanged:{
console.log(AppId);
if(AppId == "org.kde.dolphin"){
console.log("1. Minimized:"+hasMinimized);
console.log("2. Active:"+hasActive);
console.log("3. Shown:"+hasShown);
}
}
onHasShownChanged:{
console.log(AppId);
if(AppId == "org.kde.dolphin"){
console.log("1. Minimized:"+hasMinimized);
console.log("2. Active:"+hasActive);
console.log("3. Shown:"+hasShown);
}
}
onHasActiveChanged:{
console.log(AppId);
if(AppId == "org.kde.dolphin"){
console.log("1. Minimized:"+hasMinimized);
console.log("2. Active:"+hasActive);
console.log("3. Shown:"+hasShown);
}
}*/
/* Rectangle{
anchors.fill: parent
border.width: 1
@ -207,28 +184,6 @@ MouseArea{
NumberAnimation { duration: root.durationTime*units.longDuration }
}
/* PlasmaCore.ToolTipArea {
id: toolTip
anchors.fill: parent
// active: !inPopup && !groupDialog.visible && plasmoid.configuration.showToolTips
active: plasmoid.configuration.showToolTips && mainItemContainer.isWindow && mainItemContainer.containsMouse
enabled: mainItemContainer.isWindow
interactive: true
location: plasmoid.location
mainItem: toolTipDelegate
onContainsMouseChanged: {
}
}*/
TaskWindows{
id: tasksWindows
@ -291,337 +246,7 @@ MouseArea{
}*/
}
Item{
id: wrapper
opacity: 0
width: {
if (!mainItemContainer.visible)
return 0;
if (mainItemContainer.isSeparator){
if (!root.vertical)
return 5 + root.widthMargins;
else
return (root.iconSize + root.widthMargins) * mScale + root.statesLineSize;
}
if (mainItemContainer.isStartup && root.durationTime !==0 ) {
var moreThickness = root.vertical ? addedSpace : 0;
return cleanScalingWidth + moreThickness;
} else {
return showDelegateWidth;
}
}
height: {
if (!mainItemContainer.visible)
return 0;
if (mainItemContainer.isSeparator){
if (root.vertical)
return 5 + root.heightMargins;
else
return (root.iconSize + root.heightMargins) * mScale + root.statesLineSize;
}
if (mainItemContainer.isStartup && root.durationTime !==0){
var moreThickness = !root.vertical ? addedSpace : 0;
return cleanScalingHeight + moreThickness;
} else {
return showDelegateheight;
}
}
//size needed fom the states below icons
//property int statesLineSize: root.statesLineSize
property int addedSpace: root.statesLineSize //7
property real showDelegateWidth: root.vertical ? basicScalingWidth+addedSpace :
basicScalingWidth
property real showDelegateheight: root.vertical ? basicScalingHeight :
basicScalingHeight + addedSpace
//scales which are used mainly for activating InLauncher
////Scalers///////
property bool inTempScaling: (((tempScaleWidth !== 1) || (tempScaleHeight !== 1) ) && (!mainItemContainer.mouseEntered) )
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: mainItemContainer.isSeparator ? separatorRegWidth : basicScalingWidth;
property real regulatorHeight: mainItemContainer.isSeparator ? separatorRegHeight : basicScalingHeight;
property int separatorRegLength: root.vertical ? separatorRegWidth : separatorRegHeight
property real separatorRegWidth: {
if (!mainItemContainer.isSeparator)
return;
if (!root.vertical)
return 5 + root.widthMargins;
else
return (root.iconSize + root.thickMargin) * wrapper.mScale;
}
property real separatorRegHeight: {
if (!mainItemContainer.isSeparator)
return;
if (root.vertical)
return 5 + root.heightMargins;
else
return (root.iconSize + root.thickMargin) * wrapper.mScale;
}
/// end of Scalers///////
//property int curIndex: icList.hoveredIndex
// property int index: mainItemContainer.Positioner.index
property real center: width / 2
signal runLauncherAnimation();
/* Rectangle{
anchors.fill: parent
border.width: 1
border.color: "green"
color: "transparent"
}*/
Behavior on mScale {
enabled: !root.globalDirectRender
NumberAnimation { duration: 3 * mainItemContainer.animationTime }
}
Behavior on mScale {
enabled: root.globalDirectRender
NumberAnimation { duration: root.directRenderAnimationTime }
}
Flow{
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
flow: root.vertical ? Flow.TopToBottom : Flow.LeftToRight
Loader{
id: firstIndicator
active:( (((root.position === PlasmaCore.Types.TopPositioned) || (root.position === PlasmaCore.Types.LeftPositioned))
&& !root.reverseLinesPosition)
|| (((root.position === PlasmaCore.Types.BottomPositioned) || (root.position === PlasmaCore.Types.RightPositioned))
&& root.reverseLinesPosition) )
visible: active
sourceComponent: Component{
TaskGroupItem{}
}
}
TaskIconItem{}
Loader{
id: secondIndicator
active: !firstIndicator.active
visible: active
sourceComponent: Component{
TaskGroupItem{}
}
}
}//Flow
//!this is used in order to update the index when the signal is for applets
//!outside the latte plasmoid
function updateIdSendScale(indx, zScale, zStep){
if ((indx>=0 && indx<=root.tasksCount-1) || (!root.latteDock)){
root.updateScale(indx, zScale, zStep);
} else{
var appletId = latteDock.latteAppletPos;
if (indx<0)
appletId = latteDock.latteAppletPos + indx;
else if (indx>root.tasksCount-1){
var step=indx-root.tasksCount+1;
appletId = latteDock.latteAppletPos + step;
}
latteDock.updateScale(appletId, zScale, zStep);
}
}
function calculateScales( currentMousePosition ){
if (root.editMode || root.zoomFactor===1 || root.durationTime===0) {
return;
}
var distanceFromHovered = Math.abs(index - icList.hoveredIndex);
// A new algorithm tryig to make the zoom calculation only once
// and at the same time fixing glitches
if ((distanceFromHovered == 0)&&
(currentMousePosition > 0)&&
(root.dragSource == null) ){
var rDistance = Math.abs(currentMousePosition - center);
//check if the mouse goes right or down according to the center
var positiveDirection = ((currentMousePosition - center) >= 0 );
var minimumZoom = 1;
if(mainItemContainer.isSeparator){
//minimumZoom for separator item
var tempZoomDifference = (root.missingSeparatorLength / (root.maxSeparatorLength+root.missingSeparatorLength)) * root.zoomFactor;
minimumZoom = Math.max(tempZoomDifference, 1);
}
//finding the zoom center e.g. for zoom:1.7, calculates 0.35
var zoomCenter = ((root.zoomFactor + minimumZoom)/2) - 1;
//computes the in the scale e.g. 0...0.35 according to the mouse distance
//0.35 on the edge and 0 in the center
var firstComputation = (rDistance / center) * (zoomCenter-minimumZoom+1);
//calculates the scaling for the neighbour tasks
var bigNeighbourZoom = Math.min(1 + zoomCenter + firstComputation, root.zoomFactor);
var smallNeighbourZoom = Math.max(1 + zoomCenter - firstComputation, minimumZoom);
//bigNeighbourZoom = Number(bigNeighbourZoom.toFixed(4));
//smallNeighbourZoom = Number(smallNeighbourZoom.toFixed(4));
var leftScale;
var rightScale;
if(positiveDirection === true){
rightScale = bigNeighbourZoom;
leftScale = smallNeighbourZoom;
} else {
rightScale = smallNeighbourZoom;
leftScale = bigNeighbourZoom;
}
//! compute the neighbour separator scales
var bsNeighbourZoom = 1;
var ssNeighbourZoom = 1;
if(root.internalSeparatorPos>=0) {
if((root.internalSeparatorPos === index+1) || (root.internalSeparatorPos === index-1) ){
var sepZoomDifference = (root.maxSeparatorLength / (root.maxSeparatorLength+root.missingSeparatorLength)) * root.zoomFactor;
bsNeighbourZoom = Math.max(1,bigNeighbourZoom - sepZoomDifference);
ssNeighbourZoom = Math.max(1,smallNeighbourZoom - sepZoomDifference);
}
}
// console.debug(leftScale + " " + rightScale + " " + index);
if(!root.hasInternalSeparator || Math.abs(index-root.internalSeparatorPos)>=2
|| mainItemContainer.isSeparator){
//activate messages to update the the neighbour scales
updateIdSendScale(index+1, rightScale, 0);
updateIdSendScale(index-1, leftScale, 0);
updateIdSendScale(index+2, 1, 0);
updateIdSendScale(index-2, 1, 0);
} else if(root.internalSeparatorPos>=0) {
if(root.internalSeparatorPos === index+1){
if (!positiveDirection) {
updateIdSendScale(index+2, ssNeighbourZoom, 0);
} else {
updateIdSendScale(index+2, bsNeighbourZoom, 0);
}
updateIdSendScale(index-1, leftScale, 0);
updateIdSendScale(index+1, rightScale, 0);
updateIdSendScale(index+3, 1, 0);
updateIdSendScale(index-2, 1, 0);
} else if(root.internalSeparatorPos === index-1) {
if (!positiveDirection) {
updateIdSendScale(index-2, bsNeighbourZoom, 0);
} else {
updateIdSendScale(index-2, ssNeighbourZoom, 0);
}
updateIdSendScale(index-1, leftScale, 0);
updateIdSendScale(index+1, rightScale, 0);
updateIdSendScale(index+2, 1, 0);
updateIdSendScale(index-3, 1, 0);
}
}
//Left hiddenSpacer
if(((index === 0 )&&(icList.count > 1)) && !root.disableLeftSpacer){
hiddenSpacerLeft.nScale = leftScale - 1;
}
//Right hiddenSpacer
if(((index === icList.count - 1 )&&(icList.count>1)) && (!root.disableRightSpacer)){
hiddenSpacerRight.nScale = rightScale - 1;
}
mScale = root.zoomFactor;
}
} //nScale
function signalUpdateScale(nIndex, nScale, step){
if ((index === nIndex)&&(mainItemContainer.hoverEnabled)&&(waitingLaunchers.length===0)){
if(nScale >= 0) {
mScale = nScale + step;
} else {
mScale = mScale + step;
}
// console.log(index+ ", "+mScale);
}
}
function sendEndOfNeedBothAxisAnimation(){
if (mainItemContainer.isZoomed) {
mainItemContainer.isZoomed = false;
root.signalAnimationsNeedBothAxis(-1);
}
}
onMScaleChanged: {
if ((mScale === root.zoomFactor) && !root.directRenderTimerIsRunning && !root.globalDirectRender) {
root.startEnableDirectRenderTimer();
}
if ((mScale > 1) && !mainItemContainer.isZoomed) {
mainItemContainer.isZoomed = true;
root.signalAnimationsNeedBothAxis(1);
} else if ((mScale == 1) && mainItemContainer.isZoomed) {
sendEndOfNeedBothAxisAnimation();
}
}
Component.onCompleted: {
root.updateScale.connect(signalUpdateScale);
}
}// Main task area // id:wrapper
TaskWrapper{ id: wrapper }
// a hidden spacer on the right for the last item to add stability
Item{
@ -1192,6 +817,17 @@ MouseArea{
}
///window previews////
function launcherIsPresent(url) {
var activities = tasksModel.launcherActivities(url);
var NULL_UUID = "00000000-0000-0000-0000-000000000000";
if (activities.indexOf(NULL_UUID) !== -1 || activities.indexOf(activityInfo.currentActivity) !== -1)
return true;
return false;
}
function modelIndex(){
return tasksModel.makeModelIndex(index);
}
@ -1361,141 +997,9 @@ MouseArea{
/////Animations
///item's added Animation
SequentialAnimation{
id:showWindowAnimation
property int speed: Latte.WindowSystem.compositingActive ? root.durationTime* (1.2*units.longDuration) : 0
property bool animationSent: false
//Ghost animation that acts as a delayer, in order to fix #342
PropertyAnimation {
target: wrapper
property: "opacity"
to: 0
//it is not depend to durationTime when animations are active
duration: root.durationTime > 0 ? 750 : 0
easing.type: Easing.InQuad
}
//end of ghost animation
ScriptAction{
script:{
if (!showWindowAnimation.animationSent) {
showWindowAnimation.animationSent = true;
root.signalAnimationsNeedLength(1);
}
}
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleHeight" : "tempScaleWidth"
to: 1
duration: showWindowAnimation.speed
easing.type: Easing.OutQuad
}
ParallelAnimation{
TaskAnimations.TaskShowWindowAnimation{ id: showWindowAnimation }
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: showWindowAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: "opacity"
from: 0
to: 1
duration: showWindowAnimation.speed
easing.type: Easing.OutQuad
}
}
onStopped: {
mainItemContainer.inAddRemoveAnimation = false;
if(mainItemContainer.isWindow || mainItemContainer.isStartup){
taskInitComponent.createObject(wrapper);
if (mainItemContainer.isDemandingAttention){
mainItemContainer.groupWindowAdded();
}
}
mainItemContainer.inAnimation = false;
if (showWindowAnimation.animationSent) {
root.signalAnimationsNeedLength(-1);
showWindowAnimation.animationSent = false;
}
}
function execute(){
//Animation Add/Remove (2) - when is window with no launcher, animations enabled
//Animation Add/Remove (3) - when is launcher with no window, animations enabled
var animation2 = ((((tasksModel.launcherPosition(mainItemContainer.launcherUrl) == -1)
&& (tasksModel.launcherPosition(mainItemContainer.launcherUrlWithIcon) == -1) )
|| !launcherIsPresent(mainItemContainer.launcherUrl))
&& mainItemContainer.isWindow);
var animation3 = ((!root.taskExists(mainItemContainer.launcherUrl) && mainItemContainer.isLauncher));
if (( animation2 || animation3) && (root.durationTime !== 0)){
wrapper.tempScaleWidth = 0;
wrapper.tempScaleHeight = 0;
start();
} else {
wrapper.tempScaleWidth = 1;
wrapper.tempScaleHeight = 1;
wrapper.opacity = 1;
mainItemContainer.inAnimation = false;
}
}
function showWindow(){
execute();
}
Component.onDestruction: {
if (animationSent){
//console.log("SAFETY REMOVAL 2: animation removing ended");
animationSent = false;
root.signalAnimationsNeedLength(-1);
}
}
}
///////Restore Zoom Animation/////
ParallelAnimation{
id: restoreAnimation
PropertyAnimation {
target: wrapper
property: "mScale"
to: 1
duration: 3 * mainItemContainer.animationTime
easing.type: Easing.Linear
}
PropertyAnimation {
target: hiddenSpacerLeft
property: "nScale"
to: 0
duration: 3 * mainItemContainer.animationTime
easing.type: Easing.Linear
}
PropertyAnimation {
target: hiddenSpacerRight
property: "nScale"
to: 0
duration: 3 * mainItemContainer.animationTime
easing.type: Easing.Linear
}
}
TaskAnimations.TaskRestoreAnimation{ id: restoreAnimation}
//A Timer to check how much time the task is hovered in order to check if we must
//show window previews
@ -1549,7 +1053,6 @@ MouseArea{
}
}
///trying to compete with the crazy situation in the tasksModel
///with launchers and startups... There are windows that stay
///startup mode e.g. chrome, libreoffice... not showing startups
@ -1609,144 +1112,8 @@ MouseArea{
}
}
function launcherIsPresent(url) {
var activities = tasksModel.launcherActivities(url);
var NULL_UUID = "00000000-0000-0000-0000-000000000000";
if (activities.indexOf(NULL_UUID) !== -1 || activities.indexOf(activityInfo.currentActivity) !== -1)
return true;
return false;
}
///Item's Removal Animation
ListView.onRemove: SequentialAnimation {
id: taskRealRemovalAnimation
PropertyAction { target: mainItemContainer; property: "ListView.delayRemove"; value: true }
PropertyAction { target: mainItemContainer; property: "inRemoveStage"; value: true }
//Animation Add/Remove (1) - when is window with no launcher, animations enabled
//Animation Add/Remove (4) - the user removes a launcher, animation enabled
property bool animation1: ((((tasksModel.launcherPosition(mainItemContainer.launcherUrl) == -1)
&& (tasksModel.launcherPosition(mainItemContainer.launcherUrlWithIcon) == -1) )
|| !launcherIsPresent(mainItemContainer.launcherUrl))
&& !mainItemContainer.isStartup)
property bool animation4: ((mainItemContainer.launcherUrl===root.launcherForRemoval
|| mainItemContainer.launcherUrlWithIcon===root.launcherForRemoval )&& mainItemContainer.isLauncher)
property bool enabledAnimation: (animation1 || animation4) && (root.durationTime !== 0) && !mainItemContainer.inBouncingAnimation;
ScriptAction{
script:{
root.mouseWasEntered.disconnect(signalMouseWasEntered);
root.draggingFinished.disconnect(handlerDraggingFinished);
root.clearZoomSignal.disconnect(clearZoom);
root.publishTasksGeometries.disconnect(slotPublishGeometries);
root.showPreviewForTasks.disconnect(slotShowPreviewForTasks);
root.updateScale.disconnect(wrapper.signalUpdateScale);
mainItemContainer.inAnimation = true;
icList.delayingRemoval = true;
mainItemContainer.inAddRemoveAnimation = true;
//trying to fix the ListView nasty behavior
//during the removal the anchoring for ListView children changes a lot
var previousTask = icList.childAtIndex(mainItemContainer.lastValidIndex-1);
if (previousTask !== undefined){
if (root.vertical) {
mainItemContainer.anchors.top = previousTask.bottom;
} else {
mainItemContainer.anchors.left = previousTask.right;
}
}
// console.log("1." + mainItemContainer.launcherUrl + " - " + taskRealRemovalAnimation.enabledAnimation);
// console.log("2." + root.launcherForRemoval + " - " + mainItemContainer.isLauncher);
root.signalAnimationsNeedLength(1);
}
}
//Ghost animation that acts as a delayer in case there is a bouncing animation
//taking place
PropertyAnimation {
target: wrapper
property: "opacity"
to: 1
duration: mainItemContainer.inBouncingAnimation ? //exactly how much the bounche animation lasts
5*(root.durationTime * 0.8 * units.longDuration) : 0
easing.type: Easing.InQuad
}
//end of ghost animation
PropertyAnimation {
target: wrapper
property: "mScale"
to: 1
duration: taskRealRemovalAnimation.enabledAnimation ? showWindowAnimation.speed : 0
easing.type: Easing.InQuad
}
//PropertyAction { target: wrapper; property: "opacity"; value: isWindow ? 0 : 1 }
//animation mainly for launchers removal and startups
ParallelAnimation{
id: removalAnimation
// property int speed: (IsStartup && !mainItemContainer.visible)? 0 : 400
//property int speed: 400
NumberAnimation {
target: wrapper;
property: "opacity";
to: 0;
duration: taskRealRemovalAnimation.enabledAnimation ? showWindowAnimation.speed : 0
easing.type: Easing.InQuad }
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 0
duration: taskRealRemovalAnimation.enabledAnimation ? showWindowAnimation.speed : 0
easing.type: Easing.InQuad
}
}
//smooth move into place the surrounding tasks
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleHeight" : "tempScaleWidth"
to: 0
duration: taskRealRemovalAnimation.enabledAnimation ? showWindowAnimation.speed : 0
easing.type: Easing.InQuad
}
ScriptAction{
script:{
if (showWindowAnimation.animationSent){
//console.log("SAFETY REMOVAL 1: animation removing ended");
showWindowAnimation.animationSent = false;
root.signalAnimationsNeedLength(-1);
}
root.signalAnimationsNeedLength(-1);
mainItemContainer.inAnimation = false;
icList.delayingRemoval = false;
if(mainItemContainer.launcherUrl===root.launcherForRemoval && mainItemContainer.isLauncher)
root.launcherForRemoval="";
//send signal that the launcher is really removing
if (mainItemContainer.inBouncingAnimation) {
mainItemContainer.visible = false;
root.removeWaitingLauncher(mainItemContainer.launcherUrl);
}
}
}
PropertyAction { target: mainItemContainer; property: "ListView.delayRemove"; value: false }
}
ListView.onRemove: TaskAnimations.TaskRealRemovalAnimation{ id: taskRealRemovalAnimation }
}// main Item

@ -30,6 +30,9 @@ import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlAddons
import org.kde.latte 0.1 as Latte
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
@ -536,67 +539,6 @@ Item{
lightness:0
}
///////Activate animation/////
SequentialAnimation{
id: clickedAnimation
property bool pressed: mainItemContainer.pressed
property int speed: root.durationTime*units.longDuration
property real maxMScale: Math.max(1,Math.root.zoomFactor - (root.zoomFactor - 1) / 2)
ParallelAnimation{
PropertyAnimation {
target: brightnessTaskEffect
property: "brightness"
to: -0.5
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: "mScale"
to: root.taskInAnimation ? 1 : Math.max(clickedAnimation.maxMScale, wrapper.mScale - (root.zoomFactor - 1) / 2)
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
}
ParallelAnimation{
PropertyAnimation {
target: brightnessTaskEffect
property: "brightness"
to: 0
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: "mScale"
to: root.taskInAnimation ? 1 : root.zoomFactor
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
}
onPressedChanged: {
if( (pressed)&&
((mainItemContainer.lastButtonClicked == Qt.LeftButton)||(mainItemContainer.lastButtonClicked == Qt.MidButton)) ){
mainItemContainer.animationStarted();
start();
}
}
onStopped: {
if( !mainItemContainer.isDragged){
mainItemContainer.animationEnded();
if(!root.latteDock)
checkListHovered.startDuration(6*units.longDuration);
}
}
}
Component.onCompleted: {
}
@ -608,161 +550,7 @@ Item{
gc();
}
////end of activate animation////
////bouncing task, e.g. on launcher activating and when a new window is
////added in a group task
SequentialAnimation{
id:launcherAnimation
property bool launchedAlready: false
property int speed: root.durationTime * 0.8 * units.longDuration
SequentialAnimation{
ScriptAction {
script: mainItemContainer.launcherAction();
}
//Ghost animation that acts as a delayer
PropertyAnimation {
target: wrapper
property: "opacity"
to: 1
duration: 50
easing.type: Easing.InQuad
}
//end of ghost animation
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: root.zoomFactor
duration: launcherAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Horizontal) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: launcherAnimation.speed
easing.type: Easing.OutQuad
}
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: 3*root.durationTime*launcherAnimation.speed
easing.type: Easing.OutBounce
}
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleHeight" : "tempScaleWidth"
to: 1
duration: root.durationTime*launcherAnimation.speed
easing.type: Easing.OutBounce
}
PropertyAnimation {
target: wrapper
property: "mScale"
to: 1
duration: root.durationTime*launcherAnimation.speed
easing.type: Easing.OutQuad
}
}
}
onStopped: {
clearAnimationsSignals();
mainItemContainer.setBlockingAnimation(false);
mainItemContainer.animationEnded();
if (!mainItemContainer.inRemoveStage) {
mainItemContainer.inBouncingAnimation = false;
root.removeWaitingLauncher(mainItemContainer.launcherUrl);
}
}
function clearAnimationsSignals() {
if ( launchedAlready && root.noTasksInAnimation>0 ) {
root.noTasksInAnimation--;
}
if ( launchedAlready ) {
root.signalAnimationsNeedThickness(-1);
}
launchedAlready = false;
}
function init(){
//console.log ("Nooo 1 : "+root.noTasksInAnimation);
if(!launchedAlready) {
launchedAlready = true;
root.signalAnimationsNeedThickness(1);
if (root.latteDock)
root.latteDock.disableDirectRender();
else
icList.directRender=false;
wrapper.updateIdSendScale(index+2, 1, 0);
wrapper.updateIdSendScale(index+1, 1, 0);
wrapper.updateIdSendScale(index-1, 1, 0);
wrapper.updateIdSendScale(index-2, 1, 0);
root.noTasksInAnimation++;
mainItemContainer.setBlockingAnimation(true);
//trying to fix the ListView nasty behavior
//during the removal the anchoring for ListView children changes a lot
var previousTask = icList.childAtIndex(mainItemContainer.lastValidIndex-1);
if (previousTask !== undefined){
if (root.vertical) {
mainItemContainer.anchors.top = previousTask.bottom;
} else {
mainItemContainer.anchors.left = previousTask.right;
}
}
}
wrapper.tempScaleWidth = wrapper.mScale;
wrapper.tempScaleHeight = wrapper.mScale;
icList.hoveredIndex = -1;
}
function bounceLauncher(){
if(root.zoomFactor > 1){
mainItemContainer.animationStarted();
init();
start();
}
else{
stopped();
mainItemContainer.launcherAction();
}
}
Component.onCompleted: {
wrapper.runLauncherAnimation.connect(bounceLauncher);
}
Component.onDestruction: {
clearAnimationsSignals();
}
}
/////////////////// end of launcher animation
////////////////// new window and needs attention animation
Connections{
target: mainItemContainer
onContainsMouseChanged: {
@ -772,247 +560,15 @@ Item{
}
}
SequentialAnimation{
id:newWindowAnimation
property int speed: root.durationTime*units.longDuration
property bool isDemandingAttention: (IsDemandingAttention === true)
property bool entered: mainItemContainer.mouseEntered
property bool needsThicknessSent: false //flag to check if the signal for thickness was sent
SequentialAnimation{
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1 + (0.6 * (root.zoomFactor-1))
duration: newWindowAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Horizontal) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: newWindowAnimation.speed
easing.type: Easing.OutQuad
}
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: 3*root.durationTime*newWindowAnimation.speed
easing.type: Easing.OutBounce
}
ScriptAction{
script:{
if (mainItemContainer.containsMouse) {
newWindowAnimation.stop();
}
if (!newWindowAnimation.isDemandingAttention
|| (plasmoid.status === PlasmaCore.Types.PassiveStatus && newWindowAnimation.loops > 2)){
newWindowAnimation.clear();
}
}
}
}
function clear(){
loops = 1;
newWindowAnimation.stop();
// iconImageBuffer.anchors.centerIn = iconImageBuffer.parent;
wrapper.tempScaleWidth = 1;
wrapper.tempScaleHeight = 1;
}
onStopped: {
sendEndOfNeedThicknessAnimation();
clear();
}
onIsDemandingAttentionChanged: {
if(isDemandingAttention){
bounceNewWindow();
}
}
function sendEndOfNeedThicknessAnimation(){
if (needsThicknessSent) {
needsThicknessSent = false;
root.signalAnimationsNeedThickness(-1);
}
}
function init(){
wrapper.tempScaleWidth = wrapper.mScale;
wrapper.tempScaleHeight = wrapper.mScale;
if(!isDemandingAttention)
loops = 2;
else
loops = 20;
if (!needsThicknessSent) {
needsThicknessSent = true;
root.signalAnimationsNeedThickness(1);
}
// icList.hoveredIndex = -1;
}
function bounceNewWindow(){
if (isDemandingAttention && !root.dockIsHidden && (root.zoomFactor > 1)){
newWindowAnimation.init();
start();
}
}
Component.onCompleted: {
mainItemContainer.groupWindowAdded.connect(bounceNewWindow);
}
Component.onDestruction: {
sendEndOfNeedThicknessAnimation();
}
}
/////Removing a Window from a group////
///// Animations /////
Item{
id:removingAnimation
TaskAnimations.TaskClickedAnimation { id: clickedAnimation }
function init(){
var relavantPoint = root.mapFromItem(centralItem,0,0);
TaskAnimations.TaskLauncherAnimation { id:launcherAnimation }
var removingItem = removeTaskComponent.createObject(root);
removingItem.x = relavantPoint.x;
removingItem.y = relavantPoint.y;
TaskAnimations.TaskNewWindowAnimation { id: newWindowAnimation }
removingItem.start();
}
function removeTask(){
if(!centralItem.toBeDestroyed && plasmoid.configuration.showShadows && Latte.WindowSystem.compositingActive){
removingAnimation.init();
}
}
Component.onCompleted: {
mainItemContainer.groupWindowRemoved.connect(removeTask);
}
///////////// Component for animating removing window from group
Component {
id: removeTaskComponent
Item{
id: removeTask
width: centralItem.width
height: centralItem.height
visible: false
Latte.IconItem{
id: tempRemoveIcon
anchors.rightMargin: root.position === PlasmaCore.Types.LeftPositioned ? root.thickMarginBase : 0
anchors.leftMargin: root.position === PlasmaCore.Types.RightPositioned ? root.thickMarginBase : 0
anchors.topMargin: root.position === PlasmaCore.Types.BottomPositioned ? root.thickMarginBase : 0
anchors.bottomMargin: root.position === PlasmaCore.Types.TopPositioned ? root.thickMarginBase : 0
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;
width: iconImageBuffer.width
height: width
visible: root.enableShadows ? false : true
source: iconImageBuffer.lastValidSourceName
}
Loader{
id: tempTaskShadow
anchors.fill: tempRemoveIcon
active: root.enableShadows
sourceComponent: DropShadow{
anchors.fill: parent
color: "#ff080808"
samples: 2 * radius
source: tempRemoveIcon
radius: centralItem.shadowSize
verticalOffset: 2
}
}
Colorize{
source: tempRemoveIcon
anchors.fill: tempRemoveIcon
hue: 0
saturation: 0
lightness: 0
}
ParallelAnimation{
id: componentRemoveAnimation
property int speed: 2*root.durationTime*units.longDuration
property Item removingItem: parent
property int toPoint: 0
PropertyAnimation {
target: removeTask
property: "opacity"
to: 0
duration: componentRemoveAnimation.speed
easing.type: Easing.InQuad
}
PropertyAnimation {
target: removeTask
property: (icList.orientation == Qt.Horizontal) ? "y" : "x"
to: componentRemoveAnimation.toPoint
duration: componentRemoveAnimation.speed
easing.type: Easing.InQuad
}
onStopped: {
removeTask.destroy();
gc();
}
}
function start(){
var tempPoint = 0;
if(icList.orientation == Qt.Horizontal)
tempPoint = y;
else
tempPoint = x;
if( (root.position === PlasmaCore.Types.BottomPositioned) ||
(root.position === PlasmaCore.Types.RightPositioned) ){
componentRemoveAnimation.toPoint = tempPoint + root.iconSize;
}
else{
componentRemoveAnimation.toPoint = tempPoint - root.iconSize;
}
visible = true;
componentRemoveAnimation.start();
}
}
}
}
TaskAnimations.TaskRemoveWindowFromGroupAnimation { id: removingAnimation }
//////////// States ////////////////////
states: [

@ -0,0 +1,335 @@
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
Item{
id: wrapper
opacity: 0
width: {
if (!mainItemContainer.visible)
return 0;
if (mainItemContainer.isSeparator){
if (!root.vertical)
return 5 + root.widthMargins;
else
return (root.iconSize + root.widthMargins) * mScale + root.statesLineSize;
}
if (mainItemContainer.isStartup && root.durationTime !==0 ) {
var moreThickness = root.vertical ? addedSpace : 0;
return cleanScalingWidth + moreThickness;
} else {
return showDelegateWidth;
}
}
height: {
if (!mainItemContainer.visible)
return 0;
if (mainItemContainer.isSeparator){
if (root.vertical)
return 5 + root.heightMargins;
else
return (root.iconSize + root.heightMargins) * mScale + root.statesLineSize;
}
if (mainItemContainer.isStartup && root.durationTime !==0){
var moreThickness = !root.vertical ? addedSpace : 0;
return cleanScalingHeight + moreThickness;
} else {
return showDelegateheight;
}
}
//size needed fom the states below icons
//property int statesLineSize: root.statesLineSize
property int addedSpace: root.statesLineSize //7
property real showDelegateWidth: root.vertical ? basicScalingWidth+addedSpace :
basicScalingWidth
property real showDelegateheight: root.vertical ? basicScalingHeight :
basicScalingHeight + addedSpace
//scales which are used mainly for activating InLauncher
////Scalers///////
property bool inTempScaling: (((tempScaleWidth !== 1) || (tempScaleHeight !== 1) ) && (!mainItemContainer.mouseEntered) )
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: mainItemContainer.isSeparator ? separatorRegWidth : basicScalingWidth;
property real regulatorHeight: mainItemContainer.isSeparator ? separatorRegHeight : basicScalingHeight;
property int separatorRegLength: root.vertical ? separatorRegWidth : separatorRegHeight
property real separatorRegWidth: {
if (!mainItemContainer.isSeparator)
return;
if (!root.vertical)
return 5 + root.widthMargins;
else
return (root.iconSize + root.thickMargin) * wrapper.mScale;
}
property real separatorRegHeight: {
if (!mainItemContainer.isSeparator)
return;
if (root.vertical)
return 5 + root.heightMargins;
else
return (root.iconSize + root.thickMargin) * wrapper.mScale;
}
/// end of Scalers///////
//property int curIndex: icList.hoveredIndex
// property int index: mainItemContainer.Positioner.index
property real center: width / 2
signal runLauncherAnimation();
/* Rectangle{
anchors.fill: parent
border.width: 1
border.color: "green"
color: "transparent"
}*/
Behavior on mScale {
enabled: !root.globalDirectRender
NumberAnimation { duration: 3 * mainItemContainer.animationTime }
}
Behavior on mScale {
enabled: root.globalDirectRender
NumberAnimation { duration: root.directRenderAnimationTime }
}
Flow{
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
flow: root.vertical ? Flow.TopToBottom : Flow.LeftToRight
Loader{
id: firstIndicator
active:( (((root.position === PlasmaCore.Types.TopPositioned) || (root.position === PlasmaCore.Types.LeftPositioned))
&& !root.reverseLinesPosition)
|| (((root.position === PlasmaCore.Types.BottomPositioned) || (root.position === PlasmaCore.Types.RightPositioned))
&& root.reverseLinesPosition) )
visible: active
sourceComponent: Component{
TaskGroupItem{}
}
}
TaskIconItem{}
Loader{
id: secondIndicator
active: !firstIndicator.active
visible: active
sourceComponent: Component{
TaskGroupItem{}
}
}
}//Flow
//!this is used in order to update the index when the signal is for applets
//!outside the latte plasmoid
function updateIdSendScale(indx, zScale, zStep){
if ((indx>=0 && indx<=root.tasksCount-1) || (!root.latteDock)){
root.updateScale(indx, zScale, zStep);
} else{
var appletId = latteDock.latteAppletPos;
if (indx<0)
appletId = latteDock.latteAppletPos + indx;
else if (indx>root.tasksCount-1){
var step=indx-root.tasksCount+1;
appletId = latteDock.latteAppletPos + step;
}
latteDock.updateScale(appletId, zScale, zStep);
}
}
function calculateScales( currentMousePosition ){
if (root.editMode || root.zoomFactor===1 || root.durationTime===0) {
return;
}
var distanceFromHovered = Math.abs(index - icList.hoveredIndex);
// A new algorithm tryig to make the zoom calculation only once
// and at the same time fixing glitches
if ((distanceFromHovered == 0)&&
(currentMousePosition > 0)&&
(root.dragSource == null) ){
var rDistance = Math.abs(currentMousePosition - center);
//check if the mouse goes right or down according to the center
var positiveDirection = ((currentMousePosition - center) >= 0 );
var minimumZoom = 1;
if(mainItemContainer.isSeparator){
//minimumZoom for separator item
var tempZoomDifference = (root.missingSeparatorLength / (root.maxSeparatorLength+root.missingSeparatorLength)) * root.zoomFactor;
minimumZoom = Math.max(tempZoomDifference, 1);
}
//finding the zoom center e.g. for zoom:1.7, calculates 0.35
var zoomCenter = ((root.zoomFactor + minimumZoom)/2) - 1;
//computes the in the scale e.g. 0...0.35 according to the mouse distance
//0.35 on the edge and 0 in the center
var firstComputation = (rDistance / center) * (zoomCenter-minimumZoom+1);
//calculates the scaling for the neighbour tasks
var bigNeighbourZoom = Math.min(1 + zoomCenter + firstComputation, root.zoomFactor);
var smallNeighbourZoom = Math.max(1 + zoomCenter - firstComputation, minimumZoom);
//bigNeighbourZoom = Number(bigNeighbourZoom.toFixed(4));
//smallNeighbourZoom = Number(smallNeighbourZoom.toFixed(4));
var leftScale;
var rightScale;
if(positiveDirection === true){
rightScale = bigNeighbourZoom;
leftScale = smallNeighbourZoom;
} else {
rightScale = smallNeighbourZoom;
leftScale = bigNeighbourZoom;
}
//! compute the neighbour separator scales
var bsNeighbourZoom = 1;
var ssNeighbourZoom = 1;
if(root.internalSeparatorPos>=0) {
if((root.internalSeparatorPos === index+1) || (root.internalSeparatorPos === index-1) ){
var sepZoomDifference = (root.maxSeparatorLength / (root.maxSeparatorLength+root.missingSeparatorLength)) * root.zoomFactor;
bsNeighbourZoom = Math.max(1,bigNeighbourZoom - sepZoomDifference);
ssNeighbourZoom = Math.max(1,smallNeighbourZoom - sepZoomDifference);
}
}
// console.debug(leftScale + " " + rightScale + " " + index);
if(!root.hasInternalSeparator || Math.abs(index-root.internalSeparatorPos)>=2
|| mainItemContainer.isSeparator){
//activate messages to update the the neighbour scales
updateIdSendScale(index+1, rightScale, 0);
updateIdSendScale(index-1, leftScale, 0);
updateIdSendScale(index+2, 1, 0);
updateIdSendScale(index-2, 1, 0);
} else if(root.internalSeparatorPos>=0) {
if(root.internalSeparatorPos === index+1){
if (!positiveDirection) {
updateIdSendScale(index+2, ssNeighbourZoom, 0);
} else {
updateIdSendScale(index+2, bsNeighbourZoom, 0);
}
updateIdSendScale(index-1, leftScale, 0);
updateIdSendScale(index+1, rightScale, 0);
updateIdSendScale(index+3, 1, 0);
updateIdSendScale(index-2, 1, 0);
} else if(root.internalSeparatorPos === index-1) {
if (!positiveDirection) {
updateIdSendScale(index-2, bsNeighbourZoom, 0);
} else {
updateIdSendScale(index-2, ssNeighbourZoom, 0);
}
updateIdSendScale(index-1, leftScale, 0);
updateIdSendScale(index+1, rightScale, 0);
updateIdSendScale(index+2, 1, 0);
updateIdSendScale(index-3, 1, 0);
}
}
//Left hiddenSpacer
if(((index === 0 )&&(icList.count > 1)) && !root.disableLeftSpacer){
hiddenSpacerLeft.nScale = leftScale - 1;
}
//Right hiddenSpacer
if(((index === icList.count - 1 )&&(icList.count>1)) && (!root.disableRightSpacer)){
hiddenSpacerRight.nScale = rightScale - 1;
}
mScale = root.zoomFactor;
}
} //nScale
function signalUpdateScale(nIndex, nScale, step){
if ((index === nIndex)&&(mainItemContainer.hoverEnabled)&&(waitingLaunchers.length===0)){
if(nScale >= 0) {
mScale = nScale + step;
} else {
mScale = mScale + step;
}
// console.log(index+ ", "+mScale);
}
}
function sendEndOfNeedBothAxisAnimation(){
if (mainItemContainer.isZoomed) {
mainItemContainer.isZoomed = false;
root.signalAnimationsNeedBothAxis(-1);
}
}
onMScaleChanged: {
if ((mScale === root.zoomFactor) && !root.directRenderTimerIsRunning && !root.globalDirectRender) {
root.startEnableDirectRenderTimer();
}
if ((mScale > 1) && !mainItemContainer.isZoomed) {
mainItemContainer.isZoomed = true;
root.signalAnimationsNeedBothAxis(1);
} else if ((mScale == 1) && mainItemContainer.isZoomed) {
sendEndOfNeedBothAxisAnimation();
}
}
Component.onCompleted: {
root.updateScale.connect(signalUpdateScale);
}
}// Main task area // id:wrapper

@ -0,0 +1,83 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
///////Activate animation/////
SequentialAnimation{
id: clickedAnimation
property bool pressed: mainItemContainer.pressed
property int speed: root.durationTime*units.longDuration
property real maxMScale: Math.max(1,Math.root.zoomFactor - (root.zoomFactor - 1) / 2)
ParallelAnimation{
PropertyAnimation {
target: brightnessTaskEffect
property: "brightness"
to: -0.5
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: "mScale"
to: root.taskInAnimation ? 1 : Math.max(clickedAnimation.maxMScale, wrapper.mScale - (root.zoomFactor - 1) / 2)
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
}
ParallelAnimation{
PropertyAnimation {
target: brightnessTaskEffect
property: "brightness"
to: 0
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: "mScale"
to: root.taskInAnimation ? 1 : root.zoomFactor
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
}
onPressedChanged: {
if( (pressed)&&
((mainItemContainer.lastButtonClicked == Qt.LeftButton)||(mainItemContainer.lastButtonClicked == Qt.MidButton)) ){
mainItemContainer.animationStarted();
start();
}
}
onStopped: {
if( !mainItemContainer.isDragged){
mainItemContainer.animationEnded();
if(!root.latteDock)
checkListHovered.startDuration(6*units.longDuration);
}
}
}

@ -0,0 +1,174 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
////bouncing task, e.g. on launcher activating and when a new window is
////added in a group task
SequentialAnimation{
id:launcherAnimation
property bool launchedAlready: false
property int speed: root.durationTime * 0.8 * units.longDuration
SequentialAnimation{
ScriptAction {
script: mainItemContainer.launcherAction();
}
//Ghost animation that acts as a delayer
PropertyAnimation {
target: wrapper
property: "opacity"
to: 1
duration: 50
easing.type: Easing.InQuad
}
//end of ghost animation
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: root.zoomFactor
duration: launcherAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Horizontal) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: launcherAnimation.speed
easing.type: Easing.OutQuad
}
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: 3*root.durationTime*launcherAnimation.speed
easing.type: Easing.OutBounce
}
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleHeight" : "tempScaleWidth"
to: 1
duration: root.durationTime*launcherAnimation.speed
easing.type: Easing.OutBounce
}
PropertyAnimation {
target: wrapper
property: "mScale"
to: 1
duration: root.durationTime*launcherAnimation.speed
easing.type: Easing.OutQuad
}
}
}
onStopped: {
clearAnimationsSignals();
mainItemContainer.setBlockingAnimation(false);
mainItemContainer.animationEnded();
if (!mainItemContainer.inRemoveStage) {
mainItemContainer.inBouncingAnimation = false;
root.removeWaitingLauncher(mainItemContainer.launcherUrl);
}
}
function clearAnimationsSignals() {
if ( launchedAlready && root.noTasksInAnimation>0 ) {
root.noTasksInAnimation--;
}
if ( launchedAlready ) {
root.signalAnimationsNeedThickness(-1);
}
launchedAlready = false;
}
function init(){
//console.log ("Nooo 1 : "+root.noTasksInAnimation);
if(!launchedAlready) {
launchedAlready = true;
root.signalAnimationsNeedThickness(1);
if (root.latteDock)
root.latteDock.disableDirectRender();
else
icList.directRender=false;
wrapper.updateIdSendScale(index+2, 1, 0);
wrapper.updateIdSendScale(index+1, 1, 0);
wrapper.updateIdSendScale(index-1, 1, 0);
wrapper.updateIdSendScale(index-2, 1, 0);
root.noTasksInAnimation++;
mainItemContainer.setBlockingAnimation(true);
//trying to fix the ListView nasty behavior
//during the removal the anchoring for ListView children changes a lot
var previousTask = icList.childAtIndex(mainItemContainer.lastValidIndex-1);
if (previousTask !== undefined){
if (root.vertical) {
mainItemContainer.anchors.top = previousTask.bottom;
} else {
mainItemContainer.anchors.left = previousTask.right;
}
}
}
wrapper.tempScaleWidth = wrapper.mScale;
wrapper.tempScaleHeight = wrapper.mScale;
icList.hoveredIndex = -1;
}
function bounceLauncher(){
if(root.zoomFactor > 1){
mainItemContainer.animationStarted();
init();
start();
}
else{
stopped();
mainItemContainer.launcherAction();
}
}
Component.onCompleted: {
wrapper.runLauncherAnimation.connect(bounceLauncher);
}
Component.onDestruction: {
clearAnimationsSignals();
}
}
/////////////////// end of launcher animation

@ -0,0 +1,133 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
////////////////// new window and needs attention animation
SequentialAnimation{
id:newWindowAnimation
property int speed: root.durationTime*units.longDuration
property bool isDemandingAttention: (IsDemandingAttention === true)
property bool entered: mainItemContainer.mouseEntered
property bool needsThicknessSent: false //flag to check if the signal for thickness was sent
SequentialAnimation{
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1 + (0.6 * (root.zoomFactor-1))
duration: newWindowAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Horizontal) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: newWindowAnimation.speed
easing.type: Easing.OutQuad
}
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: 3*root.durationTime*newWindowAnimation.speed
easing.type: Easing.OutBounce
}
ScriptAction{
script:{
if (mainItemContainer.containsMouse) {
newWindowAnimation.stop();
}
if (!newWindowAnimation.isDemandingAttention
|| (plasmoid.status === PlasmaCore.Types.PassiveStatus && newWindowAnimation.loops > 2)){
newWindowAnimation.clear();
}
}
}
}
function clear(){
loops = 1;
newWindowAnimation.stop();
// iconImageBuffer.anchors.centerIn = iconImageBuffer.parent;
wrapper.tempScaleWidth = 1;
wrapper.tempScaleHeight = 1;
}
onStopped: {
sendEndOfNeedThicknessAnimation();
clear();
}
onIsDemandingAttentionChanged: {
if(isDemandingAttention){
bounceNewWindow();
}
}
function sendEndOfNeedThicknessAnimation(){
if (needsThicknessSent) {
needsThicknessSent = false;
root.signalAnimationsNeedThickness(-1);
}
}
function init(){
wrapper.tempScaleWidth = wrapper.mScale;
wrapper.tempScaleHeight = wrapper.mScale;
if(!isDemandingAttention)
loops = 2;
else
loops = 20;
if (!needsThicknessSent) {
needsThicknessSent = true;
root.signalAnimationsNeedThickness(1);
}
// icList.hoveredIndex = -1;
}
function bounceNewWindow(){
if (isDemandingAttention && !root.dockIsHidden && (root.zoomFactor > 1)){
newWindowAnimation.init();
start();
}
}
Component.onCompleted: {
mainItemContainer.groupWindowAdded.connect(bounceNewWindow);
}
Component.onDestruction: {
sendEndOfNeedThicknessAnimation();
}
}

@ -0,0 +1,150 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
SequentialAnimation {
id: taskRealRemovalAnimation
PropertyAction { target: mainItemContainer; property: "ListView.delayRemove"; value: true }
PropertyAction { target: mainItemContainer; property: "inRemoveStage"; value: true }
//Animation Add/Remove (1) - when is window with no launcher, animations enabled
//Animation Add/Remove (4) - the user removes a launcher, animation enabled
property bool animation1: ((((tasksModel.launcherPosition(mainItemContainer.launcherUrl) == -1)
&& (tasksModel.launcherPosition(mainItemContainer.launcherUrlWithIcon) == -1) )
|| !launcherIsPresent(mainItemContainer.launcherUrl))
&& !mainItemContainer.isStartup)
property bool animation4: ((mainItemContainer.launcherUrl===root.launcherForRemoval
|| mainItemContainer.launcherUrlWithIcon===root.launcherForRemoval )&& mainItemContainer.isLauncher)
property bool enabledAnimation: (animation1 || animation4) && (root.durationTime !== 0) && !mainItemContainer.inBouncingAnimation;
ScriptAction{
script:{
root.mouseWasEntered.disconnect(signalMouseWasEntered);
root.draggingFinished.disconnect(handlerDraggingFinished);
root.clearZoomSignal.disconnect(clearZoom);
root.publishTasksGeometries.disconnect(slotPublishGeometries);
root.showPreviewForTasks.disconnect(slotShowPreviewForTasks);
root.updateScale.disconnect(wrapper.signalUpdateScale);
mainItemContainer.inAnimation = true;
icList.delayingRemoval = true;
mainItemContainer.inAddRemoveAnimation = true;
//trying to fix the ListView nasty behavior
//during the removal the anchoring for ListView children changes a lot
var previousTask = icList.childAtIndex(mainItemContainer.lastValidIndex-1);
if (previousTask !== undefined){
if (root.vertical) {
mainItemContainer.anchors.top = previousTask.bottom;
} else {
mainItemContainer.anchors.left = previousTask.right;
}
}
// console.log("1." + mainItemContainer.launcherUrl + " - " + taskRealRemovalAnimation.enabledAnimation);
// console.log("2." + root.launcherForRemoval + " - " + mainItemContainer.isLauncher);
root.signalAnimationsNeedLength(1);
}
}
//Ghost animation that acts as a delayer in case there is a bouncing animation
//taking place
PropertyAnimation {
target: wrapper
property: "opacity"
to: 1
duration: mainItemContainer.inBouncingAnimation ? //exactly how much the bounche animation lasts
5*(root.durationTime * 0.8 * units.longDuration) : 0
easing.type: Easing.InQuad
}
//end of ghost animation
PropertyAnimation {
target: wrapper
property: "mScale"
to: 1
duration: taskRealRemovalAnimation.enabledAnimation ? showWindowAnimation.speed : 0
easing.type: Easing.InQuad
}
//PropertyAction { target: wrapper; property: "opacity"; value: isWindow ? 0 : 1 }
//animation mainly for launchers removal and startups
ParallelAnimation{
id: removalAnimation
// property int speed: (IsStartup && !mainItemContainer.visible)? 0 : 400
//property int speed: 400
NumberAnimation {
target: wrapper;
property: "opacity";
to: 0;
duration: taskRealRemovalAnimation.enabledAnimation ? showWindowAnimation.speed : 0
easing.type: Easing.InQuad }
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 0
duration: taskRealRemovalAnimation.enabledAnimation ? showWindowAnimation.speed : 0
easing.type: Easing.InQuad
}
}
//smooth move into place the surrounding tasks
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleHeight" : "tempScaleWidth"
to: 0
duration: taskRealRemovalAnimation.enabledAnimation ? showWindowAnimation.speed : 0
easing.type: Easing.InQuad
}
ScriptAction{
script:{
if (showWindowAnimation.animationSent){
//console.log("SAFETY REMOVAL 1: animation removing ended");
showWindowAnimation.animationSent = false;
root.signalAnimationsNeedLength(-1);
}
root.signalAnimationsNeedLength(-1);
mainItemContainer.inAnimation = false;
icList.delayingRemoval = false;
if(mainItemContainer.launcherUrl===root.launcherForRemoval && mainItemContainer.isLauncher)
root.launcherForRemoval="";
//send signal that the launcher is really removing
if (mainItemContainer.inBouncingAnimation) {
mainItemContainer.visible = false;
root.removeWaitingLauncher(mainItemContainer.launcherUrl);
}
}
}
PropertyAction { target: mainItemContainer; property: "ListView.delayRemove"; value: false }
}

@ -0,0 +1,159 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import QtGraphicalEffects 1.0
import org.kde.plasma.plasmoid 2.0
import org.kde.latte 0.1 as Latte
/////Removing a Window from a group////
Item{
id:removingAnimation
function init(){
var relavantPoint = root.mapFromItem(centralItem,0,0);
var removingItem = removeTaskComponent.createObject(root);
removingItem.x = relavantPoint.x;
removingItem.y = relavantPoint.y;
removingItem.start();
}
function removeTask(){
if(!centralItem.toBeDestroyed && plasmoid.configuration.showShadows && Latte.WindowSystem.compositingActive){
removingAnimation.init();
}
}
Component.onCompleted: {
mainItemContainer.groupWindowRemoved.connect(removeTask);
}
///////////// Component for animating removing window from group
Component {
id: removeTaskComponent
Item{
id: removeTask
width: centralItem.width
height: centralItem.height
visible: false
Latte.IconItem{
id: tempRemoveIcon
anchors.rightMargin: root.position === PlasmaCore.Types.LeftPositioned ? root.thickMarginBase : 0
anchors.leftMargin: root.position === PlasmaCore.Types.RightPositioned ? root.thickMarginBase : 0
anchors.topMargin: root.position === PlasmaCore.Types.BottomPositioned ? root.thickMarginBase : 0
anchors.bottomMargin: root.position === PlasmaCore.Types.TopPositioned ? root.thickMarginBase : 0
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;
width: iconImageBuffer.width
height: width
visible: root.enableShadows ? false : true
source: iconImageBuffer.lastValidSourceName
}
Loader{
id: tempTaskShadow
anchors.fill: tempRemoveIcon
active: root.enableShadows
sourceComponent: DropShadow{
anchors.fill: parent
color: "#ff080808"
samples: 2 * radius
source: tempRemoveIcon
radius: centralItem.shadowSize
verticalOffset: 2
}
}
Colorize{
source: tempRemoveIcon
anchors.fill: tempRemoveIcon
hue: 0
saturation: 0
lightness: 0
}
ParallelAnimation{
id: componentRemoveAnimation
property int speed: 2*root.durationTime*units.longDuration
property Item removingItem: parent
property int toPoint: 0
PropertyAnimation {
target: removeTask
property: "opacity"
to: 0
duration: componentRemoveAnimation.speed
easing.type: Easing.InQuad
}
PropertyAnimation {
target: removeTask
property: (icList.orientation == Qt.Horizontal) ? "y" : "x"
to: componentRemoveAnimation.toPoint
duration: componentRemoveAnimation.speed
easing.type: Easing.InQuad
}
onStopped: {
removeTask.destroy();
gc();
}
}
function start(){
var tempPoint = 0;
if(icList.orientation == Qt.Horizontal)
tempPoint = y;
else
tempPoint = x;
if( (root.position === PlasmaCore.Types.BottomPositioned) ||
(root.position === PlasmaCore.Types.RightPositioned) ){
componentRemoveAnimation.toPoint = tempPoint + root.iconSize;
}
else{
componentRemoveAnimation.toPoint = tempPoint - root.iconSize;
}
visible = true;
componentRemoveAnimation.start();
}
}
}
}

@ -0,0 +1,52 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
///////Restore Zoom Animation/////
ParallelAnimation{
id: restoreAnimation
PropertyAnimation {
target: wrapper
property: "mScale"
to: 1
duration: 3 * mainItemContainer.animationTime
easing.type: Easing.Linear
}
PropertyAnimation {
target: hiddenSpacerLeft
property: "nScale"
to: 0
duration: 3 * mainItemContainer.animationTime
easing.type: Easing.Linear
}
PropertyAnimation {
target: hiddenSpacerRight
property: "nScale"
to: 0
duration: 3 * mainItemContainer.animationTime
easing.type: Easing.Linear
}
}

@ -0,0 +1,132 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.latte 0.1 as Latte
///item's added Animation
SequentialAnimation{
id:showWindowAnimation
property int speed: Latte.WindowSystem.compositingActive ? root.durationTime* (1.2*units.longDuration) : 0
property bool animationSent: false
//Ghost animation that acts as a delayer, in order to fix #342
PropertyAnimation {
target: wrapper
property: "opacity"
to: 0
//it is not depend to durationTime when animations are active
duration: root.durationTime > 0 ? 750 : 0
easing.type: Easing.InQuad
}
//end of ghost animation
ScriptAction{
script:{
if (!showWindowAnimation.animationSent) {
showWindowAnimation.animationSent = true;
root.signalAnimationsNeedLength(1);
}
}
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleHeight" : "tempScaleWidth"
to: 1
duration: showWindowAnimation.speed
easing.type: Easing.OutQuad
}
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: showWindowAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: "opacity"
from: 0
to: 1
duration: showWindowAnimation.speed
easing.type: Easing.OutQuad
}
}
onStopped: {
mainItemContainer.inAddRemoveAnimation = false;
if(mainItemContainer.isWindow || mainItemContainer.isStartup){
taskInitComponent.createObject(wrapper);
if (mainItemContainer.isDemandingAttention){
mainItemContainer.groupWindowAdded();
}
}
mainItemContainer.inAnimation = false;
if (showWindowAnimation.animationSent) {
root.signalAnimationsNeedLength(-1);
showWindowAnimation.animationSent = false;
}
}
function execute(){
//Animation Add/Remove (2) - when is window with no launcher, animations enabled
//Animation Add/Remove (3) - when is launcher with no window, animations enabled
var animation2 = ((((tasksModel.launcherPosition(mainItemContainer.launcherUrl) == -1)
&& (tasksModel.launcherPosition(mainItemContainer.launcherUrlWithIcon) == -1) )
|| !launcherIsPresent(mainItemContainer.launcherUrl))
&& mainItemContainer.isWindow);
var animation3 = ((!root.taskExists(mainItemContainer.launcherUrl) && mainItemContainer.isLauncher));
if (( animation2 || animation3) && (root.durationTime !== 0)){
wrapper.tempScaleWidth = 0;
wrapper.tempScaleHeight = 0;
start();
} else {
wrapper.tempScaleWidth = 1;
wrapper.tempScaleHeight = 1;
wrapper.opacity = 1;
mainItemContainer.inAnimation = false;
}
}
function showWindow(){
execute();
}
Component.onDestruction: {
if (animationSent){
//console.log("SAFETY REMOVAL 2: animation removing ended");
animationSent = false;
root.signalAnimationsNeedLength(-1);
}
}
}
Loading…
Cancel
Save