You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
457 lines
17 KiB
QML
457 lines
17 KiB
QML
/*
|
|
* 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.1
|
|
import QtQuick.Layouts 1.1
|
|
|
|
import org.kde.plasma.plasmoid 2.0
|
|
|
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
|
|
import org.kde.latte.core 0.2 as LatteCore
|
|
import org.kde.latte.private.containment 0.1 as LatteContainment
|
|
|
|
import "./abilities" as AbilitiesTypes
|
|
import "../debug" as Debug
|
|
|
|
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
|
|
|
|
property int currentSpot: -1000
|
|
|
|
readonly property alias startLayout : _startLayout
|
|
readonly property alias mainLayout: _mainLayout
|
|
readonly property alias endLayout: _endLayout
|
|
|
|
readonly property AbilitiesTypes.AbilityLayouts applets: AbilitiesTypes.AbilityLayouts{
|
|
startLayout: _startLayout
|
|
mainLayout: _mainLayout
|
|
endLayout: _endLayout
|
|
}
|
|
|
|
signal contentsLengthChanged();
|
|
|
|
Binding {
|
|
target: layoutsContainer
|
|
property: "x"
|
|
when: !visibilityManager.inLocationAnimation
|
|
value: {
|
|
if (root.behaveAsPlasmaPanel) {
|
|
return 0;
|
|
}
|
|
|
|
if ( latteView && root.isHorizontal && useMaxLength ){
|
|
return ((latteView.width/2) - (root.maxLength/2) + background.offset);
|
|
} else {
|
|
if ((visibilityManager.inSlidingIn || visibilityManager.inSlidingOut) && root.isVertical){
|
|
return;
|
|
}
|
|
|
|
if (layoutsContainer.isHidden && root.isVertical) {
|
|
if (LatteCore.WindowSystem.compositingActive) {
|
|
return visibilityManager.slidingOutToPos;
|
|
} else {
|
|
if ((plasmoid.location===PlasmaCore.Types.LeftEdge)||(plasmoid.location===PlasmaCore.Types.TopEdge)) {
|
|
return visibilityManager.slidingOutToPos + 1;
|
|
} else {
|
|
return visibilityManager.slidingOutToPos - 1;
|
|
}
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Binding{
|
|
target: layoutsContainer
|
|
property: "y"
|
|
when: !visibilityManager.inLocationAnimation
|
|
value: {
|
|
if (root.behaveAsPlasmaPanel) {
|
|
return 0;
|
|
}
|
|
|
|
if ( latteView && root.isVertical && useMaxLength ) {
|
|
return ((latteView.height/2) - (root.maxLength/2) + background.offset);
|
|
} else {
|
|
if ((visibilityManager.inSlidingIn || visibilityManager.inSlidingOut) && root.isHorizontal){
|
|
return;
|
|
}
|
|
|
|
if (layoutsContainer.isHidden && root.isHorizontal) {
|
|
if (LatteCore.WindowSystem.compositingActive) {
|
|
return visibilityManager.slidingOutToPos;
|
|
} else {
|
|
if ((plasmoid.location===PlasmaCore.Types.LeftEdge)||(plasmoid.location===PlasmaCore.Types.TopEdge)) {
|
|
return visibilityManager.slidingOutToPos + 1;
|
|
} else {
|
|
return visibilityManager.slidingOutToPos - 1;
|
|
}
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
width: root.isHorizontal && useMaxLength ? root.maxLength : parent.width
|
|
height: root.isVertical && useMaxLength ? root.maxLength : parent.height
|
|
z:10
|
|
|
|
property bool animationSent: false
|
|
property bool shouldCheckHalfs: (plasmoid.configuration.alignment === LatteCore.Types.Justify) && (_mainLayout.children>1)
|
|
|
|
property int contentsWidth: _startLayout.width + _mainLayout.width + _endLayout.width
|
|
property int contentsHeight: _startLayout.height + _mainLayout.height + _endLayout.height
|
|
|
|
onContentsWidthChanged: {
|
|
if (root.isHorizontal){
|
|
var firstHalfExited = false;
|
|
var secondHalfExited = false;
|
|
|
|
if (shouldCheckHalfs){
|
|
firstHalfExited = ( (_startLayout.width + _mainLayout.width/2) >= root.maxLength/2 );
|
|
secondHalfExited = ( (_endLayout.width + _mainLayout.width/2) >= root.maxLength/2 );
|
|
}
|
|
|
|
if (latteView && ((contentsWidth >= root.maxLength) || firstHalfExited || secondHalfExited)) {
|
|
autosize.updateIconSize();
|
|
}
|
|
|
|
if (!animationSent) {
|
|
animationSent = true;
|
|
animations.needLength.addEvent(layoutsContainer);
|
|
}
|
|
|
|
contentsLengthChanged();
|
|
|
|
delayUpdateMaskArea.start();
|
|
}
|
|
}
|
|
|
|
onContentsHeightChanged: {
|
|
if (root.isVertical){
|
|
var firstHalfExited = false;
|
|
var secondHalfExited = false;
|
|
|
|
if (shouldCheckHalfs){
|
|
firstHalfExited = ( (_startLayout.height + _mainLayout.height/2) >= root.maxLength/2 );
|
|
secondHalfExited = ( (_endLayout.height + _mainLayout.height/2) >= root.maxLength/2 );
|
|
}
|
|
|
|
if (latteView && ((contentsHeight >= root.maxLength) || firstHalfExited || secondHalfExited)) {
|
|
autosize.updateIconSize();
|
|
}
|
|
|
|
if (!animationSent) {
|
|
animationSent = true;
|
|
animations.needLength.removeEvent(layoutsContainer);
|
|
}
|
|
|
|
contentsLengthChanged();
|
|
|
|
delayUpdateMaskArea.start();
|
|
}
|
|
}
|
|
|
|
onXChanged: root.updateEffectsArea();
|
|
onYChanged: root.updateEffectsArea();
|
|
|
|
EnvironmentActions {
|
|
active: root.scrollAction !== LatteContainment.Types.ScrollNone || root.dragActiveWindowEnabled || root.closeActiveWindowEnabled
|
|
alignment: _mainLayout.alignment
|
|
}
|
|
|
|
AppletsContainer {
|
|
id: _startLayout
|
|
beginIndex: 0
|
|
offset: background.totals.shadowsLength/2 //it is applied only in Justify when both background length shadows are drawn
|
|
alignment: {
|
|
switch(plasmoid.location) {
|
|
case PlasmaCore.Types.BottomEdge: return LatteCore.Types.BottomEdgeLeftAlign;
|
|
case PlasmaCore.Types.TopEdge: return LatteCore.Types.TopEdgeLeftAlign;
|
|
case PlasmaCore.Types.LeftEdge: return LatteCore.Types.LeftEdgeTopAlign;
|
|
case PlasmaCore.Types.RightEdge: return LatteCore.Types.RightEdgeTopAlign;
|
|
}
|
|
|
|
return LatteCore.Types.BottomEdgeLeftAlign;
|
|
}
|
|
}
|
|
|
|
AppletsContainer {
|
|
id: _mainLayout
|
|
z:10 //be on top of start and end layouts
|
|
beginIndex: 100
|
|
offset: {
|
|
if (inConfigureOffset!==0) {
|
|
return inConfigureOffset;
|
|
}
|
|
|
|
if (background.hasBothLengthShadows && !centered) {
|
|
//! it is used for Top/Bottom/Left/Right alignments when they show both background length shadows
|
|
return background.offset + background.totals.shadowsLength/2;
|
|
}
|
|
|
|
return (root.panelAlignment === LatteCore.Types.Justify) ? 0 : background.offset
|
|
}
|
|
|
|
readonly property bool centered: (root.panelAlignment === LatteCore.Types.Center) || (root.panelAlignment === LatteCore.Types.Justify)
|
|
readonly property bool reversed: Qt.application.layoutDirection === Qt.RightToLeft
|
|
|
|
//! do not update during dragging/moving applets inConfigureAppletsMode
|
|
readonly property bool offsetUpdateIsBlocked: ((root.dragOverlay && root.dragOverlay.pressed) || layouter.appletsInParentChange)
|
|
property bool isCoveredFromSideLayouts: false
|
|
property int inConfigureOffset: 0
|
|
|
|
alignment: {
|
|
if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
|
|
if (centered) return LatteCore.Types.LeftEdgeCenterAlign;
|
|
if (root.panelAlignment === LatteCore.Types.Top) return LatteCore.Types.LeftEdgeTopAlign;
|
|
if (root.panelAlignment === LatteCore.Types.Bottom) return LatteCore.Types.LeftEdgeBottomAlign;
|
|
}
|
|
|
|
if (plasmoid.location === PlasmaCore.Types.RightEdge) {
|
|
if (centered) return LatteCore.Types.RightEdgeCenterAlign;
|
|
if (root.panelAlignment === LatteCore.Types.Top) return LatteCore.Types.RightEdgeTopAlign;
|
|
if (root.panelAlignment === LatteCore.Types.Bottom) return LatteCore.Types.RightEdgeBottomAlign;
|
|
}
|
|
|
|
if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
|
|
if (centered) return LatteCore.Types.BottomEdgeCenterAlign;
|
|
|
|
if ((root.panelAlignment === LatteCore.Types.Left && !reversed)
|
|
|| (root.panelAlignment === LatteCore.Types.Right && reversed)) {
|
|
return LatteCore.Types.BottomEdgeLeftAlign;
|
|
}
|
|
|
|
if ((root.panelAlignment === LatteCore.Types.Right && !reversed)
|
|
|| (root.panelAlignment === LatteCore.Types.Left && reversed)) {
|
|
return LatteCore.Types.BottomEdgeRightAlign;
|
|
}
|
|
}
|
|
|
|
if (plasmoid.location === PlasmaCore.Types.TopEdge) {
|
|
if (centered) return LatteCore.Types.TopEdgeCenterAlign;
|
|
|
|
if ((root.panelAlignment === LatteCore.Types.Left && !reversed)
|
|
|| (root.panelAlignment === LatteCore.Types.Right && reversed)) {
|
|
return LatteCore.Types.TopEdgeLeftAlign;
|
|
}
|
|
|
|
if ((root.panelAlignment === LatteCore.Types.Right && !reversed)
|
|
|| (root.panelAlignment === LatteCore.Types.Left && reversed)) {
|
|
return LatteCore.Types.TopEdgeRightAlign;
|
|
}
|
|
}
|
|
|
|
return LatteCore.Types.BottomEdgeCenterAlign;
|
|
}
|
|
|
|
transitions: Transition {
|
|
enabled: editModeVisual.plasmaEditMode
|
|
AnchorAnimation {
|
|
duration: 0.8 * animations.duration.proposed
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
Binding{
|
|
target: _mainLayout
|
|
property:"isCoveredFromSideLayouts"
|
|
when: !_mainLayout.offsetUpdateIsBlocked && layouter.inNormalFillCalculationsState
|
|
value: {
|
|
if (!layouter.mainLayout.onlyInternalSplitters) {
|
|
//! one of side layouts goes underneath the main layout when the main layout contains valid applets
|
|
var limit = (root.maxLength - mainLayout.length)/2;
|
|
return ((startLayout.length > limit ) || (endLayout.length > limit));
|
|
}
|
|
|
|
//! start and end layouts length exceed the maximum length
|
|
return (startLayout.length + endLayout.length) > (root.maxLength);
|
|
}
|
|
}
|
|
|
|
Binding{
|
|
target: _mainLayout
|
|
property:"inConfigureOffset"
|
|
when: !_mainLayout.offsetUpdateIsBlocked && layouter.inNormalFillCalculationsState
|
|
value: {
|
|
if (!root.inConfigureAppletsMode
|
|
|| root.panelAlignment !== LatteCore.Types.Justify
|
|
|| !layouter.mainLayout.onlyInternalSplitters) {
|
|
return 0;
|
|
}
|
|
|
|
var layoutMaxLength = root.maxLength / 2;
|
|
|
|
if (_mainLayout.isCoveredFromSideLayouts) {
|
|
return layoutMaxLength - mainLayout.length/2;
|
|
}
|
|
|
|
if (startLayout.length > layoutMaxLength) {
|
|
return (layoutMaxLength - endLayout.length - mainLayout.length/2);
|
|
} else if (endLayout.length > layoutMaxLength) {
|
|
return -(layoutMaxLength - startLayout.length - mainLayout.length/2);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
AppletsContainer {
|
|
id: _endLayout
|
|
beginIndex: 200
|
|
offset: background.totals.shadowsLength/2 //it is applied only in Justify when both background length shadows are drawn
|
|
alignment: {
|
|
switch(plasmoid.location) {
|
|
case PlasmaCore.Types.BottomEdge: return LatteCore.Types.BottomEdgeRightAlign;
|
|
case PlasmaCore.Types.TopEdge: return LatteCore.Types.TopEdgeRightAlign;
|
|
case PlasmaCore.Types.LeftEdge: return LatteCore.Types.LeftEdgeBottomAlign;
|
|
case PlasmaCore.Types.RightEdge: return LatteCore.Types.RightEdgeBottomAlign;
|
|
}
|
|
|
|
return LatteCore.Types.BottomEdgeLeftAlign;
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: metrics
|
|
onIconSizeAnimationEnded: delayUpdateMaskArea.start();
|
|
}
|
|
|
|
//! Debug Elements
|
|
Loader{
|
|
anchors.top: startLayout.top
|
|
anchors.horizontalCenter: startLayout.horizontalCenter
|
|
active: root.debugModeLayouter
|
|
|
|
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.grid.width : debugLayout.grid.height
|
|
|
|
readonly property string tagText: {
|
|
return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
Loader{
|
|
anchors.top: endLayout.top
|
|
anchors.horizontalCenter: endLayout.horizontalCenter
|
|
active: root.debugModeLayouter
|
|
|
|
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.grid.width : debugLayout.grid.height
|
|
|
|
readonly property string tagText: {
|
|
return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
Loader{
|
|
anchors.top: mainLayout.top
|
|
anchors.horizontalCenter: mainLayout.horizontalCenter
|
|
active: root.debugModeLayouter
|
|
z:70
|
|
|
|
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.grid.width : debugLayout.grid.height
|
|
|
|
readonly property string tagText: {
|
|
return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
Loader{
|
|
anchors.top: mainLayout.top
|
|
anchors.left: parent.left
|
|
active: root.debugModeLayouter
|
|
|
|
readonly property Item debugLayout: layoutsContainer
|
|
|
|
sourceComponent: Debug.Tag{
|
|
background.color: "blue"
|
|
label.text: tagText
|
|
label.color: "yellow"
|
|
label.font.pointSize: 13
|
|
label.font.bold: true
|
|
readonly property int layoutLength: root.isHorizontal ? debugLayout.width : debugLayout.height
|
|
|
|
readonly property int layoutsLength: {
|
|
if (root.isVertical) {
|
|
return layouter.startLayout.grid.height + layouter.mainLayout.grid.height + layouter.endLayout.grid.height;
|
|
}
|
|
|
|
return layouter.startLayout.grid.width + layouter.mainLayout.grid.width + layouter.endLayout.grid.width;
|
|
}
|
|
|
|
readonly property string tagText: {
|
|
return "MAX:" + root.maxLength + " / TOT:"+layoutLength + " / LAYS:"+ layoutsLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
//! This timer is needed in order to update mask area after ContentsWidth/Height and iconSize changes
|
|
Timer{
|
|
id:delayUpdateMaskArea
|
|
repeat:false;
|
|
interval:300;
|
|
|
|
onTriggered: {
|
|
if (layoutsContainer.animationSent) {
|
|
animations.needLength.removeEvent(layoutsContainer);
|
|
layoutsContainer.animationSent = false;
|
|
}
|
|
|
|
visibilityManager.updateMaskArea();
|
|
|
|
if (root.debugModeTimers) {
|
|
console.log("LayoutsContainer timer: delayUpdateMaskArea called...");
|
|
}
|
|
}
|
|
}
|
|
}
|