ToolStrip.qml 15.2 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.
 *
 ****************************************************************************/

Don Gagne's avatar
Don Gagne committed
10 11
import QtQuick          2.11
import QtQuick.Controls 1.4
12
import QtQuick.Layouts  1.11
13 14 15 16

import QGroundControl.ScreenTools   1.0
import QGroundControl.Palette       1.0

17
// Tool Strip not tested for mobile devices!
18 19 20
Rectangle {
    id:         _root
    color:      qgcPal.window
21 22
    width:      toolStripGrid.width + (toolStripGrid.anchors.margins * 2)
    height:     toolStripGrid.height + (toolStripGrid.anchors.margins * 2)
23
    radius:     _radius
24 25
    border.width:   1
    border.color:   qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.35) : Qt.rgba(1,1,1,0.35)
26 27 28

    property string title:              "Title"
    property alias  model:              repeater.model
29 30
    property var    showAlternateIcon                   ///< List of bool values, one for each button in strip - true: show alternate icon, false: show normal icon
    property var    rotateImage                         ///< List of bool values, one for each button in strip - true: animation rotation, false: static image
31
    property var    animateImage                        ///< List of bool values, one for each button in strip - true: animate image, false: static image
32 33
    property var    buttonEnabled                       ///< List of bool values, one for each button in strip - true: button enabled, false: button disabled
    property var    buttonVisible                       ///< List of bool values, one for each button in strip - true: button visible, false: button invisible
34
    property var    maxHeight                           /// legacy parameter, does not have any impact
35 36 37 38
    property bool   horizontal:         false           /// toolstrip horizontal or vertical ?
    property bool   enableSwitchButton: false           /// enable horizontal vertical button ?


39 40 41

    signal clicked(int index, bool checked)

Don Gagne's avatar
Don Gagne committed
42 43
    readonly property real  _radius:                ScreenTools.defaultFontPixelWidth / 2
    readonly property real  _margin:                ScreenTools.defaultFontPixelWidth / 2
Don Gagne's avatar
Don Gagne committed
44
    readonly property real  _buttonSpacing:         ScreenTools.defaultFontPixelHeight / 4
45

46
    readonly property real _buttonWidthHeight: ScreenTools.isMobile ? ScreenTools.minTouchPixels : ScreenTools.defaultFontPixelWidth * 6
47 48 49 50

    Component.onCompleted: toolStripGrid.horizontal = _root.horizontal

    onHorizontalChanged: toolStripGrid.horizontal = _root.horizontal
51

Don Gagne's avatar
Don Gagne committed
52 53
    QGCPalette { id: qgcPal }
    ExclusiveGroup { id: dropButtonsExclusiveGroup }
54 55 56 57 58

    function uncheckAll() {
        dropButtonsExclusiveGroup.current = null
        // Signal all toggles as off
        for (var i=0; i<model.length; i++) {
59 60
            if (model[i].toggle === true) {
                _root.clicked(i, false)
61 62 63 64
            }
        }
    }

65 66 67 68
    DeadMouseArea {
        anchors.fill: parent
    }

69
    Grid {
70
        id:                 toolStripGrid
71 72 73
        anchors.margins:    ScreenTools.defaultFontPixelWidth  / 2
        anchors.top:        parent.top
        anchors.left:       parent.left
74 75
        columnSpacing:      _buttonSpacing
        rowSpacing:         _buttonSpacing
76 77 78 79 80 81 82 83

        // Lable + Separator + GridLayout + Spearator + Switch Button
        property int numItems: enableSwitchButton ? 5 : 3
        rows:               toolStripGrid.horizontal ? 1 : numItems
        columns:            toolStripGrid.horizontal ? numItems : 1

        horizontalItemAlignment:    Grid.AlignHCenter
        verticalItemAlignment:      Grid.AlignVCenter
84 85

        property bool horizontal
86 87 88

        QGCLabel {
            text:                       title
89
            font.pointSize:             ScreenTools.mobile ? ScreenTools.smallFontPointSize : ScreenTools.defaultFontPointSize
90 91
        }

92

93
        // separator
94
        Rectangle {
95 96
            height:             toolStripGrid.horizontal ? _buttonWidthHeight : 1
            width:              toolStripGrid.horizontal ? 1 : _buttonWidthHeight
97 98 99
            color:              qgcPal.text
        }

100
        GridLayout {
101
            id:             modelButtonsGrid
102 103
            rows:           toolStripGrid.horizontal ?            1 : model.length
            columns:        toolStripGrid.horizontal ? model.length : 1
104 105
            columnSpacing:  _buttonSpacing
            rowSpacing:     _buttonSpacing
Don Gagne's avatar
Don Gagne committed
106

107

108

Don Gagne's avatar
Don Gagne committed
109 110 111 112 113
            Repeater {
                id: repeater

                delegate: FocusScope {
                    id:         scope
114
                    width:      buttonRect.width
Don Gagne's avatar
Don Gagne committed
115 116
                    height:     buttonRect.height
                    visible:    _root.buttonVisible ? _root.buttonVisible[index] : true
117
                    Layout.alignment: toolStripGrid.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
Don Gagne's avatar
Don Gagne committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

                    property bool checked: false
                    property ExclusiveGroup exclusiveGroup: dropButtonsExclusiveGroup

                    property bool   _buttonEnabled:         _root.buttonEnabled ? _root.buttonEnabled[index] : true
                    property var    _iconSource:            modelData.iconSource
                    property var    _alternateIconSource:   modelData.alternateIconSource
                    property var    _source:                (_root.showAlternateIcon && _root.showAlternateIcon[index]) ? _alternateIconSource : _iconSource
                    property bool   rotateImage:            _root.rotateImage ? _root.rotateImage[index] : false
                    property bool   animateImage:           _root.animateImage ? _root.animateImage[index] : false
                    property bool   _hovered:               false
                    property bool   _showHighlight:         checked || (_buttonEnabled && _hovered)

                    QGCPalette { id: _repeaterPal; colorGroupEnabled: _buttonEnabled }

                    onExclusiveGroupChanged: {
                        if (exclusiveGroup) {
                            exclusiveGroup.bindCheckable(scope)
                        }
137 138
                    }

Don Gagne's avatar
Don Gagne committed
139 140 141 142 143 144 145 146
                    onRotateImageChanged: {
                        if (rotateImage) {
                            imageRotation.running = true
                        } else {
                            imageRotation.running = false
                            buttonImage.rotation = 0
                        }
                    }
147

Don Gagne's avatar
Don Gagne committed
148 149 150 151 152 153 154 155
                    onAnimateImageChanged: {
                        if (animateImage) {
                            opacityAnimation.running = true
                        } else {
                            opacityAnimation.running = false
                            buttonImage.opacity = 1
                        }
                    }
156

157
                    Rectangle {
Don Gagne's avatar
Don Gagne committed
158
                        id:             buttonRect
159 160
                        height:         _buttonWidthHeight
                        width:          _buttonWidthHeight
Don Gagne's avatar
Don Gagne committed
161
                        color:          _showHighlight ? _repeaterPal.buttonHighlight : _repeaterPal.window
162 163 164
                        clip:           true
                        radius:         ScreenTools.defaultFontPixelWidth/2

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
                        Column {

                            anchors.horizontalCenter: parent.horizontalCenter

                            QGCColoredImage {
                                id:             buttonImage
                                height:             _buttonWidthHeight-buttonLabel.height
                                width:              _buttonWidthHeight-buttonLabel.height
                                source:             _source
                                anchors.horizontalCenter: parent.horizontalCenter
                                sourceSize.height:  _buttonWidthHeight-buttonLabel.height
                                sourceSize.width:   _buttonWidthHeight-buttonLabel.height
                                fillMode:           Image.PreserveAspectCrop
                                mipmap:             true
                                smooth:             true
                                color:              _showHighlight ? _repeaterPal.buttonHighlightText : _repeaterPal.text

                                RotationAnimation on rotation {
                                    id:             imageRotation
                                    loops:          Animation.Infinite
                                    from:           0
                                    to:             360
                                    duration:       500
                                    running:        false
                                }
190

191 192 193 194 195 196 197 198
                                NumberAnimation on opacity {
                                    id:         opacityAnimation
                                    running:    false
                                    from:       0
                                    to:         1.0
                                    loops:      Animation.Infinite
                                    duration:   2000
                                }
199
                            }
200

201 202
                            QGCLabel {
                                id:                         buttonLabel
203

204 205 206 207 208 209 210
                                anchors.horizontalCenter:   parent.horizontalCenter
                                font.pointSize:             ScreenTools.smallFontPointSize
                                text:                       modelData.name
                                color:                      _showHighlight ? _repeaterPal.buttonHighlightText : _repeaterPal.text
                                enabled:                    _buttonEnabled
                            }
                        }
211

212
                        QGCMouseArea {
Don Gagne's avatar
Don Gagne committed
213 214 215 216 217 218 219
                            anchors.fill:       parent
                            visible:            _buttonEnabled
                            hoverEnabled:       true
                            preventStealing:    true

                            onContainsMouseChanged: _hovered = containsMouse
                            onContainsPressChanged: _hovered = containsPress
220 221 222 223 224 225 226 227 228 229 230 231

                            onClicked: {
                                scope.focus = true
                                if (modelData.dropPanelComponent === undefined) {
                                    dropPanel.hide()
                                    if (modelData.toggle === true) {
                                        checked = !checked
                                    } else {
                                        // dropPanel.hide above will close panel, but we need to do this to clear toggles
                                        uncheckAll()
                                    }
                                    _root.clicked(index, checked)
232
                                } else {
233 234 235 236 237 238 239 240 241
                                    if (checked) {
                                        dropPanel.hide()    // hide affects checked, so this needs to be duplicated inside not outside if
                                    } else {
                                        dropPanel.hide()    // hide affects checked, so this needs to be duplicated inside not outside if
                                        uncheckAll()
                                        checked = true
                                        var panelEdgeTopPoint = mapToItem(_root, width, 0)
                                        dropPanel.show(panelEdgeTopPoint, height, modelData.dropPanelComponent)
                                    }
242 243 244
                                }
                            }
                        }
Don Gagne's avatar
Don Gagne committed
245 246
                    } // Rectangle
                } // FocusScope
247 248 249 250 251
            } // Repeater
        } // GridLayout

        // separator
        Rectangle {
252 253
            height:             toolStripGrid.horizontal ? _buttonWidthHeight : 1
            width:              toolStripGrid.horizontal ? 1 : _buttonWidthHeight
254 255
            color:              qgcPal.text
            visible:            enableSwitchButton
256
        }
257 258 259 260

        // switch button, tool strip horizontal <-> vertical
        Rectangle {
            id:             switchButtonRect
261 262
            height:         enableSwitchButton ? _buttonWidthHeight : 0
            width:          enableSwitchButton ? _buttonWidthHeight : 0
263
            color:          _showHighlight ? _switchButtonPal.buttonHighlight : _switchButtonPal.window
264
            visible:        enableSwitchButton
265
            radius:         ScreenTools.defaultFontPixelWidth/2
266
            clip:           true
267 268 269 270 271 272

            property bool   _hovered:               false
            property bool   _showHighlight:         (enableSwitchButton && _hovered)

            QGCPalette { id: _switchButtonPal; colorGroupEnabled: enableSwitchButton }

273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
            Column {
                anchors.horizontalCenter: parent.horizontalCenter
                QGCColoredImage {
                    id:             switchButtonImage
                    height:             _buttonWidthHeight-switchButtonLabel.height
                    width:              _buttonWidthHeight-switchButtonLabel.height
                    source:             "/res/clockwise-arrow.svg"
                    anchors.horizontalCenter: parent.horizontalCenter
                    sourceSize.height:  _buttonWidthHeight-switchButtonLabel.height
                    sourceSize.width:   _buttonWidthHeight-switchButtonLabel.height
                    fillMode:           Image.PreserveAspectCrop
                    mipmap:             true
                    smooth:             true
                    color:              switchButtonRect._showHighlight ? _switchButtonPal.buttonHighlightText : _switchButtonPal.text
                }
288

289 290 291 292 293 294 295 296
                QGCLabel {
                    id:                         switchButtonLabel
                    anchors.horizontalCenter:   parent.horizontalCenter
                    font.pointSize:             ScreenTools.smallFontPointSize
                    text:                       toolStripGrid.horizontal ? "Vert" : "Hor"
                    color:                      switchButtonRect._showHighlight ? _switchButtonPal.buttonHighlightText : _switchButtonPal.text
                    enabled:                    enableSwitchButton
                }
297
            }
298 299 300 301 302 303 304 305 306 307 308 309

            QGCMouseArea {
                anchors.fill:       parent
                visible:            enableSwitchButton
                hoverEnabled:       true
                preventStealing:    true

                onContainsMouseChanged: switchButtonRect._hovered = containsMouse
                onContainsPressChanged: switchButtonRect._hovered = containsPress

                onClicked: {
                    dropPanel.hide()    // hide affects checked, so this needs to be duplicated inside not outside if
310 311
                    if (toolStripGrid.horizontal === true) {
                        toolStripGrid.horizontal = false
312
                    } else {
313
                        toolStripGrid.horizontal = true
314 315 316 317 318
                    }
                }
            }
        } // switchButton Rectangle
    } // GridLayout
319 320 321 322 323 324

    DropPanel {
        id:         dropPanel
        toolStrip:  _root
    }
}