Kirigami2

PagePoolAction.qml
1 /*
2  * SPDX-FileCopyrightText: 2016 Marco Martin <[email protected]>
3  *
4  * SPDX-License-Identifier: LGPL-2.0-or-later
5  */
6 
7 import QtQuick 2.7
8 import QtQml 2.7
9 import QtQuick.Controls 2.5 as QQC2
10 import org.kde.kirigami 2.11 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  */
18 Kirigami.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 QQC2.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
88 
89  /**
90  * @returns the page item held in the PagePool or null if it has not been loaded yet.
91  */
92  function pageItem() {
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() {
101  if (!useLayers || !pageStack.hasOwnProperty("layers")) return false
102 
103  const item = pageStack.layers.find((item, index) => {
104  return item === pagePool.pageForUrl(page)
105  })
106  return !!item
107  }
108 
109  /**
110  * @returns true if the page has been loaded and placed on the pageStack,
111  * otherwise returns null.
112  */
113  function stackContainsPage() {
114  if (useLayers) return false
115  return pageStack.columnView.containsItem(pagePool.pageForUrl(page))
116  }
117 
118  checkable: true
119 
120  onTriggered: {
121  if (page.length === 0 || !pagePool || !pageStack) {
122  return;
123  }
124 
125  // User intends to "go back" to this layer.
126  if (layerContainsPage() && pageItem() !== pageStack.layers.currentItem) {
127  pageStack.layers.replace(pageItem(), pageItem()) // force pop above
128  return
129  }
130 
131  // User intends to "go back" to this page.
132  if (stackContainsPage()) {
133  if (pageStack.hasOwnProperty("layers")) {
134  pageStack.layers.clear()
135  }
136  }
137 
138  const pageStack_ = useLayers ? pageStack.layers : pageStack
139 
140  if (initialProperties && typeof(initialProperties) !== "object") {
141  console.warn("initialProperties must be of type object");
142  return;
143  }
144 
145  if (!pageStack_.hasOwnProperty("pop") || typeof pageStack_.pop !== "function" || !pageStack_.hasOwnProperty("push") || typeof pageStack_.push !== "function") {
146  return;
147  }
148 
149  if (pagePool.isLocalUrl(page)) {
150  if (basePage) {
151  pageStack_.pop(basePage);
152 
153  } else if (!useLayers) {
154  pageStack_.clear();
155  }
156 
157  pageStack_.push(initialProperties ?
158  pagePool.loadPageWithProperties(page, initialProperties) :
159  pagePool.loadPage(page));
160  } else {
161  const callback = function(item) {
162  if (basePage) {
163  pageStack_.pop(basePage);
164 
165  } else if (!useLayers) {
166  pageStack_.clear();
167  }
168  pageStack_.push(item);
169  };
170 
171  if (initialProperties) {
172  pagePool.loadPage(page, initialProperties, callback);
173 
174  } else {
175  pagePool.loadPage(page, callback);
176  }
177  }
178  }
179 
180  // Exposing this as a property is required as Action does not have a default property
181  property QtObject _private: QtObject {
182  id: _private
183 
184  function setChecked(checked) {
185  root.checked = checked
186  }
187 
188  function clearLayers() {
189  pageStack.layers.clear()
190  }
191 
192  property list<Connections> connections: [
193  Connections {
194  target: pageStack
195 
196  function onCurrentItemChanged() {
197  if (root.useLayers) {
198  if (root.layerContainsPage()) {
199  _private.clearLayers()
200  }
201  if (root.checkable)
202  _private.setChecked(false);
203 
204  } else {
205  if (root.checkable)
206  _private.setChecked(root.stackContainsPage());
207  }
208  }
209  },
210  Connections {
211  enabled: pageStack.hasOwnProperty("layers")
212  target: pageStack.layers
213 
214  function onCurrentItemChanged() {
215  if (root.useLayers && root.checkable) {
216  _private.setChecked(root.layerContainsPage());
217 
218  } else {
219  if (pageStack.layers.depth === 1 && root.stackContainsPage()) {
220  _private.setChecked(true)
221  }
222  }
223  }
224  }
225  ]
226  }
227 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:14:23 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.