5 changed files with 305 additions and 3 deletions
@ -0,0 +1,230 @@
@@ -0,0 +1,230 @@
|
||||
import QtQuick 2.2 |
||||
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 label: buttonLabel.text |
||||
property alias radius: button.radius |
||||
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 |
||||
|
||||
function hideDropDown() { |
||||
_showDropDown = false |
||||
} |
||||
|
||||
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 |
||||
|
||||
property bool _showDropDown: false |
||||
|
||||
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 |
||||
visible: _showDropDown |
||||
|
||||
onClicked: _showDropDown = false |
||||
} |
||||
|
||||
// Button |
||||
Rectangle { |
||||
id: button |
||||
anchors.fill: parent |
||||
radius: (ScreenTools.defaultFontPixelHeight * 3) / 2 |
||||
color: qgcPal.button |
||||
opacity: _showDropDown ? 1.0 : 0.75 |
||||
|
||||
QGCLabel { |
||||
id: buttonLabel |
||||
anchors.fill: parent |
||||
horizontalAlignment: Text.AlignHCenter |
||||
verticalAlignment: Text.AlignVCenter |
||||
color: "white" |
||||
} |
||||
|
||||
MouseArea { |
||||
anchors.fill: parent |
||||
|
||||
onClicked: _showDropDown = !_showDropDown |
||||
} |
||||
} // Rectangle - button |
||||
|
||||
Item { |
||||
id: dropDownItem |
||||
visible: _showDropDown |
||||
|
||||
Canvas { |
||||
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 |
||||
} |
||||
} |
||||
} // Item - dropDownItem |
||||
} |
Loading…
Reference in new issue