Warning, /frameworks/kirigami/src/controls/templates/AbstractApplicationHeader.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
0008 import QtQuick.Layouts
0009 import QtQuick.Controls as QQC2
0010 import org.kde.kirigami as Kirigami
0011 import "private"
0012 
0013 /**
0014  * @brief An item that can be used as a title for the application.
0015  *
0016  * Scrolling the main page will make it taller or shorter (through the point of going away)
0017  * It's a behavior similar to the typical mobile web browser addressbar
0018  * the minimum, preferred and maximum heights of the item can be controlled with
0019  * * minimumHeight: default is 0, i.e. hidden
0020  * * preferredHeight: default is Units.gridUnit * 1.6
0021  * * maximumHeight: default is Units.gridUnit * 3
0022  *
0023  * To achieve a titlebar that stays completely fixed just set the 3 sizes as the same
0024  *
0025  * @inherit QtQuick.Item
0026  */
0027 Item {
0028     id: root
0029     z: 90
0030     property int minimumHeight: 0
0031     // Use an inline arrow function, referring to an external normal function makes QV4 crash, see https://bugreports.qt.io/browse/QTBUG-119395
0032     property int preferredHeight: mainItem.children.reduce((accumulator, item) => {
0033         return Math.max(accumulator, item.implicitHeight);
0034     }, 0) + topPadding + bottomPadding
0035     property int maximumHeight: Kirigami.Units.gridUnit * 3
0036 
0037     property int position: QQC2.ToolBar.Header
0038 
0039     property Kirigami.PageRow pageRow: __appWindow?.pageStack ?? null
0040     property Kirigami.Page page: pageRow?.currentItem ?? null
0041 
0042     default property alias contentItem: mainItem.data
0043     readonly property int paintedHeight: headerItem.y + headerItem.height - 1
0044 
0045     property int leftPadding: 0
0046     property int topPadding: 0
0047     property int rightPadding: 0
0048     property int bottomPadding: 0
0049     property bool separatorVisible: true
0050 
0051     /**
0052      * This property specifies whether the header should be pushed back when
0053      * scrolling using the touch screen.
0054      */
0055     property bool hideWhenTouchScrolling: root.pageRow?.globalToolBar.hideWhenTouchScrolling ?? false
0056 
0057     LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
0058     LayoutMirroring.childrenInherit: true
0059 
0060     Kirigami.Theme.inherit: true
0061 
0062     // FIXME: remove
0063     property QtObject __appWindow: typeof applicationWindow !== "undefined" ? applicationWindow() : null
0064     implicitHeight: preferredHeight
0065     height: Layout.preferredHeight
0066 
0067     /**
0068      * @brief This property holds the background item.
0069      * @note the background will be automatically sized to fill the whole control
0070      */
0071     property Item background
0072 
0073     onBackgroundChanged: {
0074         background.z = -1;
0075         background.parent = headerItem;
0076         background.anchors.fill = headerItem;
0077     }
0078 
0079     Component.onCompleted: AppHeaderSizeGroup.items.push(this)
0080 
0081     onMinimumHeightChanged: implicitHeight = preferredHeight;
0082     onPreferredHeightChanged: implicitHeight = preferredHeight;
0083 
0084     opacity: height > 0 ? 1 : 0
0085 
0086     NumberAnimation {
0087         id: heightAnim
0088         target: root
0089         property: "implicitHeight"
0090         duration: Kirigami.Units.longDuration
0091         easing.type: Easing.InOutQuad
0092     }
0093 
0094     Connections {
0095         target: root.__appWindow
0096 
0097         function onControlsVisibleChanged() {
0098             heightAnim.from = root.implicitHeight;
0099             heightAnim.to = root.__appWindow.controlsVisible ? root.preferredHeight : 0;
0100             heightAnim.restart();
0101         }
0102     }
0103 
0104     Connections {
0105         target: root.page?.Kirigami.ColumnView ?? null
0106 
0107         function onScrollIntention(event) {
0108             headerItem.scrollIntentHandler(event);
0109         }
0110     }
0111 
0112     Item {
0113         id: headerItem
0114         anchors {
0115             left: parent.left
0116             right: parent.right
0117             bottom: !Kirigami.Settings.isMobile || root.position === QQC2.ToolBar.Header ? parent.bottom : undefined
0118             top: !Kirigami.Settings.isMobile || root.position === QQC2.ToolBar.Footer ? parent.top : undefined
0119         }
0120 
0121         height: Math.max(root.height, root.minimumHeight > 0 ? root.minimumHeight : root.preferredHeight)
0122 
0123         function scrollIntentHandler(event) {
0124             if (!root.hideWhenTouchScrolling) {
0125                 return
0126             }
0127 
0128             if (root.pageRow
0129                 && root.pageRow.globalToolBar.actualStyle !== Kirigami.ApplicationHeaderStyle.Breadcrumb) {
0130                 return;
0131             }
0132             if (!root.page.flickable || (root.page.flickable.atYBeginning && root.page.flickable.atYEnd)) {
0133                 return;
0134             }
0135 
0136             root.implicitHeight = Math.max(0, Math.min(root.preferredHeight, root.implicitHeight + event.delta.y))
0137             event.accepted = root.implicitHeight > 0 && root.implicitHeight < root.preferredHeight;
0138             slideResetTimer.restart();
0139             if ((root.page.flickable instanceof ListView) && root.page.flickable.verticalLayoutDirection === ListView.BottomToTop) {
0140                 root.page.flickable.contentY -= event.delta.y;
0141             }
0142         }
0143 
0144         Connections {
0145             target: root.page?.globalToolBarItem ?? null
0146             enabled: target
0147             function onImplicitHeightChanged() {
0148                 root.implicitHeight = root.page.globalToolBarItem.implicitHeight;
0149             }
0150         }
0151 
0152         Timer {
0153            id: slideResetTimer
0154            interval: 500
0155            onTriggered: {
0156                 if ((root.pageRow?.wideMode ?? (root.__appWindow?.wideScreen ?? false)) || !Kirigami.Settings.isMobile) {
0157                     return;
0158                 }
0159                 if (root.height > root.minimumHeight + (root.preferredHeight - root.minimumHeight) / 2) {
0160                     heightAnim.to = root.preferredHeight;
0161                 } else {
0162                     heightAnim.to = root.minimumHeight;
0163                 }
0164                 heightAnim.from = root.implicitHeight
0165                 heightAnim.restart();
0166             }
0167         }
0168 
0169         Connections {
0170             target: pageRow
0171             function onCurrentItemChanged() {
0172                 if (!root.page) {
0173                     return;
0174                 }
0175 
0176                 heightAnim.from = root.implicitHeight;
0177                 heightAnim.to = root.preferredHeight;
0178 
0179                 heightAnim.restart();
0180             }
0181         }
0182 
0183         Item {
0184             id: mainItem
0185             clip: childrenRect.width > width
0186 
0187             onChildrenChanged: {
0188                 for (const child of children) {
0189                     child.anchors.verticalCenter = verticalCenter;
0190                 }
0191             }
0192 
0193             anchors {
0194                 fill: parent
0195                 topMargin: root.topPadding
0196                 leftMargin: root.leftPadding
0197                 rightMargin: root.rightPadding
0198                 bottomMargin: root.bottomPadding
0199             }
0200         }
0201     }
0202 }