Warning, /plasma/latte-dock/containment/package/contents/ui/layouts/LayoutsContainer.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2016 Smith AR <audoban@openmailbox.org> 0003 SPDX-FileCopyrightText: 2016 Michail Vourlakos <mvourlakos@gmail.com> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.1 0008 import QtQuick.Layouts 1.1 0009 0010 import org.kde.plasma.plasmoid 2.0 0011 0012 import org.kde.plasma.core 2.0 as PlasmaCore 0013 0014 import org.kde.latte.private.app 0.1 as LatteApp 0015 import org.kde.latte.core 0.2 as LatteCore 0016 import org.kde.latte.private.containment 0.1 as LatteContainment 0017 0018 import "../debugger" as Debugger 0019 0020 Item{ 0021 id: layoutsContainer 0022 //! WorkAround: Do not use "visible" because when it becomes "false" the contained applets can hide/show their elements. 0023 //! That approach can create a conflict with Latte Tasks that after showing the view they reshow windows 0024 //! that were already shown before hiding. 0025 //! visible: !(latteView && latteView.visibility.isHidden) 0026 opacity: !(latteView && latteView.visibility.isHidden) ? 1 : 0 0027 0028 readonly property bool isHidden: root.inStartup || (latteView && latteView.visibility && latteView.visibility.isHidden) 0029 0030 property int currentSpot: -1000 0031 0032 readonly property alias startLayout : _startLayout 0033 readonly property alias mainLayout: _mainLayout 0034 readonly property alias endLayout: _endLayout 0035 readonly property alias contextMenuIsShown: contextMenuLayer.menuIsShown 0036 0037 signal contentsLengthChanged(); 0038 0039 Binding { 0040 target: layoutsContainer 0041 property: "x" 0042 when: !visibilityManager.inRelocationAnimation 0043 value: { 0044 if (root.behaveAsPlasmaPanel) { 0045 return 0; 0046 } 0047 0048 if ( latteView && root.isHorizontal && root.myView.alignment === LatteCore.Types.Justify ){ 0049 return ((latteView.width/2) - (root.maxLength/2) + background.offset); 0050 } else { 0051 if ((root.myView.inSlidingIn || root.myView.inSlidingOut) && root.isVertical){ 0052 return; 0053 } 0054 0055 if (layoutsContainer.isHidden && root.isVertical) { 0056 if (LatteCore.WindowSystem.compositingActive) { 0057 return visibilityManager.slidingOutToPos; 0058 } else { 0059 if ((plasmoid.location===PlasmaCore.Types.LeftEdge)||(plasmoid.location===PlasmaCore.Types.TopEdge)) { 0060 return visibilityManager.slidingOutToPos + 1; 0061 } else { 0062 return visibilityManager.slidingOutToPos - 1; 0063 } 0064 } 0065 } else { 0066 return 0; 0067 } 0068 } 0069 } 0070 } 0071 0072 Binding{ 0073 target: layoutsContainer 0074 property: "y" 0075 when: !visibilityManager.inRelocationAnimation 0076 value: { 0077 if (root.behaveAsPlasmaPanel) { 0078 return 0; 0079 } 0080 0081 if ( latteView && root.isVertical && root.myView.alignment === LatteCore.Types.Justify ) { 0082 return ((latteView.height/2) - (root.maxLength/2) + background.offset); 0083 } else { 0084 if ((root.myView.inSlidingIn || root.myView.inSlidingOut) && root.isHorizontal){ 0085 return; 0086 } 0087 0088 if (layoutsContainer.isHidden && root.isHorizontal) { 0089 if (LatteCore.WindowSystem.compositingActive) { 0090 return visibilityManager.slidingOutToPos; 0091 } else { 0092 if ((plasmoid.location===PlasmaCore.Types.LeftEdge)||(plasmoid.location===PlasmaCore.Types.TopEdge)) { 0093 return visibilityManager.slidingOutToPos + 1; 0094 } else { 0095 return visibilityManager.slidingOutToPos - 1; 0096 } 0097 } 0098 } else { 0099 return 0; 0100 } 0101 } 0102 } 0103 } 0104 0105 width: root.isHorizontal && root.myView.alignment === LatteCore.Types.Justify ? root.maxLength : parent.width 0106 height: root.isVertical && root.myView.alignment === LatteCore.Types.Justify ? root.maxLength : parent.height 0107 z:10 0108 0109 property bool animationSent: false 0110 property bool shouldCheckHalfs: (plasmoid.configuration.alignment === LatteCore.Types.Justify) && (_mainLayout.children>1) 0111 0112 property int contentsWidth: root.isHorizontal ? _startLayout.width + _mainLayout.width + _endLayout.width : 0113 Math.max(_startLayout.width, _mainLayout.width ,_endLayout.width) 0114 property int contentsHeight: root.isVertical ? _startLayout.height + _mainLayout.height + _endLayout.height : 0115 Math.max(_startLayout.height, _mainLayout.height, _endLayout.height) 0116 0117 0118 readonly property int backgroundShadowTailLength: { 0119 if (root.behaveAsPlasmaPanel) { 0120 return 0; 0121 } 0122 0123 if (root.myView.alignment === LatteCore.Types.Left) { 0124 return background.shadows.left; 0125 } else if (root.myView.alignment === LatteCore.Types.Right) { 0126 return background.shadows.right; 0127 } else if (root.myView.alignment === LatteCore.Types.Top) { 0128 return background.shadows.top; 0129 } else if (root.myView.alignment === LatteCore.Types.Bottom) { 0130 return background.shadows.bottom; 0131 } 0132 0133 //! centered case 0134 return root.isHorizontal ? background.shadows.left : background.shadows.top; 0135 } 0136 0137 readonly property int backgroundShadowHeadLength: { 0138 if (root.behaveAsPlasmaPanel) { 0139 return 0; 0140 } 0141 0142 if (root.myView.alignment === LatteCore.Types.Left) { 0143 return background.shadows.right; 0144 } else if (root.myView.alignment === LatteCore.Types.Right) { 0145 return background.shadows.left; 0146 } else if (root.myView.alignment === LatteCore.Types.Top) { 0147 return background.shadows.bottom; 0148 } else if (root.myView.alignment === LatteCore.Types.Bottom) { 0149 return background.shadows.top; 0150 } 0151 0152 //! centered case 0153 return root.isHorizontal ? background.shadows.right : background.shadows.bottom; 0154 } 0155 0156 readonly property int lengthTailPadding: { 0157 var minimumPadding = metrics.margin.length; 0158 var bestMatchingPadding = 0; 0159 0160 if (root.myView.alignment === LatteCore.Types.Left) { 0161 bestMatchingPadding = Math.max(background.paddings.left, minimumPadding) - minimumPadding; 0162 } else if (root.myView.alignment === LatteCore.Types.Right) { 0163 bestMatchingPadding = Math.max(background.paddings.right, minimumPadding) - minimumPadding; 0164 } else if (root.myView.alignment === LatteCore.Types.Top) { 0165 bestMatchingPadding = Math.max(background.paddings.top, minimumPadding) - minimumPadding; 0166 } else if (root.myView.alignment === LatteCore.Types.Bottom) { 0167 bestMatchingPadding = Math.max(background.paddings.bottom, minimumPadding) - minimumPadding; 0168 } else if (root.myView.alignment === LatteCore.Types.Center) { 0169 bestMatchingPadding = Math.max(background.paddings.left, minimumPadding) - minimumPadding; 0170 } else if (root.myView.alignment === LatteCore.Types.Justify) { 0171 var backpadding = root.isHorizontal ? background.paddings.left : background.paddings.top; 0172 bestMatchingPadding = Math.max(backpadding, minimumPadding) - minimumPadding; 0173 } 0174 0175 //shadow is already calculated in Justify mode 0176 return root.myView.alignment !== LatteCore.Types.Justify ? backgroundShadowTailLength + bestMatchingPadding : bestMatchingPadding; 0177 } 0178 0179 readonly property int lengthHeadPadding: { 0180 var minimumPadding = metrics.margin.length; 0181 var bestMatchingPadding = 0; 0182 0183 if (root.myView.alignment === LatteCore.Types.Left) { 0184 bestMatchingPadding = Math.max(background.paddings.right, minimumPadding) - minimumPadding; 0185 } else if (root.myView.alignment === LatteCore.Types.Right) { 0186 bestMatchingPadding = Math.max(background.paddings.left, minimumPadding) - minimumPadding; 0187 } else if (root.myView.alignment === LatteCore.Types.Top) { 0188 bestMatchingPadding = Math.max(background.paddings.bottom, minimumPadding) - minimumPadding; 0189 } else if (root.myView.alignment === LatteCore.Types.Bottom) { 0190 bestMatchingPadding = Math.max(background.paddings.top, minimumPadding) - minimumPadding; 0191 } else if (root.myView.alignment === LatteCore.Types.Center) { 0192 bestMatchingPadding = Math.max(background.paddings.right, minimumPadding) - minimumPadding; 0193 } else if (root.myView.alignment === LatteCore.Types.Justify) { 0194 var backpadding = root.isHorizontal ? background.paddings.right : background.paddings.bottom; 0195 bestMatchingPadding = Math.max(backpadding, minimumPadding) - minimumPadding; 0196 } 0197 0198 //shadow is already calculated in Justify mode 0199 return root.myView.alignment !== LatteCore.Types.Justify ? backgroundShadowHeadLength + bestMatchingPadding : bestMatchingPadding; 0200 } 0201 0202 onContentsWidthChanged: { 0203 if (root.isHorizontal){ 0204 var firstHalfExited = false; 0205 var secondHalfExited = false; 0206 0207 if (shouldCheckHalfs){ 0208 firstHalfExited = ( (_startLayout.width + _mainLayout.width/2) >= root.maxLength/2 ); 0209 secondHalfExited = ( (_endLayout.width + _mainLayout.width/2) >= root.maxLength/2 ); 0210 } 0211 0212 if (latteView && ((contentsWidth >= root.maxLength) || firstHalfExited || secondHalfExited)) { 0213 autosize.updateIconSize(); 0214 } 0215 0216 if (!animationSent) { 0217 animationSent = true; 0218 animations.needLength.addEvent(layoutsContainer); 0219 } 0220 0221 contentsLengthChanged(); 0222 0223 delayUpdateMaskArea.start(); 0224 } 0225 } 0226 0227 onContentsHeightChanged: { 0228 if (root.isVertical){ 0229 var firstHalfExited = false; 0230 var secondHalfExited = false; 0231 0232 if (shouldCheckHalfs){ 0233 firstHalfExited = ( (_startLayout.height + _mainLayout.height/2) >= root.maxLength/2 ); 0234 secondHalfExited = ( (_endLayout.height + _mainLayout.height/2) >= root.maxLength/2 ); 0235 } 0236 0237 if (latteView && ((contentsHeight >= root.maxLength) || firstHalfExited || secondHalfExited)) { 0238 autosize.updateIconSize(); 0239 } 0240 0241 if (!animationSent) { 0242 animationSent = true; 0243 animations.needLength.removeEvent(layoutsContainer); 0244 } 0245 0246 contentsLengthChanged(); 0247 0248 delayUpdateMaskArea.start(); 0249 } 0250 } 0251 0252 onXChanged: root.updateEffectsArea(); 0253 onYChanged: root.updateEffectsArea(); 0254 0255 EnvironmentActions { 0256 id: environmentActions 0257 active: root.scrollAction !== LatteContainment.Types.ScrollNone || root.dragActiveWindowEnabled || root.closeActiveWindowEnabled 0258 alignment: _mainLayout.alignment 0259 } 0260 0261 LatteApp.ContextMenuLayer { 0262 id: contextMenuLayer 0263 anchors.fill: parent 0264 view: latteView 0265 } 0266 0267 AppletsContainer { 0268 id: _startLayout 0269 beginIndex: 0 0270 offset: lengthTailPadding 0271 alignment: { 0272 switch(plasmoid.location) { 0273 case PlasmaCore.Types.BottomEdge: return LatteCore.Types.BottomEdgeLeftAlign; 0274 case PlasmaCore.Types.TopEdge: return LatteCore.Types.TopEdgeLeftAlign; 0275 case PlasmaCore.Types.LeftEdge: return LatteCore.Types.LeftEdgeTopAlign; 0276 case PlasmaCore.Types.RightEdge: return LatteCore.Types.RightEdgeTopAlign; 0277 } 0278 0279 return LatteCore.Types.BottomEdgeLeftAlign; 0280 } 0281 } 0282 0283 /*Rectangle { 0284 anchors.fill: _mainLayout 0285 color: "transparent" 0286 border.width: 1 0287 border.color: "black" 0288 }*/ 0289 0290 AppletsContainer { 0291 id: _mainLayout 0292 z:10 //be on top of start and end layouts 0293 beginIndex: 100 0294 offset: { 0295 if (!centered) { 0296 //! it is used for Top/Bottom/Left/Right alignments when they show both background length shadows 0297 return background.offset + lengthTailPadding; 0298 } 0299 0300 return (root.myView.alignment === LatteCore.Types.Justify) ? inJustifyCenterOffset : background.offset - parabolicOffsetting 0301 } 0302 0303 ignoredLength: startParabolicSpacer.length + endParabolicSpacer.length 0304 0305 readonly property alias startParabolicSpacer: _startParabolicSpacer 0306 readonly property alias endParabolicSpacer: _endParabolicSpacer 0307 0308 readonly property bool centered: (root.myView.alignment === LatteCore.Types.Center) || (root.myView.alignment === LatteCore.Types.Justify) 0309 readonly property bool reversed: Qt.application.layoutDirection === Qt.RightToLeft 0310 readonly property real parabolicOffsetting: (startParabolicSpacer.length - endParabolicSpacer.length) / 2 0311 property int inJustifyCenterOffset: 0 0312 0313 alignment: { 0314 if (plasmoid.location === PlasmaCore.Types.LeftEdge) { 0315 if (centered) return LatteCore.Types.LeftEdgeCenterAlign; 0316 if (root.myView.alignment === LatteCore.Types.Top) return LatteCore.Types.LeftEdgeTopAlign; 0317 if (root.myView.alignment === LatteCore.Types.Bottom) return LatteCore.Types.LeftEdgeBottomAlign; 0318 } 0319 0320 if (plasmoid.location === PlasmaCore.Types.RightEdge) { 0321 if (centered) return LatteCore.Types.RightEdgeCenterAlign; 0322 if (root.myView.alignment === LatteCore.Types.Top) return LatteCore.Types.RightEdgeTopAlign; 0323 if (root.myView.alignment === LatteCore.Types.Bottom) return LatteCore.Types.RightEdgeBottomAlign; 0324 } 0325 0326 if (plasmoid.location === PlasmaCore.Types.BottomEdge) { 0327 if (centered) return LatteCore.Types.BottomEdgeCenterAlign; 0328 0329 if ((root.myView.alignment === LatteCore.Types.Left && !reversed) 0330 || (root.myView.alignment === LatteCore.Types.Right && reversed)) { 0331 return LatteCore.Types.BottomEdgeLeftAlign; 0332 } 0333 0334 if ((root.myView.alignment === LatteCore.Types.Right && !reversed) 0335 || (root.myView.alignment === LatteCore.Types.Left && reversed)) { 0336 return LatteCore.Types.BottomEdgeRightAlign; 0337 } 0338 } 0339 0340 if (plasmoid.location === PlasmaCore.Types.TopEdge) { 0341 if (centered) return LatteCore.Types.TopEdgeCenterAlign; 0342 0343 if ((root.myView.alignment === LatteCore.Types.Left && !reversed) 0344 || (root.myView.alignment === LatteCore.Types.Right && reversed)) { 0345 return LatteCore.Types.TopEdgeLeftAlign; 0346 } 0347 0348 if ((root.myView.alignment === LatteCore.Types.Right && !reversed) 0349 || (root.myView.alignment === LatteCore.Types.Left && reversed)) { 0350 return LatteCore.Types.TopEdgeRightAlign; 0351 } 0352 } 0353 0354 return LatteCore.Types.BottomEdgeCenterAlign; 0355 } 0356 0357 transitions: Transition { 0358 enabled: !visibilityManager.inRelocationAnimation && !root.inStartup 0359 AnchorAnimation { 0360 duration: 0.8 * animations.duration.proposed 0361 easing.type: Easing.OutCubic 0362 } 0363 } 0364 0365 ParabolicEdgeSpacer { 0366 id: _startParabolicSpacer 0367 index: mainLayout.beginIndex - 1 0368 } 0369 0370 ParabolicEdgeSpacer { 0371 id: _endParabolicSpacer 0372 index: mainLayout.beginIndex + mainLayout.children.length - 2 0373 } 0374 0375 Binding{ 0376 target: _mainLayout 0377 property:"inJustifyCenterOffset" 0378 when: !layouter.appletsInParentChange && layouter.inNormalFillCalculationsState 0379 value: { 0380 if (root.myView.alignment !== LatteCore.Types.Justify) { 0381 return 0; 0382 } 0383 0384 var layoutMaxLength = root.maxLength / 2; 0385 var sideLayoutMaxLength = layoutMaxLength - mainLayout.length/2; 0386 var sideslength = startLayout.length + endLayout.length; 0387 0388 if (sideslength > root.maxLength) { 0389 return 0; 0390 } 0391 0392 if (startLayout.length > sideLayoutMaxLength) { 0393 return (startLayout.length - sideLayoutMaxLength); 0394 } else if (endLayout.length > sideLayoutMaxLength) { 0395 return -(endLayout.length - sideLayoutMaxLength); 0396 } 0397 0398 return 0; 0399 } 0400 } 0401 } 0402 0403 AppletsContainer { 0404 id: _endLayout 0405 beginIndex: 200 0406 offset: lengthHeadPadding 0407 alignment: { 0408 switch(plasmoid.location) { 0409 case PlasmaCore.Types.BottomEdge: return LatteCore.Types.BottomEdgeRightAlign; 0410 case PlasmaCore.Types.TopEdge: return LatteCore.Types.TopEdgeRightAlign; 0411 case PlasmaCore.Types.LeftEdge: return LatteCore.Types.LeftEdgeBottomAlign; 0412 case PlasmaCore.Types.RightEdge: return LatteCore.Types.RightEdgeBottomAlign; 0413 } 0414 0415 return LatteCore.Types.BottomEdgeLeftAlign; 0416 } 0417 } 0418 0419 Connections { 0420 target: metrics 0421 onIconSizeAnimationEnded: delayUpdateMaskArea.start(); 0422 } 0423 0424 //! Debug Elements 0425 Loader{ 0426 anchors.top: startLayout.top 0427 anchors.horizontalCenter: startLayout.horizontalCenter 0428 active: debug.layouterEnabled 0429 0430 readonly property Item debugLayout: layouter.startLayout 0431 0432 sourceComponent: Debugger.Tag{ 0433 background.color: "white" 0434 label.text: tagText 0435 label.color: "black" 0436 label.font.pointSize: 13 0437 readonly property int layoutLength: root.isHorizontal ? debugLayout.grid.width : debugLayout.grid.height 0438 0439 readonly property string tagText: { 0440 return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength; 0441 } 0442 } 0443 } 0444 0445 Loader{ 0446 anchors.top: endLayout.top 0447 anchors.horizontalCenter: endLayout.horizontalCenter 0448 active: debug.layouterEnabled 0449 0450 readonly property Item debugLayout: layouter.endLayout 0451 0452 sourceComponent: Debugger.Tag{ 0453 background.color: "white" 0454 label.text: tagText 0455 label.color: "black" 0456 label.font.pointSize: 13 0457 readonly property int layoutLength: root.isHorizontal ? debugLayout.grid.width : debugLayout.grid.height 0458 0459 readonly property string tagText: { 0460 return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength; 0461 } 0462 } 0463 } 0464 0465 Loader{ 0466 anchors.top: mainLayout.top 0467 anchors.horizontalCenter: mainLayout.horizontalCenter 0468 active: debug.layouterEnabled 0469 z:70 0470 0471 readonly property Item debugLayout: layouter.mainLayout 0472 0473 sourceComponent: Debugger.Tag{ 0474 background.color: "white" 0475 label.text: tagText 0476 label.color: "black" 0477 label.font.pointSize: 13 0478 readonly property int layoutLength: root.isHorizontal ? debugLayout.grid.width : debugLayout.grid.height 0479 0480 readonly property string tagText: { 0481 return "normal:" + debugLayout.shownApplets + " / fill:" + debugLayout.fillApplets + " / reg_len:" + debugLayout.sizeWithNoFillApplets + " / tot_len:"+layoutLength; 0482 } 0483 } 0484 } 0485 0486 Loader{ 0487 anchors.top: mainLayout.top 0488 anchors.left: parent.left 0489 active: debug.layouterEnabled 0490 0491 readonly property Item debugLayout: layoutsContainer 0492 0493 sourceComponent: Debugger.Tag{ 0494 background.color: "blue" 0495 label.text: tagText 0496 label.color: "yellow" 0497 label.font.pointSize: 13 0498 label.font.bold: true 0499 readonly property int layoutLength: root.isHorizontal ? debugLayout.width : debugLayout.height 0500 0501 readonly property int layoutsLength: { 0502 if (root.isVertical) { 0503 return layouter.startLayout.grid.height + layouter.mainLayout.grid.height + layouter.endLayout.grid.height; 0504 } 0505 0506 return layouter.startLayout.grid.width + layouter.mainLayout.grid.width + layouter.endLayout.grid.width; 0507 } 0508 0509 readonly property string tagText: { 0510 return "MAX:" + root.maxLength + " / MIN: " + root.minLength + " TOT:"+layoutLength + " / LAYS:"+ layoutsLength; 0511 } 0512 } 0513 } 0514 0515 //! This timer is needed in order to update mask area after ContentsWidth/Height and iconSize changes 0516 Timer{ 0517 id:delayUpdateMaskArea 0518 repeat:false; 0519 interval:300; 0520 0521 onTriggered: { 0522 if (layoutsContainer.animationSent) { 0523 animations.needLength.removeEvent(layoutsContainer); 0524 layoutsContainer.animationSent = false; 0525 } 0526 0527 visibilityManager.updateMaskArea(); 0528 0529 if (debug.timersEnabled) { 0530 console.log("LayoutsContainer timer: delayUpdateMaskArea called..."); 0531 } 0532 } 0533 } 0534 }