ExpandedRepresentation.qml 8.77 KB
Newer Older
Marco Martin's avatar
Marco Martin committed
1
2
/*
 *   Copyright 2016 Marco Martin <mart@kde.org>
3
 *   Copyright 2020 Nate Graham <nate@kde.org>
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.
 */

21
22
import QtQuick 2.12
import QtQuick.Layouts 1.12
23

Marco Martin's avatar
Marco Martin committed
24
import org.kde.plasma.core 2.0 as PlasmaCore
25
26
27
// We still need PC2 here for that version of Menu, as PC2 Menu is still very problematic with QActions
// Not being a proper popup window, makes it a showstopper to be used in Plasma
import org.kde.plasma.components 2.0 as PC2
28
import org.kde.plasma.components 3.0 as PlasmaComponents
Marco Martin's avatar
Marco Martin committed
29
import org.kde.plasma.extras 2.0 as PlasmaExtras
Marco Martin's avatar
Marco Martin committed
30

31
Item {
32
33
34
    id: popup
    //set width/height to avoid useless Dialog resize
    readonly property int defaultWidth: units.gridUnit * 24
35
    readonly property int defaultHeight: units.gridUnit * 24
36
37
38
39
40
41
42
43
44
45

    width: defaultWidth
    Layout.minimumWidth: defaultWidth
    Layout.preferredWidth: defaultWidth
    Layout.maximumWidth: defaultWidth

    height: defaultHeight
    Layout.minimumHeight: defaultHeight
    Layout.preferredHeight: defaultHeight
    Layout.maximumHeight: defaultHeight
Marco Martin's avatar
Marco Martin committed
46

47
    property alias hiddenLayout: hiddenItemsView.layout
Marco Martin's avatar
Marco Martin committed
48

49
    // Header
50
    PlasmaExtras.PlasmoidHeading {
51
52
53
54
55
56
57
58
59
        id: plasmoidHeading
        anchors {
            top: parent.top
            left: parent.left
            right: parent.right
        }
        height: trayHeading.height + bottomPadding + container.headingHeight
    }

60
    // Main content layout
61
62
    ColumnLayout {
        id: expandedRepresentation
63
        anchors.fill: parent
64
65
        // TODO: remove this so the scrollview fully touches the header;
        // add top padding internally
66
        spacing: plasmoidHeading.bottomPadding
67

68
        // Header content layout
69
        RowLayout {
70
            id: trayHeading
Marco Martin's avatar
Marco Martin committed
71

72
73
            PlasmaComponents.ToolButton {
                id: backButton
74
                visible: systemTrayState.activeApplet && systemTrayState.activeApplet.expanded && (hiddenItemsView.itemCount > 0)
75
                icon.name: LayoutMirroring.enabled ? "go-previous-symbolic-rtl" : "go-previous-symbolic"
76
                onClicked: systemTrayState.setActiveApplet(null)
Marco Martin's avatar
Marco Martin committed
77
            }
78

79
80
            PlasmaExtras.Heading {
                Layout.fillWidth: true
81
                leftPadding: systemTrayState.activeApplet ? 0 : units.smallSpacing * 2
82

83
                level: 1
84
                text: systemTrayState.activeApplet ? systemTrayState.activeApplet.title : i18n("Status and Notifications")
85
            }
Marco Martin's avatar
Marco Martin committed
86

87
            PlasmaComponents.ToolButton {
88
89
                id: actionsButton
                visible: visibleActions > 0
90
                checked: visibleActions > 1 ? configMenu.status !== PC2.DialogStatus.Closed : singleAction && singleAction.checked
91
                property QtObject applet: systemTrayState.activeApplet || plasmoid
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
                onAppletChanged: {
                    configMenu.clearMenuItems();
                    updateVisibleActions();
                }
                property int visibleActions: 0
                property QtObject singleAction

                function updateVisibleActions() {
                    let newSingleAction = null;
                    let newVisibleActions = 0;
                    for (let i in applet.contextualActions) {
                        let action = applet.contextualActions[i];
                        if (action.visible && action !== actionsButton.applet.action("configure")) {
                            newVisibleActions++;
                            newSingleAction = action;
                            action.changed.connect(() => {updateVisibleActions()});
                        }
                    }
                    if (newVisibleActions > 1) {
                        newSingleAction = null;
                    }
                    visibleActions = newVisibleActions;
                    singleAction = newSingleAction;
                }
                Connections {
                    target: actionsButton.applet
118
119
120
                    function onContextualActionsChanged() {
                        Qt.callLater(actionsButton.updateVisibleActions);
                    }
121
122
                }
                icon.name: "application-menu"
123
                checkable: visibleActions > 1 || (singleAction && singleAction.checkable)
124
125
126
127
128
129
130
131
132
133
134
135
                contentItem.opacity: visibleActions > 1
                // NOTE: it needs an IconItem because QtQuickControls2 buttons cannot load QIcons as their icon
                PlasmaCore.IconItem {
                    parent: actionsButton
                    anchors.centerIn: parent
                    active: actionsButton.hovered
                    implicitWidth: PlasmaCore.Units.iconSizes.smallMedium
                    implicitHeight: implicitWidth
                    source: actionsButton.singleAction !== null ? actionsButton.singleAction.icon : ""
                    visible: actionsButton.singleAction
                }
                onToggled: {
136
137
138
139
140
141
                    if (visibleActions > 1) {
                        if (checked) {
                            configMenu.openRelative();
                        } else {
                            configMenu.close();
                        }
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
                    }
                }
                onClicked: {
                    if (singleAction) {
                        singleAction.trigger();
                    }
                }
                PlasmaComponents.ToolTip {
                    text: actionsButton.singleAction ? actionsButton.singleAction.text : i18n("More actions")
                }
                PC2.Menu {
                    id: configMenu
                    visualParent: actionsButton
                    placement: PlasmaCore.Types.BottomPosedLeftAlignedPopup
                }

                Instantiator {
                    model: actionsButton.applet.contextualActions
                    delegate: PC2.MenuItem {
                        id: menuItem
                        action: modelData
                    }
                    onObjectAdded: {
                        if (object !== actionsButton.applet.action("configure")) {
                            configMenu.addMenuItem(object);
                        }
                    }
                }
            }
            PlasmaComponents.ToolButton {
172
                icon.name: "configure"
173
                visible: actionsButton.applet && actionsButton.applet.action("configure")
174
                PlasmaComponents.ToolTip {
175
                    text: parent.visible ? actionsButton.applet.action("configure").text : ""
176
                }
177
                onClicked: actionsButton.applet.action("configure").trigger();
178
179
            }

180
181
182
183
184
185
186
187
188
            PlasmaComponents.ToolButton {
                id: pinButton
                checkable: true
                checked: plasmoid.configuration.pin
                onToggled: plasmoid.configuration.pin = checked
                icon.name: "window-pin"
                PlasmaComponents.ToolTip {
                    text: i18n("Keep Open")
                }
189
190
            }
        }
191

192
193
194
195
196
197
        // Grid view of all available items
        HiddenItemsView {
            id: hiddenItemsView
            Layout.fillWidth: true
            Layout.fillHeight: true
            Layout.topMargin: units.smallSpacing
198
            visible: !systemTrayState.activeApplet
199
        }
Marco Martin's avatar
Marco Martin committed
200

201
202
203
204
205
        // Container for currently visible item
        PlasmoidPopupsContainer {
            id: container
            Layout.fillWidth: true
            Layout.fillHeight: true
206
            visible: systemTrayState.activeApplet
207

208
            // We need to add margin on the top so it matches the dialog's own margin
209
210
211
            Layout.topMargin: mergeHeadings ? 0 : dialog.margins.top
        }
    }
Marco Martin's avatar
Marco Martin committed
212

213
214
215
216
217
218
219
220
    // Footer
    PlasmaExtras.PlasmoidHeading {
        id: plasmoidFooter
        location: PlasmaExtras.PlasmoidHeading.Location.Footer
        anchors {
            bottom: parent.bottom
            left: parent.left
            right: parent.right
Marco Martin's avatar
Marco Martin committed
221
        }
222
223
224
225
226
        visible: container.appletHasFooter
        height: container.footerHeight
        // So that it doesn't appear over the content view, which results in
        // the footer controls being inaccessible
        z: -9999
Marco Martin's avatar
Marco Martin committed
227
228
    }
}