summaryrefslogtreecommitdiff
path: root/modules/drawers/Panels.qml
blob: 8b5a251c63f32b365bfeb0a56dbf2b8ea8e83a7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
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
import qs.config
import qs.modules.osd as Osd
import qs.modules.notifications as Notifications
import qs.modules.session as Session
import qs.modules.launcher as Launcher
import qs.modules.dashboard as Dashboard
import qs.modules.bar.popouts as BarPopouts
import qs.modules.utilities as Utilities
import qs.modules.utilities.toasts as Toasts
import qs.modules.sidebar as Sidebar
import qs.components
import qs.components.controls
import qs.components.effects
import qs.services
import Quickshell
import QtQuick

Item {
    id: root

    required property ShellScreen screen
    required property PersistentProperties visibilities
    required property Item bar

    readonly property alias osd: osd
    readonly property alias notifications: notifications
    readonly property alias session: session
    readonly property alias launcher: launcher
    readonly property alias dashboard: dashboard
    readonly property alias popouts: popouts
    readonly property alias utilities: utilities
    readonly property alias toasts: toasts
    readonly property alias sidebar: sidebar
    readonly property alias clearAllButton: clearAllButton

    anchors.fill: parent
    anchors.margins: Config.border.thickness
    anchors.leftMargin: bar.implicitWidth

    Osd.Wrapper {
        id: osd

        clip: session.width > 0 || sidebar.width > 0
        screen: root.screen
        visibilities: root.visibilities

        anchors.verticalCenter: parent.verticalCenter
        anchors.right: parent.right
        anchors.rightMargin: session.width + sidebar.width
    }

    Notifications.Wrapper {
        id: notifications

        visibilities: root.visibilities
        panels: root

        anchors.top: parent.top
        anchors.right: parent.right
    }

    // Clear all notifications button - positioned to the left of the notification panel
    Item {
        id: clearAllButton

        readonly property bool hasNotifications: Notifs.notClosed.length > 0
        readonly property bool panelVisible: notifications.height > 0 || notifications.implicitHeight > 0
        readonly property bool shouldShow: hasNotifications && panelVisible

        anchors.top: notifications.top
        anchors.right: notifications.left
        anchors.rightMargin: Appearance.padding.normal
        anchors.topMargin: Appearance.padding.large

        width: button.implicitWidth
        height: button.implicitHeight
        enabled: shouldShow

        IconButton {
            id: button

            icon: "clear_all"
            radius: Appearance.rounding.normal
            padding: Appearance.padding.normal
            font.pointSize: Math.round(Appearance.font.size.large * 1.2)

            onClicked: {
                // Clear all notifications
                for (const notif of Notifs.list.slice())
                    notif.close();
            }

            Elevation {
                anchors.fill: parent
                radius: parent.radius
                z: -1
                level: button.stateLayer.containsMouse ? 4 : 3
            }
        }

        // Keep notification panel visible when hovering over the button
        MouseArea {
            anchors.fill: button
            hoverEnabled: true
            acceptedButtons: Qt.NoButton
            onEntered: {
                if (notifications.content && Notifs.notClosed.length > 0) {
                    notifications.content.show();
                }
            }
            onExited: {
                // Panel will be hidden by Interactions.qml if mouse is not over panel or button
            }
        }

        Behavior on opacity {
            Anim {
                duration: Appearance.anim.durations.expressiveDefaultSpatial
                easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
            }
        }

        Behavior on scale {
            Anim {
                duration: Appearance.anim.durations.expressiveDefaultSpatial
                easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
            }
        }

        opacity: shouldShow ? 1 : 0
        scale: shouldShow ? 1 : 0.5
    }

    Notifications.NotificationToasts {
        id: notificationToasts

        panels: root

        anchors.top: parent.top
        anchors.right: parent.right
        anchors.topMargin: Config.border.thickness
        anchors.rightMargin: Config.border.thickness
    }

    Session.Wrapper {
        id: session

        clip: sidebar.width > 0
        visibilities: root.visibilities
        panels: root

        anchors.verticalCenter: parent.verticalCenter
        anchors.right: parent.right
        anchors.rightMargin: sidebar.width
    }

    Launcher.Wrapper {
        id: launcher

        screen: root.screen
        visibilities: root.visibilities
        panels: root

        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
    }

    Dashboard.Wrapper {
        id: dashboard

        visibilities: root.visibilities

        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top
    }

    BarPopouts.Wrapper {
        id: popouts

        screen: root.screen

        x: isDetached ? (root.width - nonAnimWidth) / 2 : 0
        y: {
            if (isDetached)
                return (root.height - nonAnimHeight) / 2;

            const off = currentCenter - Config.border.thickness - nonAnimHeight / 2;
            const diff = root.height - Math.floor(off + nonAnimHeight);
            if (diff < 0)
                return off + diff;
            return Math.max(off, 0);
        }
    }

    Utilities.Wrapper {
        id: utilities

        visibilities: root.visibilities
        sidebar: sidebar

        anchors.bottom: parent.bottom
        anchors.right: parent.right
    }

    Toasts.Toasts {
        id: toasts

        anchors.bottom: sidebar.visible ? parent.bottom : utilities.top
        anchors.right: sidebar.left
        anchors.margins: Appearance.padding.normal
    }

    Sidebar.Wrapper {
        id: sidebar

        visibilities: root.visibilities
        panels: root

        anchors.top: notifications.bottom
        anchors.bottom: utilities.top
        anchors.right: parent.right
    }
}