DropPanel.qml 6.46 KB
Newer Older
1 2 3 4 5 6 7 8 9
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

10 11
import QtQuick                  2.3
import QtQuick.Controls         1.2
12
import QtQuick.Controls.Styles  1.4
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

import QGroundControl               1.0
import QGroundControl.ScreenTools   1.0
import QGroundControl.Palette       1.0

Item {
    id:         _root
    z:          QGroundControl.zOrderWidgets
    visible:    false

    signal          clicked()
    property real   radius:             ScreenTools.isMobile ? ScreenTools.defaultFontPixelHeight * 1.75 : ScreenTools.defaultFontPixelHeight * 1.25
    property real   viewportMargins:    0
    property var    toolStrip


    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

38 39
    readonly property real _arrowBaseHeight:    radius             // Height of vertical side of arrow
    readonly property real _arrowPointWidth:    radius * 0.666     // Distance from vertical side to point
40 41 42 43 44 45 46
    readonly property real _dropCornerRadius:   ScreenTools.defaultFontPixelWidth * 0.5
    readonly property real _dropCornerRadiusX2: _dropCornerRadius * 2
    readonly property real _dropMargin:         _dropCornerRadius
    readonly property real _dropMarginX2:       _dropMargin * 2

    property var    _dropEdgeTopPoint
    property real   _dropEdgeHeight
47
    property alias  _dropDownComponent: panelLoader.sourceComponent
48 49
    property real   _viewportMaxTop:    0
    property real   _viewportMaxBottom: parent.parent.height - parent.y
50
    property real   _viewportMaxHeight: _viewportMaxBottom - _viewportMaxTop
51
    property var    _dropPanelCancel
52 53 54 55 56 57 58

    function show(panelEdgeTopPoint, panelEdgeHeight, panelComponent) {
        _dropEdgeTopPoint = panelEdgeTopPoint
        _dropEdgeHeight = panelEdgeHeight
        _dropDownComponent = panelComponent
        _calcPositions()
        visible = true
59
        _dropPanelCancel = dropPanelCancelComponent.createObject(toolStrip.parent)
60 61 62
    }

    function hide() {
63 64 65
        if (_dropPanelCancel) {
            _dropPanelCancel.destroy()
        }
66 67 68 69 70 71 72 73
        if (visible) {
            visible = false
            _dropDownComponent = undefined
            toolStrip.uncheckAll()
        }
    }

    function _calcPositions() {
74
        var panelComponentWidth  = panelLoader.item.width
75
        var panelComponentHeight = panelLoader.item.height
76

77 78
        dropDownItem.width  = panelComponentWidth  + (_dropMarginX2 * 2) + _arrowPointWidth
        dropDownItem.height = panelComponentHeight + (_dropMarginX2 * 2)
79 80

        dropDownItem.x = _dropEdgeTopPoint.x + _dropMargin
81
        dropDownItem.y = _dropEdgeTopPoint.y -(dropDownItem.height / 2) + radius
82 83 84

        // Validate that dropdown is within viewport
        dropDownItem.y = Math.min(dropDownItem.y + dropDownItem.height, _viewportMaxBottom) - dropDownItem.height
85
        dropDownItem.y = Math.max(dropDownItem.y, _viewportMaxTop)
86

87 88 89
        // Adjust height to not exceed viewport bounds
        dropDownItem.height = Math.min(dropDownItem.height, _viewportMaxHeight - dropDownItem.y)

90 91 92
        // Arrow points
        arrowCanvas.arrowPoint.y = (_dropEdgeTopPoint.y + radius) - dropDownItem.y
        arrowCanvas.arrowPoint.x = 0
93 94
        arrowCanvas.arrowBase1.x = _arrowPointWidth
        arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - (_arrowBaseHeight / 2)
95
        arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x
96
        arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + _arrowBaseHeight
97 98 99 100 101
        arrowCanvas.requestPaint()
    } // function - _calcPositions

    QGCPalette { id: qgcPal }

102 103 104 105 106 107 108 109 110 111 112
    Component {
        // Overlay which is used to cancel the panel when the user clicks away
        id: dropPanelCancelComponent

        MouseArea {
            anchors.fill:   parent
            z:              toolStrip.z - 1
            onClicked:      dropPanel.hide()
        }
    }

113
    // This item is sized to hold the entirety of the drop panel including the arrow point
114 115 116
    Item {
        id: dropDownItem

DonLakeFlyer's avatar
DonLakeFlyer committed
117 118 119 120
        DeadMouseArea {
            anchors.fill: parent
        }

121 122 123 124
        Canvas {
            id:             arrowCanvas
            anchors.fill:   parent

125 126 127
            property point arrowPoint: Qt.point(0, 0)
            property point arrowBase1: Qt.point(0, 0)
            property point arrowBase2: Qt.point(0, 0)
128 129

            onPaint: {
130 131 132 133 134
                var panelX = _arrowPointWidth
                var panelY = 0
                var panelWidth = parent.width - _arrowPointWidth
                var panelHeight = parent.height

135 136 137 138
                var context = getContext("2d")
                context.reset()
                context.beginPath()

139 140 141 142
                context.moveTo(panelX, panelY)                              // top left
                context.lineTo(panelX + panelWidth, panelY)                 // top right
                context.lineTo(panelX + panelWidth, panelX + panelHeight)   // bottom right
                context.lineTo(panelX, panelY + panelHeight)                // bottom left
143 144 145
                context.lineTo(arrowBase2.x, arrowBase2.y)
                context.lineTo(arrowPoint.x, arrowPoint.y)
                context.lineTo(arrowBase1.x, arrowBase1.y)
146 147
                context.lineTo(panelX, panelY)                              // top left

148 149 150 151 152 153
                context.closePath()
                context.fillStyle = qgcPal.windowShade
                context.fill()
            }
        } // Canvas - arrowCanvas

154 155 156 157 158 159 160 161
        QGCFlickable {
            id:                 panelItemFlickable
            anchors.margins:    _dropMargin
            anchors.leftMargin: _dropMargin + _arrowPointWidth
            anchors.fill:       parent
            flickableDirection: Flickable.VerticalFlick
            contentWidth:       panelLoader.width
            contentHeight:      panelLoader.height
162 163

            Loader {
164
                id: panelLoader
165

166 167 168
                onHeightChanged:    _calcPositions()
                onWidthChanged:     _calcPositions()

169 170 171 172 173
                property var dropPanel: _root
            }
        }
    } // Item - dropDownItem
}