Kirigami2

Page.qml
1/*
2 * SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7import QtQuick
8import QtQuick.Layouts
9import QtQuick.Templates as T
10import QtQuick.Controls as QQC2
11import org.kde.kirigami as Kirigami
12import "private" as P
13
14/**
15 * Page is a container for all the app pages: everything pushed to the
16 * ApplicationWindow's pageStack should be a Page.
17 *
18 * @see ScrollablePage
19 * For content that should be scrollable, such as ListViews, use ScrollablePage instead.
20 * @inherit QtQuick.Controls.Page
21 */
22QQC2.Page {
23 id: root
24
25//BEGIN properties
26 padding: Kirigami.Units.gridUnit
27
28 /**
29 * @brief If the central element of the page is a Flickable
30 * (ListView and Gridview as well) you can set it there.
31 *
32 * Normally, you wouldn't need to do that, but just use the
33 * ScrollablePage element instead.
34 *
35 * Use this if your flickable has some non standard properties, such as not covering the whole Page.
36 *
37 * @see ScrollablePage
38 */
39 property Flickable flickable
40
41 /**
42 * @brief This property holds the actions for the page.
43 *
44 * These actions will be displayed in the toolbar on the desktop and inside
45 * the ContextDrawer on mobile.
46 *
47 * @code
48 * import org.kde.kirigami as Kirigami
49 *
50 * Kirigami.Page {
51 * actions: [
52 * Kirigami.Action {...},
53 * Kirigami.Action {...}
54 * }
55 * }
56 * @endcode
57 */
58 property list<T.Action> actions
59
60 /**
61 * @brief This property tells us if it is the currently active page.
62 *
63 * Specifies if it's the currently selected page in the window's pages row, or if layers
64 * are used whether this is the topmost item on the layers stack. If the page is
65 * not attached to either a column view or a stack view, expect this to be true.
66 *
67 * @since 2.1
68 */
69 //TODO KF6: remove this or at least all the assumptions about the internal tree structure of items
70 // Kirigami.ColumnView.view.parent.parent is the StackView in which the ColumnView is, the condition means "is the ColumnView the current layer of the pagerow"
71 readonly property bool isCurrentPage: Kirigami.ColumnView.view
72 ? (Kirigami.ColumnView.index === Kirigami.ColumnView.view.currentIndex && Kirigami.ColumnView.view.parent.parent.currentItem === Kirigami.ColumnView.view.parent)
73 : (parent && parent instanceof QQC2.StackView
74 ? parent.currentItem === root
75 : true)
76
77 /**
78 * An item which stays on top of every other item in the page,
79 * if you want to make sure some elements are completely in a
80 * layer on top of the whole content, parent items to this one.
81 * It's a "local" version of ApplicationWindow's overlay
82 *
83 * @property Item overlay
84 * @since 2.5
85 */
86 readonly property alias overlay: overlayItem
87
88 /**
89 * @brief This holds the icon that represents this page.
90 * @property var icon
91 */
92 property P.ActionIconGroup icon: P.ActionIconGroup {}
93
94 /**
95 * @brief Progress of a task this page is doing.
96 *
97 * Set to undefined to indicate that there are no ongoing tasks.
98 *
99 * default: ``undefined``
100 *
101 * @property real progress
102 */
103 property var progress: undefined
104
105 /**
106 * @brief The delegate which will be used to draw the page title.
107 *
108 * It can be customized to put any kind of Item in there.
109 *
110 * @since 2.7
111 */
112 property Component titleDelegate: Component {
113 id: defaultTitleDelegate
114 P.DefaultPageTitleDelegate {
115 text: root.title
116 }
117 }
118
119 /**
120 * The item used as global toolbar for the page
121 * present only if we are in a PageRow as a page or as a layer,
122 * and the style is either Titles or ToolBar.
123 *
124 * @since 2.5
125 */
126 readonly property Item globalToolBarItem: globalToolBar.item
127
128 /**
129 * The style for the automatically generated global toolbar: by default the Page toolbar is the one set globally in the PageRow in its globalToolBar.style property.
130 * A single page can override the application toolbar style for itself.
131 * It is discouraged to use this, except very specific exceptions, like a chat
132 * application which can't have controls on the bottom except the text field.
133 * If the Page is not in a PageRow, by default the toolbar will be invisible,
134 * so has to be explicitly set to Kirigami.ApplicationHeaderStyle.ToolBar if
135 * desired to be used in that case.
136 */
137 property int globalToolBarStyle: {
138 if (globalToolBar.row && !globalToolBar.stack) {
139 return globalToolBar.row.globalToolBar.actualStyle;
140 } else if (globalToolBar.stack) {
141 return Kirigami.Settings.isMobile ? Kirigami.ApplicationHeaderStyle.Titles : Kirigami.ApplicationHeaderStyle.ToolBar;
142 } else {
143 return Kirigami.ApplicationHeaderStyle.None;
144 }
145 }
146//END properties
147
148//BEGIN signal and signal handlers
149 /**
150 * @brief Emitted when the application requests a Back action.
151 *
152 * For instance a global "back" shortcut or the Android
153 * Back button has been pressed.
154 * The page can manage the back event by itself,
155 * and if it set event.accepted = true, it will stop the main
156 * application to manage the back event.
157 */
158 signal backRequested(var event);
159
160 background: Rectangle {
161 color: Kirigami.Theme.backgroundColor
162 }
163
164 // FIXME: on material the shadow would bleed over
165 clip: root.header !== null;
166
167 Component.onCompleted: {
168 headerChanged();
169 parentChanged(root.parent);
170 globalToolBar.syncSource();
171 bottomToolBar.pageComplete = true
172 }
173
174 onParentChanged: {
175 if (!parent) {
176 return;
177 }
178 globalToolBar.stack = null;
179 globalToolBar.row = null;
180
181 if (root.Kirigami.ColumnView.view) {
182 globalToolBar.row = root.Kirigami.ColumnView.view.__pageRow;
183 }
184 if (root.T.StackView.view) {
185 globalToolBar.stack = root.T.StackView.view;
186 globalToolBar.row = root.T.StackView.view.parent instanceof Kirigami.PageRow ? root.T.StackView.view.parent : null;
187 }
188 if (globalToolBar.row) {
189 root.globalToolBarStyleChanged.connect(globalToolBar.syncSource);
190 globalToolBar.syncSource();
191 }
192 }
193//END signals and signal handlers
194
195 // in data in order for them to not be considered for contentItem, contentChildren, contentData
196 data: [
197 Item {
198 id: overlayItem
199 parent: root
200 z: 9997
201 anchors {
202 fill: parent
203 topMargin: globalToolBar.height
204 }
205 }
206 ]
207 // global top toolbar if we are in a PageRow (in the row or as a layer)
208 Kirigami.ColumnView.globalHeader: Loader {
209 id: globalToolBar
210 z: 9999
211 height: item ? item.implicitHeight : 0
212
213 width: root.width
214 property Kirigami.PageRow row
215 property T.StackView stack
216
217 // don't load async so that on slower devices we don't have the page content height changing while loading in
218 // otherwise, it looks unpolished and jumpy
219 asynchronous: false
220
221 visible: active
222 active: (root.titleDelegate !== defaultTitleDelegate || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.ToolBar || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.Titles)
223 onActiveChanged: {
224 if (active) {
225 syncSource();
226 }
227 }
228
229 function syncSource() {
230 if (root.globalToolBarStyle !== Kirigami.ApplicationHeaderStyle.ToolBar &&
231 root.globalToolBarStyle !== Kirigami.ApplicationHeaderStyle.Titles &&
232 root.titleDelegate !== defaultTitleDelegate) {
233 sourceComponent = root.titleDelegate;
234 } else if (active) {
235 const url = root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.ToolBar
236 ? "private/globaltoolbar/ToolBarPageHeader.qml"
237 : "private/globaltoolbar/TitlesPageHeader.qml";
238 // TODO: find container reliably, remove assumption
239 setSource(Qt.resolvedUrl(url), {
240 pageRow: Qt.binding(() => row),
241 page: root,
242 current: Qt.binding(() => {
243 if (!row && !stack) {
244 return true;
245 } else if (stack) {
246 return stack;
247 } else {
248 return row.currentIndex === root.Kirigami.ColumnView.level;
249 }
250 }),
251 });
252 }
253 }
254 }
255 // bottom action buttons
256 Kirigami.ColumnView.globalFooter: Loader {
257 id: bottomToolBar
258
259 property T.Page page: root
260 property bool pageComplete: false
261
262 visible: active
263
264 active: {
265 // Important! Do not do anything until the page has been
266 // completed, so we are sure what the globalToolBarStyle is,
267 // otherwise we risk creating the content and then discarding it.
268 if (!pageComplete) {
269 return false;
270 }
271
272 if ((globalToolBar.row && globalToolBar.row.globalToolBar.actualStyle === Kirigami.ApplicationHeaderStyle.ToolBar)
273 || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.ToolBar
274 || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.None) {
275 return false;
276 }
277
278 if (root.actions.length === 0) {
279 return false;
280 }
281
282 // Legacy
283 if (typeof applicationWindow === "undefined") {
284 return true;
285 }
286
287 const drawer = applicationWindow() ? applicationWindow()['contextDrawer'] : undefined;
288 if (Boolean(drawer) && drawer.enabled && drawer.handleVisible) {
289 return false;
290 }
291
292 return true;
293 }
294
295 source: Qt.resolvedUrl("./private/globaltoolbar/ToolBarPageFooter.qml")
296 }
297
298 Layout.fillWidth: true
299}
KIOCORE_EXPORT QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:05:44 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.