Warning, /plasma/plasma-desktop/desktoppackage/contents/applet/CompactApplet.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 import QtQuick 2.15
0007 import QtQuick.Layouts 1.15
0008 import QtQuick.Window 2.15
0009 
0010 import org.kde.plasma.core as PlasmaCore
0011 import org.kde.ksvg 1.0 as KSvg
0012 import org.kde.plasma.plasmoid 2.0
0013 import org.kde.kquickcontrolsaddons 2.0
0014 import org.kde.kirigami 2.20 as Kirigami
0015 
0016 PlasmaCore.ToolTipArea {
0017     id: root
0018     objectName: "org.kde.desktop-CompactApplet"
0019     anchors.fill: parent
0020 
0021     mainText: plasmoidItem ? plasmoidItem.toolTipMainText : ""
0022     subText: plasmoidItem ? plasmoidItem.toolTipSubText : ""
0023     location: Plasmoid.location
0024     active: plasmoidItem ? !plasmoidItem.expanded : false
0025     textFormat: plasmoidItem ? plasmoidItem.toolTipTextFormat : 0
0026     mainItem: plasmoidItem && plasmoidItem.toolTipItem ? plasmoidItem.toolTipItem : null
0027 
0028     readonly property bool vertical: location === PlasmaCore.Types.RightEdge || location === PlasmaCore.Types.LeftEdge
0029 
0030     property Item fullRepresentation
0031     property Item compactRepresentation
0032     property Item expandedFeedback: expandedItem
0033     property PlasmoidItem plasmoidItem
0034 
0035     onCompactRepresentationChanged: {
0036         if (compactRepresentation) {
0037             compactRepresentation.anchors.fill = null;
0038             compactRepresentation.parent = compactRepresentationParent;
0039             compactRepresentation.anchors.fill = compactRepresentationParent;
0040             compactRepresentation.visible = true;
0041         }
0042         root.visible = true;
0043     }
0044 
0045     onFullRepresentationChanged: {
0046         if (fullRepresentation) {
0047             fullRepresentation.anchors.fill = null;
0048             fullRepresentation.parent = appletParent;
0049             fullRepresentation.anchors.fill = appletParent;
0050         }
0051     }
0052 
0053     FocusScope {
0054         id: compactRepresentationParent
0055         anchors.fill: parent
0056         activeFocusOnTab: true
0057         onActiveFocusChanged: {
0058             // When the scope gets the active focus, try to focus its first descendant,
0059             // if there is on which has activeFocusOnTab
0060             if (!activeFocus) {
0061                 return;
0062             }
0063             let nextItem = nextItemInFocusChain();
0064             let candidate = nextItem;
0065             while (candidate.parent) {
0066                 if (candidate === compactRepresentationParent) {
0067                     nextItem.forceActiveFocus();
0068                     return;
0069                 }
0070                 candidate = candidate.parent;
0071             }
0072         }
0073 
0074         objectName: "expandApplet"
0075         Accessible.name: root.mainText
0076         Accessible.description: i18nd("plasma_shell_org.kde.plasma.desktop", "Open %1", root.subText)
0077         Accessible.role: Accessible.Button
0078         Accessible.onPressAction: Plasmoid.activated()
0079 
0080         Keys.onPressed: {
0081             switch (event.key) {
0082                 case Qt.Key_Space:
0083                 case Qt.Key_Enter:
0084                 case Qt.Key_Return:
0085                 case Qt.Key_Select:
0086                     Plasmoid.activated();
0087                     break;
0088             }
0089         }
0090     }
0091 
0092     KSvg.FrameSvgItem {
0093         id: expandedItem
0094         z: -100
0095 
0096         property var containerMargins: {
0097             let item = root;
0098             while (item.parent) {
0099                 item = item.parent;
0100                 if (item.isAppletContainer) {
0101                     return item.getMargins;
0102                 }
0103             }
0104             return undefined;
0105         }
0106 
0107         anchors {
0108             fill: parent
0109             property bool returnAllMargins: true
0110             // The above makes sure margin is returned even for side margins, that
0111             // would be otherwise turned off.
0112             bottomMargin: !vertical && containerMargins ? -containerMargins('bottom', returnAllMargins) : 0;
0113             topMargin: !vertical && containerMargins ? -containerMargins('top', returnAllMargins) : 0;
0114             leftMargin: vertical && containerMargins ? -containerMargins('left', returnAllMargins) : 0;
0115             rightMargin: vertical && containerMargins ? -containerMargins('right', returnAllMargins) : 0;
0116         }
0117         imagePath: "widgets/tabbar"
0118         visible: opacity > 0
0119         prefix: {
0120             let prefix;
0121             switch (Plasmoid.location) {
0122             case PlasmaCore.Types.LeftEdge:
0123                 prefix = "west-active-tab";
0124                 break;
0125             case PlasmaCore.Types.TopEdge:
0126                 prefix = "north-active-tab";
0127                 break;
0128             case PlasmaCore.Types.RightEdge:
0129                 prefix = "east-active-tab";
0130                 break;
0131             default:
0132                 prefix = "south-active-tab";
0133             }
0134             if (!hasElementPrefix(prefix)) {
0135                 prefix = "active-tab";
0136             }
0137             return prefix;
0138         }
0139         opacity: plasmoidItem && plasmoidItem.expanded ? 1 : 0
0140         Behavior on opacity {
0141             NumberAnimation {
0142                 duration: Kirigami.Units.shortDuration
0143                 easing.type: Easing.InOutQuad
0144             }
0145         }
0146     }
0147 
0148     Timer {
0149         id: expandedSync
0150         interval: 100
0151         onTriggered: plasmoidItem.expanded = dialog.visible;
0152     }
0153 
0154     Connections {
0155         target: Plasmoid.internalAction("configure")
0156         function onTriggered() {
0157             if (root.plasmoidItem.hideOnWindowDeactivate) {
0158                 plasmoidItem.expanded = false
0159             }
0160         }
0161     }
0162 
0163     Connections {
0164         target: root.Plasmoid
0165         function onContextualActionsAboutToShow() { root.hideImmediately() }
0166     }
0167 
0168     PlasmaCore.AppletPopup {
0169         id: dialog
0170         objectName: "popupWindow"
0171 
0172         popupDirection: switch (Plasmoid.location) {
0173             case PlasmaCore.Types.TopEdge:
0174                 return Qt.BottomEdge
0175             case PlasmaCore.Types.LeftEdge:
0176                 return Qt.RightEdge
0177             case PlasmaCore.Types.RightEdge:
0178                 return Qt.LeftEdge
0179             default:
0180                 return Qt.TopEdge
0181         }
0182         margin: (Plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentPrefersFloatingApplets) ? Kirigami.Units.largeSpacing : 0
0183         floating: Plasmoid.location == PlasmaCore.Types.Floating
0184         removeBorderStrategy: Plasmoid.location === PlasmaCore.Types.Floating
0185             ? PlasmaCore.AppletPopup.AtScreenEdges
0186             : PlasmaCore.AppletPopup.AtScreenEdges | PlasmaCore.AppletPopup.AtPanelEdges
0187 
0188         hideOnWindowDeactivate: root.plasmoidItem && root.plasmoidItem.hideOnWindowDeactivate
0189         visible: root.plasmoidItem && root.plasmoidItem.expanded && fullRepresentation
0190         visualParent: root.compactRepresentation
0191         backgroundHints: (Plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentPrefersOpaqueBackground) ? PlasmaCore.AppletPopup.SolidBackground : PlasmaCore.AppletPopup.StandardBackground
0192         appletInterface: root.plasmoidItem
0193 
0194         property var oldStatus: PlasmaCore.Types.UnknownStatus
0195 
0196         onVisibleChanged: {
0197             if (!visible) {
0198                 expandedSync.restart();
0199                 Plasmoid.status = oldStatus;
0200             } else {
0201                 oldStatus = Plasmoid.status;
0202                 Plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus;
0203                 // This call currently fails and complains at runtime:
0204                 // QWindow::setWindowState: QWindow::setWindowState does not accept Qt::WindowActive
0205                 dialog.requestActivate();
0206             }
0207         }
0208         //It's a MouseEventListener to get all the events, so the eventfilter will be able to catch them
0209         mainItem: MouseEventListener {
0210             id: appletParent
0211 
0212             focus: true
0213 
0214             Keys.onEscapePressed: {
0215                 root.plasmoidItem.expanded = false;
0216             }
0217 
0218             Layout.minimumWidth: fullRepresentation ? fullRepresentation.Layout.minimumWidth : 0
0219             Layout.minimumHeight: fullRepresentation ? fullRepresentation.Layout.minimumHeight : 0
0220 
0221             Layout.maximumWidth: fullRepresentation ? fullRepresentation.Layout.maximumWidth : Infinity
0222             Layout.maximumHeight: fullRepresentation ? fullRepresentation.Layout.maximumHeight : Infinity
0223 
0224             implicitWidth: {
0225                 if (root.fullRepresentation !== null) {
0226                     /****/ if (root.fullRepresentation.Layout.preferredWidth > 0) {
0227                         return root.fullRepresentation.Layout.preferredWidth;
0228                     } else if (root.fullRepresentation.implicitWidth > 0) {
0229                         return root.fullRepresentation.implicitWidth;
0230                     }
0231                 }
0232                 return Kirigami.Units.iconSizes.sizeForLabels * 35;
0233             }
0234             implicitHeight: {
0235                 if (root.fullRepresentation !== null) {
0236                     /****/ if (fullRepresentation.Layout.preferredHeight > 0) {
0237                         return fullRepresentation.Layout.preferredHeight;
0238                     } else if (fullRepresentation.implicitHeight > 0) {
0239                         return fullRepresentation.implicitHeight;
0240                     }
0241                 }
0242                 return Kirigami.Units.iconSizes.sizeForLabels * 25;
0243             }
0244 
0245             onActiveFocusChanged: {
0246                 if (activeFocus && fullRepresentation) {
0247                     fullRepresentation.forceActiveFocus()
0248                 }
0249             }
0250 
0251             // Draws a line between the applet dialog and the panel
0252             KSvg.SvgItem {
0253                 id: separator
0254                 // Only draw for popups of panel applets, not desktop applets
0255                 visible: [PlasmaCore.Types.TopEdge, PlasmaCore.Types.LeftEdge, PlasmaCore.Types.RightEdge, PlasmaCore.Types.BottomEdge]
0256                     .includes(Plasmoid.location) && !dialog.margin
0257                 anchors {
0258                     topMargin: -dialog.topMargin
0259                     leftMargin: -dialog.leftMargin
0260                     rightMargin: -dialog.rightMargin
0261                     bottomMargin: -dialog.bottomMargin
0262                 }
0263                 z: 999 /* Draw the line on top of the applet */
0264                 elementId: (Plasmoid.location === PlasmaCore.Types.TopEdge || Plasmoid.location === PlasmaCore.Types.BottomEdge) ? "horizontal-line" : "vertical-line"
0265                 imagePath: "widgets/line"
0266                 states: [
0267                     State {
0268                         when: Plasmoid.location === PlasmaCore.Types.TopEdge
0269                         AnchorChanges {
0270                             target: separator
0271                             anchors {
0272                                 top: separator.parent.top
0273                                 left: separator.parent.left
0274                                 right: separator.parent.right
0275                             }
0276                         }
0277                         PropertyChanges {
0278                             target: separator
0279                             height: 1
0280                         }
0281                     },
0282                     State {
0283                         when: Plasmoid.location === PlasmaCore.Types.LeftEdge
0284                         AnchorChanges {
0285                             target: separator
0286                             anchors {
0287                                 left: separator.parent.left
0288                                 top: separator.parent.top
0289                                 bottom: separator.parent.bottom
0290                             }
0291                         }
0292                         PropertyChanges {
0293                             target: separator
0294                             width: 1
0295                         }
0296                     },
0297                     State {
0298                         when: Plasmoid.location === PlasmaCore.Types.RightEdge
0299                         AnchorChanges {
0300                             target: separator
0301                             anchors {
0302                                 top: separator.parent.top
0303                                 right: separator.parent.right
0304                                 bottom: separator.parent.bottom
0305                             }
0306                         }
0307                         PropertyChanges {
0308                             target: separator
0309                             width: 1
0310                         }
0311                     },
0312                     State {
0313                         when: Plasmoid.location === PlasmaCore.Types.BottomEdge
0314                         AnchorChanges {
0315                             target: separator
0316                             anchors {
0317                                 left: separator.parent.left
0318                                 right: separator.parent.right
0319                                 bottom: separator.parent.bottom
0320                             }
0321                         }
0322                         PropertyChanges {
0323                             target: separator
0324                             height: 1
0325                         }
0326                     }
0327                 ]
0328             }
0329 
0330             LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
0331             LayoutMirroring.childrenInherit: true
0332         }
0333     }
0334 }