ToolStrip.qml 14.7 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 17 18 19

import QGroundControl.ScreenTools   1.0
import QGroundControl.Palette       1.0

Rectangle {
    id:         _root
    color:      qgcPal.window
20 21
    width:      toolStripGrid.width + (toolStripGrid.anchors.margins * 2)
    height:     toolStripGrid.height + (toolStripGrid.anchors.margins * 2)
22
    radius:     _radius
23 24
    border.width:   1
    border.color:   qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.35) : Qt.rgba(1,1,1,0.35)
25 26 27

    property string title:              "Title"
    property alias  model:              repeater.model
28 29
    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
30
    property var    animateImage                        ///< List of bool values, one for each button in strip - true: animate image, false: static image
31 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
    property real   maxHeight                           ///< Maximum height for control, determines whether text is hidden to make control shorter
34 35 36 37
    property bool   horizontal:         false           /// toolstrip horizontal or vertical ?
    property bool   enableSwitchButton: false           /// enable horizontal vertical button ?


38 39 40

    signal clicked(int index, bool checked)

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

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

    Component.onCompleted: toolStripGrid.horizontal = _root.horizontal

    onHorizontalChanged: toolStripGrid.horizontal = _root.horizontal
50

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

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

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

68
    Grid {
69
        id:                 toolStripGrid
70 71 72
        anchors.margins:    ScreenTools.defaultFontPixelWidth  / 2
        anchors.top:        parent.top
        anchors.left:       parent.left
73 74
        columnSpacing:      _buttonSpacing
        rowSpacing:         _buttonSpacing
75 76 77 78
        rows:               toolStripGrid.horizontal  ?            1 : model.length
        columns:            toolStripGrid.horizontal  ? model.length : 1

        property bool horizontal
79 80 81

        QGCLabel {
            text:                       title
82
            font.pointSize:             ScreenTools.mobile ? ScreenTools.smallFontPointSize : ScreenTools.defaultFontPointSize
83 84
            Layout.alignment:           toolStripGrid.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter

85 86
        }

87

88
        // separator
89
        Rectangle {
90 91
            height:             toolStripGrid.horizontal ? _buttonWidthHeight : 1
            width:              toolStripGrid.horizontal ? 1 : _buttonWidthHeight
92 93 94
            color:              qgcPal.text
        }

95
        GridLayout {
96 97
            rows:           toolStripGrid.horizontal ?            1 : model.length
            columns:        toolStripGrid.horizontal ? model.length : 1
98 99
            columnSpacing:  _buttonSpacing
            rowSpacing:     _buttonSpacing
Don Gagne's avatar
Don Gagne committed
100

101

Don Gagne's avatar
Don Gagne committed
102 103 104 105 106
            Repeater {
                id: repeater

                delegate: FocusScope {
                    id:         scope
107
                    width:      buttonRect.width
Don Gagne's avatar
Don Gagne committed
108 109
                    height:     buttonRect.height
                    visible:    _root.buttonVisible ? _root.buttonVisible[index] : true
110
                    Layout.alignment: toolStripGrid.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
Don Gagne's avatar
Don Gagne committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

                    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)
                        }
130 131
                    }

Don Gagne's avatar
Don Gagne committed
132 133 134 135 136 137 138 139
                    onRotateImageChanged: {
                        if (rotateImage) {
                            imageRotation.running = true
                        } else {
                            imageRotation.running = false
                            buttonImage.rotation = 0
                        }
                    }
140

Don Gagne's avatar
Don Gagne committed
141 142 143 144 145 146 147 148
                    onAnimateImageChanged: {
                        if (animateImage) {
                            opacityAnimation.running = true
                        } else {
                            opacityAnimation.running = false
                            buttonImage.opacity = 1
                        }
                    }
149

150
                    Rectangle {
Don Gagne's avatar
Don Gagne committed
151 152
                        id:             buttonRect
                        anchors.left:   parent.left
153
                        anchors.top:    parent.top
154 155
                        height:         _buttonWidthHeight
                        width:          _buttonWidthHeight
Don Gagne's avatar
Don Gagne committed
156
                        color:          _showHighlight ? _repeaterPal.buttonHighlight : _repeaterPal.window
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
                        clip:           true
                        radius:         ScreenTools.defaultFontPixelWidth/2

                        QGCColoredImage {
                            id:             buttonImage
                            height:             _buttonWidthHeight-buttonLabel.height
                            width:              _buttonWidthHeight-buttonLabel.height
                            anchors.centerIn:   parent
                            source:             _source
                            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
180 181
                            }

182 183 184 185 186 187 188
                            NumberAnimation on opacity {
                                id:         opacityAnimation
                                running:    false
                                from:       0
                                to:         1.0
                                loops:      Animation.Infinite
                                duration:   2000
189
                            }
190 191 192 193 194 195 196 197 198 199 200 201
                        }

                        QGCLabel {
                            id:                         buttonLabel
                            anchors.horizontalCenter:   parent.horizontalCenter
                            anchors.bottom:             parent.bottom
                            font.pointSize:             ScreenTools.smallFontPointSize
                            text:                       modelData.name
                            color:                      _showHighlight ? _repeaterPal.buttonHighlightText : _repeaterPal.text
                            enabled:                    _buttonEnabled
                        }

202

203
                        QGCMouseArea {
Don Gagne's avatar
Don Gagne committed
204 205 206 207 208 209 210
                            anchors.fill:       parent
                            visible:            _buttonEnabled
                            hoverEnabled:       true
                            preventStealing:    true

                            onContainsMouseChanged: _hovered = containsMouse
                            onContainsPressChanged: _hovered = containsPress
211 212 213 214 215 216 217 218 219 220 221 222

                            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)
223
                                } else {
224 225 226 227 228 229 230 231 232
                                    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)
                                    }
233 234 235
                                }
                            }
                        }
Don Gagne's avatar
Don Gagne committed
236 237
                    } // Rectangle
                } // FocusScope
238 239 240 241 242
            } // Repeater
        } // GridLayout

        // separator
        Rectangle {
243 244
            height:             toolStripGrid.horizontal ? _buttonWidthHeight : 1
            width:              toolStripGrid.horizontal ? 1 : _buttonWidthHeight
245 246
            color:              qgcPal.text
            visible:            enableSwitchButton
247
        }
248 249 250 251

        // switch button, tool strip horizontal <-> vertical
        Rectangle {
            id:             switchButtonRect
252 253
            height:         _buttonWidthHeight
            width:          _buttonWidthHeight
254
            color:          _showHighlight ? _switchButtonPal.buttonHighlight : _switchButtonPal.window
255 256
            visible:       enableSwitchButton            
            radius:         ScreenTools.defaultFontPixelWidth/2
257 258 259 260 261 262

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

            QGCPalette { id: _switchButtonPal; colorGroupEnabled: enableSwitchButton }

263 264 265 266 267 268 269 270 271 272 273 274 275 276
            QGCColoredImage {
                id:             switchButtonImage
                height:             _buttonWidthHeight-switchButtonLabel.height
                width:              _buttonWidthHeight-switchButtonLabel.height
                anchors.top:        parent.top
                anchors.centerIn:   parent
                source:             "/res/clockwise-arrow.svg"
                sourceSize.height:  _buttonWidthHeight-switchButtonLabel.height
                sourceSize.width:   _buttonWidthHeight-switchButtonLabel.height
                fillMode:           Image.PreserveAspectCrop
                mipmap:             true
                smooth:             true
                color:              switchButtonRect._showHighlight ? _switchButtonPal.buttonHighlightText : _switchButtonPal.text
            }
277

278 279 280 281 282 283 284 285 286
            QGCLabel {
                id:                         switchButtonLabel
                anchors.horizontalCenter:   parent.horizontalCenter
                anchors.bottom:             parent.bottom
                font.pointSize:             ScreenTools.smallFontPointSize
                text:                       toolStripGrid.horizontal ? "Vert" : "Hor"
                color:                      switchButtonRect._showHighlight ? _switchButtonPal.buttonHighlightText : _switchButtonPal.text
                enabled:                    enableSwitchButton
            }
287 288 289 290 291 292 293 294 295 296 297 298

            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
299 300
                    if (toolStripGrid.horizontal === true) {
                        toolStripGrid.horizontal = false
301
                    } else {
302
                        toolStripGrid.horizontal = true
303 304 305 306 307
                    }
                }
            }
        } // switchButton Rectangle
    } // GridLayout
308 309 310 311 312 313

    DropPanel {
        id:         dropPanel
        toolStrip:  _root
    }
}