Kirigami2

controls/templates/AbstractApplicationHeader.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.Controls as QQC2
10import org.kde.kirigami as Kirigami
11
12/**
13 * @brief An item that can be used as a title for the application.
14 *
15 * Scrolling the main page will make it taller or shorter (through the point of going away)
16 * It's a behavior similar to the typical mobile web browser addressbar
17 * the minimum, preferred and maximum heights of the item can be controlled with
18 * * minimumHeight: default is 0, i.e. hidden
19 * * preferredHeight: default is Units.gridUnit * 1.6
20 * * maximumHeight: default is Units.gridUnit * 3
21 *
22 * To achieve a titlebar that stays completely fixed just set the 3 sizes as the same
23 *
24 * @inherit QtQuick.Item
25 */
26Item {
27 id: root
28 z: 90
29 property int minimumHeight: 0
30 // Use an inline arrow function, referring to an external normal function makes QV4 crash, see https://bugreports.qt.io/browse/QTBUG-119395
31 property int preferredHeight: mainItem.children.reduce((accumulator, item) => {
32 return Math.max(accumulator, item.implicitHeight);
33 }, 0) + topPadding + bottomPadding
34 property int maximumHeight: Kirigami.Units.gridUnit * 3
35
36 property int position: QQC2.ToolBar.Header
37
38 // These properties are items due to issues with multiple engine type registration
39 // The stronger types can probably be used after we depend on Qt 6.9
40 property /*Kirigami.PageRow*/ Item pageRow: __appWindow?.pageStack ?? null
41 property /*Kirigami.Page*/ Item page: pageRow?.currentItem as Kirigami.Page ?? null
42
43 default property alias contentItem: mainItem.data
44 readonly property int paintedHeight: headerItem.y + headerItem.height - 1
46 property int leftPadding: 0
47 property int topPadding: 0
48 property int rightPadding: 0
49 property int bottomPadding: 0
50 property bool separatorVisible: true
51
52 /**
53 * This property specifies whether the header should be pushed back when
54 * scrolling using the touch screen.
55 */
56 property bool hideWhenTouchScrolling: root.pageRow?.globalToolBar.hideWhenTouchScrolling ?? false
57
58 LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
59 LayoutMirroring.childrenInherit: true
60
61 Kirigami.Theme.inherit: true
62
63 // FIXME: remove
64 property QtObject __appWindow: typeof applicationWindow !== "undefined" ? applicationWindow() : null
65 implicitHeight: preferredHeight
66 height: Layout.preferredHeight
67
68 /**
69 * @brief This property holds the background item.
70 * @note the background will be automatically sized to fill the whole control
71 */
72 property Item background
73
74 onBackgroundChanged: {
75 background.z = -1;
76 background.parent = headerItem;
77 background.anchors.fill = headerItem;
78 }
79
80 Component.onCompleted: AppHeaderSizeGroup.items.push(this)
81
82 onMinimumHeightChanged: implicitHeight = preferredHeight;
83 onPreferredHeightChanged: implicitHeight = preferredHeight;
84
85 opacity: height > 0 ? 1 : 0
86
87 NumberAnimation {
88 id: heightAnim
89 target: root
90 property: "implicitHeight"
91 duration: Kirigami.Units.longDuration
92 easing.type: Easing.InOutQuad
93 }
94
95 Connections {
96 target: root.__appWindow
97
98 function onControlsVisibleChanged() {
99 heightAnim.from = root.implicitHeight;
100 heightAnim.to = root.__appWindow.controlsVisible ? root.preferredHeight : 0;
101 heightAnim.restart();
102 }
103 }
104
105 Connections {
106 target: root.page?.Kirigami.ColumnView ?? null
107
108 function onScrollIntention(event) {
109 headerItem.scrollIntentHandler(event);
110 }
111 }
112
113 Item {
114 id: headerItem
115 anchors {
116 left: parent.left
117 right: parent.right
118 bottom: !Kirigami.Settings.isMobile || root.position === QQC2.ToolBar.Header ? parent.bottom : undefined
119 top: !Kirigami.Settings.isMobile || root.position === QQC2.ToolBar.Footer ? parent.top : undefined
120 }
121
122 height: Math.max(root.height, root.minimumHeight > 0 ? root.minimumHeight : root.preferredHeight)
123
124 function scrollIntentHandler(event) {
125 if (!root.hideWhenTouchScrolling) {
126 return
127 }
128
129 if (root.pageRow
130 && root.pageRow.globalToolBar.actualStyle !== Kirigami.ApplicationHeaderStyle.Breadcrumb) {
131 return;
132 }
133 if (!root.page.flickable || (root.page.flickable.atYBeginning && root.page.flickable.atYEnd)) {
134 return;
135 }
136
137 root.implicitHeight = Math.max(0, Math.min(root.preferredHeight, root.implicitHeight + event.delta.y))
138 event.accepted = root.implicitHeight > 0 && root.implicitHeight < root.preferredHeight;
139 slideResetTimer.restart();
140 if ((root.page.flickable instanceof ListView) && root.page.flickable.verticalLayoutDirection === ListView.BottomToTop) {
141 root.page.flickable.contentY -= event.delta.y;
142 }
143 }
144
145 Connections {
146 target: root.page?.globalToolBarItem ?? null
147 enabled: target
148 function onImplicitHeightChanged() {
149 root.implicitHeight = root.page.globalToolBarItem.implicitHeight;
150 }
151 }
152
153 Timer {
154 id: slideResetTimer
155 interval: 500
156 onTriggered: {
157 if ((root.pageRow?.wideMode ?? (root.__appWindow?.wideScreen ?? false)) || !Kirigami.Settings.isMobile) {
158 return;
159 }
160 if (root.height > root.minimumHeight + (root.preferredHeight - root.minimumHeight) / 2) {
161 heightAnim.to = root.preferredHeight;
162 } else {
163 heightAnim.to = root.minimumHeight;
164 }
165 heightAnim.from = root.implicitHeight
166 heightAnim.restart();
167 }
168 }
169
170 Connections {
171 target: pageRow
172 function onCurrentItemChanged() {
173 if (!root.page) {
174 return;
175 }
176
177 heightAnim.from = root.implicitHeight;
178 heightAnim.to = root.preferredHeight;
179
180 heightAnim.restart();
181 }
182 }
183
184 Item {
185 id: mainItem
186 clip: childrenRect.width > width
187
188 onChildrenChanged: {
189 for (const child of children) {
190 child.anchors.verticalCenter = verticalCenter;
191 }
192 }
193
194 anchors {
195 fill: parent
196 topMargin: root.topPadding
197 leftMargin: root.leftPadding
198 rightMargin: root.rightPadding
199 bottomMargin: root.bottomPadding
200 }
201 }
202 }
203}
bool hideWhenTouchScrolling
This property specifies whether the header should be pushed back when scrolling using the touch scree...
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri May 2 2025 12:02:16 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.