JoystickThumbPad.qml 7.8 KB
Newer Older
1
import QtQuick                  2.12
2
import QtQuick.Controls         1.2
Don Gagne's avatar
Don Gagne committed
3

4
import QGroundControl               1.0
Don Gagne's avatar
Don Gagne committed
5 6 7
import QGroundControl.Palette       1.0
import QGroundControl.ScreenTools   1.0

dogmaphobic's avatar
dogmaphobic committed
8
Item {
9
    id:             _joyRoot
Don Gagne's avatar
Don Gagne committed
10

11 12 13 14 15 16 17
    property alias  lightColors:            mapPal.lightColors  ///< true: use light colors from QGCMapPalette for drawing
    property real   xAxis:                  0                   ///< Value range [-1,1], negative values left stick, positive values right stick
    property real   yAxis:                  0                   ///< Value range [-1,1], negative values down stick, positive values up stick
    property bool   yAxisPositiveRangeOnly: false               ///< true: value range [0,1], false: value range [-1,1]
    property bool   yAxisReCenter:          true                ///< true: snaps back to center on release, false: stays at current position on release
    property real   xPositionDelta:         0                   ///< Amount to move the control on x axis
    property real   yPositionDelta:         0                   ///< Amount to move the control on y axis
Don Gagne's avatar
Don Gagne committed
18

Don Gagne's avatar
Don Gagne committed
19 20
    property real   _centerXY:              width / 2
    property bool   _processTouchPoints:    false
21 22
    property color  _fgColor:               QGroundControl.globalPalette.text
    property color  _bgColor:               QGroundControl.globalPalette.window
23 24
    property real   stickPositionX:         _centerXY
    property real   stickPositionY:         yAxisReCenter ? _centerXY : height
Don Gagne's avatar
Don Gagne committed
25

26 27 28 29 30 31 32
    QGCMapPalette { id: mapPal }

    onWidthChanged:                     calculateXAxis()
    onStickPositionXChanged:            calculateXAxis()
    onHeightChanged:                    calculateYAxis()
    onStickPositionYChanged:            calculateYAxis()
    onYAxisPositiveRangeOnlyChanged:    calculateYAxis()
33

34 35
    function calculateXAxis() {
        if(!_joyRoot.visible) {
36 37
            return;
        }
Don Gagne's avatar
Don Gagne committed
38
        var xAxisTemp = stickPositionX / width
Don Gagne's avatar
Don Gagne committed
39 40 41
        xAxisTemp *= 2.0
        xAxisTemp -= 1.0
        xAxis = xAxisTemp
Don Gagne's avatar
Don Gagne committed
42
    }
Don Gagne's avatar
Don Gagne committed
43

44 45
    function calculateYAxis() {
        if(!_joyRoot.visible) {
46 47
            return;
        }
48 49 50 51 52
        var fullRange = yAxisPositiveRangeOnly ? 1 : 2
        var pctUp = 1.0 - (stickPositionY / height)
        var rangeUp = pctUp * fullRange
        if (!yAxisPositiveRangeOnly) {
            rangeUp -= 1
Don Gagne's avatar
Don Gagne committed
53
        }
54
        yAxis = rangeUp
Don Gagne's avatar
Don Gagne committed
55 56
    }

57
    function reCenter() {
Don Gagne's avatar
Don Gagne committed
58
        _processTouchPoints = false
59

Don Gagne's avatar
Don Gagne committed
60 61 62
        // Move control back to original position
        xPositionDelta = 0
        yPositionDelta = 0
63

64
        // Re-Center sticks as needed
Don Gagne's avatar
Don Gagne committed
65
        stickPositionX = _centerXY
66
        if (yAxisReCenter) {
67 68
            stickPositionY = _centerXY
        }
Don Gagne's avatar
Don Gagne committed
69 70
    }

71
    function thumbDown(touchPoints) {
72
        // Position the control around the initial thumb position
Don Gagne's avatar
Don Gagne committed
73
        xPositionDelta = touchPoints[0].x - _centerXY
74
        if (yAxisPositiveRangeOnly) {
75 76 77 78
            yPositionDelta = touchPoints[0].y - stickPositionY
        } else {
            yPositionDelta = touchPoints[0].y - _centerXY
        }
Don Gagne's avatar
Don Gagne committed
79 80
        // We need to wait until we move the control to the right position before we process touch points
        _processTouchPoints = true
Don Gagne's avatar
Don Gagne committed
81 82
    }

Don Gagne's avatar
Don Gagne committed
83
    /*
Don Gagne's avatar
Don Gagne committed
84
    // Keep in for debugging
Don Gagne's avatar
Don Gagne committed
85 86 87 88
    Column {
        QGCLabel { text: xAxis }
        QGCLabel { text: yAxis }
    }
Don Gagne's avatar
Don Gagne committed
89
    */
Don Gagne's avatar
Don Gagne committed
90

dogmaphobic's avatar
dogmaphobic committed
91 92
    Image {
        anchors.fill:       parent
93
        source:             "/res/JoystickBezelLight.png"
dogmaphobic's avatar
dogmaphobic committed
94 95
        mipmap:             true
        smooth:             true
Don Gagne's avatar
Don Gagne committed
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
    Rectangle {
        anchors.fill:       parent
        radius:             width / 2
        color:              _bgColor
        opacity:            0.5

        Rectangle {
            anchors.margins:    parent.width / 4
            anchors.fill:       parent
            radius:             width / 2
            border.color:       _fgColor
            border.width:       2
            color:              "transparent"
        }

        Rectangle {
            anchors.fill:       parent
            radius:             width / 2
            border.color:       _fgColor
            border.width:       2
            color:              "transparent"
        }
    }

122
    QGCColoredImage {
123
        color:                      _fgColor
124
        visible:                    yAxisPositiveRangeOnly
125 126 127 128 129 130 131 132 133 134 135 136
        height:                     ScreenTools.defaultFontPixelHeight
        width:                      height
        sourceSize.height:          height
        mipmap:                     true
        fillMode:                   Image.PreserveAspectFit
        source:                     "/res/clockwise-arrow.svg"
        anchors.right:              parent.right
        anchors.rightMargin:        ScreenTools.defaultFontPixelWidth
        anchors.verticalCenter:     parent.verticalCenter
    }

    QGCColoredImage {
137
        color:                      _fgColor
138
        visible:                    yAxisPositiveRangeOnly
139 140 141 142 143 144 145 146 147 148 149 150
        height:                     ScreenTools.defaultFontPixelHeight
        width:                      height
        sourceSize.height:          height
        mipmap:                     true
        fillMode:                   Image.PreserveAspectFit
        source:                     "/res/counter-clockwise-arrow.svg"
        anchors.left:               parent.left
        anchors.leftMargin:         ScreenTools.defaultFontPixelWidth
        anchors.verticalCenter:     parent.verticalCenter
    }

    QGCColoredImage {
151
        color:                      _fgColor
152
        visible:                    yAxisPositiveRangeOnly
153 154 155 156 157 158 159 160 161 162 163 164
        height:                     ScreenTools.defaultFontPixelHeight
        width:                      height
        sourceSize.height:          height
        mipmap:                     true
        fillMode:                   Image.PreserveAspectFit
        source:                     "/res/chevron-up.svg"
        anchors.top:                parent.top
        anchors.topMargin:          ScreenTools.defaultFontPixelWidth
        anchors.horizontalCenter:   parent.horizontalCenter
    }

    QGCColoredImage {
165
        color:                      _fgColor
166
        visible:                    yAxisPositiveRangeOnly
167 168 169 170 171 172 173 174 175 176 177
        height:                     ScreenTools.defaultFontPixelHeight
        width:                      height
        sourceSize.height:          height
        mipmap:                     true
        fillMode:                   Image.PreserveAspectFit
        source:                     "/res/chevron-down.svg"
        anchors.bottom:             parent.bottom
        anchors.bottomMargin:       ScreenTools.defaultFontPixelWidth
        anchors.horizontalCenter:   parent.horizontalCenter
    }

Don Gagne's avatar
Don Gagne committed
178
    Rectangle {
179 180 181 182 183 184 185 186
        width:          hatWidth
        height:         hatWidth
        radius:         hatWidthHalf
        border.color:   _fgColor
        border.width:   1
        color:          Qt.rgba(_fgColor.r, _fgColor.g, _fgColor.b, 0.5)
        x:              stickPositionX - hatWidthHalf
        y:              stickPositionY - hatWidthHalf
Don Gagne's avatar
Don Gagne committed
187 188 189 190

        readonly property real hatWidth:        ScreenTools.defaultFontPixelHeight
        readonly property real hatWidthHalf:    ScreenTools.defaultFontPixelHeight / 2
    }
Don Gagne's avatar
Don Gagne committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211

    Connections {
        target: touchPoint

        onXChanged: {
            if (_processTouchPoints) {
                _joyRoot.stickPositionX = Math.max(Math.min(touchPoint.x, _joyRoot.width), 0)
            }
        }
        onYChanged: {
            if (_processTouchPoints) {
                _joyRoot.stickPositionY = Math.max(Math.min(touchPoint.y, _joyRoot.height), 0)
            }
        }
    }

    MultiPointTouchArea {
        anchors.fill:       parent
        minimumTouchPoints: 1
        maximumTouchPoints: 1
        touchPoints:        [ TouchPoint { id: touchPoint } ]
Gus Grubba's avatar
Gus Grubba committed
212
        onPressed:          _joyRoot.thumbDown(touchPoints)
213
        onReleased:         _joyRoot.reCenter()
Don Gagne's avatar
Don Gagne committed
214
    }
Don Gagne's avatar
Don Gagne committed
215
}