QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
QGCTabBar.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Layouts
4
5import QGroundControl
6import QGroundControl.Controls
7
8// We implement our own TabBar to get around the fact that QtQuick.Controls TabBar does not
9// support hiding tabs. This version supports hiding tabs by setting the visible property
10// on the QGCTabButton instances.
11RowLayout {
12 property int currentIndex: 0
13
14 id: control
15 spacing: 0
16
17 property bool _preventCurrentIndexBindingLoop: false
18 property var _buttons: []
19
20 function _updateButtons() {
21 let btns = []
22 for (var i = 0; i < control.children.length; i++) {
23 if (control.children[i].hasOwnProperty("checkable")) {
24 btns.push(control.children[i])
25 }
26 }
27 _buttons = btns
28 buttonGroup.buttons = _buttons
29 _selectCurrentIndexButton()
30 }
31
32 function _updateSeparators() {
33 for (var i = 0; i < _buttons.length; i++) {
34 if (!_buttons[i].visible || _buttons[i].checked) {
35 _buttons[i]._showSeparator = false
36 continue
37 }
38 // Find the next visible button
39 var nextVisible = null
40 for (var j = i + 1; j < _buttons.length; j++) {
41 if (_buttons[j].visible) {
42 nextVisible = _buttons[j]
43 break
44 }
45 }
46 _buttons[i]._showSeparator = nextVisible !== null && !nextVisible.checked
47 }
48 }
49
50 function _selectCurrentIndexButton() {
51 if (_buttons.length === 0) return
52
53 _preventCurrentIndexBindingLoop = true
54
55 if (control.currentIndex === -1) {
56 for (var i = 0; i < _buttons.length; i++) {
57 _buttons[i].checked = false
58 }
59 } else {
60 let index = Math.min(Math.max(control.currentIndex, 0), _buttons.length - 1)
61 if (_buttons[index].visible) {
62 _buttons[index].checked = true
63 } else {
64 // Select the first visible tab if the current index is not visible
65 index = -1
66 for (var j = 0; j < _buttons.length; j++) {
67 if (_buttons[j].visible) {
68 _buttons[j].checked = true
69 index = j
70 break
71 }
72 }
73 }
74 // Sync currentIndex to the actually-selected button so it never remains stale
75 if (control.currentIndex !== index) {
76 control.currentIndex = index
77 }
78 }
79
80 _preventCurrentIndexBindingLoop = false
81 _updateSeparators()
82 }
83
84 Component.onCompleted: _updateButtons()
85 onChildrenChanged: _updateButtons()
86 onCurrentIndexChanged: _selectCurrentIndexButton()
87 onVisibleChildrenChanged: _selectCurrentIndexButton()
88
89 onVisibleChanged: {
90 if (visible) {
91 // When becoming visible, ensure the current index is valid and a button is selected
92 currentIndex = 0
93 _selectCurrentIndexButton()
94 }
95 }
96
97
98 ButtonGroup {
99 id: buttonGroup
100
101 onCheckedButtonChanged: {
102 if (control._preventCurrentIndexBindingLoop) return
103
104 for (var i = 0; i < control._buttons.length; i++) {
105 if (control._buttons[i] === checkedButton) {
106 control.currentIndex = i
107 break
108 }
109 }
110 }
111 }
112}