Warning, /frameworks/kirigami/src/controls/Page.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.5 0008 import QtQuick.Layouts 1.2 0009 import QtQuick.Templates 2.1 as T2 0010 import QtQuick.Controls 2.1 as QQC2 0011 import org.kde.kirigami 2.10 as Kirigami 0012 import "private" as P 0013 0014 /** 0015 * Page is a container for all the app pages: everything pushed to the 0016 * @link ApplicationWindow::pageStack pageStack @endlink should be a Page. 0017 * 0018 * For content that should be scrollable, such as QtQuick.ListView, use ScrollablePage instead. 0019 * @inherit QtQuick.Controls.Page 0020 */ 0021 QQC2.Page { 0022 id: root 0023 0024 //BEGIN properties 0025 /** 0026 * @brief If the central element of the page is a Flickable 0027 * (ListView and Gridview as well) you can set it there. 0028 * 0029 * Normally, you wouldn't need to do that, but just use the 0030 * ScrollablePage element instead. 0031 * 0032 * Use this if your flickable has some non standard properties, 0033 * such as not covering the whole Page. 0034 * 0035 * @see kirigami::ScrollablePage 0036 */ 0037 property Flickable flickable 0038 0039 /** 0040 * @brief Defines the contextual actions for the page: 0041 * an easy way to assign actions in the right sliding panel 0042 * 0043 * Example usage: 0044 * @code{.qml} 0045 * import org.kde.kirigami 2.4 as Kirigami 0046 * 0047 * Kirigami.ApplicationWindow { 0048 * [...] 0049 * contextDrawer: Kirigami.ContextDrawer { 0050 * id: contextDrawer 0051 * } 0052 * [...] 0053 * } 0054 * @endcode 0055 * 0056 * @code{.qml} 0057 * import org.kde.kirigami 2.4 as Kirigami 0058 * 0059 * Kirigami.Page { 0060 * [...] 0061 * actions.contextualActions: [ 0062 * Kirigami.Action { 0063 * icon.name: "edit" 0064 * text: "Action text" 0065 * onTriggered: { 0066 * // do stuff 0067 * } 0068 * }, 0069 * Kirigami.Action { 0070 * icon.name: "edit" 0071 * text: "Action text" 0072 * onTriggered: { 0073 * // do stuff 0074 * } 0075 * } 0076 * ] 0077 * [...] 0078 * } 0079 * @endcode 0080 * @warning This will be removed in KF6. 0081 * @property list<QtQml.QtObject> contextualActions 0082 */ 0083 // TODO: remove 0084 property alias contextualActions: actionsGroup.contextualActions 0085 0086 /** 0087 * @brief An optional single action for the action button. 0088 * 0089 * Example usage: 0090 * @code{.qml} 0091 * import org.kde.kirigami 2.4 as Kirigami 0092 * Kirigami.Page { 0093 * actions.main: Kirigami.Action { 0094 * icon.name: "edit" 0095 * onTriggered: { 0096 * // do stuff 0097 * } 0098 * } 0099 * } 0100 * @endcode 0101 * @warning This will be removed in KF6. 0102 * @property Action mainAction 0103 */ 0104 //TODO: remove 0105 property alias mainAction: actionsGroup.main 0106 0107 /** 0108 * @brief An optional extra action at the left of the main action button. 0109 * 0110 * Example usage: 0111 * @code{.qml} 0112 * import org.kde.kirigami 2.4 as Kirigami 0113 * Kirigami.Page { 0114 * actions.left: Kirigami.Action { 0115 * icon.name: "edit" 0116 * onTriggered: { 0117 * // do stuff 0118 * } 0119 * } 0120 * } 0121 * @endcode 0122 * @warning This will be removed in KF6. 0123 * @property Action leftAction 0124 */ 0125 // TODO: remove 0126 property alias leftAction: actionsGroup.left 0127 0128 /** 0129 * @brief An optional extra action at the right of the main action button. 0130 * 0131 * Example usage: 0132 * @code{.qml} 0133 * import org.kde.kirigami 2.4 as Kirigami 0134 * Kirigami.Page { 0135 * actions.right: Kirigami.Action { 0136 * icon.name: "edit" 0137 * onTriggered: { 0138 * // do stuff 0139 * } 0140 * } 0141 * } 0142 * @endcode 0143 * @warning This will be removed in KF6. 0144 * @property Action rightAction 0145 */ 0146 // TODO: remove 0147 property alias rightAction: actionsGroup.right 0148 0149 /** 0150 * @brief This property holds the actions group. 0151 * @code 0152 * import org.kde.kirigami 2.4 as Kirigami 0153 * Kirigami.Page { 0154 * actions { 0155 * main: Kirigami.Action {...} 0156 * left: Kirigami.Action {...} 0157 * right: Kirigami.Action {...} 0158 * contextualActions: [ 0159 * Kirigami.Action {...}, 0160 * Kirigami.Action {...} 0161 * ] 0162 * } 0163 * } 0164 * @endcode 0165 * @see <a href="https://develop.kde.org/hig/components/navigation/actionbutton">KDE Human Interface Guidelines on Actions</a> 0166 * @property kirigami::private::PageActionPropertyGroup actions 0167 */ 0168 readonly property alias actions: actionsGroup 0169 0170 /** 0171 * @brief This property specifies us if it is the currently active page. 0172 * 0173 * Specifies if it's the currently selected page in the window's pages 0174 * row, or if layers are used whether this is the topmost item on the 0175 * layers stack. If the page is not attached to either a column view or 0176 * a stack view, expect this to be true. 0177 * 0178 * @since org.kde.kirigami 2.1 0179 */ 0180 //TODO KF6: remove this or at least all the assumptions about the internal tree structure of items 0181 readonly property bool isCurrentPage: Kirigami.ColumnView.view 0182 ? (Kirigami.ColumnView.index === Kirigami.ColumnView.view.currentIndex && Kirigami.ColumnView.view.parent.parent.currentItem === Kirigami.ColumnView.view.parent) 0183 : (parent && parent instanceof QQC2.StackView 0184 ? parent.currentItem === root 0185 : true) 0186 0187 /** 0188 * An item which stays on top of every other item in the page, 0189 * if you want to make sure some elements are completely in a 0190 * layer on top of the whole content, parent items to this one. 0191 * It's a "local" version of ApplicationWindow's overlay 0192 * 0193 * @property Item overlay 0194 * @since org.kde.kirigami 2.5 0195 */ 0196 readonly property alias overlay: overlayItem 0197 0198 /** 0199 * @brief This holds the icon that represents this page. 0200 */ 0201 property P.ActionIconGroup icon: P.ActionIconGroup {} 0202 0203 /** 0204 * @brief Whether this page needs user attention. 0205 */ 0206 property bool needsAttention 0207 0208 /** 0209 * @brief Progress of a task this page is doing. 0210 * 0211 * Set to undefined to indicate that there are no ongoing tasks. 0212 * 0213 * default: ``undefined`` 0214 * 0215 * @property real progress 0216 */ 0217 property var progress: undefined 0218 0219 /** 0220 * @brief The delegate which will be used to draw the page title. 0221 * 0222 * It can be customized to put any kind of Item in there. 0223 * 0224 * @since org.kde.kirigami 2.7 0225 */ 0226 property Component titleDelegate: Component { 0227 id: defaultTitleDelegate 0228 P.DefaultPageTitleDelegate { 0229 text: root.title 0230 } 0231 } 0232 0233 /** 0234 * The item used as global toolbar for the page 0235 * present only if we are in a PageRow as a page or as a layer, 0236 * and the style is either Titles or ToolBar. 0237 * 0238 * @since org.kde.kirigami 2.5 0239 */ 0240 readonly property Item globalToolBarItem: globalToolBar.item 0241 0242 /** 0243 * @brief This property holds the style for the automatically generated 0244 * toolbar of the PageRow where the Page is inserted. 0245 * 0246 * By default, the Page's globalToolBarStyle determines the style used by 0247 * the PageRow where it is inserted, updating the PageRow's globalToolBar 0248 * style. This allows for a single page to override the application toolbar 0249 * style for itself. 0250 * 0251 * It is discouraged to use this, except in very specific cases, like a 0252 * chat application that can't have controls at the bottom except for a 0253 * text field. If the Page is not in a PageRow, by default, the toolbar 0254 * will be invisible, so Page::globalToolBarStyle has to be explicitly 0255 * set to ApplicationHeaderStyle.ToolBar to be used in that case. 0256 */ 0257 property int globalToolBarStyle: { 0258 if (globalToolBar.row && !globalToolBar.stack) { 0259 return globalToolBar.row.globalToolBar.actualStyle; 0260 } else if (globalToolBar.stack) { 0261 return Kirigami.Settings.isMobile ? Kirigami.ApplicationHeaderStyle.Titles : Kirigami.ApplicationHeaderStyle.ToolBar; 0262 } else { 0263 return Kirigami.ApplicationHeaderStyle.None; 0264 } 0265 } 0266 //END properties 0267 0268 //BEGIN signals and signal handlers 0269 /** 0270 * Emitted when a visualization for the actions is about to 0271 * be shown, such as the toolbar menu or the ContextDrawer. 0272 * 0273 * @since org.kde.kirigami 2.7 0274 */ 0275 signal contextualActionsAboutToShow 0276 0277 /** 0278 * @brief Emitted when the application requests a Back action. 0279 * 0280 * For instance a global "back" shortcut or the Android 0281 * Back button has been pressed. 0282 * The page can manage the back event by itself, 0283 * and if it set event.accepted = true, it will stop the main 0284 * application to manage the back event. 0285 */ 0286 signal backRequested(var event); 0287 0288 0289 // Look for sheets and cose them 0290 // FIXME: port Sheets to Popup? 0291 onBackRequested: event => { 0292 let item; 0293 for (const i in root.resources) { 0294 item = root.resources[i]; 0295 if (item.hasOwnProperty("close") && item.hasOwnProperty("sheetOpen") && item.sheetOpen) { 0296 item.close() 0297 event.accepted = true; 0298 return; 0299 } 0300 } 0301 } 0302 0303 onHeaderChanged: { 0304 if (header) { 0305 header.anchors.top = Qt.binding(() => globalToolBar.visible ? globalToolBar.bottom : root.top); 0306 } 0307 } 0308 0309 Component.onCompleted: { 0310 headerChanged(); 0311 parentChanged(root.parent); 0312 globalToolBar.syncSource(); 0313 actionButtons.pageComplete = true 0314 } 0315 0316 onParentChanged: { 0317 if (!parent) { 0318 return; 0319 } 0320 globalToolBar.stack = null; 0321 globalToolBar.row = null; 0322 0323 if (root.Kirigami.ColumnView.view) { 0324 globalToolBar.row = root.Kirigami.ColumnView.view.__pageRow; 0325 } 0326 if (root.T2.StackView.view) { 0327 globalToolBar.stack = root.T2.StackView.view; 0328 globalToolBar.row = root.T2.StackView.view ? root.T2.StackView.view.parent : null; 0329 } 0330 if (globalToolBar.row) { 0331 root.globalToolBarStyleChanged.connect(globalToolBar.syncSource); 0332 globalToolBar.syncSource(); 0333 } 0334 } 0335 //END signals and signal handlers 0336 0337 // 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 0338 contentItem: Item { 0339 anchors { 0340 top: (root.header && root.header.visible) 0341 ? root.header.bottom 0342 : (globalToolBar.visible ? globalToolBar.bottom : parent.top) 0343 topMargin: root.topPadding + root.spacing 0344 bottom: (root.footer && root.footer.visible) ? root.footer.top : parent.bottom 0345 bottomMargin: root.bottomPadding + root.spacing 0346 } 0347 } 0348 0349 background: Rectangle { 0350 color: Kirigami.Theme.backgroundColor 0351 } 0352 0353 implicitHeight: ((header && header.visible) ? header.implicitHeight : 0) + ((footer && footer.visible) ? footer.implicitHeight : 0) + contentItem.implicitHeight + topPadding + bottomPadding 0354 implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding 0355 0356 // FIXME: on material the shadow would bleed over 0357 clip: root.header !== null; 0358 0359 padding: Kirigami.Units.gridUnit 0360 bottomPadding: actionButtons.item ? actionButtons.height : verticalPadding 0361 0362 // in data in order for them to not be considered for contentItem, contentChildren, contentData 0363 data: [ 0364 P.PageActionPropertyGroup { 0365 id: actionsGroup 0366 }, 0367 0368 Item { 0369 id: overlayItem 0370 parent: root 0371 z: 9997 0372 anchors { 0373 fill: parent 0374 topMargin: globalToolBar.height 0375 } 0376 }, 0377 // global top toolbar if we are in a PageRow (in the row or as a layer) 0378 Loader { 0379 id: globalToolBar 0380 z: 9999 0381 height: item ? item.implicitHeight : 0 0382 anchors { 0383 left: parent.left 0384 right: parent.right 0385 top: parent.top 0386 } 0387 property Kirigami.PageRow row 0388 property T2.StackView stack 0389 0390 // don't load async so that on slower devices we don't have the page content height changing while loading in 0391 // otherwise, it looks unpolished and jumpy 0392 asynchronous: false 0393 0394 visible: active 0395 active: (root.titleDelegate !== defaultTitleDelegate || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.ToolBar || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.Titles) 0396 onActiveChanged: { 0397 if (active) { 0398 syncSource(); 0399 } 0400 } 0401 0402 function syncSource() { 0403 if (root.globalToolBarStyle !== Kirigami.ApplicationHeaderStyle.ToolBar && 0404 root.globalToolBarStyle !== Kirigami.ApplicationHeaderStyle.Titles && 0405 root.titleDelegate !== defaultTitleDelegate) { 0406 sourceComponent = root.titleDelegate; 0407 } else if (active) { 0408 const url = root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.ToolBar 0409 ? "private/globaltoolbar/ToolBarPageHeader.qml" 0410 : "private/globaltoolbar/TitlesPageHeader.qml"; 0411 // TODO: find container reliably, remove assumption 0412 setSource(Qt.resolvedUrl(url), { 0413 pageRow: Qt.binding(() => row), 0414 page: root, 0415 current: Qt.binding(() => { 0416 if (!row && !stack) { 0417 return true; 0418 } else if (stack) { 0419 return stack; 0420 } else { 0421 return row.currentIndex === root.Kirigami.ColumnView.level; 0422 } 0423 }), 0424 }); 0425 } 0426 } 0427 }, 0428 // bottom action buttons 0429 Loader { 0430 id: actionButtons 0431 z: 9999 0432 parent: root 0433 anchors { 0434 left: parent.left 0435 right: parent.right 0436 bottom: parent.bottom 0437 } 0438 // if the page doesn't inherit, assume it has custom colors we want to use them here too 0439 Kirigami.Theme.inherit: !root.Kirigami.Theme.inherit 0440 Kirigami.Theme.colorSet: Kirigami.Theme.Button 0441 0442 // It should be T2.Page, Qt 5.7 doesn't like it 0443 property Item page: root 0444 height: item ? item.implicitHeight : 0 0445 0446 asynchronous: true 0447 0448 property bool pageComplete: false 0449 0450 active: { 0451 // Important! Do not do anything until the page has been 0452 // completed, so we are sure what the globalToolBarStyle is, 0453 // otherwise we risk creating the content and then discarding it. 0454 if (!pageComplete) { 0455 return false; 0456 } 0457 0458 if ((globalToolBar.row && globalToolBar.row.globalToolBar.actualStyle === Kirigami.ApplicationHeaderStyle.ToolBar) 0459 || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.ToolBar 0460 || root.globalToolBarStyle === Kirigami.ApplicationHeaderStyle.None) { 0461 return false; 0462 } 0463 0464 if (!root.actions.main && !root.actions.left && !root.actions.right && root.actions.contextualActions.length === 0) { 0465 return false; 0466 } 0467 0468 // Legacy 0469 if (typeof applicationWindow === "undefined") { 0470 return true; 0471 } 0472 0473 if (applicationWindow().header && applicationWindow().header.toString().indexOf("ToolBarApplicationHeader") !== -1) { 0474 return false; 0475 } 0476 0477 if (applicationWindow().footer && applicationWindow().footer.toString().indexOf("ToolBarApplicationHeader") !== -1) { 0478 return false; 0479 } 0480 0481 return true; 0482 } 0483 0484 source: Qt.resolvedUrl("./private/ActionButton.qml") 0485 } 0486 ] 0487 0488 Layout.fillWidth: true 0489 }