MauiKit Controls

TabView.qml
1import QtQuick
2import QtQml
3
4import QtQuick.Controls
5import QtQuick.Layouts
6import QtQuick.Effects
7
8import org.mauikit.controls as Maui
9
10/**
11 * @brief Container to organize items as a tab view.
12 *
13 * <a href="https://doc.qt.io/qt-6/qml-qtquick-controls-pane.html">This controls inherits from QQC2 Pane, to checkout its inherited properties refer to the Qt Docs.</a>
14 *
15 * The TabView organizes its children into different tabs - a tab for each child.
16 * There are two ways for adding tabs to this view. The first one and easier is to declare the items as children. This will create a tab for each declared child item.
17 * @see content
18 *
19 * @code
20 * TabView
21 * {
22 * Rectangle
23 * {
24 * Controls.title: "Tab1"
25 * Controls.iconName: "folder"
26 * color: "blue"
27 * }
28 *
29 * Rectangle
30 * {
31 * Controls.title: "Tab2"
32 * Controls.iconName: "folder"
33 * color: "yellow"
34 * }
35 * }
36 * @endcode
37 *
38 * The second way to create tabs dynamically by adding new items using the control functions.
39 * @see addTab
40 *
41 * @code
42 * TabView
43 * {
44 * id: _tabView
45 * tabBar.leftContent: Button
46 * {
47 * text: "Add Tab"
48 * onClicked:
49 * {
50 * _tabView.addTab(_component)
51 * }
52 * }
53 *
54 * Component
55 * {
56 * id: _component
57 * Rectangle
58 * {
59 * Controls.title: "Tab1"
60 * Controls.iconName: "folder"
61 * color: "blue"
62 * }
63 * }
64 * }
65 * @endcode
66 *
67 * @section structure Structure
68 *
69 * @note If you use this as the application window main control, remember you can use the attached Controls.showCSD property to display the window control buttons.
70 * @code
71 * TabView
72 * {
73 * Controls.showCSD : true
74 * }
75 * @endcode
76 *
77 * The TabView has two main sections, [1] the main contents area and [2] the tab bar, where the tab buttons - representing all the tab views - are listed.
78 *
79 * The tab bar listing has two "modes": one designed to fit desktop computers as a horizontal set of tab buttons; and the other one - more mobile friendly - as a grid overview of miniatures of the tab-views. Both modes can be toggle by using the mobile property.
80 * @see mobile
81 *
82 * The main tab bar - usually in the top section - can be moved to the bottom area, for better reachability.
83 * @see altTabBar
84 *
85 * The tab bar component is exposed via an alias, and items can be added to it - to the left or right side, using the leftContent or rightContent properties. This tab bar is handled by a MauiKit TabBar.
86 * @see tabBar
87 * @see TabBar
88 *
89 * @image html TabView/tabviews.png "TabView different states/sections. Further down the regular tab view with a tab bar on top, in the middle the tab view overview mode, and in the front the mobile mode with a single tab - other tab buttons can be flicked."
90 *
91 * @subsection finder Finder
92 * The TabView has an integrated dialog to quickly perform searchers for an tab.
93 *
94 * @section notes Notes
95 *
96 * @subsection tabinfo Tabs Info
97 * To add information, such as title, icon, etc, to the views, there is the `Controls` metadata attached property.
98 * Some of the available properties are:
99 * - Controls.title
100 * - Controls.toolTipText
101 * - Controls.color
102 * - Controls.iconName
103 * @see Controls
104 *
105 * @subsection menus Menus
106 * It is possible to add actions to the the tab contextual menus.
107 * @see menuActions
108 *
109 * @subsection customize Custom Tab Button
110 * It is possible to set a different tab button for the tab bar. This will allow you to have more control about how the tab button is presented. To make it easier to integrate there is a control template that can be use as a base TabViewButton - different from TabButton.
111 * @see tabViewButton
112 * @see TabViewButton
113 *
114 * @note If you plan to change the tab button, consider using TabViewButton as a base, since it already has many of the needed things by the TabView to be integrated smoothly.
115 *
116 * @subsection functionality Functionality
117 *
118 * By default when clicking/tapping on the current tab button, the overview of tabs miniatures will be opened. The overview can also be oped using the corresponding function.
119 * @see openOverview
120 * @see closeOverview
121 *
122 * <a href="https://invent.kde.org/maui/mauikit/-/blob/qt6-2/examples/TabView.qml">You can find a more complete example at this link.</a>
123 *
124 */
125Pane
126{
127 id: control
128
129 /**
130 * @brief Each one of the items declared as the children of this component will become a tab view.
131 * @property list<QtObject> TabView::content
132 */
133 default property alias content: _listView.contentData
134
135 /**
136 * @brief An alias to the model of the container.
137 * @property model TabView::contentModel
138 */
139 readonly property alias contentModel: _listView.contentModel
141 /**
142 * @brief Current index number of the current tab in the view port.
143 * @property int TabView::currentIndex
144 */
145 property alias currentIndex: _listView.currentIndex
147 /**
148 * @brief The current item/tab view in focus.
149 * @property Item TabView::currentItem
150 */
151 readonly property alias currentItem: _listView.currentItem
153 /**
154 * @brief The total amount of views in this container.
155 * @property int TabView::count
156 */
157 readonly property alias count: _listView.count
159 /**
160 * @brief An alias to a place holder text handled by a MauiKit Holder control. This is useful to display messages when there is not tab views in this container. To see how to set the message, icon and actions to it checkout the Holder documentation.
161 * @see holder
162 * @property Holder TabView::holder
163 */
164 property alias holder : _holder
165
166 /**
167 * @brief Whether the layout of the tab bar should be in mobile or desktop mode. In mobile mode there is only one tab button in the tab bar view port, other tab button can be navigated by using the touch swipe gesture. In mobile mode the main method to switch between tab views is using the overview.
168 * @see structure
169 */
170 property bool mobile : control.width <= Maui.Style.units.gridUnit * 30
171
172 /**
173 * @brief Whether the tab bar hosting the tab buttons, should go in the bottom section or not. Moving it to the bottom section is a good idea for reachability in hand-held devices, such a phones. You can check if the current platform is a mobile one using the Handy attached property `Handy.isMobile`
174 * @see Handy
175 *
176 */
177 property bool altTabBar : false
179 /**
180 * @brief Whether the view will support swipe gestures for switching between tab views.
181 */
182 property bool interactive: Maui.Handy.isTouch
183
184 /**
185 * @brief Checks if the overview mode is open.
186 */
187 readonly property bool overviewMode : _stackView.depth === 2
188
189 /**
190 * @brief An alias to the tab bar element. This is exposed so any other items can be placed on the right or left sections of it, or to fine tweak its public properties.
191 * @see TabBar
192 * @property TabBar TabView::tabBar
193 */
194 property alias tabBar: _tabBar
195
196 /**
197 * @brief An alias to the contextual menu for the tab buttons. This has a child property named index, which refers to the index number of the tab for which the contextual menu was opened.
198 * @see ContextualMenu
199 * @property ContextualMenu TabView::menu
200 */
201 property alias menu :_menu
202
203 /**
204 * @brief A set of actions can be added to the tab button contextual menu.
205 * @code
206 * TabView
207 * {
208 * id: _tabView
209 * menuActions: Action
210 * {
211 * text: "Detach Tab"
212 * onTriggered:
213 * {
214 * console.log("Detach tab at index, ", _tabView.menu.index)
215 * }
216 * }
217 * }
218 * @endcode
219 */
220 property list<Action> menuActions
221
222 /**
223 * @brief The component to be used as the tab button in the tab bar. This can be changed to any other item, but it is recommend it to use TabViewButton as the base of the new custom control for the better integration.
224 * @see TabViewButton
225 */
226 property Component tabViewButton : _tabButtonComponent
227
228 onWidthChanged: _tabBar.positionViewAtIndex(control.currentIndex)
229 onCurrentIndexChanged: _tabBar.positionViewAtIndex(control.currentIndex)
230
231 spacing: 0
232 padding: 0
233
234 Component
235 {
236 id: _tabButtonComponent
237
238 Maui.TabViewButton
239 {
240 id: _tabButton
241 tabView: control
242 closeButtonVisible: !control.mobile
243 onClicked:
244 {
245 if(_tabButton.mindex === control.currentIndex && control.count > 1)
246 {
247 control.openOverview()
248 return
249 }
250
251 _listView.setCurrentIndex(_tabButton.mindex)
252 _listView.itemAt(_tabButton.mindex).forceActiveFocus()
253 }
255 onRightClicked:
256 {
257 openTabMenu(_tabButton.mindex)
259
260 onCloseClicked:
261 {
262 control.closeTabClicked(_tabButton.mindex)
263 }
264 }
265 }
267 /**
268 * @brief Emitted when the new-tab button has been clicked. This is the same as catching the signal from the TabBar element itself, using the exposed alias property.
269 * @see tabBar
270 */
271 signal newTabClicked()
273 /**
274 * @brief Emitted when the close button has been clicked on a tab button, or tab miniature in the overview. This signal sends the index of the tab. To correctly close the tab and release the resources, use the function `closeTab()`.
275 * @param The index of the tab requested to be closed.
276 * @see closeTab
277 */
278 signal closeTabClicked(int index)
279
280 Keys.enabled: true
281 Keys.onPressed: (event) =>
283 if((event.key === Qt.Key_H) && (event.modifiers & Qt.ControlModifier))
284 {
285 control.findTab()
287
288 if(event.key == Qt.Key_Return)
289 {
290 control.closeOverview()
291 _listView.setCurrentIndex(currentIndex)
292 event.accepted = true
293 }
294 }
295
296 Maui.ContextualMenu
297 {
298 id: _menu
299 parent: control
300 property int index //tabindex
301
302 Repeater
303 {
304 model: control.menuActions
305 delegate: MenuItem
306 {
307 action: modelData
308 }
309 }
310
311 MenuItem
312 {
313 text: i18nd("mauikit", "Open")
314 icon.name: "tab-new"
315 onTriggered:
316 {
317 _listView.setCurrentIndex(_menu.index)
318 control.closeOverview()
319 }
320 }
321
322 MenuItem
323 {
324 text: i18nd("mauikit", "Close")
325 icon.name: "tab-close"
326 onTriggered:
327 {
328 control.closeTabClicked(_menu.index)
329 }
330 }
331 }
332
333 data: Loader
334 {
335 id: _loader
336 }
337
338 Component
339 {
340 id: _quickSearchComponent
341
342 Maui.PopupPage
343 {
344 id: _quickSearch
345 persistent: false
346 headBar.visible: true
347
348 onOpened: _quickSearchField.forceActiveFocus()
349
350 function find(query)
351 {
352 for(var i = 0; i < control.count; i ++)
353 {
354 var obj = _listView.contentModel.get(i)
355 if(obj.Maui.Controls.title)
356 {
357 console.log("Trying to find tab", i, query, obj.Maui.Controls.title, String(obj.Maui.Controls.title).indexOf(query))
358
359 if(String(obj.Maui.Controls.title).toLowerCase().indexOf(query.toLowerCase()) !== -1)
360 {
361 return i
362 }
363 }
364 }
365
366 return -1
367 }
368
369 Timer
370 {
371 id: _typingTimer
372 interval: 250
373 onTriggered:
374 {
375 var index = _quickSearch.find(_quickSearchField.text)
376 if(index > -1)
377 {
378 _filterTabsList.currentIndex = index
379 }
380 }
381 }
382
383 headBar.middleContent: Maui.TextField
384 {
385 id: _quickSearchField
386 Layout.fillWidth: true
387 Layout.maximumWidth: 500
388
389 onTextChanged: _typingTimer.restart()
390
391 onAccepted:
392 {
393 control.setCurrentIndex(_filterTabsList.currentIndex)
394 _quickSearch.close()
395 }
396
397 Keys.enabled: true
398
399 Keys.onPressed: (event) =>
400 {
401 if((event.key === Qt.Key_Up))
402 {
403 _filterTabsList.flickable.decrementCurrentIndex()
404 }
405
406 if((event.key === Qt.Key_Down))
407 {
408 _filterTabsList.flickable.incrementCurrentIndex()
409 }
410 }
411 }
412
413 stack: Maui.ListBrowser
414 {
415 id: _filterTabsList
416 Layout.fillWidth: true
417 Layout.fillHeight: true
418 currentIndex: _listView.currentIndex
419
420 model: _listView.count
421
422 delegate: Maui.ListDelegate
423 {
424 width: ListView.view.width
425
426 label: _listView.contentModel.get(index).Maui.Controls.title
427
428 onClicked:
429 {
430 currentIndex =index
431 _listView.setCurrentIndex(index)
432 _quickSearch.close()
433 }
434 }
435 }
436 }
437 }
438
439 contentItem: Item
440 {
441 StackView
442 {
443 anchors.fill: parent
444 id: _stackView
445
446 initialItem: Item
447 {
448 Maui.TabBar
449 {
450 id: _tabBar
451
452 z : _listView.z+1
453
454 anchors.left: parent.left
455 anchors.right: parent.right
456
457 Maui.Controls.showCSD : control.Maui.Controls.showCSD === true && position === TabBar.Header
458
459 visible: _listView.count > 1
460
461 interactive: control.interactive
462 showNewTabButton: !control.mobile
463
464 onNewTabClicked: control.newTabClicked()
465 onNewTabFocused:
466 {
467 if(control.mobile)
468 {
469 _listView.setCurrentIndex(index)
470 }
471 }
472
473 position: control.altTabBar ? TabBar.Footer : TabBar.Header
474
475 Repeater
476 {
477 model: control.count
478 delegate: control.tabViewButton
479 }
480
481 Keys.onPressed: (event) =>
482 {
483 if(event.key == Qt.Key_Return)
484 {
485 _listView.setCurrentIndex(currentIndex)
486 event.accepted = true
487 }
488
489 if(event.key == Qt.Key_Down)
490 {
491 _listView.currentItem.forceActiveFocus()
492 event.accepted = true
493 }
494 }
495
496 Keys.forwardTo: control
497
498 states: [ State
499 {
500 when: !control.altTabBar && control.tabBar.visible
501
502 AnchorChanges
503 {
504 target: _tabBar
505 anchors.top: parent.top
506 anchors.bottom: undefined
507 }
508
509 PropertyChanges
510 {
511 target: _tabBar
512 position: TabBar.Header
513 }
514 },
515
516 State
517 {
518 when: control.altTabBar && control.tabBar.visible
519
520 AnchorChanges
521 {
522 target: _tabBar
523 anchors.top: undefined
524 anchors.bottom: parent.bottom
525 }
526
527 PropertyChanges
528 {
529 target: _tabBar
530 position: TabBar.Footer
531 }
532 } ]
533 }
534
536 {
537 id: _listView
538 anchors.fill: parent
539
540 anchors.bottomMargin: control.altTabBar && _tabBar.visible ? _tabBar.height : 0
541 anchors.topMargin: !control.altTabBar && _tabBar.visible ? _tabBar.height : 0
542
543 interactive: false
544
545 spacing: control.spacing
546
547 clip: control.clip
548
549 orientation: ListView.Horizontal
550 background: null
551
552 contentItem: ListView
553 {
554 id: _listView2
555 model: _listView.contentModel
556 interactive: false
557 currentIndex: _listView.currentIndex
558
559 spacing: _listView.spacing
560
561 clip: false
562
563 orientation: ListView.Horizontal
564 snapMode: ListView.SnapOneItem
565
566 boundsBehavior: Flickable.StopAtBounds
567 boundsMovement :Flickable.StopAtBounds
568
569 preferredHighlightBegin: 0
570 preferredHighlightEnd: width
571
572 highlightRangeMode: ListView.StrictlyEnforceRange
573 highlightMoveDuration: 0
574 highlightFollowsCurrentItem: true
575 highlightResizeDuration: 0
576 highlightMoveVelocity: -1
577 highlightResizeVelocity: -1
578
579 maximumFlickVelocity: 4 * width
580
581 cacheBuffer: _listView.count * width
582 keyNavigationEnabled : false
583 keyNavigationWraps : false
584 }
585 }
586
587 Loader
588 {
589 active: control.Maui.Controls.showCSD === true && control.altTabBar && !Maui.Handy.isMobile
590 asynchronous: true
591 width: parent.width
592
593 sourceComponent: Maui.ToolBar
594 {
595 anchors.top: parent.top
596 Maui.Controls.showCSD: true
597 background: Rectangle
598 {
599 Maui.Theme.colorSet: control.Maui.Theme.colorSet
600 Maui.Theme.inherit: false
601 opacity: 0.8
602 scale: -1 //for mirroring
603 gradient: Gradient {
604 orientation: Gradient.Horizontal
605 GradientStop { position: 0.0; color: Maui.Theme.backgroundColor }
606 GradientStop { position: 0.33; color: "transparent" }
607 GradientStop { position: 1.0; color: "transparent" }
608 }
609 }
610 }
611 }
612
613 Maui.Holder
614 {
615 id: _holder
616 anchors.fill: parent
617 visible: !control.count
618 emojiSize: Maui.Style.iconSizes.huge
619 }
620 }
621
622 Component
623 {
624 id: _overviewComponent
625
626 Pane
627 {
628 id: _pane
629 Maui.Theme.colorSet: Maui.Theme.View
630 Maui.Theme.inherit: false
631
632 background: Rectangle
633 {
634 color: Maui.Theme.backgroundColor
635 Loader
636 {
637 active: !Maui.Handy.isMobile
638 asynchronous: true
639 anchors.fill: parent
640 sourceComponent: Item
641 {
642 DragHandler
643 {
644 // acceptedDevices: PointerDevice.GenericPointer
645 grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
646 onActiveChanged: if (active) { control.Window.window.startSystemMove(); }
647 }
648 }
649 }
650 }
651
652 contentItem: Maui.GridBrowser
653 {
654 id: _overviewGrid
655 model: control.count
656
657 currentIndex: control.currentIndex
658
659 itemSize: Math.min(200, availableWidth /2)
660 Keys.forwardTo: control
661 Keys.enabled: true
662
663 Loader
664 {
665 asynchronous: true
666 anchors.bottom: parent.bottom
667 anchors.right: parent.right
668 anchors.margins: Maui.Style.space.big
669 sourceComponent: Maui.FloatingButton
670 {
671 icon.name: "list-add"
672 onClicked: control.newTabClicked()
673 }
674 }
675
676 onAreaClicked:
677 {
678 control.closeOverview()
679 }
680
681 delegate: Item
682 {
683 height: GridView.view.cellHeight
684 width: GridView.view.cellWidth
685
686 Maui.GridBrowserDelegate
687 {
688 id: _delegate
689
690 anchors.fill: parent
691 anchors.margins: Maui.Style.space.medium
692
693 isCurrentItem : parent.GridView.isCurrentItem
694 label1.text: _listView.contentModel.get(index).Maui.Controls.title
695 // template.labelSizeHint: 32
696 iconSource: "tab-new"
697 flat: false
698
699 tooltipText: _listView.contentModel.get(index).Maui.Controls.toolTipText
700
701 Rectangle
702 {
703 parent: _delegate.background
704 color: _listView.contentModel.get(index).Maui.Controls.color
705 height: 2
706 width: parent.width*0.9
707 anchors.bottom: parent.bottom
708 anchors.horizontalCenter: parent.horizontalCenter
709 }
710
711 onRightClicked:
712 {
713 _listView.setCurrentIndex(index)
714 openTabMenu(_listView.currentIndex)
715 }
716
717 onClicked:
718 {
719 control.closeOverview()
720 _listView.setCurrentIndex(index)
721 }
722
723 onPressAndHold:
724 {
725 _listView.setCurrentIndex(index)
726 openTabMenu(control.currentIndex)
727 }
728
729 template.iconComponent: Item
730 {
731 clip: true
732
733 ShaderEffectSource
734 {
735 id: _effect
736
737 anchors.centerIn: parent
738
739 readonly property double m_scale: Math.min(parent.height/sourceItem.height, parent.width/sourceItem.width)
740
741 height: sourceItem.height * m_scale
742 width: sourceItem.width * m_scale
743
744 hideSource: false
745 live: false
746 smooth: true
747
748 textureSize: Qt.size(width,height)
749 sourceItem: _listView.contentModel.get(index)
750 layer.enabled: GraphicsInfo.api !== GraphicsInfo.Software && Maui.Style.enableEffects
751 layer.smooth: true
752 layer.effect: MultiEffect
753 {
754 maskEnabled: true
755 maskThresholdMin: 0.5
756 maskSpreadAtMin: 1.0
757 maskSpreadAtMax: 0.0
758 maskThresholdMax: 1.0
759 maskSource: ShaderEffectSource
760 {
761 sourceItem: Rectangle
762 {
763 width: _effect.width
764 height: _effect.height
765 radius: Maui.Style.radiusV
766 }
767 }
768 }
769 }
770
771 Maui.CloseButton
772 {
773 id: _closeButton
774 visible: _delegate.isCurrentItem || _delegate.hovered || Maui.Handy.isMobile
775 anchors.top: parent.top
776 anchors.right: parent.right
777 // anchors.margins: Maui.Style.space.small
778
779 onClicked: control.closeTabClicked(index)
780
781 background: Rectangle
782 {
783 radius: height/2
784 color: _closeButton.hovered || _closeButton.containsPress ? Maui.Theme.negativeBackgroundColor : Maui.Theme.backgroundColor
785
786 Behavior on color
787 {
788 Maui.ColorTransition{}
789 }
790 }
791 }
792 }
793 }
794 }
795 }
796 }
797 }
798 }
799 }
800
801 /**
802 * @brief Close a tab view at a given index. This will release the resources, and move the focus to the previous tab view
803 * @param index index of the tab to be closed
804 */
805 function closeTab(index)
806 {
807 _listView.removeItem(_listView.itemAt(index))
808 // _tabBar.removeItem(_tabBar.itemAt(index))
809
810 _listView.currentItemChanged()
811 _listView.currentItem.forceActiveFocus()
812 }
813
814 /**
815 * @brief Adds a new tab view element, the passed element must be a component which will be created by the function and then added to the container
816 * @param component a Component element hosting the actual element to be created.
817 * @param properties set of values that can be passed as a map of properties to be assigned to the component when created
818 * @param quiet optionally you can choose to create the tab quietly or not: by quietly it means that the tab-component will be instantiated and created but will not be focused right away. If quiet is set to `false` - to which it defaults to - then after the creation of the component the new tab will get focused.
819 */
820 function addTab(component, properties, quiet = false) : Item
821 {
822 if(control.overviewMode)
823 {
824 control.closeOverview()
825 }
826
827 const object = component.createObject(control, properties);
828
829 _listView.addItem(object)
830
831 if(!quiet)
832 {
833 _listView.setCurrentIndex(Math.max(_listView.count -1, 0))
834 object.forceActiveFocus()
835 }
836
837 return object
838 }
839
840 /**
841 * @brief Method to open the tab finder.
842 */
843 function findTab()
844 {
845 if(control.count > 1)
846 {
847 _loader.sourceComponent = _quickSearchComponent
848 _loader.item.open()
849 }
850 }
851
852 /**
853 * @brief Method to open the tabs overview.
854 */
855 function openOverview()
856 {
857 if(_stackView.depth === 2)
858 {
859 return
860 }
861 _stackView.push(_overviewComponent)
862 }
863
864 /**
865 * @brief Close the overview of miniature tabs.
866 */
867 function closeOverview()
868 {
869 if(_stackView.depth === 1)
870 {
871 return
872 }
873
874 _stackView.pop()
875 }
876
877 /**
878 * @brief Method to correctly move a tab from one place to another by using the index numbers
879 * @param from the current index number of the tab to be moved
880 * @param to the new index value to where to move the tab
881 */
882 function moveTab(from, to)
883 {
884 _listView.moveItem(from, to)
885 _tabBar.moveItem(from, to)
886
887 _listView.setCurrentIndex(to)
888 _tabBar.setCurrentIndex(_listView.currentIndex)
889
890 _listView2.positionViewAtIndex(_listView.currentIndex, ListView.Contain)
891
892 _listView.currentItemChanged()
893 _listView.currentItem.forceActiveFocus()
894 }
895
896 /**
897 * @brief This allows to change the current tab without breaking the bindings from the `currentIndex` property
898 * @param index the index to change to
899 */
900 function setCurrentIndex(index)
901 {
902 _tabBar.setCurrentIndex(index)
903 _listView.setCurrentIndex(index)
904 _listView.currentItem.forceActiveFocus()
905 }
906
907 /**
908 * @brief Return the Item of the tab view at a given index number
909 * @return the Item element representing the tab view
910 */
911 function tabAt(index)
912 {
913 return _listView.itemAt(index)
914 }
915
916 /**
917 * @brief Opens the tab contextual menu at a given index number
918 */
919 function openTabMenu(index)
920 {
921 _menu.index = index
922 _menu.show()
923 }
924}
alias view
Views switcher component.
Tab bar alternative to QQC TabBar, and based on it.
Definition TabBar.qml:52
alias interactive
Whether the control will react to touch events to flick the tabs.
Definition TabBar.qml:75
void openTabMenu(index)
Opens the tab contextual menu at a given index number.
void newTabClicked()
Emitted when the new-tab button has been clicked.
list< Action > menuActions
A set of actions can be added to the tab button contextual menu.
Definition TabView.qml:208
Component tabViewButton
The component to be used as the tab button in the tab bar.
Definition TabView.qml:213
void closeTabClicked(int index)
Emitted when the close button has been clicked on a tab button, or tab miniature in the overview.
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
const QList< QKeySequence > & find()
QString label(StandardShortcut id)
void forceActiveFocus()
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.