Kirigami2

Page.qml
1 /*
2  * SPDX-FileCopyrightText: 2015 Marco Martin <[email protected]>
3  *
4  * SPDX-License-Identifier: LGPL-2.0-or-later
5  */
6 
7 import QtQuick 2.5
8 import QtQuick.Layouts 1.2
9 import org.kde.kirigami 2.10 as Kirigami
10 import "private"
11 import QtQuick.Templates 2.1 as T2
12 import QtQuick.Controls 2.1 as QQC2
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  * For content that should be scrollable, such as ListViews, use ScrollablePage instead.
19  *
20  * @see ScrollablePage
21  * @inherit QtQuick.Controls.Page
22  */
23 QQC2.Page {
24  id: root
25 
26  /**
27  * padding: real
28  *
29  * The default content padding is 1 gridUnit.
30  */
31  padding: Kirigami.Units.gridUnit
32 
33  /**
34  * bottomPadding: real
35  *
36  * The bottom content padding. Bound to verticalPadding or the height of floating action buttons (when present) by default.
37  */
38  bottomPadding: actionButtons.item ? actionButtons.height : verticalPadding
39 
40  /**
41  * flickable: Flickable
42  * if the central element of the page is a Flickable
43  * (ListView and Gridview as well) you can set it there.
44  * normally, you wouldn't need to do that, but just use the
45  * ScrollablePage element instead
46  * @see ScrollablePage
47  * Use this if your flickable has some non standard properties, such as not covering the whole Page
48  */
49  property Flickable flickable
50 
51  /**
52  * actions.contextualActions: list<QtObject>
53  * Defines the contextual actions for the page:
54  * an easy way to assign actions in the right sliding panel
55  *
56  * Example usage:
57  * @code
58  * import org.kde.kirigami 2.4 as Kirigami
59  *
60  * Kirigami.ApplicationWindow {
61  * [...]
62  * contextDrawer: Kirigami.ContextDrawer {
63  * id: contextDrawer
64  * }
65  * [...]
66  * }
67  * @endcode
68  *
69  * @code
70  * import org.kde.kirigami 2.4 as Kirigami
71  *
72  * Kirigami.Page {
73  * [...]
74  * actions.contextualActions: [
75  * Kirigami.Action {
76  * icon.name: "edit"
77  * text: "Action text"
78  * onTriggered: {
79  * // do stuff
80  * }
81  * },
82  * Kirigami.Action {
83  * icon.name: "edit"
84  * text: "Action text"
85  * onTriggered: {
86  * // do stuff
87  * }
88  * }
89  * ]
90  * [...]
91  * }
92  * @endcode
93  */
94  //TODO: remove
95  property alias contextualActions: actionsGroup.contextualActions
96 
97  /**
98  * actions.main: Action
99  * An optional single action for the action button.
100  * it can be a Kirigami.Action or a QAction
101  *
102  * Example usage:
103  *
104  * @code
105  * import org.kde.kirigami 2.4 as Kirigami
106  * Kirigami.Page {
107  * actions.main: Kirigami.Action {
108  * icon.name: "edit"
109  * onTriggered: {
110  * // do stuff
111  * }
112  * }
113  * }
114  * @endcode
115  */
116  //TODO: remove
117  property alias mainAction: actionsGroup.main
118 
119  /**
120  * actions.left: Action
121  * An optional extra action at the left of the main action button.
122  * it can be a Kirigami.Action or a QAction
123  *
124  * Example usage:
125  *
126  * @code
127  * import org.kde.kirigami 2.4 as Kirigami
128  * Kirigami.Page {
129  * actions.left: Kirigami.Action {
130  * icon.name: "edit"
131  * onTriggered: {
132  * // do stuff
133  * }
134  * }
135  * }
136  * @endcode
137  */
138  //TODO: remove
139  property alias leftAction: actionsGroup.left
141  /**
142  * actions.right: Action
143  * An optional extra action at the right of the main action button.
144  * it can be a Kirigami.Action or a QAction
145  *
146  * Example usage:
147  *
148  * @code
149  * import org.kde.kirigami 2.4 as Kirigami
150  * Kirigami.Page {
151  * actions.right: Kirigami.Action {
152  * icon.name: "edit"
153  * onTriggered: {
154  * // do stuff
155  * }
156  * }
157  * }
158  * @endcode
159  */
160  //TODO: remove
161  property alias rightAction: actionsGroup.right
162 
163  /**
164  * Actions properties are grouped.
165  *
166  * @code
167  * import org.kde.kirigami 2.4 as Kirigami
168  * Kirigami.Page {
169  * actions {
170  * main: Kirigami.Action {...}
171  * left: Kirigami.Action {...}
172  * right: Kirigami.Action {...}
173  * contextualActions: [
174  * Kirigami.Action {...},
175  * Kirigami.Action {...}
176  * ]
177  * }
178  * }
179  * @endcode
180  */
181  readonly property alias actions: actionsGroup
182 
183  /**
184  * contextualActionsAboutToShow: signal
185  * Emitted when a visualization for the actions is about to be shown,
186  * such as the toolbar menu or the contextDrawer
187  * @since 2.7
188  */
189  signal contextualActionsAboutToShow
190 
191  /**
192  * isCurrentPage: bool
193  *
194  * Specifies if it's the currently selected page in the window's pages row, or if layers
195  * are used whether this is the topmost item on the layers stack. If the page is
196  * not attached to either a column view or a stack view, expect this to be true.
197  *
198  * @since 2.1
199  */
200  readonly property bool isCurrentPage: Kirigami.ColumnView.view
201  ? (Kirigami.ColumnView.index == Kirigami.ColumnView.view.currentIndex && Kirigami.ColumnView.view.parent.currentItem === Kirigami.ColumnView.view)
202  : (parent && parent instanceof QQC2.StackView
203  ? parent.currentItem === root
204  : true)
205 
206  /**
207  * overlay: Item
208  * an item which stays on top of every other item in the page,
209  * if you want to make sure some elements are completely in a
210  * layer on top of the whole content, parent items to this one.
211  * It's a "local" version of ApplicationWindow's overlay
212  * @since 2.5
213  */
214  readonly property alias overlay: overlayItem
215 
216  /**
217  * icon: variant
218  *
219  * The icon that represents this page.
220  */
221  property ActionIconGroup icon: ActionIconGroup {}
222 
223  /**
224  * needsAttention: bool
225  *
226  * Whether this page needs user attention.
227  */
228  property bool needsAttention
229 
230  /**
231  * progress: real
232  *
233  * Progress of a task this page is doing. Set to undefined to indicate
234  * that there are no ongoing tasks.
235  */
236  property var progress: undefined
237 
238  /**
239  * titleDelegate: Component
240  * The delegate which will be used to draw the page title. It can be customized to put any kind of Item in there.
241  * @since 2.7
242  */
243  property Component titleDelegate: Component {
244  id: defaultTitleDelegate
245  Kirigami.Heading {
246  level: 1
247  Layout.fillWidth: true
248  Layout.maximumWidth: implicitWidth + 1 // The +1 is to make sure we do not trigger eliding at max width
249  Layout.minimumWidth: 0
250  opacity: root.isCurrentPage ? 1 : 0.4
251  maximumLineCount: 1
252  elide: Text.ElideRight
253  text: root.title
254  }
255  }
256 
257  /**
258  * emitted When the application requests a Back action
259  * For instance a global "back" shortcut or the Android
260  * Back button has been pressed.
261  * The page can manage the back event by itself,
262  * and if it set event.accepted = true, it will stop the main
263  * application to manage the back event.
264  */
265  signal backRequested(var event);
266 
267 
268  // Look for sheets and cose them
269  //FIXME: port Sheets to Popup?
270  onBackRequested: {
271  for(var i in root.resources) {
272  var item = root.resources[i];
273  if (item.hasOwnProperty("close") && item.hasOwnProperty("sheetOpen") && item.sheetOpen) {
274  item.close()
275  event.accepted = true;
276  return;
277  }
278  }
279  }
280 
281  /**
282  * globalToolBarItem: Item
283  * The item used as global toolbar for the page
284  * present only if we are in a PageRow as a page or as a layer,
285  * and the style is either Titles or ToolBar
286  * @since 2.5
287  */
288  readonly property Item globalToolBarItem: globalToolBar.item
289 
290  /**
291  * 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.
292  * A single page can override the application toolbar style for itself.
293  * It is discouraged to use this, except very specific exceptions, like a chat
294  * application which can't have controls on the bottom except the text field.
295  * If the Page is not in a PageRow, by default the toolbar will be invisible,
296  * so has to be explicitly set to Kirigami.ApplicationHeaderStyle.ToolBar if
297  * desired to be used in that case.
298  */
299  property int globalToolBarStyle: {
300  if (globalToolBar.row && !globalToolBar.stack) {
301  return globalToolBar.row.globalToolBar.actualStyle;
302  } else if (globalToolBar.stack) {
303  return Kirigami.Settings.isMobile ? Kirigami.ApplicationHeaderStyle.Titles : Kirigami.ApplicationHeaderStyle.ToolBar;
304  } else {
305  return Kirigami.ApplicationHeaderStyle.None;
306  }
307  }
308 
309  //NOTE: contentItem will be created if not existing (and contentChildren of Page would become its children) This with anchors enforces the geometry we want, where globalToolBar is a super-header, on top of header
310  contentItem: Item {
311  anchors {
312  top: root.header
313  ? root.header.bottom
314  : (globalToolBar.visible ? globalToolBar.bottom : parent.top)
315  topMargin: root.topPadding + root.spacing
316  bottom: root.footer ? root.footer.top : parent.bottom
317  bottomMargin: root.bottomPadding + root.spacing
318  }
319  }
320 
321  background: Rectangle {
322  color: Kirigami.Theme.backgroundColor
323  }
324 
325  implicitHeight: (header ? header.implicitHeight : 0) + (footer ? footer.implicitHeight : 0) + contentItem.implicitHeight + topPadding + bottomPadding
326  implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding
327 
328  //FIXME: on material the shadow would bleed over
329  clip: root.header != null;
330 
331  onHeaderChanged: {
332  if (header) {
333  header.anchors.top = Qt.binding(function() {return globalToolBar.visible ? globalToolBar.bottom : root.top});
334  }
335  }
336 
337  Component.onCompleted: {
338  headerChanged();
339  parentChanged(root.parent);
340  globalToolBar.syncSource();
341  }
342 
343  onParentChanged: {
344  if (!parent) {
345  return;
346  }
347  globalToolBar.stack = null;
348  globalToolBar.row = null;
349 
350  if (root.Kirigami.ColumnView.view) {
351  globalToolBar.row = root.Kirigami.ColumnView.view.__pageRow;
352  }
353  if (root.T2.StackView.view) {
354  globalToolBar.stack = root.T2.StackView.view;
355  globalToolBar.row = root.T2.StackView.view ? root.T2.StackView.view.parent : null;
356  }
357  if (globalToolBar.row) {
358  root.globalToolBarStyleChanged.connect(globalToolBar.syncSource);
359  globalToolBar.syncSource();
360  }
361  }
362 
363  //in data in order for them to not be considered for contentItem, contentChildren, contentData
364  data: [
365  PageActionPropertyGroup {
366  id: actionsGroup
367  },
368 
369  Item {
370  id: overlayItem
371  parent: root
372  z: 9997
373  anchors {
374  fill: parent
375  topMargin: globalToolBar.height
376  }
377  },
378  //global top toolbar if we are in a PageRow (in the row or as a layer)
379  Loader {
380  id: globalToolBar
381  z: 9999
382  height: item ? item.implicitHeight : 0
383  anchors {
384  left: parent.left
385  right: parent.right
386  top: parent.top
387  }
388  property Kirigami.PageRow row
389  property T2.StackView stack
390 
391  visible: active
392  active: (root.titleDelegate !== defaultTitleDelegate || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.ToolBar || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.Titles)
393  onActiveChanged: {
394  if (active) {
395  syncSource();
396  }
397  }
398 
399  function syncSource() {
400  if (root.globalToolBarStyle !== Kirigami.ApplicationHeaderStyle.ToolBar &&
401  root.globalToolBarStyle !== Kirigami.ApplicationHeaderStyle.Titles &&
402  root.titleDelegate !== defaultTitleDelegate) {
403  sourceComponent = root.titleDelegate;
404  } else if (active) {
405  setSource(Qt.resolvedUrl(root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.ToolBar ? "private/globaltoolbar/ToolBarPageHeader.qml" : "private/globaltoolbar/TitlesPageHeader.qml"),
406  //TODO: find container reliably, remove assumption
407  {"pageRow": Qt.binding(function() {return row}),
408  "page": root,
409  "current": Qt.binding(function() {
410  if (!row && !stack) {
411  return true;
412  } else if (stack) {
413  return stack;
414  } else {
415  return row.currentIndex === root.Kirigami.ColumnView.level;
416  }
417  })});
418  }
419  }
420  },
421  //bottom action buttons
422  Loader {
423  id: actionButtons
424  z: 9999
425  parent: root
426  anchors {
427  left: parent.left
428  right: parent.right
429  bottom: parent.bottom
430  }
431  //if the page doesn't inherit, assume it has custom colors we want to use them here too
432  Kirigami.Theme.inherit: !root.Kirigami.Theme.inherit
433  Kirigami.Theme.colorSet: Kirigami.Theme.Button
434 
435  //It should be T2.Page, Qt 5.7 doesn't like it
436  property Item page: root
437  height: item ? item.implicitHeight : 0
438  active: typeof applicationWindow !== "undefined" && (!globalToolBar.row || root.globalToolBarStyle !== Kirigami.ApplicationHeaderStyle.ToolBar) &&
439  root.actions && (root.actions.main || root.actions.left || root.actions.right || root.actions.contextualActions.length) &&
440  //Legacy
441  (typeof applicationWindow === "undefined" ||
442  (!applicationWindow().header || applicationWindow().header.toString().indexOf("ToolBarApplicationHeader") === -1) &&
443  (!applicationWindow().footer || applicationWindow().footer.toString().indexOf("ToolBarApplicationHeader") === -1))
444  source: Qt.resolvedUrl("./private/ActionButton.qml")
445  }
446  ]
447 
448  Layout.fillWidth: true
449 }
Definition: icon.h:18
QTextStream & left(QTextStream &s)
if(recurs()&&!first)
QTextStream & right(QTextStream &s)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Jun 20 2021 22:38:03 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.