Kirigami2

PagePoolAction.qml
1/*
2 * SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7import QtQuick
8import QtQml
9import QtQuick.Templates as T
10import org.kde.kirigami as Kirigami
11
12/**
13 * An action used to load Pages coming from a common PagePool
14 * in a PageRow or QtQuickControls2 StackView.
15 *
16 * @see PagePool
17 */
18Kirigami.Action {
19 id: root
20
21//BEGIN properties
22 /**
23 * @brief This property holds the url or filename of the page that this action will load.
24 */
25 property string page
26
27 /**
28 * @brief This property holds the PagePool object used by this PagePoolAction.
29 *
30 * PagePool will make sure only one instance of the page identified by the page url will be created and reused.
31 * PagePool's lastLoaderUrl property will be used to control the mutual exclusivity of the checked
32 * state of the PagePoolAction instances sharing the same PagePool.
33 */
34 property Kirigami.PagePool pagePool
35
36 /**
37 * The pageStack property accepts either a Kirigami.PageRow or a QtQuickControls2 StackView.
38 * The component that will instantiate the pages, which has to work with a stack logic.
39 * Kirigami.PageRow is recommended, but will work with QtQuicControls2 StackView as well.
40 *
41 * default: `bound to ApplicationWindow's global pageStack, which is a PageRow by default`
42 */
43 property Item pageStack: typeof applicationWindow !== 'undefined' ? applicationWindow().pageStack : null
44
45 /**
46 * @brief This property sets the page in the pageStack after which
47 * new pages will be pushed.
48 *
49 * All pages present after the given basePage will be removed from the pageStack
50 */
51 property T.Page basePage
52
53 /**
54 * This property holds a function that generate the property values for the created page
55 * when it is pushed onto the Kirigami.PagePool.
56 *
57 * Example usage:
58 * @code{.qml}
59 * Kirigami.PagePoolAction {
60 * text: i18n("Security")
61 * icon.name: "security-low"
62 * page: Qt.resolvedUrl("Security.qml")
63 * initialProperties: {
64 * return {
65 * room: root.room
66 * }
67 * }
68 * }
69 * @endcode
70 * @property QVariantMap initialProperties
71 */
72 property var initialProperties
73
74 /**
75 * @brief This property sets whether PagePoolAction will use the layers property
76 * implemented by the pageStack.
77 *
78 * This is intended for use with PageRow layers to allow PagePoolActions to
79 * push context-specific pages onto the layers stack.
80 *
81 * default: ``false``
82 *
83 * @since 5.70
84 * @since org.kde.kirigami 2.12
85 */
86 property bool useLayers: false
87//END properties
89 /**
90 * @returns the page item held in the PagePool or null if it has not been loaded yet.
91 */
92 function pageItem(): Item {
93 return pagePool.pageForUrl(page)
94 }
95
96 /**
97 * @returns true if the page has been loaded and placed on pageStack.layers
98 * and useLayers is true, otherwise returns null.
99 */
100 function layerContainsPage(): bool {
101 if (!useLayers || !pageStack.hasOwnProperty("layers")) {
102 return false;
103 }
104
105 const pageItem = this.pageItem();
106 const item = pageStack.layers.find(item => item === pageItem);
107 return item !== null;
108 }
109
110 /**
111 * @returns true if the page has been loaded and placed on the pageStack,
112 * otherwise returns null.
113 */
114 function stackContainsPage(): bool {
115 if (useLayers) {
116 return false;
117 }
118 return pageStack.columnView.containsItem(pagePool.pageForUrl(page));
119 }
120
121 checkable: true
122
123 onTriggered: {
124 if (page.length === 0 || !pagePool || !pageStack) {
125 return;
126 }
127
128 // User intends to "go back" to this layer.
129 const pageItem = this.pageItem();
130 if (layerContainsPage() && pageItem !== pageStack.layers.currentItem) {
131 pageStack.layers.replace(pageItem, pageItem); // force pop above
132 return;
133 }
134
135 // User intends to "go back" to this page.
136 if (stackContainsPage()) {
137 if (pageStack.hasOwnProperty("layers")) {
138 pageStack.layers.clear();
139 }
140 }
141
142 const stack = useLayers ? pageStack.layers : pageStack
143
144 if (pageItem != null && stack.currentItem == pageItem) {
145 return;
146 }
147
148 if (initialProperties && typeof(initialProperties) !== "object") {
149 console.warn("initialProperties must be of type object");
150 return;
151 }
152
153 if (!stack.hasOwnProperty("pop") || typeof stack.pop !== "function" || !stack.hasOwnProperty("push") || typeof stack.push !== "function") {
154 return;
155 }
156
157 if (pagePool.isLocalUrl(page)) {
158 if (basePage) {
159 stack.pop(basePage);
160
161 } else if (!useLayers) {
162 stack.clear();
163 }
164
165 stack.push(initialProperties
166 ? pagePool.loadPageWithProperties(page, initialProperties)
167 : pagePool.loadPage(page));
168 } else {
169 const callback = item => {
170 if (basePage) {
171 stack.pop(basePage);
172
173 } else if (!useLayers) {
174 stack.clear();
175 }
176
177 stack.push(item);
178 };
179
180 if (initialProperties) {
181 pagePool.loadPage(page, initialProperties, callback);
182
183 } else {
184 pagePool.loadPage(page, callback);
185 }
186 }
187 }
188
189 // Exposing this as a property is required as Action does not have a default property
190 property QtObject _private: QtObject {
191 id: _private
192
193 function setChecked(checked) {
194 root.checked = checked;
195 }
196
197 function clearLayers() {
198 root.pageStack.layers.clear();
199 }
200
201 property list<Connections> connections: [
202 Connections {
203 target: root.pageStack
204
205 function onCurrentItemChanged() {
206 if (root.useLayers) {
207 if (root.layerContainsPage()) {
208 _private.clearLayers();
209 }
210 if (root.checkable) {
211 _private.setChecked(false);
212 }
213
214 } else {
215 if (root.checkable) {
216 _private.setChecked(root.stackContainsPage());
217 }
218 }
219 }
220 },
221 Connections {
222 enabled: root.pageStack.hasOwnProperty("layers")
223 target: root.pageStack.layers
224
225 function onCurrentItemChanged() {
226 if (root.useLayers && root.checkable) {
227 _private.setChecked(root.layerContainsPage());
228
229 } else {
230 if (root.pageStack.layers.depth === 1 && root.stackContainsPage()) {
231 _private.setChecked(true);
232 }
233 }
234 }
235 }
236 ]
237 }
238}
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:46 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.