MauiKit Controls

ToolBar.qml
1/*
2 * Copyright 2018 Camilo Higuita <milo.h@aol.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20import QtQuick
21import QtQuick.Controls as QQC
22import QtQuick.Window
23
24import org.mauikit.controls as Maui
25
26import QtQuick.Layouts
27
28import "private" as Private
29
30/**
31 * @inherit QtQuick.Controls.ToolBar
32 * @brief An alternative to QQC2 ToolBar, with a custom horizontal layout - divided into three main sections - left, middle and right.
33 *
34 * This is a good companion to a page header or footer.
35 *
36 * <a href="https://doc.qt.io/qt-6/qml-qtquick-controls-toolbar.html">This control inherits from QQC2 ToolBar, to checkout its inherited properties refer to the Qt Docs.</a>
37 *
38 * @code
39 * QQC2.Page
40 * {
41 * header: ToolBar
42 * {
43 * width: parent.width
44 *
45 * ToolButton
46 * {
47 * icon.name: "love"
48 * }
49 * }
50 * }
51 * @endcode
52 *
53 * The ToolBar sections are divided into five [5] sections, and each one can be easily populated via the alias property. The left and right areas are have two sections, the far-left and far-right, alongside with the left and right.
54 * @see farLeftContent
55 * @see leftContent
56 * @see middleContent
57 * @see rightContent
58 * @see farRightContent
59 *
60 * And lastly there's the middle section - the middle section contents can be centered using the Layout attached properties.
61 * When the left and right contents are not equal in size, the middle content can be forced to be centered using the force center property.
62 * @see forceCenterMiddleContent
63 *
64 * @image html ToolBar/footbar_sections_color.png
65 * @note The ToolBar sections divided by colors. The middle section [green] is filling the available space.
66 *
67 * The bar contents will become flickable/scrollable when the child items do not fit in the available space. There will be shadows indicating that there is content to be discovered to the left or right sides.
68 * @see fits
69 *
70 * If the application window is using CSD - there is a useful property to allow dragging and moving the window by pressing the toolbar area. This can also be disabled if it is undesired.
71 * @see draggable
72 *
73 * @section notes Notes
74 * The middle section is handled by a RowLayout, so child items placed in there can be positioned using the Layout attached properties, such as Layout.fillWidth, Layout.alignment, etc.
75 *
76 * The other sections will take the size of child items, so any item place into them need to have an implicit size or explicitly set one.
77 *
78 * The far left/right sections will not be hidden when the contents of the bar does not fit and becomes scrollable, They will remain in place, so place items in those section which are important to stay always visible, and do not over populate them, instead populate the left and right areas.
79 *
80 * @image html ToolBar/footbar_fit.png
81 * @note Here the contents of the bar does not fit, so it becomes hidden and can be scrolled/flicked horizontally.
82 *
83 * @code
84 * ToolBar
85 * {
86 * farLeftContent: ToolButton
87 * {
88 * icon.name: "love"
89 * }
90 *
91 * leftContent: ToolButton
92 * {
93 * icon.name: "folder"
94 * }
95 *
96 * middleContent: ToolButton
97 * {
98 * icon.name: "folder-music"
99 * Layout.alignment: Qt.AlignHCenter
100 * }
101 *
102 * rightContent: ToolButton
103 * {
104 * icon.name: "download"
105 * }
106 *
107 * farRightContent: ToolButton
108 * {
109 * icon.name: "application-menu"
110 * }
111 * }
112 * @endcode
113 *
114 * @note This control supports the attached Controls.showCSD property to display the window control buttons when using CSD.
116 *
117 * @image html ToolBar/footbar_sections.png
118 * @note Using the example as the footer of a page, ToolButtons are placed in the different sections.
119 *
120 */
121QQC.ToolBar
122{
123 id: control
124
125 implicitHeight: preferredHeight + topPadding + bottomPadding
126
127 /**
128 * @brief By default any child item of the ToolBar will be positioned at the left section in a row. So using the leftContent property or just declaring the child items without it will have the same effect.
129 * @see leftContent
130 */
131 default property alias content : leftRowContent.content
132
133 /**
134 * @brief Set the preferred height of the toolbar. This is the preferred way to set a custom height, instead of setting it up explicitly via the height property. This is used, for example, on the Page control for the pull-back bars feature.
135 */
136 property int preferredHeight: implicitContentHeight
137
138 /**
139 * @brief Forces the middle content to be centered by adding extra space at the left and right sections to match the maximum width, so both left/right side have the same width.
140 */
141 property bool forceCenterMiddleContent : true
142
143 /**
144 * @brief Alias to add items to the left section. Multiple items can be added, separated by a coma and wrapped in brackets [].
145 * @property list<QtObject> ToolBar::leftContent
146 *
147 * @code
148 * leftContent: [
149 * Button
150 * {
151 * text: "Test"
152 * },
153 *
154 * Button
155 * {
156 * text: "Hello"
157 * }
158 * ]
159 * @endcode
160 */
161 property alias leftContent : leftRowContent.content
162
163 /**
164 * @brief Alias to add items to the middle section. Multiple items can be added, separated by a coma and wrapped in brackets [].
165 * The container used to host the child items is a ColumnLayout, so child items need to be positioned using the Layout attached properties.
166 * @property list<QtObject> ToolBar::middleContent
167 */
168 property alias middleContent : middleRowContent.data
169
170 /**
171 * @brief Alias to add items to the right section. Multiple items can be added, separated by a coma and wrapped in brackets [].
172 * @property list<QtObject> ToolBar::rightContent
173 */
174 property alias rightContent : rightRowContent.content
175
176 /**
177 * @brief Alias to add items to the far left section. Multiple items can be added, separated by a coma and wrapped in brackets [].
178 * @property list<QtObject> ToolBar::farLeftContent
179 */
180 property alias farLeftContent : farLeftRowContent.content
181
182 /**
183 * @brief Alias to add items to the far right section. Multiple items can be added, separated by a coma and wrapped in brackets [].
184 * @property list<QtObject> ToolBar::farRightContent
185 */
186 property alias farRightContent : farRightRowContent.content
187
188 /**
189 * @brief The container for the middle section. Some of its properties can be tweaked, such as the spacing and visibility.
190 * @property ColumnLayout ToolBar::middleLayout
191 */
192 readonly property alias middleLayout : middleRowContent
193
194 /**
195 * @brief The container for the left section. Some of its properties can be tweaked, such as the spacing and visibility.
196 * @property Item ToolBar::leftLayout
197 */
198 readonly property alias leftLayout : leftRowContent
199
200 /**
201 * @brief The container for the right section. Some of its properties can be tweaked, such as the spacing and visibility.
202 * @property Item ToolBar::rightLayout
203 */
204 readonly property alias rightLayout : rightRowContent
205
206 /**
207 * @brief The container for the far right section. Some of its properties can be tweaked, such as the spacing and visibility.
208 * @property Item ToolBar::farRightLayout
209 */
210 readonly property alias farRightLayout : farRightRowContent
211
212 /**
213 * @brief The container for the far left section. Some of its properties can be tweaked, such as the spacing and visibility.
214 * @property Item ToolBar::farLeftLayout
215 */
216 readonly property alias farLeftLayout : farLeftRowContent
218 /**
219 * @brief The ColumnLayout that contains all the sections of the toolbar.
220 * @property ColumnLayout ToolBar::layout
221 */
222 readonly property alias layout : layout
223
224 /**
225 * @brief If the contents width is currently smaller then the available area it means that it fits, otherwise the content is wider then the available area and overflowing and has become scrollable/flickable.
226 */
227 readonly property alias fits : _scrollView.fits
228
229 /**
230 * @brief The total amount of items in the toolbar sections, items can be non-visible and sum-up.
231 */
232 readonly property int count : leftContent.length + middleContent.length + rightContent.length + farLeftContent.length + farRightContent.length
233
234 /**
235 * @brief The total amount of visible items in the tool bar sections.
236 */
237 readonly property int visibleCount : leftRowContent.visibleChildren.length + middleRowContent.visibleChildren.length + rightRowContent.visibleChildren.length + farLeftRowContent.visibleChildren.length + farRightRowContent.visibleChildren.length
238
239 /**
240 * @brief Allow to move the window around by dragging from the toolbar area.
241 * By default this is set to `!Maui.Handy.isMobile`
242 */
243 property bool draggable : !Maui.Handy.isMobile
244
245 Loader
246 {
247 asynchronous: true
248 width: Maui.Style.iconSizes.medium
249 height: parent.height
250 active: !mainFlickable.atXEnd && !control.fits
251 visible: active
252 z: 999
253 parent: control.background
254 anchors
255 {
256 right: parent.right
257 top: parent.top
258 bottom: parent.bottom
259 }
260
261 sourceComponent: Maui.EdgeShadow
262 {
263 edge: Qt.RightEdge
264 }
265 }
266
267 Loader
268 {
269 parent: control.background
270 asynchronous: true
271 width: Maui.Style.iconSizes.medium
272 height: parent.height
273 active: !mainFlickable.atXBeginning && !control.fits
274 visible: active
275 z: 999
276 anchors
277 {
278 left: parent.left
279 top: parent.top
280 bottom: parent.bottom
281 }
282
283 sourceComponent: Maui.EdgeShadow
284 {
285 edge: Qt.LeftEdge
286 }
287 }
288
289 contentItem: Item
290 {
291 implicitWidth: _mainLayout.implicitWidth
292 implicitHeight: _mainLayout.implicitHeight
293 clip: true
294
295 Item
296 {
297 id: _container
298 height: control.preferredHeight
299 width: parent.width
300
301 property bool isHeader: control.position === ToolBar.Header
302 state: isHeader? "headerState" : "footerState"
303
304 Loader
305 {
306 active: control.draggable
307 asynchronous: true
308 anchors.fill: parent
309 sourceComponent: Item
310 {
311 TapHandler
312 {
313 onTapped: if (tapCount === 2) toggleMaximized()
314 gesturePolicy: TapHandler.DragThreshold
315 }
316
317 DragHandler
318 {
319 target: null
320 grabPermissions: TapHandler.CanTakeOverFromAnything
321 onActiveChanged: if (active) { control.Window.window.startSystemMove(); }
322 }
323 }
324 }
325
326 states: [State
327 {
328 name: "headerState"
329
330 AnchorChanges
331 {
332 target: _container
333 anchors.top: undefined
334 anchors.bottom: parent.bottom
335 }
336 },
337
338 State
339 {
340 name: "footerState"
341
342 AnchorChanges
343 {
344 target: _container
345 anchors.top: parent.top
346 anchors.bottom: undefined
347 }
348 }
349 ]
350
351 RowLayout
352 {
353 id: _mainLayout
354 anchors.fill: parent
355 spacing: control.spacing
356
357 Private.ToolBarSection
358 {
359 id: farLeftRowContent
360 Layout.fillHeight: true
361 Layout.maximumWidth: implicitWidth
362 Layout.minimumWidth: implicitWidth
363 spacing: control.spacing
364 Layout.preferredWidth: visible ? implicitWidth: -control.spacing
365 }
366
367 QQC.ScrollView
368 {
369 id: _scrollView
370 padding: 0
371 implicitHeight: layout.implicitHeight + topPadding + bottomPadding
372 readonly property bool fits : contentWidth < width
373 onFitsChanged: mainFlickable.returnToBounds()
374
375 Layout.fillHeight: true
376 Layout.fillWidth: true
377
378 contentWidth: layout.implicitWidth
379 contentHeight: availableHeight
380
381 Maui.Controls.orientation : Qt.Horizontal
382
383 QQC.ScrollBar.horizontal.policy: QQC.ScrollBar.AlwaysOff
384 QQC.ScrollBar.vertical.policy: QQC.ScrollBar.AlwaysOff
385
386 Flickable
387 {
388 id: mainFlickable
389
390 flickableDirection: Flickable.HorizontalFlick
391 interactive: !control.fits && Maui.Handy.isTouch
392
393 boundsBehavior: Flickable.StopAtBounds
394 boundsMovement :Flickable.StopAtBounds
395
396 clip: true
397
398 RowLayout
399 {
400 id: layout
401
402 width: _scrollView.availableWidth
403 height: _scrollView.availableHeight
404
405 spacing: control.spacing
406
407 Private.ToolBarSection
408 {
409 id: leftRowContent
410
411 Layout.fillHeight: true
412
413 Layout.maximumWidth: implicitWidth
414 Layout.minimumWidth: implicitWidth
415 Layout.preferredWidth: visible ? implicitWidth: -control.spacing
416 //
417 spacing: control.spacing
418 }
419
420 // Item //helper to force center middle content
421 // {
422 // id: _h1
423 // visible: middleRowContent.visibleChildren.length && control.forceCenterMiddleContent
424 //
425 // readonly property int mwidth : visible ? Math.max((rightRowContent.implicitWidth + farRightRowContent.implicitWidth) - (leftRowContent.implicitWidth + farLeftRowContent.implicitWidth), 0) : 0
426 //
427 // Layout.minimumWidth: 0
428 //
429 // Layout.preferredWidth: mwidth
430 // Layout.maximumWidth: mwidth
431 //
432 // Layout.fillHeight: true
433 // Layout.fillWidth: true
434 // }
435
436 Item
437 {
438 Layout.fillWidth: true
439 Layout.fillHeight: true
440 Layout.minimumWidth: implicitWidth
441 implicitWidth: middleRowContent.implicitWidth
442 implicitHeight: middleRowContent.implicitHeight
443 // color: "yellow"
444 RowLayout
445 {
446 id: middleRowContent
447 anchors.fill: parent
448 spacing: control.spacing
449 }
450 }
451
452 // Item //helper to force center middle content
453 // {
454 // id: _h2
455 // visible: middleRowContent.visibleChildren.length && control.forceCenterMiddleContent
456 //
457 // readonly property int mwidth : visible ? Math.max(( leftRowContent.implicitWidth + farLeftRowContent.implicitWidth) - (rightRowContent.implicitWidth + farRightRowContent.implicitWidth), 0) : 0
458 //
459 // Layout.minimumWidth: 0
460 //
461 // Layout.fillHeight: true
462 // Layout.fillWidth: true
463 //
464 // Layout.preferredWidth: mwidth
465 // Layout.maximumWidth: mwidth
466 // }
467
468 Private.ToolBarSection
469 {
470 id: rightRowContent
471
472 Layout.fillHeight: true
473
474 Layout.maximumWidth: implicitWidth
475 Layout.minimumWidth: implicitWidth
476 Layout.preferredWidth: visible ? implicitWidth: -control.spacing
477
478 spacing: control.spacing
479 }
480 }
481 }
482 }
483
484 Private.ToolBarSection
485 {
486 id: farRightRowContent
487 Layout.fillHeight: true
488 Layout.maximumWidth: implicitWidth
489 Layout.minimumWidth: implicitWidth
490 spacing: control.spacing
491 Layout.preferredWidth: visible ? implicitWidth: -control.spacing
492 }
493
494 Loader
495 {
496 id: _csdLoader
497 active: control.Maui.Controls.showCSD === true && control.position === ToolBar.Header
498 visible: active
499
500 OpacityAnimator on opacity
501 {
502 from: 0
503 to: 1
504 duration: Maui.Style.units.longDuration * 2
505 running: _csdLoader.status === Loader.Ready
506 }
507
508 asynchronous: true
509
510 sourceComponent: Maui.WindowControls {}
511 }
512 }
513 }
514 }
515}
An alternative to QQC2 ToolBar, with a custom horizontal layout - divided into three main sections - ...
Definition ToolBar.qml:115
int preferredHeight
Set the preferred height of the toolbar.
Definition ToolBar.qml:127
alias rightLayout
The container for the right section.
Definition ToolBar.qml:189
alias farRightLayout
The container for the far right section.
Definition ToolBar.qml:195
int count
The total amount of items in the toolbar sections, items can be non-visible and sum-up.
Definition ToolBar.qml:217
alias farLeftLayout
The container for the far left section.
Definition ToolBar.qml:201
alias middleContent
Alias to add items to the middle section.
Definition ToolBar.qml:156
bool forceCenterMiddleContent
Forces the middle content to be centered by adding extra space at the left and right sections to matc...
Definition ToolBar.qml:131
alias fits
If the contents width is currently smaller then the available area it means that it fits,...
Definition ToolBar.qml:212
alias leftLayout
The container for the left section.
Definition ToolBar.qml:183
alias farRightContent
Alias to add items to the far right section.
Definition ToolBar.qml:171
alias middleLayout
The container for the middle section.
Definition ToolBar.qml:177
int visibleCount
The total amount of visible items in the tool bar sections.
Definition ToolBar.qml:222
bool draggable
Allow to move the window around by dragging from the toolbar area.
Definition ToolBar.qml:227
alias rightContent
Alias to add items to the right section.
Definition ToolBar.qml:161
alias content
By default any child item of the ToolBar will be positioned at the left section in a row.
Definition ToolBar.qml:123
alias layout
The ColumnLayout that contains all the sections of the toolbar.
Definition ToolBar.qml:207
alias leftContent
Alias to add items to the left section.
Definition ToolBar.qml:150
alias farLeftContent
Alias to add items to the far left section.
Definition ToolBar.qml:166
QString name(StandardAction id)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri May 2 2025 11:57:11 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.