Kirigami2

NavigationTabBar.qml
1 /*
2  * Copyright 2021 Devin Lin <[email protected]>
3  *
4  * SPDX-License-Identifier: LGPL-2.0-or-later
5  */
6 
7 import QtQuick 2.15
8 import QtQml 2.15
9 import QtQuick.Templates 2.15 as T
10 import QtQuick.Layouts 1.15
11 import org.kde.kirigami 2.19 as Kirigami
12 import QtGraphicalEffects 1.12
13 
14 /**
15  * @brief Page navigation tab-bar, used as an alternative to sidebars for 3-5 elements.
16  *
17  * Can be combined with secondary toolbars above (if in the footer) to provide page actions.
18  *
19  * Example usage:
20  * @code{.qml}
21  * import org.kde.kirigami 2.19 as Kirigami
22  *
23  * import QtQuick 2.15
24  * import QtQuick.Controls 2.15
25  * import QtQuick.Layouts 1.15
26  * import org.kde.kirigami 2.19 as Kirigami
27  *
28  * Kirigami.ApplicationWindow {
29  * title: "Clock"
30  *
31  * pageStack.initialPage: worldPage
32  * Kirigami.Page {
33  * id: worldPage
34  * title: "World"
35  * visible: false
36  * }
37  * Kirigami.Page {
38  * id: timersPage
39  * title: "Timers"
40  * visible: false
41  * }
42  * Kirigami.Page {
43  * id: stopwatchPage
44  * title: "Stopwatch"
45  * visible: false
46  * }
47  * Kirigami.Page {
48  * id: alarmsPage
49  * title: "Alarms"
50  * visible: false
51  * }
52  *
53  *
54  * footer: Kirigami.NavigationTabBar {
55  * actions: [
56  * Kirigami.Action {
57  * iconName: "globe"
58  * text: "World"
59  * checked: worldPage.visible
60  * onTriggered: {
61  * if (!worldPage.visible) {
62  * while (pageStack.depth > 0) {
63  * pageStack.pop();
64  * }
65  * pageStack.push(worldPage);
66  * }
67  * }
68  * },
69  * Kirigami.Action {
70  * iconName: "player-time"
71  * text: "Timers"
72  * checked: timersPage.visible
73  * onTriggered: {
74  * if (!timersPage.visible) {
75  * while (pageStack.depth > 0) {
76  * pageStack.pop();
77  * }
78  * pageStack.push(timersPage);
79  * }
80  * }
81  * },
82  * Kirigami.Action {
83  * iconName: "chronometer"
84  * text: "Stopwatch"
85  * checked: stopwatchPage.visible
86  * onTriggered: {
87  * if (!stopwatchPage.visible) {
88  * while (pageStack.depth > 0) {
89  * pageStack.pop();
90  * }
91  * pageStack.push(stopwatchPage);
92  * }
93  * }
94  * },
95  * Kirigami.Action {
96  * iconName: "notifications"
97  * text: "Alarms"
98  * checked: alarmsPage.visible
99  * onTriggered: {
100  * if (!alarmsPage.visible) {
101  * while (pageStack.depth > 0) {
102  * pageStack.pop();
103  * }
104  * pageStack.push(alarmsPage);
105  * }
106  * }
107  * }
108  * ]
109  * }
110  * }
111  *
112  * @endcode
113  *
114  * @see NavigationTabButton
115  * @since 5.87
116  * @since org.kde.kirigami 2.19
117  * @inherit QtQuick.Templates.Toolbar
118  */
119 
120 T.ToolBar {
121  id: root
122 
123 //BEGIN properties
124  /**
125  * @brief This property holds the list of actions displayed in the toolbar.
126  */
127  property list<Kirigami.Action> actions
128 
129  /**
130  * @brief The property holds the maximum width of the toolbar actions, before margins are added.
131  */
132  property real maximumContentWidth: {
133  let minDelegateWidth = Kirigami.Units.gridUnit * 5;
134  // always have at least the width of 5 items (so small amounts of actions look natural)
135  return Math.max(minDelegateWidth * actions.length, minDelegateWidth * 5);
136  }
137 
138  /**
139  * @brief This property holds the background color of the toolbar.
140  *
141  * default: ``Kirigami.Theme.highlightColor``
142  */
143  property color backgroundColor: Kirigami.Theme.backgroundColor
144 
145  /**
146  * @brief This property holds the foreground color of the toolbar (text, icon).
147  */
148  property color foregroundColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.85)
149 
150  /**
151  * @brief This property holds the highlight foreground color (text, icon when action is checked).
152  */
153  property color highlightForegroundColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.85)
154 
155  /**
156  * @brief This property holds the color of the highlight bar when an action is checked.
157  *
158  * default: ``Kirigami.Theme.highlightColor``
159  */
160  property color highlightBarColor: Kirigami.Theme.highlightColor
161 
162  /**
163  * @brief This property sets whether the toolbar should provide its own shadow.
164  *
165  * default: ``true``
166  */
167  property bool shadow: true
168 
169  /**
170  * @brief This property holds the index of currently checked tab.
171  *
172  * If the index set is out of bounds, or the triggered signal did not change any checked property of an action, the index
173  * will remain the same.
174  */
175  property int currentIndex: tabGroup.checkedButton && tabGroup.buttons.length > 0 ? tabGroup.checkedButton.tabIndex : -1
176 
177  /**
178  * @brief This property holds the number of tab buttons.
179  */
180  readonly property int count: tabGroup.buttons.length
181 
182  /**
183  * @brief This property holds the ButtonGroup used to manage the tabs.
184  */
185  readonly property T.ButtonGroup tabGroup: tabGroup
186 
187  /**
188  * @brief This property sets whether the icon colors should be masked with a single color.
189  *
190  * This only applies to buttons generated by the actions property.
191  *
192  * default: ``true``
193  *
194  * @since 5.96
195  */
196  property bool recolorIcons: true
197 //END properties
198 
199  onCurrentIndexChanged: {
200  if (currentIndex === -1) {
201  if (tabGroup.checkState !== Qt.Unchecked) {
202  tabGroup.checkState = Qt.Unchecked;
203  }
204  return;
205  }
206  if (tabGroup.checkedButton.tabIndex !== currentIndex) {
207  const buttonForCurrentIndex = tabGroup.buttons[currentIndex]
208  if (buttonForCurrentIndex.action) {
209  // trigger also toggles and causes clicked() to be emitted
210  buttonForCurrentIndex.action.trigger();
211  } else {
212  // toggle() does not trigger the action,
213  // so don't use it if you want to use an action.
214  // It also doesn't cause clicked() to be emitted.
215  buttonForCurrentIndex.toggle();
216  }
217  }
218  }
219 
220  // Using Math.round() on horizontalPadding can cause the contentItem to jitter left and right when resizing the window.
221  horizontalPadding: Math.floor(Math.max(0, width - root.maximumContentWidth) / 2)
222  contentWidth: Math.ceil(Math.min(root.availableWidth, root.maximumContentWidth))
223  implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, contentWidth + leftPadding + rightPadding)
224  implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding)
225 
226  Kirigami.Theme.colorSet: Kirigami.Theme.Window
227 
228  background: Rectangle { // color & shadow
229  implicitHeight: Kirigami.Units.gridUnit * 3 + Kirigami.Units.smallSpacing * 2
230  color: root.backgroundColor
231  RectangularGlow {
232  anchors.fill: parent
233  z: -1
234  visible: root.shadow
235  glowRadius: 5
236  spread: 0.3
237  color: Qt.rgba(0.0, 0.0, 0.0, 0.15)
238  }
239  }
240 
241  // Using Row because setting just width is more convenient than having to set Layout.minimumWidth and Layout.maximumWidth
242  contentItem: Row {
243  id: rowLayout
244  spacing: root.spacing
245  }
246 
247  // Used to manage which tab is checked and change the currentIndex
248  T.ButtonGroup {
249  id: tabGroup
250  exclusive: true
251  buttons: root.contentItem.children
252 
253  onCheckedButtonChanged: {
254  if (!checkedButton) {
255  return
256  }
257  if (root.currentIndex !== checkedButton.tabIndex) {
258  root.currentIndex = checkedButton.tabIndex;
259  }
260  }
261  }
262 
263  // Using an Instantiator instead of a Repeater allows us to use parent.visibleChildren.length without including a Repeater in that count.
264  Instantiator {
265  id: instantiator
266  model: root.actions
267  delegate: NavigationTabButton {
268  id: delegate
269  parent: root.contentItem
270  action: modelData
271  visible: modelData.visible
272  recolorIcon: root.recolorIcons
273  T.ButtonGroup.group: tabGroup
274  // Workaround setting the action when checkable is not explicitly set making tabs uncheckable
275  onActionChanged: action.checkable = true
276 
277  foregroundColor: root.foregroundColor
278  highlightForegroundColor: root.highlightForegroundColor
279  highlightBarColor: root.highlightBarColor
280  }
281  }
282 }
283 
284 
Navigation buttons to be used for the NavigationTabBar component.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Tue Aug 16 2022 03:57:01 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.