Warning, /plasma/plasma-desktop/applets/kickoff/package/contents/ui/main.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2011 Martin Gräßlin <mgraesslin@kde.org>
0003     SPDX-FileCopyrightText: 2012 Gregor Taetzner <gregor@freenet.de>
0004     SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org>
0005     SPDX-FileCopyrightText: 2013 David Edmundson <davidedmundson@kde.org>
0006     SPDX-FileCopyrightText: 2015 Eike Hein <hein@kde.org>
0007     SPDX-FileCopyrightText: 2021 Mikel Johnson <mikel5764@gmail.com>
0008     SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
0009 
0010     SPDX-License-Identifier: GPL-2.0-or-later
0011 */
0012 import QtQuick 2.15
0013 import QtQuick.Layouts 1.15
0014 import QtQuick.Window 2.15
0015 import QtQml 2.15
0016 import org.kde.plasma.plasmoid 2.0
0017 import org.kde.plasma.core as PlasmaCore
0018 import org.kde.ksvg 1.0 as KSvg
0019 import org.kde.plasma.components 3.0 as PC3
0020 import org.kde.plasma.private.kicker 0.1 as Kicker
0021 import org.kde.kirigami 2.20 as Kirigami
0022 
0023 import "code/tools.js" as Tools
0024 
0025 PlasmoidItem {
0026     id: kickoff
0027 
0028     // The properties are defined here instead of the singleton because each
0029     // instance of Kickoff requires different instances of these properties
0030 
0031     readonly property bool inPanel: [
0032         PlasmaCore.Types.TopEdge,
0033         PlasmaCore.Types.RightEdge,
0034         PlasmaCore.Types.BottomEdge,
0035         PlasmaCore.Types.LeftEdge,
0036     ].includes(Plasmoid.location)
0037     readonly property bool vertical: Plasmoid.formFactor === PlasmaCore.Types.Vertical
0038 
0039     // Used to prevent the width from changing frequently when the scrollbar appears or disappears
0040     readonly property bool mayHaveGridWithScrollBar: Plasmoid.configuration.applicationsDisplay === 0
0041         || (Plasmoid.configuration.favoritesDisplay === 0 && kickoff.rootModel.favoritesModel.count > minimumGridRowCount * minimumGridRowCount)
0042 
0043     //BEGIN Models
0044     readonly property Kicker.RootModel rootModel: Kicker.RootModel {
0045         autoPopulate: false
0046 
0047         // TODO: appletInterface property now can be ported to "applet" and have the real Applet* assigned directly
0048         appletInterface: kickoff
0049 
0050         flat: true // have categories, but no subcategories
0051         sorted: Plasmoid.configuration.alphaSort
0052         showSeparators: true
0053         showTopLevelItems: true
0054 
0055         showAllApps: true
0056         showAllAppsCategorized: false
0057         showRecentApps: false
0058         showRecentDocs: false
0059         showPowerSession: false
0060         showFavoritesPlaceholder: true
0061 
0062         Component.onCompleted: {
0063             favoritesModel.initForClient("org.kde.plasma.kickoff.favorites.instance-" + Plasmoid.id)
0064 
0065             if (!Plasmoid.configuration.favoritesPortedToKAstats) {
0066                 if (favoritesModel.count < 1) {
0067                     favoritesModel.portOldFavorites(Plasmoid.configuration.favorites);
0068                 }
0069                 Plasmoid.configuration.favoritesPortedToKAstats = true;
0070             }
0071         }
0072     }
0073 
0074     readonly property Kicker.RunnerModel runnerModel: Kicker.RunnerModel {
0075         query: kickoff.searchField ? kickoff.searchField.text : ""
0076         onRequestUpdateQuery: query => {
0077             if (kickoff.searchField) {
0078                 kickoff.searchField.text = query;
0079             }
0080         }
0081         appletInterface: kickoff
0082         mergeResults: true
0083         favoritesModel: rootModel.favoritesModel
0084     }
0085 
0086     readonly property Kicker.ComputerModel computerModel: Kicker.ComputerModel {
0087         appletInterface: kickoff
0088         favoritesModel: rootModel.favoritesModel
0089         systemApplications: Plasmoid.configuration.systemApplications
0090         Component.onCompleted: {
0091             //systemApplications = Plasmoid.configuration.systemApplications;
0092         }
0093     }
0094 
0095     readonly property Kicker.RecentUsageModel recentUsageModel: Kicker.RecentUsageModel {
0096         favoritesModel: rootModel.favoritesModel
0097     }
0098 
0099     readonly property Kicker.RecentUsageModel frequentUsageModel: Kicker.RecentUsageModel {
0100         favoritesModel: rootModel.favoritesModel
0101         ordering: 1 // Popular / Frequently Used
0102     }
0103     //END
0104 
0105     //BEGIN UI elements
0106     // Set in FullRepresentation.qml
0107     property Item header: null
0108 
0109     // Set in Header.qml
0110     property PC3.TextField searchField: null
0111 
0112     // Set in FullRepresentation.qml, ApplicationPage.qml, PlacesPage.qml
0113     property Item sideBar: null // is null when searching
0114     property Item contentArea: null // is searchView when searching
0115 
0116     // Set in NormalPage.qml
0117     property Item footer: null
0118 
0119     // True when central pane (and header) LayoutMirroring diverges from global
0120     // LayoutMirroring, in order to achieve the desired sidebar position
0121     readonly property bool paneSwap: Plasmoid.configuration.paneSwap
0122     readonly property bool sideBarOnRight: (Qt.application.layoutDirection == Qt.RightToLeft) != paneSwap
0123     // References to items according to their focus chain order
0124     readonly property Item firstHeaderItem: header ? (paneSwap ? header.pinButton : header.avatar) : null
0125     readonly property Item lastHeaderItem: header ? (paneSwap ? header.avatar : header.pinButton) : null
0126     readonly property Item firstCentralPane: paneSwap ? contentArea : sideBar
0127     readonly property Item lastCentralPane: paneSwap ? sideBar : contentArea
0128     //END
0129 
0130     //BEGIN Metrics
0131     readonly property KSvg.FrameSvgItem backgroundMetrics: KSvg.FrameSvgItem {
0132         // Inset defaults to a negative value when not set by margin hints
0133         readonly property real leftPadding: margins.left - Math.max(inset.left, 0)
0134         readonly property real rightPadding: margins.right - Math.max(inset.right, 0)
0135         readonly property real topPadding: margins.top - Math.max(inset.top, 0)
0136         readonly property real bottomPadding: margins.bottom - Math.max(inset.bottom, 0)
0137         readonly property real spacing: leftPadding
0138         visible: false
0139         imagePath: Plasmoid.formFactor === PlasmaCore.Types.Planar ? "widgets/background" : "dialogs/background"
0140     }
0141 
0142     // This is here rather than in the singleton with the other metrics items
0143     // because the list delegate's height depends on a configuration setting
0144     // and the singleton can't access those
0145     readonly property real listDelegateHeight: listDelegate.height
0146     KickoffListDelegate {
0147         id: listDelegate
0148         visible: false
0149         enabled: false
0150         model: null
0151         index: -1
0152         text: "asdf"
0153         url: ""
0154         decoration: "start-here-kde"
0155         description: "asdf"
0156         action: null
0157         indicator: null
0158     }
0159 
0160     // Used to show smaller Kickoff on small screens
0161     readonly property int minimumGridRowCount: Math.min(Screen.desktopAvailableWidth, Screen.desktopAvailableHeight) * Screen.devicePixelRatio < KickoffSingleton.gridCellSize * 4 + (fullRepresentationItem ? fullRepresentationItem.normalPage.preferredSideBarWidth : KickoffSingleton.gridCellSize * 2) ? 2 : 4
0162     //END
0163 
0164     Plasmoid.icon: Plasmoid.configuration.icon
0165 
0166     switchWidth: fullRepresentationItem ? fullRepresentationItem.Layout.minimumWidth : -1
0167     switchHeight: fullRepresentationItem ? fullRepresentationItem.Layout.minimumHeight : -1
0168 
0169     preferredRepresentation: compactRepresentation
0170 
0171     fullRepresentation: FullRepresentation { focus: true }
0172 
0173     // Only exists because the default CompactRepresentation doesn't:
0174     // - open on drag
0175     // - allow defining a custom drop handler
0176     // - expose the ability to show text below or beside the icon
0177     // TODO remove once it gains those features
0178     compactRepresentation: MouseArea {
0179         id: compactRoot
0180 
0181         // Taken from DigitalClock to ensure uniform sizing when next to each other
0182         readonly property bool tooSmall: Plasmoid.formFactor === PlasmaCore.Types.Horizontal && Math.round(2 * (compactRoot.height / 5)) <= Kirigami.Theme.smallFont.pixelSize
0183 
0184         readonly property bool shouldHaveIcon: Plasmoid.formFactor === PlasmaCore.Types.Vertical || Plasmoid.icon !== ""
0185         readonly property bool shouldHaveLabel: Plasmoid.formFactor !== PlasmaCore.Types.Vertical && Plasmoid.configuration.menuLabel !== ""
0186 
0187         readonly property int iconSize: 48
0188 
0189         readonly property var sizing: {
0190             const displayedIcon = buttonIcon.valid ? buttonIcon : buttonIconFallback;
0191 
0192             let impWidth = 0;
0193             if (shouldHaveIcon) {
0194                 impWidth += displayedIcon.width;
0195             }
0196             if (shouldHaveLabel) {
0197                 impWidth += labelTextField.contentWidth + labelTextField.Layout.leftMargin + labelTextField.Layout.rightMargin;
0198             }
0199             const impHeight = displayedIcon.height > 0 ? displayedIcon.height : iconSize
0200 
0201             // at least square, but can be wider/taller
0202             if (kickoff.inPanel) {
0203                 if (kickoff.vertical) {
0204                     return {
0205                         preferredWidth: iconSize,
0206                         preferredHeight: impHeight
0207                     };
0208                 } else { // horizontal
0209                     return {
0210                         preferredWidth: impWidth,
0211                         preferredHeight: iconSize
0212                     };
0213                 }
0214             } else {
0215                 return {
0216                     preferredWidth: impWidth,
0217                     preferredHeight: Kirigami.Units.iconSizes.small,
0218                 };
0219             }
0220         }
0221 
0222         implicitWidth: iconSize
0223         implicitHeight: iconSize
0224 
0225         Layout.preferredWidth: sizing.preferredWidth
0226         Layout.preferredHeight: sizing.preferredHeight
0227         Layout.minimumWidth: Layout.preferredWidth
0228         Layout.minimumHeight: Layout.preferredHeight
0229 
0230         hoverEnabled: true
0231 
0232         property bool wasExpanded
0233 
0234         Accessible.name: Plasmoid.title
0235 
0236         onPressed: wasExpanded = kickoff.expanded
0237         onClicked: kickoff.expanded = !wasExpanded
0238 
0239         DropArea {
0240             id: compactDragArea
0241             anchors.fill: parent
0242         }
0243 
0244         Timer {
0245             id: expandOnDragTimer
0246             // this is an interaction and not an animation, so we want it as a constant
0247             interval: 250
0248             running: compactDragArea.containsDrag
0249             onTriggered: kickoff.expanded = true
0250         }
0251 
0252         RowLayout {
0253             id: iconLabelRow
0254             anchors.fill: parent
0255             spacing: 0
0256 
0257             Kirigami.Icon {
0258                 id: buttonIcon
0259 
0260                 Layout.fillWidth: kickoff.vertical
0261                 Layout.fillHeight: !kickoff.vertical
0262                 Layout.preferredWidth: kickoff.vertical ? -1 : height / (implicitHeight / implicitWidth)
0263                 Layout.preferredHeight: !kickoff.vertical ? -1 : width * (implicitHeight / implicitWidth)
0264                 Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
0265                 source: Tools.iconOrDefault(Plasmoid.formFactor, Plasmoid.icon)
0266                 active: compactRoot.containsMouse || compactDragArea.containsDrag
0267                 roundToIconSize: implicitHeight === implicitWidth
0268                 visible: valid
0269             }
0270 
0271             Kirigami.Icon {
0272                 id: buttonIconFallback
0273                 // fallback is assumed to be square
0274                 Layout.fillWidth: kickoff.vertical
0275                 Layout.fillHeight: !kickoff.vertical
0276                 Layout.preferredWidth: kickoff.vertical ? -1 : height
0277                 Layout.preferredHeight: !kickoff.vertical ? -1 : width
0278                 Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
0279 
0280                 source: buttonIcon.valid ? null : Tools.defaultIconName
0281                 active: compactRoot.containsMouse || compactDragArea.containsDrag
0282                 visible: !buttonIcon.valid && Plasmoid.icon !== ""
0283             }
0284 
0285             PC3.Label {
0286                 id: labelTextField
0287 
0288                 Layout.fillHeight: true
0289                 Layout.leftMargin: Kirigami.Units.smallSpacing
0290                 Layout.rightMargin: Kirigami.Units.smallSpacing
0291 
0292                 text: Plasmoid.configuration.menuLabel
0293                 textFormat: Text.PlainText
0294                 horizontalAlignment: Text.AlignLeft
0295                 verticalAlignment: Text.AlignVCenter
0296                 wrapMode: Text.NoWrap
0297                 fontSizeMode: Text.VerticalFit
0298                 font.pixelSize: compactRoot.tooSmall ? Kirigami.Theme.defaultFont.pixelSize : Kirigami.Units.iconSizes.roundedIconSize(Kirigami.Units.gridUnit * 2)
0299                 minimumPointSize: Kirigami.Theme.smallFont.pointSize
0300                 visible: compactRoot.shouldHaveLabel
0301             }
0302         }
0303     }
0304 
0305     Kicker.ProcessRunner {
0306         id: processRunner;
0307     }
0308 
0309     Plasmoid.contextualActions: [
0310         PlasmaCore.Action {
0311             text: i18n("Edit Applications…")
0312             icon.name: "kmenuedit"
0313             visible: Plasmoid.immutability !== PlasmaCore.Types.SystemImmutable
0314             onTriggered: processRunner.runMenuEditor()
0315         }
0316     ]
0317 
0318     Component.onCompleted: {
0319         if (Plasmoid.hasOwnProperty("activationTogglesExpanded")) {
0320             Plasmoid.activationTogglesExpanded = true
0321         }
0322     }
0323 } // root