main.qml 8.99 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 ? units.iconSizes.small : mainLayout.implicitWidth + units.smallSpacing
34

35
    Layout.minimumHeight: vertical ? mainLayout.implicitHeight + units.smallSpacing : 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
43
    readonly property int smallIconSize: units.iconSizes.smallMedium

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 ? units.roundToIconSize(Math.min(Math.min(tasksGrid.implicitWidth / rowsOrColumns, tasksGrid.implicitHeight / rowsOrColumns), 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.min(tasksGrid.count, 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
            }
        }
    }

84
    Connections {
Marco Martin's avatar
Marco Martin committed
85
86
        target: plasmoid.configuration

87
88
        function onExtraItemsChanged() {
            plasmoid.nativeInterface.allowedPlasmoids = plasmoid.configuration.extraItems
89
        }
Marco Martin's avatar
Marco Martin committed
90
91
    }

Marco Martin's avatar
Marco Martin committed
92
    CurrentItemHighLight {
93
        readonly property bool visibleAppletActivated: root.activeApplet && root.activeApplet.parent && root.activeApplet.parent.inVisibleLayout
94
        parent: visibleAppletActivated ? root.activeApplet.parent.container : root
Marco Martin's avatar
Marco Martin committed
95
96
        location: plasmoid.location
    }
Marco Martin's avatar
Marco Martin committed
97

98
99
100
101
102
103
104
105
106
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
    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;
            }
        }
    }

138
    //Main Layout
139
140
141
142
143
144
145
146
147
148
149
    GridLayout {
        id: mainLayout

        rowSpacing: 0
        columnSpacing: 0
        anchors.fill: parent

        flow: vertical ? GridLayout.TopToBottom : GridLayout.LeftToRight

        GridView {
            id: tasksGrid
150
            readonly property int smallSizeCellLength: root.cellThickness >= root.smallIconSize ? root.smallIconSize + units.smallSpacing * 2
151
                                                                                               : root.smallIconSize
152
153
            readonly property int totalLength: root.vertical ? cellHeight * Math.ceil(count / root.rowsOrColumns)
                                                             : cellWidth * Math.ceil(count / root.rowsOrColumns)
154

155
156
157
158
159
            Layout.alignment: Qt.AlignCenter

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

160
161
            implicitHeight: root.vertical ? totalLength : root.height
            implicitWidth: !root.vertical ? totalLength : root.width
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
            cellHeight: {
                if (root.vertical) {
                    return root.autoSize ? root.width : smallSizeCellLength
                } else {
                    return root.autoSize ? root.height : Math.floor(root.height / root.rowsOrColumns)
                }
            }
            cellWidth: {
                if (root.vertical) {
                    return root.autoSize ? root.width : Math.floor(root.width / root.rowsOrColumns)
                } else {
                    return root.autoSize ? root.height : smallSizeCellLength
                }
            }
177
178
179
180
181
182
183

            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
184
            }
185
186
187
188
189
190
191
192
193
194
195
196
197

            delegate: ItemLoader {}

            add: Transition {
                enabled: root.itemSize > 0

                NumberAnimation {
                    property: "scale"
                    from: 0
                    to: 1
                    easing.type: Easing.InOutQuad
                    duration: units.longDuration
                }
198
            }
Marco Martin's avatar
Marco Martin committed
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
            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
                    duration: units.longDuration
                }
            }

            move: Transition {
                NumberAnimation {
                    properties: "x,y"
                    easing.type: Easing.InOutQuad
                    duration: units.longDuration
                }
            }
        }

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

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

Marco Martin's avatar
Marco Martin committed
235
        onVisibleChanged: {
236
237
238
239
240
241
242
            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
243
            }
244
            plasmoid.expanded = visible;
Marco Martin's avatar
Marco Martin committed
245
        }
Marco Martin's avatar
Marco Martin committed
246
247
        mainItem: ExpandedRepresentation {
            id: expandedRepresentation
248
249
250
251
252

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

253
            activeApplet: root.activeApplet
254
255
256

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