introduce Layouter ability

pull/15/head
Michail Vourlakos 5 years ago
parent 2a91cb55c1
commit 2ef0cdd944

@ -1,336 +0,0 @@
/*
* Copyright 2017-2018 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/>.
*/
//! FILLWIDTH/FILLHEIGHT COMPUTATIONS
//! Computations in order to calculate correctly the sizes for applets
//! that are requesting fillWidth or fillHeight
//! qBound style function that is specialized in Layouts
//! meaning that -1 values are ignored for fillWidth(s)/Height(s)
function layoutBound(min, pref, max){
if (max === -1) {
max = pref === -1 ? min : pref;
}
if (pref === -1) {
pref = max === -1 ? min : pref;
}
return Math.min(Math.max(min,pref),max);
}
//! initialize AppletItems flag "inFillCalculations" in order
//! to inform them that new calculations are taking place
function initLayoutForFillsCalculations(layout) {
for(var i=0; i<layout.children.length; ++i) {
var curApplet = layout.children[i];
if (curApplet.needsFillSpace) {
curApplet.inFillCalculations = true;
}
}
}
//! during step1/pass1 all applets that provide valid metrics (minimum/preferred/maximum values)
//! they gain a valid space in order to draw themeselves
function computeStep1ForLayout(layout, availableSpace, sizePerApplet, noOfApplets) {
for(var i=0; i<layout.children.length; ++i) {
var curApplet = layout.children[i];
if (curApplet.needsFillSpace) {
if (curApplet && curApplet.applet && curApplet.applet.Layout) {
var minSize = root.isVertical ? curApplet.applet.Layout.minimumHeight : curApplet.applet.Layout.minimumWidth;
var prefSize = root.isVertical ? curApplet.applet.Layout.preferredHeight : curApplet.applet.Layout.preferredWidth;
var maxSize = root.isVertical ? curApplet.applet.Layout.maximumHeight : curApplet.applet.Layout.maximumWidth;
// console.log( " s3_0 " + curApplet.applet.pluginName + " : (" +minSize+","+prefSize+","+maxSize+") ");
minSize = minSize>=0 && minSize!==Infinity ? minSize : -1;
prefSize = minSize>=0 && prefSize!==Infinity ? prefSize : -1;
maxSize = maxSize>=0 && maxSize!== Infinity ? maxSize : -1;
var appliedSize = -1;
//! check if the applet does not provide any valid metrics and for that case
//! the system must decide what space to be given after the applets that provide
//! nice metrics are assigned their sizes
var systemDecide = ((minSize<0) && (prefSize<0) && (maxSize<0));
if (!systemDecide) {
if (noOfApplets>1) {
appliedSize = layoutBound(minSize, prefSize, maxSize);
// console.log( " s3_1 " + curApplet.applet.pluginName + " : (" +minSize+","+prefSize+","+maxSize+") -> " + appliedSize);
} else if (noOfApplets===1) {
//! at this step if only one applet has remained for which the max size is not null,
//! then for this applet we make sure the maximum size does not exceed the available space
//! in order for the applet to not be drawn outside the boundaries
appliedSize = layoutBound(minSize, prefSize, Math.min(maxSize, sizePerApplet));
// console.log( " s3_2 " + curApplet.applet.pluginName + " : (" +minSize+","+prefSize+","+maxSize+") -> " + appliedSize);
}
//! appliedSize is valid and is also lower than the availableSpace, if it is not lower then
//! for this applet the needed space will be provided as a second pass in a fair way
//! between all remained applets that did not gain a valid fill space
if (appliedSize>=0 && appliedSize<=sizePerApplet) {
var properSize = Math.min(appliedSize, availableSpace);
var thickness = root.isVertical ? root.width : root.height;
var adjustedSize = curApplet.isHidden ? 0 : Math.max(thickness, properSize);
curApplet.sizeForFill = adjustedSize;
curApplet.inFillCalculations = false;
availableSpace = Math.max(0, availableSpace - curApplet.sizeForFill);
noOfApplets = noOfApplets - 1;
sizePerApplet = noOfApplets > 1 ? Math.floor(availableSpace / noOfApplets) : availableSpace;
// console.log( " s3_3 " + curApplet.applet.pluginName + " assigned: " + curApplet.sizeForFill);
}
}
// console.log("s3_r " +curApplet.applet.pluginName + " : " + availableSpace + " _ " + sizePerApplet + " _ " + noOfApplets + "\n");
}
}
}
return [availableSpace, sizePerApplet, noOfApplets];
}
//! during step2/pass2 all the applets with fills
//! that remained with no computations from pass1
//! are updated with the algorithm's proposed size
function computeStep2ForLayout(layout, sizePerApplet, noOfApplets) {
if (sizePerApplet>0) {
if (noOfApplets === 0) {
//! when all applets have assigned some size and there is still free space, we must find
//! the most demanding space applet and assign the remaining space to it
var mostDemandingAppletSize = 0;
var mostDemandingApplet = undefined;
//! applets with no strong opinion
var neutralAppletsNo = 0;
var neutralApplets = [];
for(var i=0; i<layout.children.length; ++i) {
var curApplet = layout.children[i];
//! the most demanding applet is the one that has maximum size set to Infinity
//! AND is not Neutral, meaning that it provided some valid metrics
//! AND at the same time gained from step one the biggest space
if (curApplet && curApplet.needsFillSpace && curApplet.applet && curApplet.applet.Layout) {
var minSize = root.isVertical ? curApplet.applet.Layout.minimumHeight : curApplet.applet.Layout.minimumWidth;
var prefSize = root.isVertical ? curApplet.applet.Layout.preferredHeight : curApplet.applet.Layout.preferredWidth;
var maxSize = root.isVertical ? curApplet.applet.Layout.maximumHeight : curApplet.applet.Layout.maximumWidth;
var isNeutral = (minSize<=0 && prefSize<=0);
// console.log( " s4_0 " + curApplet.applet.pluginName + " : (" +minSize+","+prefSize+","+maxSize+") ");
if (!isNeutral && maxSize===Infinity && curApplet.sizeForFill>mostDemandingAppletSize) {
mostDemandingApplet = curApplet;
mostDemandingAppletSize = curApplet.sizeForFill;
} else if (isNeutral) {
neutralAppletsNo = neutralAppletsNo + 1;
neutralApplets.push(curApplet);
}
}
}
if (mostDemandingApplet) {
//! the most demanding applet gains all the remaining space
mostDemandingApplet.sizeForFill = mostDemandingApplet.sizeForFill + sizePerApplet;
// console.log("s4_1 "+ mostDemandingApplet.applet.pluginName + " assigned: " + mostDemandingApplet.sizeForFill + "\n");
} else if (neutralAppletsNo>0) {
//! if no demanding applets was found then the available space is splitted equally
//! between all neutralApplets
var adjustedAppletSize = (sizePerApplet / neutralAppletsNo);
for (var j=0; j<neutralApplets.length; ++j) {
// console.log("s4_2.0 "+ neutralApplets[j].applet.pluginName + " _ " + neutralApplets[j].sizeForFill + " _ " + adjustedAppletSize);
neutralApplets[j].sizeForFill = neutralApplets[j].sizeForFill + adjustedAppletSize;
// console.log("s4_2 "+ neutralApplets[j].applet.pluginName + " assigned: " + sizePerApplet + "\n");
}
}
} else {
for(var i=0; i<layout.children.length; ++i) {
var curApplet = layout.children[i];
if (curApplet && curApplet.needsFillSpace && curApplet.inFillCalculations) {
curApplet.sizeForFill = sizePerApplet;
// console.log("s4_3 "+ curApplet.applet.pluginName + " assigned: " + sizePerApplet + "\n");
curApplet.inFillCalculations = false;
}
}
}
}
}
//! initialize the three layouts and execute the step1/phase1
//! it is used when the Centered (Main)Layout is used only or when the Main(Layout)
//! is empty in Justify mode
function initializationPhase(availableSpace, sizePerApplet, noOfApplets){
if (root.panelAlignment === LatteCore.Types.Justify) {
initLayoutForFillsCalculations(startLayout);
initLayoutForFillsCalculations(endLayout);
}
initLayoutForFillsCalculations(mainLayout);
// console.log("s3...");
//! first pass in order to update sizes for applet that want to fill space
//! but their maximum metrics are lower than the sizePerApplet
var res = computeStep1ForLayout(mainLayout, availableSpace, sizePerApplet, noOfApplets);
availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];
// console.log( " i1 : " + availableSpace + " _ " + sizePerApplet + " _ " + noOfApplets );
if (root.panelAlignment === LatteCore.Types.Justify) {
res = computeStep1ForLayout(startLayout, availableSpace, sizePerApplet, noOfApplets);
availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];
// console.log( " i2 : " + availableSpace + " _ " + sizePerApplet + " _ " + noOfApplets );
res = computeStep1ForLayout(endLayout, availableSpace, sizePerApplet, noOfApplets);
availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];
// console.log( " i3 : " + availableSpace + " _ " + sizePerApplet + " _ " + noOfApplets );
}
return [availableSpace, sizePerApplet, noOfApplets];
}
function updateSizeForAppletsInFill() {
if (animations.inNormalFillCalculationsState) {
// console.log("-------------");
// console.log("s1...");
var noA = startLayout.fillApplets + mainLayout.fillApplets + endLayout.fillApplets;
if (noA === 0)
return;
// console.log("s2...");
if (mainLayout.shownApplets === 0 || root.panelAlignment !== LatteCore.Types.Justify) {
// console.log(" S2 _ SIZES ::: " + root.maxLength + " ___ " + startLayout.sizeWithNoFillApplets + " ___ " + mainLayout.sizeWithNoFillApplets + " ___ " + endLayout.sizeWithNoFillApplets);
var availableSpace = Math.max(0, root.maxLength - startLayout.sizeWithNoFillApplets - mainLayout.sizeWithNoFillApplets - endLayout.sizeWithNoFillApplets - root.panelEdgeSpacing);
var sizePerApplet = availableSpace / noA;
var res = initializationPhase(availableSpace, sizePerApplet, noA);
availableSpace = res[0]; sizePerApplet = res[1]; noA = res[2];
// console.log("s4...");
//! after step1 there is a chance that all applets were assigned a valid space
//! but at the same time some space remained free. In such case we make sure
//! that remained space will be assigned to the most demanding applet.
//! This is achieved by <layout>No values. For step2 passing value!=0
//! means default step2 behavior BUT value=0 means that remained space
//! must be also assigned at the end.
var remainedSpace = (noA === 0 && sizePerApplet > 0) ? true : false
var startNo = -1;
var mainNo = -1;
var endNo = -1;
if (remainedSpace) {
if (startLayout.fillApplets > 0) {
startNo = 0;
} else if (endLayout.fillApplets > 0) {
endNo = 0;
} else if (mainLayout.fillApplets > 0) {
mainNo = 0;
}
}
//! second pass in order to update sizes for applet that want to fill space
//! these applets get the direct division of the available free space that
//! remained from step1 OR the the free available space that no applet requested yet
computeStep2ForLayout(startLayout, sizePerApplet, startNo); //default behavior
computeStep2ForLayout(mainLayout, sizePerApplet, mainNo); //default behavior
computeStep2ForLayout(endLayout, sizePerApplet, endNo); //default behavior
//console.log("s5...");
} else {
//! Justify mode in all remaining cases
// console.log(" S3 _ SIZES ::: " + root.maxLength + " ___ " + startLayout.sizeWithNoFillApplets + " ___ " + mainLayout.sizeWithNoFillApplets + " ___ " + endLayout.sizeWithNoFillApplets);
//! compute the two free spaces around the centered layout
//! they are called start and end accordingly
var halfMainLayout = mainLayout.sizeWithNoFillApplets / 2;
var availableSpaceStart = Math.max(0, root.maxLength/2 - startLayout.sizeWithNoFillApplets - halfMainLayout - root.panelEdgeSpacing/2);
var availableSpaceEnd = Math.max(0, root.maxLength/2 - endLayout.sizeWithNoFillApplets - halfMainLayout - root.panelEdgeSpacing/2);
var availableSpace = availableSpaceStart + availableSpaceEnd - mainLayout.sizeWithNoFillApplets;
var sizePerAppletMain = mainLayout.fillApplets > 0 ? availableSpace / noA : 0 ;
var noStart = startLayout.fillApplets;
var noMain = mainLayout.fillApplets;
var noEnd = endLayout.fillApplets;
//! initialize the computations
initLayoutForFillsCalculations(startLayout);
initLayoutForFillsCalculations(mainLayout);
initLayoutForFillsCalculations(endLayout);
var res;
//! first pass
if (mainLayout.fillApplets > 0){
res = computeStep1ForLayout(mainLayout, availableSpace, sizePerAppletMain, noMain);
sizePerAppletMain = res[1]; noMain = res[2];
var dif = (availableSpace - res[0]) / 2;
availableSpaceStart = availableSpaceStart - dif;
availableSpaceEnd = availableSpaceEnd - dif;
}
var sizePerAppletStart = startLayout.fillApplets > 0 ? availableSpaceStart / noStart : 0 ;
var sizePerAppletEnd = endLayout.fillApplets > 0 ? availableSpaceEnd / noEnd : 0 ;
if (startLayout.fillApplets > 0) {
res = computeStep1ForLayout(startLayout, availableSpaceStart, sizePerAppletStart, noStart);
availableSpaceStart = res[0]; sizePerAppletStart = res[1]; noStart = res[2];
}
if (endLayout.fillApplets > 0) {
res = computeStep1ForLayout(endLayout, availableSpaceEnd, sizePerAppletEnd, noEnd);
availableSpaceEnd = res[0]; sizePerAppletEnd = res[1]; noEnd = res[2];
}
////
//! second pass
// console.log(" S ::: " +startLayout.fillApplets + " _ " + sizePerAppletStart + " _ " + noStart);
if (mainLayout.fillApplets > 0) {
computeStep2ForLayout(mainLayout, sizePerAppletMain, noMain); //default behavior
}
if (startLayout.fillApplets > 0) {
computeStep2ForLayout(startLayout, sizePerAppletStart, noStart);
}
if (endLayout.fillApplets > 0) {
computeStep2ForLayout(endLayout, sizePerAppletEnd, noEnd);
}
}
}
}

@ -433,7 +433,7 @@ Item{
onNormalStateChanged: {
if (normalState) {
autosize.updateIconSize();
root.updateSizeForAppletsInFill();
layouter.updateSizeForAppletsInFill();
}
}

@ -29,15 +29,6 @@ ContainerAbility.Animations {
property Item metrics: null
property QtObject settings: null
//TO BE MOVED in LAYOUTER ability
property bool appletsInParentChange: false
readonly property bool inNormalFillCalculationsState: needBothAxis.count === 0
&& needThickness.count === 0
&& ((needLength.count === 0)
|| (needLength.count===1 && editModeVisual.inEditMode))
&& (!dragOverlay || (dragOverlay && !dragOverlay.pressed)) /*do not update during moving/dragging applets*/
&& !appletsInParentChange
//! Public Properties
active: plasmoid.configuration.animationsEnabled && LatteCore.WindowSystem.compositingActive

@ -31,7 +31,7 @@ Item {
// the automatic icon size algorithm should better be disabled
readonly property bool isActive: plasmoid.configuration.autoSizeEnabled
&& !root.containsOnlyPlasmaTasks
&& layouts.fillApplets<=0
&& layouter.fillApplets<=0
&& latteView && latteView.visibility.mode !== LatteCore.Types.SideBar
property int iconSize: -1 //it is not set, this is the default
@ -49,6 +49,7 @@ Item {
//! required elements
property Item layouts
property Item layouter
property Item metrics
property Item visibility

@ -25,7 +25,7 @@ import "./privates" as Ability
Ability.IndexerPrivate {
//! do not update during dragging/moving applets inConfigureAppletsMode
updateIsBlocked: (root.dragOverlay && root.dragOverlay.pressed)
|| animations.appletsInParentChange
|| layouter.appletsInParentChange
function getClientBridge(index) {
if (clientsBridges.length<=0) {

@ -0,0 +1,64 @@
/*
* Copyright 2020 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.7
import org.kde.plasma.plasmoid 2.0
import "./privates" as Ability
Ability.LayouterPrivate {
id: _layouter
property bool appletsInParentChange: false
readonly property bool inNormalFillCalculationsState: animations.needBothAxis.count === 0
&& animations.needThickness.count === 0
&& ((animations.needLength.count === 0)
|| (animations.needLength.count===1 && editModeVisual.inEditMode))
&& (!dragOverlay || (dragOverlay && !dragOverlay.pressed)) /*do not update during moving/dragging applets*/
&& !appletsInParentChange
function updateSizeForAppletsInFill() {
if (!updateSizeForAppletsInFillTimer.running) {
_layouter._updateSizeForAppletsInFill();
updateSizeForAppletsInFillTimer.start();
}
}
onInNormalFillCalculationsStateChanged: {
if (inNormalFillCalculationsState) {
_layouter.updateSizeForAppletsInFill();
}
}
Connections {
target: layouts
onContentsLengthChanged: _layouter.updateSizeForAppletsInFill();
}
//! This timer is needed in order to reduce the calls to heavy cpu function
//! updateSizeForAppletsInFill()
Timer{
id: updateSizeForAppletsInFillTimer
interval: 50
onTriggered: _layouter._updateSizeForAppletsInFill();
}
}

@ -0,0 +1,363 @@
/*
* Copyright 2020 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.7
import org.kde.plasma.plasmoid 2.0
import org.kde.latte.core 0.2 as LatteCore
import "./layouter" as LayouterElements
Item {
property Item layouts: null
property Item animations: null
property Item indexer: null
readonly property int fillApplets: startLayout.fillApplets + mainLayout.fillApplets + endLayout.fillApplets
readonly property Item startLayout: LayouterElements.AppletsContainer {
grid: layouts.startLayout
}
readonly property Item mainLayout: LayouterElements.AppletsContainer {
grid: layouts.mainLayout
}
readonly property Item endLayout: LayouterElements.AppletsContainer {
grid: layouts.endLayout
}
//! FILLWIDTH/FILLHEIGHT COMPUTATIONS
//! Computations in order to calculate correctly the sizes for applets
//! that are requesting fillWidth or fillHeight
//! qBound style function that is specialized in Layouts
//! meaning that -1 values are ignored for fillWidth(s)/Height(s)
function layoutBound(min, pref, max){
if (max === -1) {
max = pref === -1 ? min : pref;
}
if (pref === -1) {
pref = max === -1 ? min : pref;
}
return Math.min(Math.max(min,pref),max);
}
//! initialize AppletItems flag "inFillCalculations" in order
//! to inform them that new calculations are taking place
function initLayoutForFillsCalculations(layout) {
for(var i=0; i<layout.children.length; ++i) {
var curApplet = layout.children[i];
if (curApplet.needsFillSpace) {
curApplet.inFillCalculations = true;
}
}
}
//! during step1/pass1 all applets that provide valid metrics (minimum/preferred/maximum values)
//! they gain a valid space in order to draw themeselves
function computeStep1ForLayout(layout, availableSpace, sizePerApplet, noOfApplets) {
for(var i=0; i<layout.children.length; ++i) {
var curApplet = layout.children[i];
if (curApplet.needsFillSpace) {
if (curApplet && curApplet.applet && curApplet.applet.Layout) {
var minSize = root.isVertical ? curApplet.applet.Layout.minimumHeight : curApplet.applet.Layout.minimumWidth;
var prefSize = root.isVertical ? curApplet.applet.Layout.preferredHeight : curApplet.applet.Layout.preferredWidth;
var maxSize = root.isVertical ? curApplet.applet.Layout.maximumHeight : curApplet.applet.Layout.maximumWidth;
// console.log( " s3_0 " + curApplet.applet.pluginName + " : (" +minSize+","+prefSize+","+maxSize+") ");
minSize = minSize>=0 && minSize!==Infinity ? minSize : -1;
prefSize = minSize>=0 && prefSize!==Infinity ? prefSize : -1;
maxSize = maxSize>=0 && maxSize!== Infinity ? maxSize : -1;
var appliedSize = -1;
//! check if the applet does not provide any valid metrics and for that case
//! the system must decide what space to be given after the applets that provide
//! nice metrics are assigned their sizes
var systemDecide = ((minSize<0) && (prefSize<0) && (maxSize<0));
if (!systemDecide) {
if (noOfApplets>1) {
appliedSize = layoutBound(minSize, prefSize, maxSize);
// console.log( " s3_1 " + curApplet.applet.pluginName + " : (" +minSize+","+prefSize+","+maxSize+") -> " + appliedSize);
} else if (noOfApplets===1) {
//! at this step if only one applet has remained for which the max size is not null,
//! then for this applet we make sure the maximum size does not exceed the available space
//! in order for the applet to not be drawn outside the boundaries
appliedSize = layoutBound(minSize, prefSize, Math.min(maxSize, sizePerApplet));
// console.log( " s3_2 " + curApplet.applet.pluginName + " : (" +minSize+","+prefSize+","+maxSize+") -> " + appliedSize);
}
//! appliedSize is valid and is also lower than the availableSpace, if it is not lower then
//! for this applet the needed space will be provided as a second pass in a fair way
//! between all remained applets that did not gain a valid fill space
if (appliedSize>=0 && appliedSize<=sizePerApplet) {
var properSize = Math.min(appliedSize, availableSpace);
var thickness = root.isVertical ? root.width : root.height;
var adjustedSize = curApplet.isHidden ? 0 : Math.max(thickness, properSize);
curApplet.sizeForFill = adjustedSize;
curApplet.inFillCalculations = false;
availableSpace = Math.max(0, availableSpace - curApplet.sizeForFill);
noOfApplets = noOfApplets - 1;
sizePerApplet = noOfApplets > 1 ? Math.floor(availableSpace / noOfApplets) : availableSpace;
// console.log( " s3_3 " + curApplet.applet.pluginName + " assigned: " + curApplet.sizeForFill);
}
}
// console.log("s3_r " +curApplet.applet.pluginName + " : " + availableSpace + " _ " + sizePerApplet + " _ " + noOfApplets + "\n");
}
}
}
return [availableSpace, sizePerApplet, noOfApplets];
}
//! during step2/pass2 all the applets with fills
//! that remained with no computations from pass1
//! are updated with the algorithm's proposed size
function computeStep2ForLayout(layout, sizePerApplet, noOfApplets) {
if (sizePerApplet>0) {
if (noOfApplets === 0) {
//! when all applets have assigned some size and there is still free space, we must find
//! the most demanding space applet and assign the remaining space to it
var mostDemandingAppletSize = 0;
var mostDemandingApplet = undefined;
//! applets with no strong opinion
var neutralAppletsNo = 0;
var neutralApplets = [];
for(var i=0; i<layout.children.length; ++i) {
var curApplet = layout.children[i];
//! the most demanding applet is the one that has maximum size set to Infinity
//! AND is not Neutral, meaning that it provided some valid metrics
//! AND at the same time gained from step one the biggest space
if (curApplet && curApplet.needsFillSpace && curApplet.applet && curApplet.applet.Layout) {
var minSize = root.isVertical ? curApplet.applet.Layout.minimumHeight : curApplet.applet.Layout.minimumWidth;
var prefSize = root.isVertical ? curApplet.applet.Layout.preferredHeight : curApplet.applet.Layout.preferredWidth;
var maxSize = root.isVertical ? curApplet.applet.Layout.maximumHeight : curApplet.applet.Layout.maximumWidth;
var isNeutral = (minSize<=0 && prefSize<=0);
// console.log( " s4_0 " + curApplet.applet.pluginName + " : (" +minSize+","+prefSize+","+maxSize+") ");
if (!isNeutral && maxSize===Infinity && curApplet.sizeForFill>mostDemandingAppletSize) {
mostDemandingApplet = curApplet;
mostDemandingAppletSize = curApplet.sizeForFill;
} else if (isNeutral) {
neutralAppletsNo = neutralAppletsNo + 1;
neutralApplets.push(curApplet);
}
}
}
if (mostDemandingApplet) {
//! the most demanding applet gains all the remaining space
mostDemandingApplet.sizeForFill = mostDemandingApplet.sizeForFill + sizePerApplet;
// console.log("s4_1 "+ mostDemandingApplet.applet.pluginName + " assigned: " + mostDemandingApplet.sizeForFill + "\n");
} else if (neutralAppletsNo>0) {
//! if no demanding applets was found then the available space is splitted equally
//! between all neutralApplets
var adjustedAppletSize = (sizePerApplet / neutralAppletsNo);
for (var j=0; j<neutralApplets.length; ++j) {
// console.log("s4_2.0 "+ neutralApplets[j].applet.pluginName + " _ " + neutralApplets[j].sizeForFill + " _ " + adjustedAppletSize);
neutralApplets[j].sizeForFill = neutralApplets[j].sizeForFill + adjustedAppletSize;
// console.log("s4_2 "+ neutralApplets[j].applet.pluginName + " assigned: " + sizePerApplet + "\n");
}
}
} else {
for(var i=0; i<layout.children.length; ++i) {
var curApplet = layout.children[i];
if (curApplet && curApplet.needsFillSpace && curApplet.inFillCalculations) {
curApplet.sizeForFill = sizePerApplet;
// console.log("s4_3 "+ curApplet.applet.pluginName + " assigned: " + sizePerApplet + "\n");
curApplet.inFillCalculations = false;
}
}
}
}
}
//! initialize the three layouts and execute the step1/phase1
//! it is used when the Centered (Main)Layout is used only or when the Main(Layout)
//! is empty in Justify mode
function initializationPhase(availableSpace, sizePerApplet, noOfApplets){
if (root.panelAlignment === LatteCore.Types.Justify) {
initLayoutForFillsCalculations(startLayout.grid);
initLayoutForFillsCalculations(endLayout.grid);
}
initLayoutForFillsCalculations(mainLayout.grid);
// console.log("s3...");
//! first pass in order to update sizes for applet that want to fill space
//! but their maximum metrics are lower than the sizePerApplet
var res = computeStep1ForLayout(mainLayout.grid, availableSpace, sizePerApplet, noOfApplets);
availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];
// console.log( " i1 : " + availableSpace + " _ " + sizePerApplet + " _ " + noOfApplets );
if (root.panelAlignment === LatteCore.Types.Justify) {
res = computeStep1ForLayout(startLayout.grid, availableSpace, sizePerApplet, noOfApplets);
availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];
// console.log( " i2 : " + availableSpace + " _ " + sizePerApplet + " _ " + noOfApplets );
res = computeStep1ForLayout(endLayout.grid, availableSpace, sizePerApplet, noOfApplets);
availableSpace = res[0]; sizePerApplet = res[1]; noOfApplets = res[2];
// console.log( " i3 : " + availableSpace + " _ " + sizePerApplet + " _ " + noOfApplets );
}
return [availableSpace, sizePerApplet, noOfApplets];
}
function _updateSizeForAppletsInFill() {
if (inNormalFillCalculationsState) {
// console.log("-------------");
// console.log("s1...");
var noA = startLayout.fillApplets + mainLayout.fillApplets + endLayout.fillApplets;
if (noA === 0)
return;
// console.log("s2...");
if (mainLayout.shownApplets === 0 || root.panelAlignment !== LatteCore.Types.Justify) {
// console.log(" S2 _ SIZES ::: " + root.maxLength + " ___ " + startLayout.sizeWithNoFillApplets + " ___ " + mainLayout.sizeWithNoFillApplets + " ___ " + endLayout.sizeWithNoFillApplets);
var availableSpace = Math.max(0, root.maxLength - startLayout.sizeWithNoFillApplets - mainLayout.sizeWithNoFillApplets - endLayout.sizeWithNoFillApplets - root.panelEdgeSpacing);
var sizePerApplet = availableSpace / noA;
var res = initializationPhase(availableSpace, sizePerApplet, noA);
availableSpace = res[0]; sizePerApplet = res[1]; noA = res[2];
// console.log("s4...");
//! after step1 there is a chance that all applets were assigned a valid space
//! but at the same time some space remained free. In such case we make sure
//! that remained space will be assigned to the most demanding applet.
//! This is achieved by <layout>No values. For step2 passing value!=0
//! means default step2 behavior BUT value=0 means that remained space
//! must be also assigned at the end.
var remainedSpace = (noA === 0 && sizePerApplet > 0) ? true : false
var startNo = -1;
var mainNo = -1;
var endNo = -1;
if (remainedSpace) {
if (startLayout.fillApplets > 0) {
startNo = 0;
} else if (lendLayout.fillApplets > 0) {
endNo = 0;
} else if (mainLayout.fillApplets > 0) {
mainNo = 0;
}
}
//! second pass in order to update sizes for applet that want to fill space
//! these applets get the direct division of the available free space that
//! remained from step1 OR the the free available space that no applet requested yet
computeStep2ForLayout(startLayout.grid, sizePerApplet, startNo); //default behavior
computeStep2ForLayout(mainLayout.grid, sizePerApplet, mainNo); //default behavior
computeStep2ForLayout(endLayout.grid, sizePerApplet, endNo); //default behavior
//console.log("s5...");
} else {
//! Justify mode in all remaining cases
// console.log(" S3 _ SIZES ::: " + root.maxLength + " ___ " + startLayout.sizeWithNoFillApplets + " ___ " + mainLayout.sizeWithNoFillApplets + " ___ " + endLayout.sizeWithNoFillApplets);
//! compute the two free spaces around the centered layout
//! they are called start and end accordingly
var halfMainLayout = mainLayout.sizeWithNoFillApplets / 2;
var availableSpaceStart = Math.max(0, root.maxLength/2 - startLayout.sizeWithNoFillApplets - halfMainLayout - root.panelEdgeSpacing/2);
var availableSpaceEnd = Math.max(0, root.maxLength/2 - endLayout.sizeWithNoFillApplets - halfMainLayout - root.panelEdgeSpacing/2);
var availableSpace = availableSpaceStart + availableSpaceEnd - mainLayout.sizeWithNoFillApplets;
var sizePerAppletMain = mainLayout.fillApplets > 0 ? availableSpace / noA : 0 ;
var noStart = startLayout.fillApplets;
var noMain = mainLayout.fillApplets;
var noEnd = endLayout.fillApplets;
//! initialize the computations
initLayoutForFillsCalculations(startLayout.grid);
initLayoutForFillsCalculations(mainLayout.grid);
initLayoutForFillsCalculations(endLayout.grid);
var res;
//! first pass
if (mainLayout.fillApplets > 0){
res = computeStep1ForLayout(mainLayout.grid, availableSpace, sizePerAppletMain, noMain);
sizePerAppletMain = res[1]; noMain = res[2];
var dif = (availableSpace - res[0]) / 2;
availableSpaceStart = availableSpaceStart - dif;
availableSpaceEnd = availableSpaceEnd - dif;
}
var sizePerAppletStart = startLayout.fillApplets > 0 ? availableSpaceStart / noStart : 0 ;
var sizePerAppletEnd = endLayout.fillApplets > 0 ? availableSpaceEnd / noEnd : 0 ;
if (startLayout.fillApplets > 0) {
res = computeStep1ForLayout(startLayout.grid, availableSpaceStart, sizePerAppletStart, noStart);
availableSpaceStart = res[0]; sizePerAppletStart = res[1]; noStart = res[2];
}
if (endLayout.fillApplets > 0) {
res = computeStep1ForLayout(endLayout.grid, availableSpaceEnd, sizePerAppletEnd, noEnd);
availableSpaceEnd = res[0]; sizePerAppletEnd = res[1]; noEnd = res[2];
}
////
//! second pass
// console.log(" S ::: " +startLayout.fillApplets + " _ " + sizePerAppletStart + " _ " + noStart);
if (mainLayout.fillApplets > 0) {
computeStep2ForLayout(mainLayout.grid, sizePerAppletMain, noMain); //default behavior
}
if (startLayout.fillApplets > 0) {
computeStep2ForLayout(startLayout.grid, sizePerAppletStart, noStart);
}
if (endLayout.fillApplets > 0) {
computeStep2ForLayout(endLayout.grid, sizePerAppletEnd, noEnd);
}
}
}
}
}

@ -0,0 +1,155 @@
/*
* Copyright 2020 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.7
Item {
id: appletsContainer
property Item grid: null
// items in grid
readonly property int count: grid.children.length
//it is used in calculations for fillWidth,fillHeight applets
property int shownApplets: 0
property int fillApplets: 0
//it is used in calculations for fillWidth,fillHeight applets
property int sizeWithNoFillApplets: 0
readonly property int maxIndex: 99999
property int firstVisibleIndex: -1
property int lastVisibleIndex: -1
//! do not update during dragging/moving applets inConfigureAppletsMode
readonly property bool updateIsBlocked: (root.dragOverlay && root.dragOverlay.pressed) || appletsInParentChange
Binding{
target: appletsContainer
property:"sizeWithNoFillApplets"
when: appletsContainer && grid && !updateIsBlocked && inNormalFillCalculationsState
value: {
var space = 0;
for (var i=0; i<grid.children.length; ++i){
if (grid.children[i]
&& !grid.children[i].needsFillSpace
&& !grid.children[i].isHidden) {
space = root.isHorizontal ? space + grid.children[i].width : space + grid.children[i].height;
}
}
return space;
}
}
Binding{
target: appletsContainer
property:"shownApplets"
when: appletsContainer && grid && !updateIsBlocked
value: {
var res = 0;
for (var i=0; i<grid.children.length; ++i){
if (grid.children[i] && grid.children[i].isHidden) {
//do nothing
} else if (grid.children[i] && (grid.children[i].applet || grid.children[i].isInternalViewSplitter)){
res = res + 1;
}
}
return res;
}
}
Binding{
target: appletsContainer
property:"fillApplets"
when: appletsContainer && grid && !updateIsBlocked
value: {
var no = 0;
for (var i=0; i<grid.children.length; ++i){
if (grid.children[i] && grid.children[i].needsFillSpace) {
//console.log("fill :::: " + children[i].applet.pluginName);
no++;
}
}
return no;
}
}
Binding{
target: appletsContainer
property:"firstVisibleIndex"
when: appletsContainer && grid && !updateIsBlocked
value: {
var ind = maxIndex;
for(var i=0; i<grid.children.length; ++i) {
var appletItem = grid.children[i];
if (appletItem && appletItem.index>=0
&& indexer.hidden.indexOf(appletItem.index)<0
&& indexer.separators.indexOf(appletItem.index)<0
&& appletItem.index < ind) {
ind = appletItem.index;
}
}
return ind === maxIndex ? -1 : ind;
}
}
Binding{
target: appletsContainer
property:"lastVisibleIndex"
when: appletsContainer && grid && !updateIsBlocked
value: {
var ind = -1;
for(var i=0; i<grid.children.length; ++i) {
var appletItem = grid.children[i];
if (appletItem && appletItem.index>=0
&& indexer.hidden.indexOf(appletItem.index)<0
&& indexer.separators.indexOf(appletItem.index)<0
&& appletItem.index > ind) {
ind = appletItem.index;
}
}
return ind;
}
}
onCountChanged: {
if (root.editMode) {
//! this is mainly used when removing/adding internal view splitters
//! in order to not break the parabolic effect from wrong indexes
root.updateIndexes();
}
}
onFillAppletsChanged: layouter.updateSizeForAppletsInFill();
onShownAppletsChanged: layouter.updateSizeForAppletsInFill();
onSizeWithNoFillAppletsChanged: {
console.log(sizeWithNoFillApplets)
layouter.updateSizeForAppletsInFill();
}
}

@ -87,10 +87,10 @@ Item {
property bool isSpacer: applet && (applet.pluginName === "org.kde.latte.spacer")
property bool isSystray: applet && (applet.pluginName === "org.kde.plasma.systemtray" || applet.pluginName === "org.nomad.systemtray" )
property bool firstChildOfStartLayout: index === layoutsContainer.startLayout.firstVisibleIndex
property bool firstChildOfMainLayout: index === layoutsContainer.mainLayout.firstVisibleIndex
property bool lastChildOfMainLayout: index === layoutsContainer.mainLayout.lastVisibleIndex
property bool lastChildOfEndLayout: index === layoutsContainer.endLayout.lastVisibleIndex
property bool firstChildOfStartLayout: index === appletItem.layouter.startLayout.firstVisibleIndex
property bool firstChildOfMainLayout: index === appletItem.layouter.mainLayout.firstVisibleIndex
property bool lastChildOfMainLayout: index === appletItem.layouter.mainLayout.lastVisibleIndex
property bool lastChildOfEndLayout: index === appletItem.layouter.endLayout.lastVisibleIndex
readonly property bool atScreenEdge: {
if (root.panelAlignment !== LatteCore.Types.Justify || root.inConfigureAppletsMode || plasmoid.configuration.offset!==0) {
@ -141,14 +141,14 @@ Item {
//applet is in starting edge
property bool firstAppletInContainer: (index >=0) &&
((index === layoutsContainer.startLayout.firstVisibleIndex)
|| (index === layoutsContainer.mainLayout.firstVisibleIndex)
|| (index === layoutsContainer.endLayout.firstVisibleIndex))
((index === layouter.startLayout.firstVisibleIndex)
|| (index === layouter.mainLayout.firstVisibleIndex)
|| (index === layouter.endLayout.firstVisibleIndex))
//applet is in ending edge
property bool lastAppletInContainer: (index >=0) &&
((index === layoutsContainer.startLayout.lastVisibleIndex)
|| (index === layoutsContainer.mainLayout.lastVisibleIndex)
|| (index === layoutsContainer.endLayout.lastVisibleIndex))
((index === layouter.startLayout.lastVisibleIndex)
|| (index === layouter.mainLayout.lastVisibleIndex)
|| (index === layouter.endLayout.lastVisibleIndex))
readonly property bool acceptMouseEvents: applet && !isLattePlasmoid && !originalAppletBehavior && !appletItem.isSeparator && !communicator.requires.parabolicEffectLocked
readonly property bool originalAppletBehavior: (appletItem.parabolic.factor.zoom === 1 && !lockZoom /*hacky flag to keep Latte behavior*/)
@ -282,6 +282,7 @@ Item {
property Item animations: null
property Item indexer: null
property Item layouter: null
property Item metrics: null
property Item parabolic: null
@ -419,7 +420,7 @@ Item {
function checkIndex(){
index = -1;
for(var i=0; i<layoutsContainer.startLayout.count; ++i){
for(var i=0; i<appletItem.layouter.startLayout.count; ++i){
var child = layoutsContainer.startLayout.children[i];
if (child === appletItem){
index = layoutsContainer.startLayout.beginIndex + i;
@ -427,7 +428,7 @@ Item {
}
}
for(var i=0; i<layoutsContainer.mainLayout.count; ++i){
for(var i=0; i<appletItem.layouter.mainLayout.count; ++i){
var child = layoutsContainer.mainLayout.children[i];
if (child === appletItem){
index = layoutsContainer.mainLayout.beginIndex + i;
@ -435,7 +436,7 @@ Item {
}
}
for(var i=0; i<layoutsContainer.endLayout.count; ++i){
for(var i=0; i<appletItem.layouter.endLayout.count; ++i){
var child = layoutsContainer.endLayout.children[i];
if (child === appletItem){
//create a very high index in order to not need to exchange hovering messages
@ -451,9 +452,9 @@ Item {
else
latteApplet.disableLeftSpacer = true;
if( index === layoutsContainer.startLayout.beginIndex + layoutsContainer.startLayout.count - 1
|| index===layoutsContainer.mainLayout.beginIndex + layoutsContainer.mainLayout.count - 1
|| index === layoutsContainer.endLayout.beginIndex + layoutsContainer.endLayout.count - 1)
if( index === layoutsContainer.startLayout.beginIndex + appletItem.layouter.startLayout.count - 1
|| index===layoutsContainer.mainLayout.beginIndex + appletItem.layouter.mainLayout.count - 1
|| index === layoutsContainer.endLayout.beginIndex + appletItem.layouter.endLayout.count - 1)
latteApplet.disableRightSpacer = false;
else
latteApplet.disableRightSpacer = true;

@ -295,7 +295,7 @@ Item{
appletItem.movingForResize = true;
if (appletItem.needsFillSpace && root.isVertical) {
layoutsContainer.updateSizeForAppletsInFill();
appletItem.layouter.updateSizeForAppletsInFill();
return;
}
@ -356,7 +356,7 @@ Item{
appletItem.movingForResize = true;
if (appletItem.needsFillSpace && root.isHorizontal) {
layoutsContainer.updateSizeForAppletsInFill();
appletItem.layouter.updateSizeForAppletsInFill();
return;
}

@ -691,7 +691,7 @@ Window{
}
Text{
text: layoutsContainer.startLayout.shownApplets
text: layouter.startLayout.shownApplets
}
Text{
@ -699,7 +699,7 @@ Window{
}
Text{
text: layoutsContainer.startLayout.fillApplets
text: layouter.startLayout.fillApplets
}
Text{
@ -707,7 +707,7 @@ Window{
}
Text{
text: layoutsContainer.startLayout.sizeWithNoFillApplets+" px."
text: layouter.startLayout.sizeWithNoFillApplets+" px."
}
Text{
@ -723,7 +723,7 @@ Window{
}
Text{
text: layoutsContainer.mainLayout.shownApplets
text: layouter.mainLayout.shownApplets
}
Text{
@ -731,7 +731,7 @@ Window{
}
Text{
text: layoutsContainer.mainLayout.fillApplets
text: layouter.mainLayout.fillApplets
}
Text{
@ -739,7 +739,7 @@ Window{
}
Text{
text: layoutsContainer.mainLayout.sizeWithNoFillApplets+" px."
text: layouter.mainLayout.sizeWithNoFillApplets+" px."
}
Text{
@ -763,7 +763,7 @@ Window{
}
Text{
text: layoutsContainer.endLayout.fillApplets
text: layouter.endLayout.fillApplets
}
Text{
@ -771,7 +771,7 @@ Window{
}
Text{
text: layoutsContainer.endLayout.sizeWithNoFillApplets+" px."
text: layouter.endLayout.sizeWithNoFillApplets+" px."
}
Text{

@ -21,7 +21,6 @@ import QtQuick 2.0
Item {
id: tag
width: _label.width + 4
height: _label.height + 4

@ -238,7 +238,7 @@ MouseArea {
// handle.height = currentApplet.height;
root.layoutManagerSave();
root.layoutManagerMoveAppletsBasedOnJustifyAlignment();
layoutsContainer.updateSizeForAppletsInFill();
layouter.updateSizeForAppletsInFill();
}
onWheel: {

@ -41,132 +41,6 @@ Abilities.AbilityGrid {
property int beginIndex: 0
property int offset: 0
readonly property int count: children.length
//it is used in calculations for fillWidth,fillHeight applets
property int shownApplets: 0
property int fillApplets: 0
//it is used in calculations for fillWidth,fillHeight applets
property int sizeWithNoFillApplets: 0
readonly property int maxIndex: 99999
property int firstVisibleIndex: -1
property int lastVisibleIndex: -1
//! do not update during dragging/moving applets inConfigureAppletsMode
readonly property bool updateIsBlocked: (root.dragOverlay && root.dragOverlay.pressed)
|| animations.appletsInParentChange
Binding{
target: appletsContainer
property:"sizeWithNoFillApplets"
when: appletsContainer && !updateIsBlocked && animations.inNormalFillCalculationsState
value: {
var space = 0;
for (var i=0; i<appletsContainer.children.length; ++i){
if (appletsContainer.children[i]
&& !appletsContainer.children[i].needsFillSpace
&& !appletsContainer.children[i].isHidden) {
space = root.isHorizontal ? space + appletsContainer.children[i].width : space + appletsContainer.children[i].height;
}
}
return space;
}
}
Binding{
target: appletsContainer
property:"shownApplets"
when: appletsContainer && !updateIsBlocked
value: {
var res = 0;
for (var i=0; i<children.length; ++i){
if (children[i] && children[i].isHidden) {
//do nothing
} else if (children[i] && (children[i].applet || children[i].isInternalViewSplitter)){
res = res + 1;
}
}
return res;
}
}
Binding{
target: appletsContainer
property:"fillApplets"
when: appletsContainer && !updateIsBlocked
value: {
var no = 0;
for (var i=0; i<children.length; ++i){
if (children[i] && children[i].needsFillSpace) {
//console.log("fill :::: " + children[i].applet.pluginName);
no++;
}
}
return no;
}
}
Binding{
target: appletsContainer
property:"firstVisibleIndex"
when: appletsContainer && !updateIsBlocked
value: {
var ind = maxIndex;
for(var i=0; i<appletsContainer.children.length; ++i) {
var appletItem = appletsContainer.children[i];
if (appletItem && appletItem.index>=0
&& indexer.hidden.indexOf(appletItem.index)<0
&& indexer.separators.indexOf(appletItem.index)<0
&& appletItem.index < ind) {
ind = appletItem.index;
}
}
return ind === maxIndex ? -1 : ind;
}
}
Binding{
target: appletsContainer
property:"lastVisibleIndex"
when: appletsContainer && !updateIsBlocked
value: {
var ind = -1;
for(var i=0; i<appletsContainer.children.length; ++i) {
var appletItem = appletsContainer.children[i];
if (appletItem && appletItem.index>=0
&& indexer.hidden.indexOf(appletItem.index)<0
&& indexer.separators.indexOf(appletItem.index)<0
&& appletItem.index > ind) {
ind = appletItem.index;
}
}
return ind;
}
}
onCountChanged: {
if (root.editMode) {
//! this is mainly used when removing/adding internal view splitters
//! in order to not break the parabolic effect from wrong indexes
root.updateIndexes();
}
}
onFillAppletsChanged: layoutsContainer.updateSizeForAppletsInFill();
onShownAppletsChanged: layoutsContainer.updateSizeForAppletsInFill();
onSizeWithNoFillAppletsChanged: layoutsContainer.updateSizeForAppletsInFill();
//////////////////////////BEGIN states
//user set Panel Positions
// 0-Center, 1-Left, 2-Right, 3-Top, 4-Bottom

@ -30,21 +30,15 @@ import org.kde.latte.private.containment 0.1 as LatteContainment
import "./abilities" as AbilitiesTypes
import "../debug" as Debug
import "../../code/HeuristicTools.js" as HeuristicTools
Item{
id: layoutsContainer
readonly property bool isHidden: root.inStartup || (latteView && latteView.visibility && latteView.visibility.isHidden)
readonly property bool useMaxLength: plasmoid.configuration.alignment === LatteCore.Types.Justify
/* && ((!root.inConfigureAppletsMode && !root.behaveAsPlasmaPanel )
|| (behaveAsPlasmaPanel && root.inConfigureAppletsMode))*/
property int allCount: root.latteApplet ? _mainLayout.count-1+latteApplet.tasksCount : _mainLayout.count
property int currentSpot: -1000
readonly property int fillApplets: _startLayout.fillApplets + _mainLayout.fillApplets + _endLayout.fillApplets
readonly property alias startLayout : _startLayout
readonly property alias mainLayout: _mainLayout
readonly property alias endLayout: _endLayout
@ -55,6 +49,8 @@ Item{
endLayout: _endLayout
}
signal contentsLengthChanged();
Binding {
target: layoutsContainer
property: "x"
@ -150,7 +146,7 @@ Item{
animations.needLength.addEvent(layoutsContainer);
}
layoutsContainer.updateSizeForAppletsInFill();
contentsLengthChanged();
delayUpdateMaskArea.start();
}
@ -175,7 +171,7 @@ Item{
animations.needLength.removeEvent(layoutsContainer);
}
layoutsContainer.updateSizeForAppletsInFill();
contentsLengthChanged();
delayUpdateMaskArea.start();
}
@ -290,91 +286,75 @@ Item{
}
}
function updateSizeForAppletsInFill() {
if (!updateSizeForAppletsInFillTimer.running) {
HeuristicTools.updateSizeForAppletsInFill();
updateSizeForAppletsInFillTimer.start();
}
}
Connections {
target: metrics
onIconSizeAnimationEnded: delayUpdateMaskArea.start();
}
Connections {
target: animations
onInNormalFillCalculationsStateChanged: {
if (animations.inNormalFillCalculationsState) {
layoutsContainer.updateSizeForAppletsInFill();
}
}
}
//! Debug Elements
Loader{
anchors.top: debugLayout.top
anchors.horizontalCenter: debugLayout.horizontalCenter
anchors.top: startLayout.top
anchors.horizontalCenter: startLayout.horizontalCenter
active: root.debugModeLayouter
readonly property Item debugLayout: _startLayout
readonly property Item debugLayout: layouter.startLayout
sourceComponent: Debug.Tag{
background.color: "white"
label.text: tagText
label.color: "black"
label.font.pointSize: 13
readonly property int layoutLength: root.isHorizontal ? debugLayout.width : debugLayout.height
readonly property int layoutLength: root.isHorizontal ? debugLayout.grid.width : debugLayout.grid.height
readonly property string tagText: {
return "no_show:" + debugLayout.shownApplets + " / no_fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
}
}
}
Loader{
anchors.top: debugLayout.top
anchors.horizontalCenter: debugLayout.horizontalCenter
anchors.top: endLayout.top
anchors.horizontalCenter: endLayout.horizontalCenter
active: root.debugModeLayouter
readonly property Item debugLayout: _endLayout
readonly property Item debugLayout: layouter.endLayout
sourceComponent: Debug.Tag{
background.color: "white"
label.text: tagText
label.color: "black"
label.font.pointSize: 13
readonly property int layoutLength: root.isHorizontal ? debugLayout.width : debugLayout.height
readonly property int layoutLength: root.isHorizontal ? debugLayout.grid.width : debugLayout.grid.height
readonly property string tagText: {
return "no_show:" + debugLayout.shownApplets + " / no_fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
}
}
}
Loader{
anchors.top: debugLayout.top
anchors.horizontalCenter: debugLayout.horizontalCenter
anchors.top: mainLayout.top
anchors.horizontalCenter: mainLayout.horizontalCenter
active: root.debugModeLayouter
z:70
readonly property Item debugLayout: _mainLayout
readonly property Item debugLayout: layouter.mainLayout
sourceComponent: Debug.Tag{
background.color: "white"
label.text: tagText
label.color: "black"
label.font.pointSize: 13
readonly property int layoutLength: root.isHorizontal ? debugLayout.width : debugLayout.height
readonly property int layoutLength: root.isHorizontal ? debugLayout.grid.width : debugLayout.grid.height
readonly property string tagText: {
return "no_show:" + debugLayout.shownApplets + " / no_fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
}
}
}
Loader{
anchors.top: _mainLayout.top
anchors.top: mainLayout.top
anchors.left: parent.left
active: root.debugModeLayouter
@ -390,10 +370,10 @@ Item{
readonly property int layoutsLength: {
if (root.isVertical) {
return _startLayout.height + _mainLayout.height + _endLayout.height;
return layouter.startLayout.grid.height + layouter.mainLayout.grid.height + layouter.endLayout.grid.height;
}
return _startLayout.width + _mainLayout.width + _endLayout.width;
return layouter.startLayout.grid.width + layouter.mainLayout.grid.width + layouter.endLayout.grid.width;
}
readonly property string tagText: {
@ -402,14 +382,6 @@ Item{
}
}
//! This timer is needed in order to reduce the calls to heavy cpu function
//! HeuristicTools.updateSizeForAppletsInFill()
Timer{
id: updateSizeForAppletsInFillTimer
interval: 50
onTriggered: HeuristicTools.updateSizeForAppletsInFill();
}
//! This timer is needed in order to update mask area after ContentsWidth/Height and iconSize changes
Timer{
id:delayUpdateMaskArea

@ -387,6 +387,7 @@ Item {
readonly property alias autosize: _autosize
readonly property alias indexer: _indexer
readonly property alias indicatorsManager: indicators
readonly property alias layouter: _layouter
readonly property alias metrics: _metrics
readonly property alias parabolic: _parabolic
readonly property alias parabolicManager: _parabolicManager
@ -490,7 +491,7 @@ Item {
//////////////START OF CONNECTIONS
onEditModeChanged: {
if (!editMode) {
layoutsContainer.updateSizeForAppletsInFill();
layouter.updateSizeForAppletsInFill();
}
//! This is used in case the dndspacer has been left behind
@ -545,7 +546,7 @@ Item {
}
onMaxLengthChanged: {
layoutsContainer.updateSizeForAppletsInFill();
layouter.updateSizeForAppletsInFill();
}
onToolBoxChanged: {
@ -596,7 +597,7 @@ Item {
Component.onDestruction: {
console.debug("Destroying Latte Dock Containment ui...");
animations.appletsInParentChange = true;
layouter.appletsInParentChange = true;
if (latteView) {
latteView.positioner.hideDockDuringLocationChangeStarted.disconnect(visibilityManager.slotHideDockDuringLocationChange);
@ -806,7 +807,7 @@ Item {
if(pos>=0 ){
LayoutManager.insertAtIndex(layoutsContainer.mainLayout, container, pos);
} else {
LayoutManager.insertAtIndex(layoutsContainer.mainLayout, container, Math.floor(layoutsContainer.mainLayout.count / 2));
LayoutManager.insertAtIndex(layoutsContainer.mainLayout, container, Math.floor(layouter.mainLayout.count / 2));
}
}
}
@ -1079,15 +1080,11 @@ Item {
}
}
function updateSizeForAppletsInFill() {
layoutsContainer.updateSizeForAppletsInFill();
}
function layoutManagerMoveAppletsBasedOnJustifyAlignment() {
if (plasmoid.configuration.alignment !== 10) {
return;
}
animations.appletsInParentChange = true;
layouter.appletsInParentChange = true;
var splitter = -1;
var startChildrenLength = layoutsContainer.startLayout.children.length;
@ -1134,12 +1131,12 @@ Item {
//! Validate applets positioning and move applets out of splitters to start/endlayouts accordingly
splitMainLayoutToLayouts();
animations.appletsInParentChange = false;
layouter.appletsInParentChange = false;
}
function splitMainLayoutToLayouts() {
if (internalViewSplittersCount() === 2) {
animations.appletsInParentChange = true;
layouter.appletsInParentChange = true;
console.log("LAYOUTS: Moving applets from MAIN to THREE Layouts mode...");
var splitter = -1;
@ -1177,12 +1174,12 @@ Item {
}
}
animations.appletsInParentChange = false;
layouter.appletsInParentChange = false;
}
}
function joinLayoutsToMainLayout() {
animations.appletsInParentChange = true;
layouter.appletsInParentChange = true;
console.log("LAYOUTS: Moving applets from THREE to MAIN Layout mode...");
var totalChildren1 = layoutsContainer.mainLayout.children.length;
@ -1204,7 +1201,7 @@ Item {
itemL.parent = layoutsContainer.mainLayout;
}
animations.appletsInParentChange = false;
layouter.appletsInParentChange = false;
}
function upgrader_v010_alignment() {
@ -1360,6 +1357,7 @@ Item {
Applet.AppletItem{
animations: _animations
indexer: _indexer
layouter: _layouter
metrics: _metrics
parabolic: _parabolic
}
@ -1577,6 +1575,7 @@ Item {
Ability.AutoSize {
id: _autosize
layouts: layoutsContainer
layouter: _layouter
metrics: _metrics
visibility: visibilityManager
}
@ -1586,6 +1585,13 @@ Item {
layouts: layoutsContainer
}
Ability.Layouter {
id: _layouter
animations: _animations
indexer: _indexer
layouts: layoutsContainer
}
Ability.Metrics {
id: _metrics
animations: _animations

Loading…
Cancel
Save