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 }