Warning, /plasma/latte-dock/containment/package/contents/ui/main.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.8
0008 import QtQuick.Layouts 1.1
0009 import QtQuick.Window 2.2
0010 import QtGraphicalEffects 1.0
0011 
0012 import org.kde.plasma.core 2.0 as PlasmaCore
0013 import org.kde.plasma.components 2.0 as PlasmaComponents
0014 import org.kde.kquickcontrolsaddons 2.0
0015 import org.kde.plasma.plasmoid 2.0
0016 
0017 import org.kde.latte.abilities.host 0.1 as AbilityHost
0018 
0019 import org.kde.latte.core 0.2 as LatteCore
0020 import org.kde.latte.components 1.0 as LatteComponents
0021 import org.kde.latte.private.app 0.1 as LatteApp
0022 import org.kde.latte.private.containment 0.1 as LatteContainment
0023 
0024 import "abilities" as Ability
0025 import "applet" as Applet
0026 import "colorizer" as Colorizer
0027 import "editmode" as EditMode
0028 import "layouts" as Layouts
0029 import "./background" as Background
0030 import "./debugger" as Debugger
0031 
0032 Item {
0033     id: root
0034     objectName: "containmentViewLayout"
0035 
0036     LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft && !root.isVertical
0037     LayoutMirroring.childrenInherit: true
0038 
0039     //// BEGIN SIGNALS
0040     signal destroyInternalViewSplitters();
0041     signal emptyAreasWheel(QtObject wheel);
0042     signal separatorsUpdated();
0043     signal updateEffectsArea();
0044     signal updateIndexes();
0045 
0046     signal broadcastedToApplet(string pluginName, string action, variant value);
0047     //// END SIGNALS
0048 
0049     ////BEGIN properties
0050     readonly property int version: LatteCore.Environment.makeVersion(0,9,75)
0051     readonly property bool kirigamiLibraryIsFound: LatteCore.Environment.frameworksVersion >= LatteCore.Environment.makeVersion(5,69,0)
0052 
0053     property bool backgroundOnlyOnMaximized: plasmoid.configuration.backgroundOnlyOnMaximized
0054     readonly property bool behaveAsPlasmaPanel: viewType === LatteCore.Types.PanelView
0055     readonly property bool behaveAsDockWithMask: !behaveAsPlasmaPanel
0056 
0057     readonly property bool viewIsAvailable: latteView && latteView.visibility && latteView.effects
0058 
0059     property int viewType: {
0060         if (!latteView || !latteView.visibility) {
0061             return LatteCore.Types.DockView;
0062         }
0063 
0064         if (screenEdgeMarginEnabled && root.floatingInternalGapIsForced) {
0065             //! dont use when floating views are requesting internal floating gap which is in client side
0066             return LatteCore.Types.DockView;
0067         }
0068 
0069         return viewTypeInQuestion;
0070     }
0071 
0072     property int viewTypeInQuestion: {
0073         //! viewType as chosen before considering other optios such as floating internal gap enforcement.
0074         //! It helps with binding loops
0075         if (!latteView || !latteView.visibility) {
0076             return LatteCore.Types.DockView;
0077         }
0078 
0079         if (background.customShadowedRectangleIsEnabled) {
0080             return LatteCore.Types.DockView;
0081         }
0082 
0083         var staticLayout = (plasmoid.configuration.minLength === plasmoid.configuration.maxLength);
0084 
0085         if ((plasmoid.configuration.alignment === LatteCore.Types.Justify || staticLayout)
0086                 && background.isGreaterThanItemThickness
0087                 && (parabolic.factor.maxZoom === 1.0)) {
0088             return LatteCore.Types.PanelView;
0089         }
0090 
0091         return LatteCore.Types.DockView;
0092     }
0093 
0094     property bool blurEnabled: plasmoid.configuration.blurEnabled && (!forceTransparentPanel || forcePanelForBusyBackground)
0095 
0096     readonly property bool inDraggingOverAppletOrOutOfContainment: latteView && latteView.containsDrag && !backDropArea.containsDrag
0097 
0098     readonly property Item dragInfo: Item {
0099         property bool entered: backDropArea.dragInfo.entered
0100         property bool isTask: backDropArea.dragInfo.isTask
0101         property bool isPlasmoid: backDropArea.dragInfo.isPlasmoid
0102         property bool isSeparator: backDropArea.dragInfo.isSeparator
0103         property bool isLatteTasks: backDropArea.dragInfo.isLatteTasks
0104         property bool onlyLaunchers: backDropArea.dragInfo.onlyLaunchers
0105     }
0106 
0107     property bool containsOnlyPlasmaTasks: latteView ? latteView.extendedInterface.hasPlasmaTasks && !latteView.extendedInterface.hasLatteTasks : false
0108     property bool dockContainsMouse: latteView && latteView.visibility ? latteView.visibility.containsMouse : false
0109 
0110     property bool disablePanelShadowMaximized: plasmoid.configuration.disablePanelShadowForMaximized && LatteCore.WindowSystem.compositingActive
0111     property bool drawShadowsExternal: panelShadowsActive && behaveAsPlasmaPanel
0112 
0113     property bool editMode: plasmoid.userConfiguring
0114     property bool windowIsTouching: latteView && latteView.windowsTracker
0115                                     && (latteView.windowsTracker.currentScreen.activeWindowTouching
0116                                         || latteView.windowsTracker.currentScreen.activeWindowTouchingEdge
0117                                         || hasExpandedApplet)
0118 
0119     property bool floatingInternalGapIsForced: plasmoid.configuration.floatingInternalGapIsForced
0120 
0121     property bool hasFloatingGapInputEventsDisabled: root.screenEdgeMarginEnabled
0122                                                      && !latteView.byPassWM
0123                                                      && !root.inConfigureAppletsMode
0124                                                      && !parabolic.isEnabled
0125                                                      && (root.behaveAsPlasmaPanel || (root.behaveAsDockWithMask && !root.floatingInternalGapIsForced))
0126 
0127     property bool forceSolidPanel: (latteView && latteView.visibility
0128                                     && LatteCore.WindowSystem.compositingActive
0129                                     && !inConfigureAppletsMode
0130                                     && userShowPanelBackground
0131                                     && ( (plasmoid.configuration.solidBackgroundForMaximized
0132                                           && !(hasExpandedApplet && !plasmaBackgroundForPopups)
0133                                           && (latteView.windowsTracker.currentScreen.existsWindowTouching
0134                                               || latteView.windowsTracker.currentScreen.existsWindowTouchingEdge))
0135                                         || (hasExpandedApplet && plasmaBackgroundForPopups) ))
0136                                    || !LatteCore.WindowSystem.compositingActive
0137 
0138     property bool forceTransparentPanel: root.backgroundOnlyOnMaximized
0139                                          && latteView && latteView.visibility
0140                                          && LatteCore.WindowSystem.compositingActive
0141                                          && !inConfigureAppletsMode
0142                                          && !forceSolidPanel
0143                                          && !(latteView.windowsTracker.currentScreen.existsWindowTouching
0144                                               || latteView.windowsTracker.currentScreen.existsWindowTouchingEdge)
0145                                          && !(windowColors === LatteContainment.Types.ActiveWindowColors && selectedWindowsTracker.existsWindowActive)
0146 
0147     property bool forcePanelForBusyBackground: userShowPanelBackground && (normalBusyForTouchingBusyVerticalView
0148                                                                            || ( root.forceTransparentPanel
0149                                                                                && colorizerManager.backgroundIsBusy
0150                                                                                && root.themeColors === LatteContainment.Types.SmartThemeColors))
0151 
0152     property bool normalBusyForTouchingBusyVerticalView: (latteView && latteView.windowsTracker /*is touching a vertical view that is in busy state and the user prefers isBusy transparency*/
0153                                                           && latteView.windowsTracker.currentScreen.isTouchingBusyVerticalView
0154                                                           && plasmoid.configuration.backgroundOnlyOnMaximized)
0155 
0156     property bool appletIsDragged: root.dragOverlay && root.dragOverlay.pressed
0157     property bool hideThickScreenGap: false /*set through binding*/
0158     property bool hideLengthScreenGaps: false /*set through binding*/
0159 
0160     property bool mirrorScreenGap: screenEdgeMarginEnabled
0161                                    && plasmoid.configuration.floatingGapIsMirrored
0162                                    && latteView.visibility.mode === LatteCore.Types.AlwaysVisible
0163 
0164 
0165 
0166     property int themeColors: plasmoid.configuration.themeColors
0167     property int windowColors: plasmoid.configuration.windowColors
0168 
0169     property bool colorizerEnabled: themeColors !== LatteContainment.Types.PlasmaThemeColors || windowColors !== LatteContainment.Types.NoneWindowColors
0170 
0171     property bool plasmaBackgroundForPopups: plasmoid.configuration.plasmaBackgroundForPopups
0172 
0173     readonly property bool hasExpandedApplet: latteView && latteView.extendedInterface.hasExpandedApplet;
0174     readonly property bool hasUserSpecifiedBackground: (latteView && latteView.layout && latteView.layout.background.startsWith("/")) ?
0175                                                            true : false
0176 
0177     readonly property bool inConfigureAppletsMode: root.editMode && universalSettings && universalSettings.inConfigureAppletsMode
0178 
0179     property bool closeActiveWindowEnabled: plasmoid.configuration.closeActiveWindowEnabled
0180     property bool dragActiveWindowEnabled: plasmoid.configuration.dragActiveWindowEnabled
0181     property bool immutable: plasmoid.immutable
0182     property bool inFullJustify: (plasmoid.configuration.alignment === LatteCore.Types.Justify) && (maxLengthPerCentage===100)
0183     property bool inStartup: true
0184 
0185     property bool isHorizontal: plasmoid.formFactor === PlasmaCore.Types.Horizontal
0186     property bool isVertical: !isHorizontal
0187 
0188     property bool mouseWheelActions: plasmoid.configuration.mouseWheelActions
0189     property bool onlyAddingStarup: true //is used for the initialization phase in startup where there aren't removals, this variable provides a way to grow icon size
0190 
0191     //FIXME: possibly this is going to be the default behavior, this user choice
0192     //has been dropped from the Dock Configuration Window
0193     //property bool smallAutomaticIconJumps: plasmoid.configuration.smallAutomaticIconJumps
0194     property bool smallAutomaticIconJumps: true
0195 
0196     property bool userShowPanelBackground: LatteCore.WindowSystem.compositingActive ? plasmoid.configuration.useThemePanel : true
0197     property bool useThemePanel: noApplets === 0 || !LatteCore.WindowSystem.compositingActive ?
0198                                      true : (plasmoid.configuration.useThemePanel || plasmoid.configuration.solidBackgroundForMaximized)
0199 
0200     property bool plasma515: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,15,0)
0201     property bool plasma518: LatteCore.Environment.plasmaDesktopVersion >= LatteCore.Environment.makeVersion(5,18,0)
0202 
0203     readonly property int minAppletLengthInConfigure: 16
0204     readonly property int maxJustifySplitterSize: 64
0205 
0206     property bool maximizeWhenMaximized: plasmoid.configuration.maximizeWhenMaximized;
0207     property real minLengthPerCentage: plasmoid.configuration.minLength
0208     property real maxLengthPerCentage: hideLengthScreenGaps ? 100 : plasmoid.configuration.maxLength
0209 
0210     property int minLength: {
0211         if (myView.alignment === LatteCore.Types.Justify) {
0212             return maxLength;
0213         }
0214 
0215         if (root.isHorizontal) {
0216             return behaveAsPlasmaPanel && LatteCore.WindowSystem.compositingActive ? width : width * (minLengthPerCentage/100)
0217         } else {
0218             return behaveAsPlasmaPanel && LatteCore.WindowSystem.compositingActive ? height : height * (minLengthPerCentage/100)
0219         }
0220     }
0221 
0222     property int maxLength: {
0223         const maximize = behaveAsPlasmaPanel
0224           || (maximizeWhenMaximized && latteView.windowsTracker.currentScreen.existsWindowMaximized);
0225         if (root.isHorizontal) {
0226             return maximize ? width : width * (maxLengthPerCentage/100)
0227         } else {
0228             return maximize ? height : height * (maxLengthPerCentage/100)
0229         }
0230     }
0231 
0232     property int scrollAction: plasmoid.configuration.scrollAction
0233 
0234     property bool panelOutline: plasmoid.configuration.panelOutline
0235     property int panelEdgeSpacing: Math.max(background.lengthMargins, 1.5*myView.itemShadow.size)
0236 
0237     property bool backgroundShadowsInRegularStateEnabled: LatteCore.WindowSystem.compositingActive
0238                                                           && userShowPanelBackground
0239                                                           && plasmoid.configuration.panelShadows
0240 
0241     property bool panelShadowsActive: {
0242         if (!userShowPanelBackground) {
0243             return false;
0244         }
0245 
0246         if (inConfigureAppletsMode) {
0247             return plasmoid.configuration.panelShadows;
0248         }
0249 
0250         var forcedNoShadows = (plasmoid.configuration.panelShadows && disablePanelShadowMaximized
0251                                && latteView && latteView.windowsTracker && latteView.windowsTracker.currentScreen.activeWindowMaximized);
0252 
0253         if (forcedNoShadows) {
0254             return false;
0255         }
0256 
0257         var transparencyCheck = (blurEnabled || (!blurEnabled && background.currentOpacity>20));
0258 
0259         //! Draw shadows for isBusy state only when current background opacity is greater than 10%
0260         if (plasmoid.configuration.panelShadows && root.forcePanelForBusyBackground && transparencyCheck) {
0261             return true;
0262         }
0263 
0264         if (( (plasmoid.configuration.panelShadows && !root.backgroundOnlyOnMaximized)
0265              || (plasmoid.configuration.panelShadows && root.backgroundOnlyOnMaximized && !root.forceTransparentPanel))
0266                 && !forcedNoShadows) {
0267             return true;
0268         }
0269 
0270         if (hasExpandedApplet && plasmaBackgroundForPopups) {
0271             return true;
0272         }
0273 
0274         return false;
0275     }
0276 
0277     property int offset: {
0278         if (behaveAsPlasmaPanel) {
0279             return 0;
0280         }
0281 
0282         if (root.isHorizontal) {
0283             return width * (plasmoid.configuration.offset/100);
0284         } else {
0285             height * (plasmoid.configuration.offset/100)
0286         }
0287     }
0288 
0289     property int editShadow: {
0290         if (!LatteCore.WindowSystem.compositingActive) {
0291             return 0;
0292         } else if (latteView && latteView.screenGeometry) {
0293             return latteView.screenGeometry.height/90;
0294         } else {
0295             return 7;
0296         }
0297     }
0298 
0299     property bool screenEdgeMarginEnabled: plasmoid.configuration.screenEdgeMargin >= 0
0300 
0301     property int widthMargins: root.isVertical ? metrics.totals.thicknessEdges : metrics.totals.lengthEdges
0302     property int heightMargins: root.isHorizontal ? metrics.totals.thicknessEdges : metrics.totals.lengthEdges
0303 
0304     property var iconsArray: [16, 22, 32, 48, 64, 96, 128, 256]
0305 
0306     property Item dragOverlay: _dragOverlay
0307     property Item toolBox
0308 
0309     readonly property alias animations: _animations
0310     readonly property alias autosize: _autosize
0311     readonly property alias background: _background
0312     readonly property alias debug: _debug
0313     readonly property alias environment: _environment
0314     readonly property alias indexer: _indexer
0315     readonly property alias indicators: _indicators
0316     readonly property alias layouter: _layouter
0317     readonly property alias launchers: _launchers
0318     readonly property alias metrics: _metrics
0319     readonly property alias myView: _myView
0320     readonly property alias parabolic: _parabolic
0321     readonly property alias thinTooltip: _thinTooltip
0322     readonly property alias userRequests: _userRequests
0323 
0324     readonly property alias maskManager: visibilityManager
0325     readonly property alias layoutsContainerItem: layoutsContainer
0326 
0327     readonly property alias latteView: _interfaces.view
0328     readonly property alias layoutsManager: _interfaces.layoutsManager
0329     readonly property alias shortcutsEngine: _interfaces.globalShortcuts
0330     readonly property alias themeExtended: _interfaces.themeExtended
0331     readonly property alias universalSettings: _interfaces.universalSettings
0332 
0333     readonly property QtObject selectedWindowsTracker: {
0334         if (latteView && latteView.windowsTracker) {
0335             switch(plasmoid.configuration.activeWindowFilter) {
0336             case LatteContainment.Types.ActiveInCurrentScreen:
0337                 return latteView.windowsTracker.currentScreen;
0338             case LatteContainment.Types.ActiveFromAllScreens:
0339                 return latteView.windowsTracker.allScreens;
0340             }
0341         }
0342 
0343         return null;
0344     }
0345 
0346     Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground
0347 
0348     //// BEGIN properties in functions
0349     property int noApplets: {
0350         var count1 = 0;
0351         var count2 = 0;
0352 
0353         count1 = layoutsContainer.mainLayout.children.length;
0354         var tempLength = layoutsContainer.mainLayout.children.length;
0355 
0356         for (var i=tempLength-1; i>=0; --i) {
0357             var applet = layoutsContainer.mainLayout.children[i];
0358             if (applet && (applet === dndSpacer ||  applet.isInternalViewSplitter))
0359                 count1--;
0360         }
0361 
0362         count2 = layoutsContainer.endLayout.children.length;
0363         tempLength = layoutsContainer.endLayout.children.length;
0364 
0365         for (var i=tempLength-1; i>=0; --i) {
0366             var applet = layoutsContainer.endLayout.children[i];
0367             if (applet && (applet === dndSpacer || applet.isInternalViewSplitter))
0368                 count2--;
0369         }
0370 
0371         return (count1 + count2);
0372     }
0373 
0374     ///The index of user's current icon size
0375     property int currentIconIndex:{
0376         for(var i=iconsArray.length-1; i>=0; --i){
0377             if(iconsArray[i] === metrics.iconSize){
0378                 return i;
0379             }
0380         }
0381         return 3;
0382     }
0383 
0384     //// END properties in functions
0385 
0386     ////////////////END properties
0387 
0388     //////////////START OF BINDINGS
0389 
0390     //! Wait until the mouse leaves the view
0391     Binding {
0392         target: root
0393         property: "hideThickScreenGap"
0394         when: !(plasmoid.configuration.floatingGapHidingWaitsMouse && dockContainsMouse)
0395         value: screenEdgeMarginEnabled
0396                && plasmoid.configuration.hideFloatingGapForMaximized
0397                && latteView && latteView.windowsTracker
0398                && latteView.windowsTracker.currentScreen.existsWindowMaximized
0399     }
0400 
0401     //! Binding is needed in order for hideLengthScreenGaps to be activated or not only after
0402     //! View sliding in/out has finished. This way the animation is smoother for behaveAsPlasmaPanels
0403     Binding{
0404         target: root
0405         property: "hideLengthScreenGaps"
0406         when: latteView && latteView.positioner && latteView.visibility
0407               && ((root.behaveAsPlasmaPanel && latteView.positioner.slideOffset === 0)
0408                   || root.behaveAsDockWithMask)
0409               && !(plasmoid.configuration.floatingGapHidingWaitsMouse && dockContainsMouse)
0410         value: (hideThickScreenGap
0411                 && (latteView.visibility.mode === LatteCore.Types.AlwaysVisible
0412                     || latteView.visibility.mode === LatteCore.Types.WindowsGoBelow)
0413                 && (plasmoid.configuration.alignment === LatteCore.Types.Justify)
0414                 && plasmoid.configuration.maxLength>85)
0415     }
0416 
0417     //////////////END OF BINDINGS
0418 
0419 
0420     //////////////START OF CONNECTIONS
0421     onEditModeChanged: {
0422         if (!editMode) {
0423             layouter.updateSizeForAppletsInFill();
0424         }
0425 
0426         //! This is used in case the dndspacer has been left behind
0427         //! e.g. the user drops a folder and a context menu is appearing
0428         //! but the user decides to not make a choice for the applet type
0429         if (dndSpacer.parent !== root) {
0430             dndSpacer.parent = root;
0431         }
0432 
0433         //Block Hiding events
0434         if (editMode) {
0435             latteView.visibility.addBlockHidingEvent("main[qml]::inEditMode()");
0436         } else {
0437             latteView.visibility.removeBlockHidingEvent("main[qml]::inEditMode()");
0438         }
0439     }
0440 
0441     onInConfigureAppletsModeChanged: {
0442         updateIndexes();
0443     }
0444 
0445     //! It is used only when the user chooses different alignment types and not during startup
0446     Connections {
0447         target: latteView ? latteView : null
0448         onAlignmentChanged: {
0449             if (latteView.alignment === LatteCore.Types.NoneAlignment) {
0450                 return;
0451             }
0452 
0453             var previousalignment = plasmoid.configuration.alignment;
0454 
0455             if (latteView.alignment===LatteCore.Types.Justify && previousalignment!==LatteCore.Types.Justify) { // main -> justify
0456                 layouter.appletsInParentChange = true;
0457                 fastLayoutManager.addJustifySplittersInMainLayout();
0458                 console.log("LAYOUTS: Moving applets from MAIN to THREE Layouts mode...");
0459                 fastLayoutManager.moveAppletsBasedOnJustifyAlignment();
0460                 layouter.appletsInParentChange = false;
0461             } else if (latteView.alignment!==LatteCore.Types.Justify && previousalignment===LatteCore.Types.Justify ) { // justify ->main
0462                 layouter.appletsInParentChange = true;
0463                 console.log("LAYOUTS: Moving applets from THREE to MAIN Layout mode...");
0464                 fastLayoutManager.joinLayoutsToMainLayout();
0465                 layouter.appletsInParentChange = false;
0466             }
0467 
0468             root.updateIndexes();
0469             plasmoid.configuration.alignment = latteView.alignment;
0470             fastLayoutManager.save();
0471         }
0472     }
0473 
0474     onLatteViewChanged: {
0475         if (latteView) {
0476             if (latteView.positioner) {
0477                 latteView.positioner.hidingForRelocationStarted.connect(visibilityManager.slotHideDockDuringLocationChange);
0478                 latteView.positioner.showingAfterRelocationFinished.connect(visibilityManager.slotShowDockAfterLocationChange);
0479             }
0480 
0481             if (latteView.visibility) {
0482                 latteView.visibility.onContainsMouseChanged.connect(visibilityManager.slotContainsMouseChanged);
0483                 latteView.visibility.onMustBeHide.connect(visibilityManager.slotMustBeHide);
0484                 latteView.visibility.onMustBeShown.connect(visibilityManager.slotMustBeShown);
0485             }
0486         }
0487     }
0488 
0489     Connections {
0490         target: latteView
0491         onPositionerChanged: {
0492             if (latteView.positioner) {
0493                 latteView.positioner.hidingForRelocationStarted.connect(visibilityManager.slotHideDockDuringLocationChange);
0494                 latteView.positioner.showingAfterRelocationFinished.connect(visibilityManager.slotShowDockAfterLocationChange);
0495             }
0496         }
0497 
0498         onVisibilityChanged: {
0499             if (latteView.visibility) {
0500                 latteView.visibility.onContainsMouseChanged.connect(visibilityManager.slotContainsMouseChanged);
0501                 latteView.visibility.onMustBeHide.connect(visibilityManager.slotMustBeHide);
0502                 latteView.visibility.onMustBeShown.connect(visibilityManager.slotMustBeShown);
0503             }
0504         }
0505     }
0506 
0507 
0508     onMaxLengthChanged: {
0509         layouter.updateSizeForAppletsInFill();
0510     }
0511 
0512     onToolBoxChanged: {
0513         if (toolBox) {
0514             toolBox.visible = false;
0515         }
0516     }
0517 
0518     onIsVerticalChanged: {
0519         if (isVertical) {
0520             if (plasmoid.configuration.alignment === LatteCore.Types.Left)
0521                 plasmoid.configuration.alignment = LatteCore.Types.Top;
0522             else if (plasmoid.configuration.alignment === LatteCore.Types.Right)
0523                 plasmoid.configuration.alignment = LatteCore.Types.Bottom;
0524         } else {
0525             if (plasmoid.configuration.alignment === LatteCore.Types.Top)
0526                 plasmoid.configuration.alignment = LatteCore.Types.Left;
0527             else if (plasmoid.configuration.alignment === LatteCore.Types.Bottom)
0528                 plasmoid.configuration.alignment = LatteCore.Types.Right;
0529         }
0530     }
0531 
0532     Component.onCompleted: {
0533         upgrader_v010_alignment();
0534 
0535         fastLayoutManager.restore();
0536         plasmoid.action("configure").visible = !plasmoid.immutable;
0537         plasmoid.action("configure").enabled = !plasmoid.immutable;
0538     }
0539 
0540     Component.onDestruction: {
0541         console.debug("Destroying Latte Dock Containment ui...");
0542 
0543         layouter.appletsInParentChange = true;
0544         fastLayoutManager.save();
0545 
0546         if (latteView) {
0547             if (latteView.positioner) {
0548                 latteView.positioner.hidingForRelocationStarted.disconnect(visibilityManager.slotHideDockDuringLocationChange);
0549                 latteView.positioner.showingAfterRelocationFinished.disconnect(visibilityManager.slotShowDockAfterLocationChange);
0550             }
0551 
0552             if (latteView.visibility) {
0553                 latteView.visibility.onContainsMouseChanged.disconnect(visibilityManager.slotContainsMouseChanged);
0554                 latteView.visibility.onMustBeHide.disconnect(visibilityManager.slotMustBeHide);
0555                 latteView.visibility.onMustBeShown.disconnect(visibilityManager.slotMustBeShown);
0556             }
0557         }
0558     }
0559 
0560     Containment.onAppletAdded: {
0561         if (fastLayoutManager.isMasqueradedIndex(x, y)) {
0562             var index = fastLayoutManager.masquearadedIndex(x, y);
0563             fastLayoutManager.addAppletItem(applet, index);
0564         } else {
0565             fastLayoutManager.addAppletItem(applet, x, y);
0566         }
0567     }
0568 
0569     Containment.onAppletRemoved: fastLayoutManager.removeAppletItem(applet);
0570 
0571     Plasmoid.onUserConfiguringChanged: {
0572         if (plasmoid.userConfiguring) {
0573             for (var i = 0; i < plasmoid.applets.length; ++i) {
0574                 plasmoid.applets[i].expanded = false;
0575             }
0576         }
0577     }
0578 
0579     Plasmoid.onImmutableChanged: {
0580         plasmoid.action("configure").visible = !plasmoid.immutable;
0581         plasmoid.action("configure").enabled = !plasmoid.immutable;
0582     }
0583     //////////////END OF CONNECTIONS
0584 
0585     //////////////START OF FUNCTIONS
0586     function createAppletItem(applet) {
0587         var appletContainer = appletItemComponent.createObject(dndSpacer.parent);
0588         initAppletContainer(appletContainer, applet);
0589 
0590         // don't show applet if it chooses to be hidden but still make it  accessible in the panelcontroller
0591         appletContainer.visible = Qt.binding(function() {
0592             return (appletContainer.applet && appletContainer.applet.status !== PlasmaCore.Types.HiddenStatus || (!plasmoid.immutable && root.inConfigureAppletsMode)) && !appletContainer.isHidden;
0593         });
0594         return appletContainer;
0595     }
0596 
0597     function initAppletContainer(appletContainer, applet) {
0598         appletContainer.applet = applet;
0599         applet.parent = appletContainer.appletWrapper;
0600         applet.anchors.fill = appletContainer.appletWrapper;
0601         applet.visible = true;
0602     }
0603 
0604     function createJustifySplitter() {
0605         var splitter = appletItemComponent.createObject(root);
0606         splitter.internalSplitterId = internalViewSplittersCount()+1;
0607         splitter.visible = true;
0608         return splitter;
0609     }
0610 
0611     //! it is used in order to check the right click position
0612     //! the only way to take into account the visual appearance
0613     //! of the applet (including its spacers)
0614     function appletContainsPos(appletId, pos){
0615         for (var i = 0; i < layoutsContainer.startLayout.children.length; ++i) {
0616             var child = layoutsContainer.startLayout.children[i];
0617 
0618             if (child && child.applet && child.applet.id === appletId && child.containsPos(pos))
0619                 return true;
0620         }
0621 
0622         for (var i = 0; i < layoutsContainer.mainLayout.children.length; ++i) {
0623             var child = layoutsContainer.mainLayout.children[i];
0624 
0625             if (child && child.applet && child.applet.id === appletId && child.containsPos(pos))
0626                 return true;
0627         }
0628 
0629         for (var i = 0; i < layoutsContainer.endLayout.children.length; ++i) {
0630             var child = layoutsContainer.endLayout.children[i];
0631 
0632             if (child && child.applet && child.applet.id === appletId && child.containsPos(pos))
0633                 return true;
0634         }
0635 
0636         return false;
0637     }
0638 
0639     function internalViewSplittersCount(){
0640         var splitters = 0;
0641         for (var container in layoutsContainer.startLayout.children) {
0642             var item = layoutsContainer.startLayout.children[container];
0643             if(item && item.isInternalViewSplitter) {
0644                 splitters = splitters + 1;
0645             }
0646         }
0647 
0648         for (var container in layoutsContainer.mainLayout.children) {
0649             var item = layoutsContainer.mainLayout.children[container];
0650             if(item && item.isInternalViewSplitter) {
0651                 splitters = splitters + 1;
0652             }
0653         }
0654 
0655         for (var container in layoutsContainer.endLayout.children) {
0656             var item = layoutsContainer.endLayout.children[container];
0657             if(item && item.isInternalViewSplitter) {
0658                 splitters = splitters + 1;
0659             }
0660         }
0661 
0662         return splitters;
0663     }
0664 
0665     function mouseInCanBeHoveredApplet(){
0666         var applets = layoutsContainer.startLayout.children;
0667 
0668         for(var i=0; i<applets.length; ++i){
0669             var applet = applets[i];
0670 
0671             if(applet && applet.containsMouse && !applet.originalAppletBehavior && applet.parabolicEffectIsSupported){
0672                 return true;
0673             }
0674         }
0675 
0676         applets = layoutsContainer.mainLayout.children;
0677 
0678         for(var i=0; i<applets.length; ++i){
0679             var applet = applets[i];
0680 
0681             if(applet && applet.containsMouse && !applet.originalAppletBehavior && applet.parabolicEffectIsSupported){
0682                 return true;
0683             }
0684         }
0685 
0686         ///check second layout also
0687         applets = layoutsContainer.endLayout.children;
0688 
0689         for(var i=0; i<applets.length; ++i){
0690             var applet = applets[i];
0691 
0692             if(applet && applet.containsMouse && !applet.originalAppletBehavior && applet.parabolicEffectIsSupported){
0693                 return true;
0694             }
0695         }
0696 
0697         return false;
0698     }
0699 
0700     function sizeIsFromAutomaticMode(size){
0701 
0702         for(var i=iconsArray.length-1; i>=0; --i){
0703             if(iconsArray[i] === size){
0704                 return true;
0705             }
0706         }
0707 
0708         return false;
0709     }
0710 
0711     function upgrader_v010_alignment() {
0712         //! IMPORTANT, special case because it needs to be loaded on Component constructor
0713         if (!plasmoid.configuration.alignmentUpgraded) {
0714             plasmoid.configuration.alignment = plasmoid.configuration.panelPosition;
0715             plasmoid.configuration.alignmentUpgraded = true;
0716         }
0717     }
0718     //END functions
0719 
0720     ///////////////BEGIN components
0721     Component {
0722         id: appletItemComponent
0723         Applet.AppletItem{
0724             animations: _animations
0725             debug: _debug
0726             environment: _environment
0727             indexer: _indexer
0728             indicators: _indicators
0729             launchers: _launchers
0730             layouter: _layouter
0731             layouts: layoutsContainer
0732             metrics: _metrics
0733             myView: _myView
0734             parabolic: _parabolic
0735             shortcuts: _shortcuts
0736             thinTooltip: _thinTooltip
0737             userRequests: _userRequests
0738         }
0739     }
0740 
0741     Upgrader {
0742         id: upgrader
0743     }
0744 
0745     ///////////////END components
0746 
0747     PlasmaCore.ColorScope{
0748         id: colorScopePalette
0749     }
0750 
0751     LatteContainment.LayoutManager{
0752         id:fastLayoutManager
0753         plasmoidObj: plasmoid
0754         rootItem: root
0755         dndSpacerItem: dndSpacer
0756         mainLayout: layoutsContainer.mainLayout
0757         startLayout: layoutsContainer.startLayout
0758         endLayout: layoutsContainer.endLayout
0759         metrics: _metrics
0760 
0761         onAppletOrderChanged: root.updateIndexes();
0762         onSplitterPositionChanged: root.updateIndexes();
0763         onSplitterPosition2Changed: root.updateIndexes();
0764     }
0765 
0766     ///////////////BEGIN UI elements
0767 
0768     Loader{
0769         active: debug.windowEnabled
0770         sourceComponent: Debugger.DebugWindow{}
0771     }
0772 
0773     Loader{
0774         anchors.fill: parent
0775         active: debug.graphicsEnabled
0776         z:10
0777 
0778         sourceComponent: Item{
0779             Rectangle{
0780                 anchors.fill: parent
0781                 color: "yellow"
0782                 opacity: 0.06
0783             }
0784         }
0785     }
0786 
0787     BindingsExternal {
0788         id: bindingsExternal
0789     }
0790 
0791     VisibilityManager{
0792         id: visibilityManager
0793         layouts: layoutsContainer
0794     }
0795 
0796     DragDropArea {
0797         id: backDropArea
0798         anchors.fill: parent
0799 
0800         Item{
0801             anchors.fill: layoutsContainer
0802 
0803             Background.MultiLayered{
0804                 id: _background
0805             }
0806         }
0807 
0808         Layouts.LayoutsContainer {
0809             id: layoutsContainer
0810         }
0811     }
0812 
0813     Colorizer.Manager {
0814         id: colorizerManager
0815     }
0816 
0817     EditMode.ConfigOverlay{
0818         id: _dragOverlay
0819     }
0820 
0821     Item {
0822         id: dndSpacer
0823 
0824         width: root.isHorizontal ? length : thickness
0825         height: root.isHorizontal ? thickness : length
0826 
0827         property int length: opacity > 0 ? (dndSpacerAddItem.length + metrics.totals.lengthEdges + metrics.totals.lengthPaddings) : 0
0828 
0829         readonly property bool isDndSpacer: true
0830         readonly property int thickness: metrics.totals.thickness + metrics.margin.screenEdge
0831         readonly property int maxLength: 96
0832 
0833         Layout.minimumWidth: width
0834         Layout.minimumHeight: height
0835         Layout.preferredWidth: Layout.minimumWidth
0836         Layout.preferredHeight: Layout.minimumHeight
0837         Layout.maximumWidth: Layout.minimumWidth
0838         Layout.maximumHeight: Layout.minimumHeight
0839         opacity: 0
0840         visible: parent === layoutsContainer.startLayout
0841                  || parent === layoutsContainer.mainLayout
0842                  || parent === layoutsContainer.endLayout
0843 
0844         z:1500
0845 
0846         Behavior on length {
0847             NumberAnimation {
0848                 duration: animations.duration.large
0849                 easing.type: Easing.InQuad
0850             }
0851         }
0852 
0853         Behavior on opacity {
0854             NumberAnimation {
0855                 duration: animations.duration.large
0856                 easing.type: Easing.InQuad
0857             }
0858         }
0859 
0860         Item {
0861             id: dndSpacerAddItemContainer
0862             width: root.isHorizontal ? parent.length : parent.thickness - metrics.margin.screenEdge
0863             height: root.isHorizontal ? parent.thickness - metrics.margin.screenEdge : parent.length
0864 
0865             property int thickMargin: metrics.margin.screenEdge
0866 
0867             LatteComponents.AddItem{
0868                 id: dndSpacerAddItem
0869                 anchors.centerIn: parent
0870                 width: length
0871                 height: width
0872 
0873                 readonly property int length: Math.min(metrics.iconSize, 96)
0874             }
0875 
0876             states:[
0877                 State{
0878                     name: "bottom"
0879                     when: plasmoid.location === PlasmaCore.Types.BottomEdge
0880 
0881                     AnchorChanges{
0882                         target: dndSpacerAddItemContainer;
0883                         anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: undefined;
0884                         anchors.right: undefined; anchors.left: undefined; anchors.top: undefined; anchors.bottom: parent.bottom;
0885                     }
0886                     PropertyChanges{
0887                         target: dndSpacerAddItemContainer;
0888                         anchors.leftMargin: 0;    anchors.rightMargin: 0;     anchors.topMargin:0;    anchors.bottomMargin: dndSpacerAddItemContainer.thickMargin;
0889                         anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
0890                     }
0891                 },
0892                 State{
0893                     name: "top"
0894                     when: plasmoid.location === PlasmaCore.Types.TopEdge
0895 
0896                     AnchorChanges{
0897                         target: dndSpacerAddItemContainer;
0898                         anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: undefined;
0899                         anchors.right: undefined; anchors.left: undefined; anchors.top: parent.top; anchors.bottom: undefined;
0900                     }
0901                     PropertyChanges{
0902                         target: dndSpacerAddItemContainer;
0903                         anchors.leftMargin: 0;    anchors.rightMargin: 0;     anchors.topMargin: dndSpacerAddItemContainer.thickMargin;    anchors.bottomMargin: 0;
0904                         anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
0905                     }
0906                 },
0907                 State{
0908                     name: "left"
0909                     when: plasmoid.location === PlasmaCore.Types.LeftEdge
0910 
0911                     AnchorChanges{
0912                         target: dndSpacerAddItemContainer;
0913                         anchors.horizontalCenter: undefined; anchors.verticalCenter: parent.verticalCenter;
0914                         anchors.right: undefined; anchors.left: parent.left; anchors.top: undefined; anchors.bottom: undefined;
0915                     }
0916                     PropertyChanges{
0917                         target: dndSpacerAddItemContainer;
0918                         anchors.leftMargin: dndSpacerAddItemContainer.thickMargin;    anchors.rightMargin: 0;     anchors.topMargin:0;    anchors.bottomMargin: 0;
0919                         anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
0920                     }
0921                 },
0922                 State{
0923                     name: "right"
0924                     when: plasmoid.location === PlasmaCore.Types.RightEdge
0925 
0926                     AnchorChanges{
0927                         target: dndSpacerAddItemContainer;
0928                         anchors.horizontalCenter: undefined; anchors.verticalCenter: parent.verticalCenter;
0929                         anchors.right: parent.right; anchors.left: undefined; anchors.top: undefined; anchors.bottom: undefined;
0930                     }
0931                     PropertyChanges{
0932                         target: dndSpacerAddItemContainer;
0933                         anchors.leftMargin: 0;    anchors.rightMargin: dndSpacerAddItemContainer.thickMargin;     anchors.topMargin:0;    anchors.bottomMargin: 0;
0934                         anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0;
0935                     }
0936                 }
0937             ]
0938         }
0939     }
0940 
0941     Behavior on maxLengthPerCentage {
0942         enabled: root.behaveAsDockWithMask && plasmoid.configuration.floatingGapHidingWaitsMouse && dockContainsMouse
0943         NumberAnimation {
0944             duration: animations.duration.short
0945             easing.type: Easing.InQuad
0946         }
0947     }
0948 
0949     ///////////////END UI elements
0950 
0951     ///////////////BEGIN ABILITIES
0952 
0953     Ability.Animations {
0954         id: _animations
0955         layouts: layoutsContainer
0956         metrics: _metrics
0957         settings: universalSettings
0958     }
0959 
0960     Ability.AutoSize {
0961         id: _autosize
0962         layouts: layoutsContainer
0963         layouter: _layouter
0964         metrics: _metrics
0965         visibility: visibilityManager
0966     }
0967 
0968     Ability.Debug {
0969         id: _debug
0970     }
0971 
0972     AbilityHost.Environment{
0973         id: _environment
0974     }
0975 
0976     Ability.Indexer {
0977         id: _indexer
0978         layouts: layoutsContainer
0979     }
0980 
0981     Ability.Indicators{
0982         id: _indicators
0983         view: latteView
0984     }
0985 
0986     Ability.Launchers {
0987         id: _launchers
0988         layouts: layoutsContainer
0989         layoutName: latteView && latteView.layout ? latteView.layout.name : ""
0990     }
0991 
0992     Ability.Layouter {
0993         id: _layouter
0994         animations: _animations
0995         indexer: _indexer
0996         layouts: layoutsContainer
0997     }
0998 
0999     Ability.Metrics {
1000         id: _metrics
1001         animations: _animations
1002         autosize: _autosize
1003         background: _background
1004         indicators: _indicators
1005         parabolic: _parabolic
1006     }
1007 
1008     Ability.MyView {
1009         id: _myView
1010         layouts: layoutsContainer
1011     }
1012 
1013     Ability.ParabolicEffect {
1014         id: _parabolic
1015         animations: _animations
1016         debug: _debug
1017         layouts: layoutsContainer
1018         view: latteView
1019         settings: universalSettings
1020     }
1021 
1022     Ability.PositionShortcuts {
1023         id: _shortcuts
1024         layouts: layoutsContainer
1025     }
1026 
1027     Ability.ThinTooltip {
1028         id: _thinTooltip
1029         debug: _debug
1030         layouts: layoutsContainer
1031         view: latteView
1032     }
1033 
1034     Ability.UserRequests {
1035         id: _userRequests
1036         view: latteView
1037     }
1038 
1039     LatteApp.Interfaces {
1040         id: _interfaces
1041         plasmoidInterface: plasmoid
1042 
1043         Component.onCompleted: {
1044             view.interfacesGraphicObj = _interfaces;
1045         }
1046 
1047         onViewChanged: {
1048             if (view) {
1049                 view.interfacesGraphicObj = _interfaces;
1050 
1051                 if (!root.inStartup) {
1052                     //! used from recreating views
1053                     root.inStartup = true;
1054                     startupDelayer.start();
1055                 }
1056             }
1057         }
1058     }
1059 
1060     ///////////////END ABILITIES
1061 
1062     ///////////////BEGIN TIMER elements
1063 
1064     //! It is used in order to slide-in the latteView on startup
1065     onInStartupChanged: {
1066         if (!inStartup) {
1067             latteView.positioner.startupFinished();
1068             latteView.positioner.slideInDuringStartup();
1069             visibilityManager.slotMustBeShown();
1070         }
1071     }
1072 
1073     Connections {
1074         target:fastLayoutManager
1075         onHasRestoredAppletsChanged: {
1076             if (fastLayoutManager.hasRestoredApplets) {
1077                 startupDelayer.start();
1078             }
1079         }
1080     }
1081 
1082     Timer {
1083         //! Give a little more time to layouter and applets to load and be positioned properly during startup when
1084         //! the view is drawn out-of-screen and afterwards trigger the startup animation sequence:
1085         //! 1.slide-out when out-of-screen //slotMustBeHide()
1086         //! 2.be positioned properly at correct screen //slideInDuringStartup(), triggers Positioner::syncGeometry()
1087         //! 3.slide-in properly in correct screen //slotMustBeShown();
1088         id: startupDelayer
1089         interval: 1000
1090         onTriggered: {
1091             visibilityManager.slotMustBeHide();
1092         }
1093     }
1094 
1095     ///////////////END TIMER elements
1096 
1097     Loader{
1098         anchors.fill: parent
1099         active: debug.localGeometryEnabled
1100         sourceComponent: Rectangle{
1101             x: latteView.localGeometry.x
1102             y: latteView.localGeometry.y
1103             //! when view is resized there is a chance that geometry is faulty stacked in old values
1104             width: Math.min(latteView.localGeometry.width, root.width) //! fixes updating
1105             height: Math.min(latteView.localGeometry.height, root.height) //! fixes updating
1106 
1107             color: "blue"
1108             border.width: 2
1109             border.color: "red"
1110 
1111             opacity: 0.35
1112         }
1113     }
1114 
1115     Loader{
1116         anchors.fill: parent
1117         active: latteView && latteView.effects && debug.inputMaskEnabled
1118         sourceComponent: Rectangle{
1119             x: latteView.effects.inputMask.x
1120             y: latteView.effects.inputMask.y
1121             //! when view is resized there is a chance that geometry is faulty stacked in old values
1122             width: Math.min(latteView.effects.inputMask.width, root.width) //! fixes updating
1123             height: Math.min(latteView.effects.inputMask.height, root.height) //! fixes updating
1124 
1125             color: "purple"
1126             border.width: 1
1127             border.color: "black"
1128 
1129             opacity: 0.20
1130         }
1131     }
1132 }