main.qml 9.21 KB
Newer Older
Marco Martin's avatar
Marco Martin committed
1 2
/*
 *   Copyright 2011 Marco Martin <mart@kde.org>
3
 *   Copyright 2020 Konrad Materka <materka@gmail.com>
Marco Martin's avatar
Marco Martin committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Library General Public License for more details
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

Marco Martin's avatar
Marco Martin committed
21
import QtQuick 2.5
Marco Martin's avatar
Marco Martin committed
22
import QtQuick.Layouts 1.1
23
import org.kde.plasma.core 2.1 as PlasmaCore
Marco Martin's avatar
Marco Martin committed
24
import org.kde.plasma.plasmoid 2.0
25
import org.kde.draganddrop 2.0 as DnD
26
import org.kde.kirigami 2.5 as Kirigami
27

28
import "items"
Marco Martin's avatar
Marco Martin committed
29 30

MouseArea {
31
    id: root
Marco Martin's avatar
Marco Martin committed
32

33
    Layout.minimumWidth: vertical ? PlasmaCore.Units.iconSizes.small : tasksGrid.implicitWidth + (expander.visible ? expander.implicitWidth : 0) + PlasmaCore.Units.smallSpacing
34

35
    Layout.minimumHeight: vertical ? tasksGrid.implicitHeight + (expander.visible ? expander.implicitHeight : 0) + PlasmaCore.Units.smallSpacing : PlasmaCore.Units.smallSpacing
36 37

    Layout.preferredHeight: Layout.minimumHeight
Marco Martin's avatar
Marco Martin committed
38 39
    LayoutMirroring.enabled: !vertical && Qt.application.layoutDirection === Qt.RightToLeft
    LayoutMirroring.childrenInherit: true
40

41
    // The icon size to display when not using the auto-scaling setting
42
    readonly property int smallIconSize: PlasmaCore.Units.iconSizes.smallMedium
43

44 45
    // Used only by AbstractItem, but it's easiest to keep it here since it
    // uses dimensions from this item to calculate the final value
46
    readonly property int itemSize: autoSize ? PlasmaCore.Units.roundToIconSize(Math.min(Math.min(width / rowsOrColumns, height / rowsOrColumns), PlasmaCore.Units.iconSizes.enormous)) : smallIconSize
47

48 49
    // The rest are derived properties; do not modify
    readonly property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical
50
    readonly property bool autoSize: plasmoid.configuration.scaleIconsToFit
51
    readonly property int cellThickness: root.vertical ? root.width : root.height
52
    readonly property int rowsOrColumns: autoSize ? 1 : Math.max(1, Math.floor(cellThickness / (smallIconSize + PlasmaCore.Units.smallSpacing)))
Marco Martin's avatar
Marco Martin committed
53
    property alias expanded: dialog.visible
54
    property Item activeApplet
55
    property alias visibleLayout: tasksGrid
Marco Martin's avatar
Marco Martin committed
56 57
    property alias hiddenLayout: expandedRepresentation.hiddenLayout

58 59 60 61 62 63
    Plasmoid.onExpandedChanged: {
        if (!plasmoid.expanded) {
            dialog.visible = plasmoid.expanded;
        }
    }

64 65 66 67 68
    onWheel: {
        // Don't propagate unhandled wheel events
        wheel.accepted = true;
    }

69 70 71 72
    //being there forces the items to fully load, and they will be reparented in the popup one by one, this item is *never* visible
    Item {
        id: preloadedStorage
        visible: false
Marco Martin's avatar
Marco Martin committed
73 74
    }

75 76
    Connections {
        target: plasmoid
77 78
        function onUserConfiguringChanged() {
            if (plasmoid.userConfiguring) {
79 80 81 82 83
                dialog.visible = false
            }
        }
    }

Marco Martin's avatar
Marco Martin committed
84
    CurrentItemHighLight {
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
        property alias activeApplet: root.activeApplet
        property alias dialogVisible: dialog.visible

        // Not only is an applet active, but also it's an applet from the visible part of the tray, not the hidden part.
        readonly property bool visibleAppletActivated: activeApplet && activeApplet.parent && activeApplet.parent.inVisibleLayout

        onActiveAppletChanged: {
            if (activeApplet && activeApplet.parent.inVisibleLayout) {
                changeHighlightedItem(activeApplet.parent);
            } else if (dialog.visible) {
                changeHighlightedItem(root);
            }
        }

        onDialogVisibleChanged: {
            if (dialogVisible && !activeApplet) {
                changeHighlightedItemNoAnimation(root);
            }
        }

Marco Martin's avatar
Marco Martin committed
105 106
        location: plasmoid.location
    }
Marco Martin's avatar
Marco Martin committed
107

108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
    DnD.DropArea {
        anchors.fill: parent

        preventStealing: true;

        /** Extracts the name of the system tray applet in the drag data if present
         * otherwise returns null*/
        function systemTrayAppletName(event) {
            if (event.mimeData.formats.indexOf("text/x-plasmoidservicename") < 0) {
                return null;
            }
            var plasmoidId = event.mimeData.getDataAsByteArray("text/x-plasmoidservicename");

            if (!plasmoid.nativeInterface.isSystemTrayApplet(plasmoidId)) {
                return null;
            }
            return plasmoidId;
        }

        onDragEnter: {
            if (!systemTrayAppletName(event)) {
                event.ignore();
            }
        }

        onDrop: {
            var plasmoidId = systemTrayAppletName(event);
            if (!plasmoidId) {
                event.ignore();
                return;
            }

            if (plasmoid.configuration.extraItems.indexOf(plasmoidId) < 0) {
                var extraItems = plasmoid.configuration.extraItems;
                extraItems.push(plasmoidId);
                plasmoid.configuration.extraItems = extraItems;
            }
        }
    }

148
    //Main Layout
149 150 151 152 153 154 155 156 157 158 159
    GridLayout {
        id: mainLayout

        rowSpacing: 0
        columnSpacing: 0
        anchors.fill: parent

        flow: vertical ? GridLayout.TopToBottom : GridLayout.LeftToRight

        GridView {
            id: tasksGrid
160
            readonly property int smallSizeCellLength: root.cellThickness >= root.smallIconSize ? root.smallIconSize + PlasmaCore.Units.smallSpacing * 2
161
                                                                                               : root.smallIconSize
162
            readonly property int autoSizeCellLength: root.cellThickness / root.rowsOrColumns
163 164
            readonly property int totalLength: root.vertical ? cellHeight * Math.round(count / root.rowsOrColumns)
                                                             : cellWidth * Math.round(count / root.rowsOrColumns)
165

166 167 168 169 170
            Layout.alignment: Qt.AlignCenter

            interactive: false //disable features we don't need
            flow: vertical ? GridView.LeftToRight : GridView.TopToBottom

171 172
            implicitHeight: root.vertical ? totalLength : root.height
            implicitWidth: !root.vertical ? totalLength : root.width
173

174 175
            cellHeight: root.vertical && !root.autoSize ? smallSizeCellLength : autoSizeCellLength
            cellWidth:  !root.vertical && !root.autoSize ? smallSizeCellLength : autoSizeCellLength
176 177 178 179 180 181 182

            model: PlasmaCore.SortFilterModel {
                sourceModel: plasmoid.nativeInterface.systemTrayModel
                filterRole: "effectiveStatus"
                filterCallback: function(source_row, value) {
                    return value === PlasmaCore.Types.ActiveStatus
                }
Marco Martin's avatar
Marco Martin committed
183
            }
184 185 186 187 188 189 190 191 192 193 194

            delegate: ItemLoader {}

            add: Transition {
                enabled: root.itemSize > 0

                NumberAnimation {
                    property: "scale"
                    from: 0
                    to: 1
                    easing.type: Easing.InOutQuad
195
                    duration: PlasmaCore.Units.longDuration
196
                }
197
            }
Marco Martin's avatar
Marco Martin committed
198

199 200 201 202 203 204 205
            displaced: Transition {
                //ensure scale value returns to 1.0
                //https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html#handling-interrupted-animations
                NumberAnimation {
                    property: "scale"
                    to: 1
                    easing.type: Easing.InOutQuad
206
                    duration: PlasmaCore.Units.longDuration
207 208 209 210 211 212 213
                }
            }

            move: Transition {
                NumberAnimation {
                    properties: "x,y"
                    easing.type: Easing.InOutQuad
214
                    duration: PlasmaCore.Units.longDuration
215 216 217 218 219 220 221 222
                }
            }
        }

        ExpanderArrow {
            id: expander
            Layout.fillWidth: vertical
            Layout.fillHeight: !vertical
Marco Martin's avatar
Marco Martin committed
223
        }
Marco Martin's avatar
Marco Martin committed
224 225
    }

226
    //Main popup
Marco Martin's avatar
Marco Martin committed
227 228
    PlasmaCore.Dialog {
        id: dialog
Marco Martin's avatar
Marco Martin committed
229
        visualParent: root
230 231
        flags: Qt.WindowStaysOnTopHint
        location: plasmoid.location
232
        hideOnWindowDeactivate: !plasmoid.configuration.pin
233

Marco Martin's avatar
Marco Martin committed
234
        onVisibleChanged: {
235 236 237 238 239 240 241
            if (!visible) {
                plasmoid.status = PlasmaCore.Types.PassiveStatus;
                if (root.activeApplet) {
                    root.activeApplet.expanded = false;
                }
            } else {
                plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus;
Marco Martin's avatar
Marco Martin committed
242
            }
243
            plasmoid.expanded = visible;
Marco Martin's avatar
Marco Martin committed
244
        }
Marco Martin's avatar
Marco Martin committed
245 246
        mainItem: ExpandedRepresentation {
            id: expandedRepresentation
247 248 249 250 251

            Keys.onEscapePressed: {
                root.expanded = false;
            }

252
            activeApplet: root.activeApplet
253 254 255

            LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
            LayoutMirroring.childrenInherit: true
Marco Martin's avatar
Marco Martin committed
256 257 258
        }
    }
}