Kirigami2

DrawerHandle.qml
1/*
2 * SPDX-FileCopyrightText: 2023 Marco Martin <mart@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7import QtQuick
8import QtQuick.Controls as QQC2
9import QtQuick.Templates as T
10import org.kde.kirigami as Kirigami
11
12MouseArea {
13 id: root
14
15 /*
16 * This property is used to set when the tooltip is visible.
17 * It exists because the text is changed while the tooltip is still visible.
18 */
19 property bool displayToolTip: true
20
21 /**
22 * The drawer this handle will control
23 */
24 // Should be KT.OverlayDrawer, but can't due to "Cyclic dependency"
25 property T.Drawer drawer
26
27 readonly property T.Overlay overlay: drawer.T.Overlay.overlay
28
29 // Above the Overlay when modal but below when non-modal and when the drawer is closed
30 // so that other overlays can be above it.
31 parent: overlay?.parent ?? null
32 z: overlay ? overlay.z + (drawer?.modal && drawer?.drawerOpen ? 1 : - 1) : 0
33
34 preventStealing: true
35 hoverEnabled: handleAnchor?.visible ?? false
36
37 QQC2.ToolButton {
38 anchors.centerIn: parent
39 width: parent.height - Kirigami.Units.smallSpacing * 1.5
40 height: parent.height - Kirigami.Units.smallSpacing * 1.5
41 visible: !Kirigami.Settings.tabletMode && !Kirigami.Settings.hasTransientTouchInput
42
43 Accessible.name: root.drawer.drawerOpen ? root.drawer.handleOpenToolTip : root.drawer.handleClosedToolTip
44
45 onClicked: {
46 root.displayToolTip = false;
47 Qt.callLater(() => {
48 root.drawer.drawerOpen = !root.drawer.drawerOpen;
49 })
50 }
51 Keys.onEscapePressed: {
52 if (root.drawer.closePolicy & T.Popup.CloseOnEscape) {
53 root.drawer.drawerOpen = false;
54 }
55 }
56 }
57
58 QQC2.ToolTip.visible: displayToolTip && containsMouse
59 QQC2.ToolTip.text: drawer.drawerOpen ? handleOpenToolTip : handleClosedToolTip
60 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
61
62 property Item handleAnchor: {
63 if (typeof applicationWindow === "undefined") {
64 return null;
65 }
66 const window = applicationWindow();
67 const globalToolBar = window.pageStack?.globalToolBar;
68 if (!globalToolBar) {
69 return null;
70 }
71 return (drawer.edge === Qt.LeftEdge && !drawer.mirrored) || (drawer.edge === Qt.RightEdge && drawer.mirrored)
72 ? globalToolBar.leftHandleAnchor
73 : globalToolBar.rightHandleAnchor;
74 }
75
76 property int startX
77 property int mappedStartX
78
79 enabled: drawer.handleVisible
80
81 onPressed: mouse => {
82 drawer.peeking = true;
83 startX = mouse.x;
84 mappedStartX = mapToItem(parent, startX, 0).x;
85 }
86
87 onPositionChanged: mouse => {
88 if (!pressed) {
89 return;
90 }
91 const pos = mapToItem(parent, mouse.x - startX, mouse.y);
92 switch (drawer.edge) {
93 case Qt.LeftEdge:
94 drawer.position = pos.x / drawer.contentItem.width;
95 break;
96 case Qt.RightEdge:
97 drawer.position = (drawer.parent.width - pos.x - width) / drawer.contentItem.width;
98 break;
99 default:
100 }
101 }
102
103 onReleased: mouse => {
104 drawer.peeking = false;
105 if (Math.abs(mapToItem(parent, mouse.x, 0).x - mappedStartX) < Qt.styleHints.startDragDistance) {
106 if (!drawer.drawerOpen) {
107 drawer.close();
108 }
109 drawer.drawerOpen = !drawer.drawerOpen;
110 }
111 }
112
113 onCanceled: {
114 drawer.peeking = false
115 }
116
117 x: {
118 switch (drawer.edge) {
119 case Qt.LeftEdge:
120 return drawer.background.width * drawer.position + Kirigami.Units.smallSpacing;
121 case Qt.RightEdge:
122 return parent.width - (drawer.background.width * drawer.position) - width - Kirigami.Units.smallSpacing;
123 default:
124 return 0;
125 }
126 }
127
128 Binding {
129 when: root.handleAnchor && root.anchors.bottom
130 target: root
131 property: "y"
132 value: root.handleAnchor ? root.handleAnchor.Kirigami.ScenePosition.y : 0
133 restoreMode: Binding.RestoreBinding
134 }
135
136 anchors {
137 bottom: handleAnchor ? undefined : parent.bottom
138 bottomMargin: {
139 if (typeof applicationWindow === "undefined") {
140 return undefined;
141 }
142 const window = applicationWindow();
143
144 let margin = Kirigami.Units.smallSpacing;
145 if (window.footer) {
146 margin = window.footer.height + Kirigami.Units.smallSpacing;
147 }
148
149 if (drawer.parent && drawer.height < drawer.parent.height) {
150 margin = drawer.parent.height - drawer.height - drawer.y + Kirigami.Units.smallSpacing;
151 }
152
153 if (!window || !window.pageStack ||
154 !window.pageStack.contentItem ||
155 !window.pageStack.contentItem.itemAt) {
156 return margin;
157 }
158
159 let item;
160 if (window.pageStack.layers.depth > 1) {
161 item = window.pageStack.layers.currentItem;
162 } else {
163 item = window.pageStack.contentItem.itemAt(window.pageStack.contentItem.contentX + x, 0);
164 }
165
166 // try to take the last item
167 if (!item) {
168 item = window.pageStack.lastItem;
169 }
170
171 let pageFooter = item && item.page ? item.page.footer : (item ? item.footer : undefined);
172 if (pageFooter && drawer.parent) {
173 margin = drawer.height < drawer.parent.height ? margin : margin + pageFooter.height
174 }
175
176 return margin;
177 }
178
179 Behavior on bottomMargin {
180 NumberAnimation {
181 duration: Kirigami.Units.shortDuration
182 easing.type: Easing.InOutQuad
183 }
184 }
185 }
186
187 visible: drawer.enabled && (drawer.edge === Qt.LeftEdge || drawer.edge === Qt.RightEdge) && opacity > 0
188 width: handleAnchor?.visible ? handleAnchor.width : Kirigami.Units.iconSizes.smallMedium + Kirigami.Units.smallSpacing * 2
189 height: handleAnchor?.visible ? handleAnchor.height : width
190 opacity: drawer.handleVisible ? 1 : 0
191
192 Behavior on opacity {
193 NumberAnimation {
194 duration: Kirigami.Units.longDuration
195 easing.type: Easing.InOutQuad
196 }
197 }
198
199 transform: Translate {
200 x: root.drawer.handleVisible ? 0 : (root.drawer.edge === Qt.LeftEdge ? -root.width : root.width)
201 Behavior on x {
202 NumberAnimation {
203 duration: Kirigami.Units.longDuration
204 easing.type: !root.drawer.handleVisible ? Easing.OutQuad : Easing.InQuad
205 }
206 }
207 }
208}
KDOCTOOLS_EXPORT QString transform(const QString &file, const QString &stylesheet, const QList< const char * > &params=QList< const char * >())
QWidget * window(QObject *job)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
int depth() const const
LeftEdge
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 8 2024 11:57:22 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.