QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
APMAirframeComponent.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Dialogs
4import QtQuick.Layouts
5
6import QGroundControl
7import QGroundControl.FactControls
8import QGroundControl.Controls
9
10SetupPage {
11 id: airframePage
12 pageComponent: pageComponent
13
14 Component {
15 id: pageComponent
16
17 ColumnLayout {
18 id: mainColumn
19 width: availableWidth
20
21 property real _minW: ScreenTools.defaultFontPixelWidth * 20
22 property real _boxWidth: _minW
23 property real _boxSpace: ScreenTools.defaultFontPixelWidth
24 property real _margins: ScreenTools.defaultFontPixelWidth
25 property Fact _frameClass: controller.getParameterFact(-1, "FRAME_CLASS")
26 property Fact _frameType: controller.getParameterFact(-1, "FRAME_TYPE", false) // FRAME_TYPE is not available on all Rover versions
27 property bool _frameTypeAvailable: controller.vehicle.multiRotor
28
29 readonly property real spacerHeight: ScreenTools.defaultFontPixelHeight
30
31 onWidthChanged: computeDimensions()
32 Component.onCompleted: computeDimensions()
33
34 function computeDimensions() {
35 let sw = 0
36 let rw = 0
37 let idx = Math.floor(mainColumn.width / (_minW + ScreenTools.defaultFontPixelWidth))
38 if(idx < 1) {
39 _boxWidth = mainColumn.width
40 _boxSpace = 0
41 } else {
42 _boxSpace = 0
43 if(idx > 1) {
44 _boxSpace = ScreenTools.defaultFontPixelWidth
45 sw = _boxSpace * (idx - 1)
46 }
47 rw = mainColumn.width - sw
48 _boxWidth = rw / idx
49 }
50 }
51
52 APMAirframeComponentController { id: controller; }
53
54 QGCLabel {
55 id: helpText
56 Layout.fillWidth: true
57 text: (_frameClass.rawValue === 0 ?
58 qsTr("Airframe is currently not set.") :
59 qsTr("Currently set to frame class '%1'").arg(_frameClass.enumStringValue) +
60 (_frameTypeAvailable ? qsTr(" and frame type '%2'").arg(_frameType.enumStringValue) : "") +
61 qsTr(".", "period for end of sentence")) +
62 qsTr(" To change this configuration, select the desired frame class below and then reboot the vehicle.")
63 font.bold: true
64 wrapMode: Text.WordWrap
65 }
66
67 Item {
68 id: lastSpacer
69 height: parent.spacerHeight
70 width: 10
71 }
72
73 Flow {
74 id: flowView
75 Layout.fillWidth: true
76 spacing: _boxSpace
77
78 ButtonGroup {
79 id: airframeTypeExclusive
80 }
81
82 Repeater {
83 model: controller.frameClassModel
84
85 // Outer summary item rectangle
86 Rectangle {
87 id: outerRect
88 objectName: "apmAirframeBox_" + object.name
89 width: _boxWidth
90 height: ScreenTools.defaultFontPixelHeight * 14
91 color: qgcPal.window
92
93 readonly property real titleHeight: ScreenTools.defaultFontPixelHeight * 1.75
94 readonly property real innerMargin: ScreenTools.defaultFontPixelWidth
95
96 MouseArea {
97 anchors.fill: parent
98 onClicked: {
99 if (!airframeCheckBox.checked || !combo.valid) {
100 if (_frameTypeAvailable && object.defaultFrameType != -1) {
101 _frameType.rawValue = object.defaultFrameType
102 }
103 airframeCheckBox.checked = true
104 }
105 }
106 }
107
108 QGCLabel {
109 id: title
110 text: object.name
111 }
112
113 Rectangle {
114 id: imageComboRect
115 anchors.topMargin: ScreenTools.defaultFontPixelHeight / 2
116 anchors.top: title.bottom
117 anchors.bottom: parent.bottom
118 anchors.left: parent.left
119 anchors.right: parent.right
120 color: airframeCheckBox.checked ? qgcPal.buttonHighlight : qgcPal.windowShade
121 opacity: combo.valid ? 1.0 : 0.5
122
123 ColumnLayout {
124 anchors.margins: innerMargin
125 anchors.fill: parent
126 spacing: innerMargin
127
128 Image {
129 id: image
130 Layout.fillWidth: true
131 Layout.fillHeight: true
132 fillMode: Image.PreserveAspectFit
133 smooth: true
134 antialiasing: true
135 sourceSize.width: width
136 source: airframeCheckBox.checked ? object.imageResource : object.imageResourceDefault
137 }
138
139 QGCCheckBox {
140 // Although this item is invisible we still use it to manage state
141 id: airframeCheckBox
142 checked: object.frameClass === _frameClass.rawValue
143 buttonGroup: airframeTypeExclusive
144 visible: false
145
146 onCheckedChanged: {
147 if (checked) {
148 _frameClass.rawValue = object.frameClass
149 }
150 }
151 }
152
153 QGCLabel {
154 text: qsTr("Frame Type")
155 font.pointSize: ScreenTools.smallFontPointSize
156 color: qgcPal.buttonHighlightText
157 visible: airframeCheckBox.checked && object.frameTypeSupported
158 }
159
160 QGCComboBox {
161 id: combo
162 Layout.fillWidth: true
163 model: object.frameTypeEnumStrings
164 visible: airframeCheckBox.checked && object.frameTypeSupported
165 onActivated: (index) => { _frameType.rawValue = object.frameTypeEnumValues[index] }
166
167 property bool valid: true
168
169 function checkFrameType(value) {
170 return value == _frameType.rawValue
171 }
172
173 function selectFrameType() {
174 let index = object.frameTypeEnumValues.findIndex(checkFrameType)
175 if (index == -1 && combo.visible) {
176 // Frame Class/Type is set to an invalid combination
177 combo.valid = false
178 } else {
179 combo.currentIndex = index
180 combo.valid = true
181 }
182 }
183
184 Component.onCompleted: selectFrameType()
185
186 Connections {
187 target: _frameTypeAvailable ? _frameType : null
188 ignoreUnknownSignals: true
189 function onRawValueChanged(value) { combo.selectFrameType() }
190 }
191 }
192 }
193 }
194
195 QGCLabel {
196 anchors.fill: imageComboRect
197 text: qsTr("Invalid setting for FRAME_TYPE. Click to Reset.")
198 wrapMode: Text.WordWrap
199 visible: !combo.valid
200 }
201 }
202 } // Repeater - summary boxes
203 } // Flow - summary boxes
204 } // Column
205 } // Component
206} // SetupPage