Newer
Older
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
Item {
id: _root
property alias buttonImage: button.source
property real radius: (ScreenTools.defaultFontPixelHeight * 3) / 2
property int dropDirection: dropDown
property alias dropDownComponent: dropDownLoader.sourceComponent
property real viewportMargins: 0
width: radius * 2
height: radius * 2
// Should be an enum but that get's into the whole problem of creating a singleton which isn't worth the effort
readonly property int dropLeft: 1
readonly property int dropRight: 2
readonly property int dropUp: 3
readonly property int dropDown: 4
readonly property real _arrowBaseWidth: (radius * 2) / 2 // Width of long side of arrow
readonly property real _arrowPointHeight: (radius * 2) / 3 // Height is long side to point
readonly property real _dropCornerRadius: ScreenTools.defaultFontPixelWidth / 2
readonly property real _dropCornerRadiusX2: _dropCornerRadius * 2
readonly property real _dropMargin: _dropCornerRadius
readonly property real _dropMarginX2: _dropMargin * 2
property real _viewportMaxLeft: -x + viewportMargins
property real _viewportMaxRight: parent.width - (viewportMargins * 2) - x
property real _viewportMaxTop: -y + viewportMargins
property real _viewportMaxBottom: parent.height - (viewportMargins * 2) - y
// Set up ExclusiveGroup support. We use the checked property to drive visibility of drop down.
property bool checked: false
property ExclusiveGroup exclusiveGroup: null
onExclusiveGroupChanged: {
if (exclusiveGroup) {
exclusiveGroup.bindCheckable(_root)
}
}
function hideDropDown() {
checked = false
}
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
Component.onCompleted: _calcPositions()
function _calcPositions() {
var dropComponentWidth = dropDownLoader.item.width
var dropComponentHeight = dropDownLoader.item.height
var dropRectWidth = dropComponentWidth + _dropMarginX2
var dropRectHeight = dropComponentHeight + _dropMarginX2
dropItemHolderRect.width = dropRectWidth
dropItemHolderRect.height = dropRectHeight
dropDownItem.width = dropComponentWidth + _dropMarginX2
dropDownItem.height = dropComponentHeight + _dropMarginX2
if (dropDirection == dropUp || dropDirection == dropDown) {
dropDownItem.height += _arrowPointHeight
dropDownItem.x = -(dropDownItem.width / 2) + radius
dropItemHolderRect.x = 0
if (dropDirection == dropUp) {
dropDownItem.y = -(dropDownItem.height + _dropMargin)
dropItemHolderRect.y = 0
} else {
dropDownItem.y = button.height + _dropMargin
dropItemHolderRect.y = _arrowPointHeight
}
// Validate that dropdown is within viewport
dropDownItem.x = Math.max(dropDownItem.x, _viewportMaxLeft)
dropDownItem.x = Math.min(dropDownItem.x + dropDownItem.width, _viewportMaxRight) - dropDownItem.width
// Arrow points
arrowCanvas.arrowPoint.x = (button.x + radius) - dropDownItem.x
if (dropDirection == dropUp) {
arrowCanvas.arrowPoint.y = dropDownItem.height
arrowCanvas.arrowBase1.x = arrowCanvas.arrowPoint.x - (_arrowBaseWidth / 2)
arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - _arrowPointHeight
arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x + _arrowBaseWidth
arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y
} else {
arrowCanvas.arrowPoint.y = 0
arrowCanvas.arrowBase1.x = arrowCanvas.arrowPoint.x + (_arrowBaseWidth / 2)
arrowCanvas.arrowBase1.y = _arrowPointHeight
arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x - _arrowBaseWidth
arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y
}
} else {
dropDownItem.width += _arrowPointHeight
dropDownItem.y = -(dropDownItem.height / 2) + radius
dropItemHolderRect.y = 0
if (dropDirection == dropLeft) {
dropDownItem.x = dropDownItem.width + _dropMargin
dropItemHolderRect.x = 0
} else {
dropDownItem.x = button.width + _dropMargin
dropItemHolderRect.x = _arrowPointHeight
}
// Validate that dropdown is within viewport
dropDownItem.y = Math.max(dropDownItem.y, _viewportMaxTop)
dropDownItem.y = Math.min(dropDownItem.y + dropDownItem.height, _viewportMaxBottom) - dropDownItem.height
// Arrow points
arrowCanvas.arrowPoint.y = (button.y + radius) - dropDownItem.y
if (dropDirection == dropLeft) {
arrowCanvas.arrowPoint.x = dropDownItem.width
arrowCanvas.arrowBase1.x = arrowCanvas.arrowPoint.x - _arrowPointHeight
arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - (_arrowBaseWidth / 2)
arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x
arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + _arrowBaseWidth
} else {
arrowCanvas.arrowPoint.x = 0
arrowCanvas.arrowBase1.x = _arrowPointHeight
arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - (_arrowBaseWidth / 2)
arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x
arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + _arrowBaseWidth
}
}
arrowCanvas.requestPaint()
} // function - _calcPositions
QGCPalette { id: qgcPal }
MouseArea {
x: _viewportMaxLeft
y: _viewportMaxTop
width: _viewportMaxRight -_viewportMaxLeft
height: _viewportMaxBottom - _viewportMaxTop
onClicked: {
checked = false
_root.clicked()
}
radius: width / 2
border.width: 2
border.color: "white"
opacity: checked ? 0.95 : 0.65
color: checked ? qgcPal.mapButtonHighlight : qgcPal.mapButton
Image {
id: button
anchors.fill: parent
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
MouseArea {
anchors.fill: parent
onClicked: {
checked = !checked
_root.clicked()
}
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
id: arrowCanvas
anchors.fill: parent
property var arrowPoint: Qt.point(0, 0)
property var arrowBase1: Qt.point(0, 0)
property var arrowBase2: Qt.point(0, 0)
onPaint: {
var context = getContext("2d")
context.reset()
context.beginPath()
context.moveTo(dropItemHolderRect.x, dropItemHolderRect.y)
if (dropDirection == dropDown) {
context.lineTo(arrowBase2.x, arrowBase2.y)
context.lineTo(arrowPoint.x, arrowPoint.y)
context.lineTo(arrowBase1.x, arrowBase1.y)
}
context.lineTo(dropItemHolderRect.x + dropItemHolderRect.width, dropItemHolderRect.y)
if (dropDirection == dropLeft) {
context.lineTo(arrowBase2.x, arrowBase2.y)
context.lineTo(arrowPoint.x, arrowPoint.y)
context.lineTo(arrowBase1.x, arrowBase1.y)
}
context.lineTo(dropItemHolderRect.x + dropItemHolderRect.width, dropItemHolderRect.y + dropItemHolderRect.height)
if (dropDirection == dropUp) {
context.lineTo(arrowBase2.x, arrowBase2.y)
context.lineTo(arrowPoint.x, arrowPoint.y)
context.lineTo(arrowBase1.x, arrowBase1.y)
}
context.lineTo(dropItemHolderRect.x, dropItemHolderRect.y + dropItemHolderRect.height)
if (dropDirection == dropRight) {
context.lineTo(arrowBase2.x, arrowBase2.y)
context.lineTo(arrowPoint.x, arrowPoint.y)
context.lineTo(arrowBase1.x, arrowBase1.y)
}
context.lineTo(dropItemHolderRect.x, dropItemHolderRect.y)
context.closePath()
context.fillStyle = qgcPal.button
context.fill()
}
} // Canvas - arrowCanvas
Item {
id: dropItemHolderRect
//color: qgcPal.button
//radius: _dropCornerRadius
Loader {
id: dropDownLoader
x: _dropMargin
y: _dropMargin
Connections {
target: dropDownLoader.item
onWidthChanged: _calcPositions()
onHeightChanged: _calcPositions()
}