Kirigami2

templates/OverlayDrawer.qml
1/*
2 * SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7import QtQuick
8import QtQuick.Templates as T
9import QtQuick.Controls as QQC2
10import org.kde.kirigami as Kirigami
11import "private" as KTP
12
13/**
14 * Overlay Drawers are used to expose additional UI elements needed for
15 * small secondary tasks for which the main UI elements are not needed.
16 * For example in Okular Mobile, an Overlay Drawer is used to display
17 * thumbnails of all pages within a document along with a search field.
18 * This is used for the distinct task of navigating to another page.
19 *
20 * @inherit QtQuick.Controls.Drawer
21 */
22T.Drawer {
23 id: root
24
25//BEGIN properties
26 /**
27 * @brief This property tells whether the drawer is open and visible.
28 *
29 * default: ``false``
30 */
31 property bool drawerOpen: false
32
33 /**
34 * @brief This property tells whether the drawer is in a state between open
35 * and closed.
36 *
37 * The drawer is visible but not completely open. This is usually the case when
38 * the user is dragging the drawer from a screen edge, so the user is "peeking"
39 * at what's in the drawer.
40 *
41 * default: ``false``
42 */
43 property bool peeking: false
44
45 /**
46 * @brief This property tells whether the drawer is currently opening or closing itself.
47 */
48 readonly property bool animating : enterAnimation.animating || exitAnimation.animating || positionResetAnim.running
49
50 /**
51 * @brief This property holds whether the drawer can be collapsed to a
52 * very thin, usually icon only sidebar.
53 *
54 * Only modal drawers are collapsible. Collapsible is not supported in
55 * the mobile mode.
56 *
57 * @since 2.5
58 */
59 property bool collapsible: false
60
61 /**
62 * @brief This property tells whether the drawer is collapsed to a
63 * very thin sidebar, usually icon only.
64 *
65 * When true, the drawer will be collapsed to a very thin sidebar,
66 * usually icon only.
67 *
68 * default: ``false``
69 *
70 * @see collapsible Only collapsible drawers can be collapsed.
71 */
72 property bool collapsed: false
73
74 /**
75 * @brief This property holds the size of the collapsed drawer.
76 *
77 * For vertical drawers this will be the width of the drawer and for horizontal
78 * drawers this will be the height of the drawer.
79 *
80 * default: ``Units.iconSizes.medium``, just enough to accommodate medium sized icons
81 */
82 property int collapsedSize: Kirigami.Units.iconSizes.medium
83
84 /**
85 * @brief This property holds the options for handle's open icon.
86 *
87 * This is a grouped property with following components:
88 *
89 * * ``source: var``: The name of a freedesktop-compatible icon.
90 * * ``color: color``: An optional tint color for the icon.
91 *
92 * If no custom icon is set, a menu icon is shown for the application globalDrawer
93 * and an overflow menu icon is shown for the contextDrawer.
94 * That's the default for the GlobalDrawer and ContextDrawer components respectively.
95 *
96 * For OverlayDrawer the default is view-right-close or view-left-close depending on
97 * the drawer location
98 *
99 * @since 2.5
100 */
101 readonly property KTP.IconPropertiesGroup handleOpenIcon: KTP.IconPropertiesGroup {
102 source: root.edge === Qt.RightEdge ? "view-right-close" : "view-left-close"
103 }
104
105 /**
106 * @brief This property holds the options for the handle's close icon.
107 *
108 * This is a grouped property with the following components:
109 * * ``source: var``: The name of a freedesktop-compatible icon.
110 * * ``color: color``: An optional tint color for the icon.
111 *
112 * If no custom icon is set, an X icon is shown,
113 * which will morph into the Menu or overflow icons.
114 *
115 * For OverlayDrawer the default is view-right-new or view-left-new depending on
116 * the drawer location.
118 * @since 2.5
119 */
120 property KTP.IconPropertiesGroup handleClosedIcon: KTP.IconPropertiesGroup {
121 source: root.edge === Qt.RightEdge ? "view-right-new" : "view-left-new"
123
124 /**
125 * @brief This property holds the tooltip displayed when the drawer is open.
126 * @since 2.15
127 */
128 property string handleOpenToolTip: qsTr("Close drawer")
130 /**
131 * @brief This property holds the tooltip displayed when the drawer is closed.
132 * @since 2.15
133 */
134 property string handleClosedToolTip: qsTr("Open drawer")
135
136 /**
137 * @brief This property holds whether the handle is visible, to make opening the
138 * drawer easier.
139 *
140 * Currently supported only on left and right drawers.
141 */
142 property bool handleVisible: {
143 if (typeof applicationWindow === "function") {
144 const w = applicationWindow();
145 if (w) {
146 return w.controlsVisible;
147 }
148 }
149 // For a generic-purpose OverlayDrawer its handle is visible by default
150 return true;
151 }
152
153 /**
154 * @brief Readonly property that points to the item that will act as a physical
155 * handle for the Drawer.
156 * @property MouseArea handle
157 **/
158 readonly property Item handle: KTP.DrawerHandle {
159 drawer: root
160 }
161//END properties
162
163 interactive: modal
164
165 z: Kirigami.OverlayZStacking.z
166
167 Kirigami.Theme.inherit: false
168 Kirigami.Theme.colorSet: modal ? Kirigami.Theme.View : Kirigami.Theme.Window
169 Kirigami.Theme.onColorSetChanged: {
170 contentItem.Kirigami.Theme.colorSet = Kirigami.Theme.colorSet
171 background.Kirigami.Theme.colorSet = Kirigami.Theme.colorSet
172 }
173
174//BEGIN reassign properties
175 //default paddings
176 leftPadding: Kirigami.Units.smallSpacing
177 topPadding: Kirigami.Units.smallSpacing
178 rightPadding: Kirigami.Units.smallSpacing
179 bottomPadding: Kirigami.Units.smallSpacing
180
181 y: modal ? 0 : ((T.ApplicationWindow.menuBar && T.ApplicationWindow.menuBar.visible ? T.ApplicationWindow.menuBar.height : 0) + (T.ApplicationWindow.header && T.ApplicationWindow.header.visible ? T.ApplicationWindow.header.height : 0))
182
183 height: parent && (root.edge === Qt.LeftEdge || root.edge === Qt.RightEdge) ? (modal ? parent.height : (parent.height - y - (T.ApplicationWindow.footer ? T.ApplicationWindow.footer.height : 0))) : implicitHeight
184
185 parent: modal || edge === Qt.LeftEdge || edge === Qt.RightEdge ? T.ApplicationWindow.overlay : T.ApplicationWindow.contentItem
186
187 edge: Qt.LeftEdge
188 modal: true
189 // Doesn't dim on isSidebarTransitioning to not flash a dark background
190 // see https://bugs.kde.org/502260
191 dim: modal && !__internal.isSidebarTransitioning
192
193 QQC2.Overlay.modal: Rectangle {
194 color: Qt.rgba(0, 0, 0, 0.35)
195 }
196
197 dragMargin: enabled && (edge === Qt.LeftEdge || edge === Qt.RightEdge) ? Math.min(Kirigami.Units.gridUnit, Qt.styleHints.startDragDistance) : 0
198
199 contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
200 contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
201
202 implicitWidth: contentWidth + leftPadding + rightPadding
203 implicitHeight: contentHeight + topPadding + bottomPadding
204
205 enter: Transition {
206 enabled: !__internal.isSidebarTransitioning
207 SequentialAnimation {
208 id: enterAnimation
209 /* NOTE: why this? the running status of the enter transition is not relaible and
210 * the SmoothedAnimation is always marked as non running,
211 * so the only way to get to a reliable animating status is with this
212 */
213 property bool animating
214 ScriptAction {
215 script: {
216 enterAnimation.animating = true
217 // on non modal dialog we don't want drawers in the overlay
218 if (!root.modal) {
219 root.background.parent.parent = applicationWindow().overlay.parent
220 }
221 }
222 }
223 SmoothedAnimation {
224 velocity: 5
225 }
226 ScriptAction {
227 script: enterAnimation.animating = false
228 }
229 }
230 }
231
232 exit: Transition {
233 enabled: !__internal.isSidebarTransitioning
234 SequentialAnimation {
235 id: exitAnimation
236 property bool animating
237 ScriptAction {
238 script: exitAnimation.animating = true
239 }
240 SmoothedAnimation {
241 velocity: 5
242 }
243 ScriptAction {
244 script: exitAnimation.animating = false
245 }
246 }
247 }
248//END reassign properties
249
250
251//BEGIN signal handlers
252 onCollapsedChanged: {
253 if (Kirigami.Settings.isMobile) {
254 collapsed = false;
255 }
256 if (!__internal.completed) {
257 return;
258 }
259 if ((!collapsible || modal) && collapsed) {
260 collapsed = true;
261 }
262 }
263 onCollapsibleChanged: {
264 if (Kirigami.Settings.isMobile) {
265 collapsible = false;
266 }
267 if (!__internal.completed) {
268 return;
269 }
270 if (!collapsible) {
271 collapsed = false;
272 } else if (modal) {
273 collapsible = false;
274 }
275 }
276 onModalChanged: {
277 if (!__internal.completed) {
278 return;
279 }
280 if (modal) {
281 collapsible = false;
282 }
283 __internal.isSidebarTransitioning = true
284 if (modal) {
285 position = 0
286 drawerOpen = false
287 }
288 }
289
290 onPositionChanged: {
291 if (peeking) {
292 visible = true
293 }
294 }
295 onVisibleChanged: {
296 if (peeking) {
297 visible = true
298 } else {
299 drawerOpen = visible;
300 }
301 if (__internal.isSidebarTransitioning) {
302 position = visible ? 1 : 0
303 __internal.isSidebarTransitioning = false
304 }
305 }
306 onPeekingChanged: {
307 if (peeking) {
308 root.enter.enabled = false;
309 root.exit.enabled = false;
310 } else {
311 drawerOpen = position > 0.5 ? 1 : 0;
312 positionResetAnim.running = true
313 root.enter.enabled = true;
314 root.exit.enabled = true;
315 }
316 }
317 onDrawerOpenChanged: {
318 // sync this property only when the component is properly loaded
319 if (!__internal.completed) {
320 return;
321 }
322 positionResetAnim.running = false;
323 if (drawerOpen) {
324 open();
325 } else {
326 close();
327 }
328 Qt.callLater(() => root.handle.displayToolTip = true)
329 }
330
331 Component.onCompleted: {
332 // if defined as drawerOpen by default in QML, don't animate
333 if (root.drawerOpen) {
334 root.enter.enabled = false;
335 root.visible = true;
336 root.position = 1;
337 root.enter.enabled = true;
338 }
339 __internal.completed = true;
340 contentItem.Kirigami.Theme.colorSet = Kirigami.Theme.colorSet;
341 background.Kirigami.Theme.colorSet = Kirigami.Theme.colorSet;
342 }
343//END signal handlers
344
345 // this is as hidden as it can get here
346 property QtObject __internal: QtObject {
347 //here in order to not be accessible from outside
348 property bool completed: false
349 property bool isSidebarTransitioning: false
350 property SequentialAnimation positionResetAnim: SequentialAnimation {
351 id: positionResetAnim
352 property alias to: internalAnim.to
353 NumberAnimation {
354 id: internalAnim
355 target: root
356 to: drawerOpen ? 1 : 0
357 property: "position"
358 duration: (root.position)*Kirigami.Units.longDuration
359 }
360 ScriptAction {
361 script: {
362 root.drawerOpen = internalAnim.to !== 0;
363 }
364 }
365 }
366 readonly property Item statesItem: Item {
367 states: [
368 State {
369 when: root.collapsed
370 PropertyChanges {
371 target: root
372 implicitWidth: edge === Qt.TopEdge || edge === Qt.BottomEdge ? applicationWindow().width : Math.min(collapsedSize + leftPadding + rightPadding, Math.round(applicationWindow().width*0.8))
373
374 implicitHeight: edge === Qt.LeftEdge || edge === Qt.RightEdge ? applicationWindow().height : Math.min(collapsedSize + topPadding + bottomPadding, Math.round(applicationWindow().height*0.8))
375 }
376 },
377 State {
378 when: !root.collapsed
379 PropertyChanges {
380 target: root
381 implicitWidth: edge === Qt.TopEdge || edge === Qt.BottomEdge ? applicationWindow().width : Math.min(contentItem.implicitWidth, Math.round(applicationWindow().width*0.8))
382
383 implicitHeight: edge === Qt.LeftEdge || edge === Qt.RightEdge ? applicationWindow().height : Math.min(contentHeight + topPadding + bottomPadding, Math.round(applicationWindow().height*0.4))
384
385 contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
386 contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
387 }
388 }
389 ]
390 transitions: Transition {
391 reversible: true
392 NumberAnimation {
393 properties: root.edge === Qt.TopEdge || root.edge === Qt.BottomEdge ? "implicitHeight" : "implicitWidth"
394 duration: Kirigami.Units.longDuration
395 easing.type: Easing.InOutQuad
396 }
397 }
398 }
399 }
400}
bool peeking
This property tells whether the drawer is in a state between open and closed.
KTPIconPropertiesGroup handleClosedIcon
This property holds the options for the handle's close icon.
int collapsedSize
This property holds the size of the collapsed drawer.
bool collapsed
This property tells whether the drawer is collapsed to a very thin sidebar, usually icon only.
bool animating
This property tells whether the drawer is currently opening or closing itself.
bool collapsible
This property holds whether the drawer can be collapsed to a very thin, usually icon only sidebar.
KTPIconPropertiesGroup handleOpenIcon
This property holds the options for handle's open icon.
bool handleVisible
This property holds whether the handle is visible, to make opening the drawer easier.
string handleClosedToolTip
This property holds the tooltip displayed when the drawer is closed.
bool drawerOpen
This property tells whether the drawer is open and visible.
Type type(const QSqlDatabase &db)
KGuiItem properties()
KGuiItem open()
KGuiItem close()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 11 2025 11:49:27 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.