From 6940e70c1e91bfdc834bdbfce8c19231a94db330 Mon Sep 17 00:00:00 2001 From: Gus Grubba Date: Sat, 24 Aug 2019 00:00:46 -0400 Subject: [PATCH] Plan View Work Toggle Rally Point insertion on/off. Highlight current Rally Point and current Waypoint. Use tab bar instead of a row of radio buttons for selection (Mission, Fence, Rally). Fix QGCHoverButton to handle proper checked state toggle. Get rid of the many arrays used to define behaviors for the ToolStrip. They are now all defined within its model. Fixed color for disabled text within ToolStrip (it was invisible) --- src/FlightDisplay/FlightDisplayView.qml | 47 ++-- src/FlightDisplay/GuidedActionList.qml | 2 +- .../MapItems/MissionItemIndicator.qml | 2 +- src/FlightMap/MapItems/MissionItemView.qml | 11 +- src/MissionManager/RallyPointController.h | 4 +- src/PlanView/PlanView.qml | 251 +++++++++--------- src/PlanView/RallyPointEditorHeader.qml | 4 +- src/PlanView/RallyPointItemEditor.qml | 6 +- src/PlanView/RallyPointMapVisuals.qml | 10 +- src/PlanView/SimpleItemMapVisual.qml | 9 +- src/QGCPalette.cc | 2 +- src/QmlControls/MissionItemIndexLabel.qml | 12 + src/QmlControls/QGCHoverButton.qml | 36 ++- src/QmlControls/QGCTabButton.qml | 5 +- src/QmlControls/ToolStrip.qml | 43 ++- 15 files changed, 228 insertions(+), 216 deletions(-) diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml index 156bd931b..0554db1fb 100644 --- a/src/FlightDisplay/FlightDisplayView.qml +++ b/src/FlightDisplay/FlightDisplayView.qml @@ -581,9 +581,6 @@ Item { z: _mapAndVideo.z + 4 maxHeight: (_flightVideo.visible ? _flightVideo.y : parent.height) - toolStrip.y - buttonVisible: [true, _useChecklist, _guidedController.showTakeoff || !_guidedController.showLand, _guidedController.showLand && !_guidedController.showTakeoff, true, _guidedController.showPause, !_guidedController.showPause ] - buttonEnabled: [true, _useChecklist && activeVehicle && !activeVehicle.armed, _guidedController.showTakeoff, _guidedController.showLand, _guidedController.showRTL, _guidedController.showPause, _anyActionAvailable ] - property bool _anyActionAvailable: _guidedController.showStartMission || _guidedController.showResumeMission || _guidedController.showChangeAlt || _guidedController.showLandAbort property var _actionModel: [ { @@ -622,35 +619,49 @@ Item { { name: "Plan", iconSource: "/qmlimages/Plan.svg", + buttonVisible: true, + buttonEnabled: true, }, { name: "Checklist", iconSource: "/qmlimages/check.svg", + buttonVisible: _useChecklist, + buttonEnabled: _useChecklist && activeVehicle && !activeVehicle.armed, }, { - name: _guidedController.takeoffTitle, - iconSource: "/res/takeoff.svg", - action: _guidedController.actionTakeoff + name: _guidedController.takeoffTitle, + iconSource: "/res/takeoff.svg", + buttonVisible: _guidedController.showTakeoff || !_guidedController.showLand, + buttonEnabled: _guidedController.showTakeoff, + action: _guidedController.actionTakeoff }, { - name: _guidedController.landTitle, - iconSource: "/res/land.svg", - action: _guidedController.actionLand + name: _guidedController.landTitle, + iconSource: "/res/land.svg", + buttonVisible: _guidedController.showLand && !_guidedController.showTakeoff, + buttonEnabled: _guidedController.showLand, + action: _guidedController.actionLand }, { - name: _guidedController.rtlTitle, - iconSource: "/res/rtl.svg", - action: _guidedController.actionRTL + name: _guidedController.rtlTitle, + iconSource: "/res/rtl.svg", + buttonVisible: true, + buttonEnabled: _guidedController.showRTL, + action: _guidedController.actionRTL }, { - name: _guidedController.pauseTitle, - iconSource: "/res/pause-mission.svg", - action: _guidedController.actionPause + name: _guidedController.pauseTitle, + iconSource: "/res/pause-mission.svg", + buttonVisible: _guidedController.showPause, + buttonEnabled: _guidedController.showPause, + action: _guidedController.actionPause }, { - name: qsTr("Action"), - iconSource: "/res/action.svg", - action: -1 + name: qsTr("Action"), + iconSource: "/res/action.svg", + buttonVisible: !_guidedController.showPause, + buttonEnabled: _anyActionAvailable, + action: -1 } ] diff --git a/src/FlightDisplay/GuidedActionList.qml b/src/FlightDisplay/GuidedActionList.qml index 9995fcf56..3ceaf7f83 100644 --- a/src/FlightDisplay/GuidedActionList.qml +++ b/src/FlightDisplay/GuidedActionList.qml @@ -74,7 +74,7 @@ Rectangle { QGCLabel { id: actionMessage - text: modelData.text + text: modelData.text ? modelData.text : "" horizontalAlignment: Text.AlignHCenter wrapMode: Text.WordWrap Layout.minimumWidth: _width diff --git a/src/FlightMap/MapItems/MissionItemIndicator.qml b/src/FlightMap/MapItems/MissionItemIndicator.qml index d4f3f70d4..0eaf8bf43 100644 --- a/src/FlightMap/MapItems/MissionItemIndicator.qml +++ b/src/FlightMap/MapItems/MissionItemIndicator.qml @@ -36,8 +36,8 @@ MapQuickItem { gimbalYaw: missionItem.missionGimbalYaw vehicleYaw: missionItem.missionVehicleYaw showGimbalYaw: !isNaN(missionItem.missionGimbalYaw) + highlightSelected: true onClicked: _item.clicked() - property bool _isCurrentItem: missionItem ? missionItem.isCurrentItem : false } } diff --git a/src/FlightMap/MapItems/MissionItemView.qml b/src/FlightMap/MapItems/MissionItemView.qml index d3ea2173f..14c54182c 100644 --- a/src/FlightMap/MapItems/MissionItemView.qml +++ b/src/FlightMap/MapItems/MissionItemView.qml @@ -33,19 +33,16 @@ MapItemView { parent._retaskSequence = object.sequenceNumber parent.flightWidgets.guidedModeBar.confirmAction(parent.flightWidgets.guidedModeBar.confirmRetask) } - // These are the non-coordinate child mission items attached to this item Row { anchors.top: parent.top anchors.left: parent.right - Repeater { - model: object.childItems - + model: object.childItems delegate: MissionItemIndexLabel { - label: object.abbreviation - checked: object.isCurrentItem - z: 2 + label: object.abbreviation + checked: object.isCurrentItem + z: 2 } } } diff --git a/src/MissionManager/RallyPointController.h b/src/MissionManager/RallyPointController.h index 7543642ed..d443b39ea 100644 --- a/src/MissionManager/RallyPointController.h +++ b/src/MissionManager/RallyPointController.h @@ -33,8 +33,8 @@ public: Q_PROPERTY(QString editorQml READ editorQml CONSTANT) Q_PROPERTY(QObject* currentRallyPoint READ currentRallyPoint WRITE setCurrentRallyPoint NOTIFY currentRallyPointChanged) - Q_INVOKABLE void addPoint(QGeoCoordinate point); - Q_INVOKABLE void removePoint(QObject* rallyPoint); + Q_INVOKABLE void addPoint (QGeoCoordinate point); + Q_INVOKABLE void removePoint (QObject* rallyPoint); bool supported (void) const final; void save (QJsonObject& json) final; diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 70c66ef35..8ec600817 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -52,10 +52,12 @@ Item { property bool _addWaypointOnClick: false property bool _addROIOnClick: false property bool _singleComplexItem: _missionController.complexMissionItemNames.length === 1 - property int _editingLayer: _layerMission + property int _editingLayer: bar.currentIndex ? _layers[bar.currentIndex] : _layerMission property int _toolStripBottom: toolStrip.height + toolStrip.y property var _appSettings: QGroundControl.settingsManager.appSettings + readonly property var _layers: [_layerMission, _layerGeoFence, _layerRallyPoints] + readonly property int _layerMission: 1 readonly property int _layerGeoFence: 2 readonly property int _layerRallyPoints: 3 @@ -447,7 +449,7 @@ Item { } break case _layerRallyPoints: - if (_rallyPointController.supported) { + if (_rallyPointController.supported && _addWaypointOnClick) { _rallyPointController.addPoint(coordinate) } break @@ -523,91 +525,111 @@ Item { //----------------------------------------------------------- // Left tool strip - ToolStrip { + ToolStrip { id: toolStrip anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2 anchors.left: parent.left anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5 anchors.top: parent.top z: QGroundControl.zOrderWidgets + maxHeight: mapScale.y - toolStrip.y - showAlternateIcon: [ false, _planMasterController.dirty, false, false, false, false, false, false ] - rotateImage: [ false, _planMasterController.syncInProgress, false, false, false, false, false, false ] - animateImage: [ false, _planMasterController.dirty, false, false, false, false, false, false ] - buttonEnabled: [ true, !_planMasterController.syncInProgress, true, true, true, true, true, true ] - buttonVisible: [ true, true, true, _waypointsOnlyMode, true, true, _showZoom, _showZoom ] - maxHeight: mapScale.y - toolStrip.y - - property bool _showZoom: !ScreenTools.isMobile + property bool _isRally: _editingLayer == _layerRallyPoints + property bool _showZoom: !ScreenTools.isMobile - model: [ - { - name: qsTr("Fly"), - iconSource: "/qmlimages/PaperPlane.svg", + model: [ + { + name: qsTr("Fly"), + iconSource: "/qmlimages/PaperPlane.svg", + buttonEnabled: true, + buttonVisible: true, }, { - name: qsTr("File"), - iconSource: "/qmlimages/MapSync.svg", - alternateIconSource: "/qmlimages/MapSyncChanged.svg", - dropPanelComponent: syncDropPanel - }, - { - name: qsTr("Waypoint"), - iconSource: "/qmlimages/MapAddMission.svg", - toggle: true - }, - { - name: qsTr("ROI"), - iconSource: "/qmlimages/MapAddMission.svg", - toggle: true - }, - { - name: _singleComplexItem ? _missionController.complexMissionItemNames[0] : qsTr("Pattern"), - iconSource: "/qmlimages/MapDrawShape.svg", - dropPanelComponent: _singleComplexItem ? undefined : patternDropPanel - }, - { - name: qsTr("Center"), - iconSource: "/qmlimages/MapCenter.svg", - dropPanelComponent: centerMapDropPanel - }, - { - name: qsTr("In"), - iconSource: "/qmlimages/ZoomPlus.svg" - }, - { - name: qsTr("Out"), - iconSource: "/qmlimages/ZoomMinus.svg" - } - ] + name: qsTr("File"), + iconSource: "/qmlimages/MapSync.svg", + buttonEnabled: !_planMasterController.syncInProgress, + buttonVisible: true, + showAlternateIcon: _planMasterController.dirty, + alternateIconSource:"/qmlimages/MapSyncChanged.svg", + dropPanelComponent: syncDropPanel + }, + { + name: _editingLayer == _layerRallyPoints ? qsTr("Rally Point") : qsTr("Waypoint"), + iconSource: "/qmlimages/MapAddMission.svg", + buttonEnabled: true, + buttonVisible: true, + toggle: true, + checked: _addWaypointOnClick + }, + { + name: qsTr("ROI"), + iconSource: "/qmlimages/MapAddMission.svg", + buttonEnabled: true, + buttonVisible: !_isRally && _waypointsOnlyMode, + toggle: true + }, + { + name: _singleComplexItem ? _missionController.complexMissionItemNames[0] : qsTr("Pattern"), + iconSource: "/qmlimages/MapDrawShape.svg", + buttonEnabled: true, + buttonVisible: !_isRally, + dropPanelComponent: _singleComplexItem ? undefined : patternDropPanel + }, + { + name: qsTr("Center"), + iconSource: "/qmlimages/MapCenter.svg", + buttonEnabled: true, + buttonVisible: true, + dropPanelComponent: centerMapDropPanel + }, + { + name: qsTr("In"), + buttonEnabled: true, + buttonVisible: _showZoom, + iconSource: "/qmlimages/ZoomPlus.svg" + }, + { + name: qsTr("Out"), + buttonEnabled: true, + buttonVisible: _showZoom, + iconSource: "/qmlimages/ZoomMinus.svg" + } + ] - onClicked: { - switch (index) { + onClicked: { + switch (index) { case 0: mainWindow.showFlyView() break; case 2: + if(_addWaypointOnClick) { + //-- Toggle it off + _addWaypointOnClick = false + _addROIOnClick = false + setChecked(index, false) + } else { _addWaypointOnClick = checked _addROIOnClick = false - break + } + break case 3: - _addROIOnClick = checked - _addWaypointOnClick = false - break + _addROIOnClick = checked + _addWaypointOnClick = false + break case 4: - if (_singleComplexItem) { - addComplexItem(_missionController.complexMissionItemNames[0]) - } - break - case 6: + if (_singleComplexItem) { + addComplexItem(_missionController.complexMissionItemNames[0]) + } + break + case 6: editorMap.zoomLevel += 0.5 break case 7: - editorMap.zoomLevel -= 0.5 - break - } + editorMap.zoomLevel -= 0.5 + break } } + } //----------------------------------------------------------- // Right pane for mission editing controls @@ -626,6 +648,9 @@ Item { Item { anchors.fill: rightPanel anchors.topMargin: _toolButtonTopMargin + DeadMouseArea { + anchors.fill: parent + } Column { id: rightControls spacing: ScreenTools.defaultFontPixelHeight * 0.5 @@ -693,55 +718,33 @@ Item { Rectangle { id: planExpanded width: parent.width - height: (!planControlColapsed || !_airspaceEnabled) ? expandedCol.height + ScreenTools.defaultFontPixelHeight : 0 + height: (!planControlColapsed || !_airspaceEnabled) ? bar.height + ScreenTools.defaultFontPixelHeight : 0 color: qgcPal.missionItemEditor radius: _radius - visible: !planControlColapsed || !_airspaceEnabled + visible: (!planControlColapsed || !_airspaceEnabled) && QGroundControl.corePlugin.options.enablePlanViewSelector Item { - height: expandedCol.height + height: bar.height anchors.left: parent.left anchors.right: parent.right + anchors.margins: ScreenTools.defaultFontPixelWidth anchors.verticalCenter: parent.verticalCenter - Column { - id: expandedCol - spacing: ScreenTools.defaultFontPixelHeight * 0.5 - anchors.left: parent.left - anchors.right: parent.right - //-- Header - Row { - id: expandedRow - spacing: ScreenTools.defaultFontPixelWidth - anchors.left: parent.left - anchors.leftMargin: ScreenTools.defaultFontPixelWidth - readonly property real _buttonRadius: ScreenTools.defaultFontPixelHeight * 0.75 - QGCLabel { - text: qsTr("Plan") - color: qgcPal.text - visible: !QGroundControl.corePlugin.options.enablePlanViewSelector - anchors.verticalCenter: parent.verticalCenter - } - QGCRadioButton { - id: planElementMission - text: qsTr("Mission") - checked: true - visible: QGroundControl.corePlugin.options.enablePlanViewSelector - anchors.verticalCenter: parent.verticalCenter - onClicked: _editingLayer = _layerMission - } - QGCRadioButton { - id: planElementGeoFence - text: qsTr("Fence") - visible: QGroundControl.corePlugin.options.enablePlanViewSelector - anchors.verticalCenter: parent.verticalCenter - onClicked: _editingLayer = _layerGeoFence - } - QGCRadioButton { - id: planElementRallyPoints - text: qsTr("Rally") - visible: QGroundControl.corePlugin.options.enablePlanViewSelector - anchors.verticalCenter: parent.verticalCenter - onClicked: _editingLayer = _layerRallyPoints - } + QGCTabBar { + id: bar + width: parent.width + anchors.centerIn: parent + Component.onCompleted: { + currentIndex = 0 + } + QGCTabButton { + text: qsTr("Mission") + } + QGCTabButton { + text: qsTr("Fence") + enabled: _geoFenceController.supported + } + QGCTabButton { + text: qsTr("Rally") + enabled: _rallyPointController.supported } } } @@ -754,29 +757,29 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.top: rightControls.bottom - anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5 + anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 anchors.bottom: parent.bottom anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 0.25 visible: _editingLayer == _layerMission && !planControlColapsed QGCListView { - id: missionItemEditorListView - anchors.fill: parent - spacing: ScreenTools.defaultFontPixelHeight / 4 - orientation: ListView.Vertical - model: _missionController.visualItems - cacheBuffer: Math.max(height * 2, 0) - clip: true - currentIndex: _missionController.currentPlanViewIndex + id: missionItemEditorListView + anchors.fill: parent + spacing: ScreenTools.defaultFontPixelHeight / 4 + orientation: ListView.Vertical + model: _missionController.visualItems + cacheBuffer: Math.max(height * 2, 0) + clip: true + currentIndex: _missionController.currentPlanViewIndex highlightMoveDuration: 250 - visible: _editingLayer == _layerMission && !planControlColapsed + visible: _editingLayer == _layerMission && !planControlColapsed //-- List Elements delegate: MissionItemEditor { - map: editorMap + map: editorMap masterController: _planMasterController - missionItem: object - width: parent.width - readOnly: false - onClicked: _missionController.setCurrentPlanViewIndex(object.sequenceNumber, false) + missionItem: object + width: parent.width + readOnly: false + onClicked: _missionController.setCurrentPlanViewIndex(object.sequenceNumber, false) onRemove: { var removeIndex = index _missionController.removeMissionItem(removeIndex) @@ -793,7 +796,7 @@ Item { // GeoFence Editor GeoFenceEditor { anchors.top: rightControls.bottom - anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5 + anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right @@ -805,7 +808,7 @@ Item { RallyPointEditorHeader { id: rallyPointHeader anchors.top: rightControls.bottom - anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5 + anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 anchors.left: parent.left anchors.right: parent.right visible: _editingLayer == _layerRallyPoints @@ -814,7 +817,7 @@ Item { RallyPointItemEditor { id: rallyPointEditor anchors.top: rallyPointHeader.bottom - anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5 + anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 anchors.left: parent.left anchors.right: parent.right visible: _editingLayer == _layerRallyPoints && _rallyPointController.points.count diff --git a/src/PlanView/RallyPointEditorHeader.qml b/src/PlanView/RallyPointEditorHeader.qml index 0c5d677c8..0e8283b34 100644 --- a/src/PlanView/RallyPointEditorHeader.qml +++ b/src/PlanView/RallyPointEditorHeader.qml @@ -36,7 +36,7 @@ QGCFlickable { anchors.left: parent.left anchors.right: parent.right anchors.top: editorLabel.bottom - height: helpLabel.height + helpLabel.height + (_margin * 2) + height: infoLabel.height + (_margin * 2) color: qgcPal.windowShadeDark radius: _radius @@ -51,6 +51,7 @@ QGCFlickable { text: qsTr("Rally Points provide alternate landing points when performing a Return to Launch (RTL).") } + /* QGCLabel { id: helpLabel anchors.margins: _margin @@ -62,6 +63,7 @@ QGCFlickable { qsTr("Click in the map to add new rally points.") : qsTr("This vehicle does not support Rally Points.") } + */ } } } diff --git a/src/PlanView/RallyPointItemEditor.qml b/src/PlanView/RallyPointItemEditor.qml index 5d68bc5e2..ceabf4044 100644 --- a/src/PlanView/RallyPointItemEditor.qml +++ b/src/PlanView/RallyPointItemEditor.qml @@ -14,11 +14,13 @@ Rectangle { color: _currentItem ? qgcPal.missionItemEditor : qgcPal.windowShade radius: _radius + signal clicked() + property var rallyPoint ///< RallyPoint object associated with editor property var controller ///< RallyPointController property bool _currentItem: rallyPoint ? rallyPoint === controller.currentRallyPoint : false - property color _outerTextColor: _currentItem ? "black" : qgcPal.text + property color _outerTextColor: qgcPal.text // _currentItem ? "black" : qgcPal.text readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2 readonly property real _radius: ScreenTools.defaultFontPixelWidth / 2 @@ -101,7 +103,6 @@ Rectangle { Repeater { model: rallyPoint ? rallyPoint.textFieldFacts : 0 - QGCLabel { text: modelData.name + ":" } @@ -109,7 +110,6 @@ Rectangle { Repeater { model: rallyPoint ? rallyPoint.textFieldFacts : 0 - FactTextField { Layout.fillWidth: true showUnits: true diff --git a/src/PlanView/RallyPointMapVisuals.qml b/src/PlanView/RallyPointMapVisuals.qml index 1586b4c8c..890660006 100644 --- a/src/PlanView/RallyPointMapVisuals.qml +++ b/src/PlanView/RallyPointMapVisuals.qml @@ -67,11 +67,11 @@ Item { property var rallyPointObject sourceItem: MissionItemIndexLabel { - id: itemIndexLabel - label: qsTr("R", "rally point map item label") - checked: _editingLayer == _layerRallyPoints ? rallyPointObject === myRallyPointController.currentRallyPoint : false - - onClicked: myRallyPointController.currentRallyPoint = rallyPointObject + id: itemIndexLabel + label: qsTr("R", "rally point map item label") + checked: _editingLayer == _layerRallyPoints ? rallyPointObject === myRallyPointController.currentRallyPoint : false + highlightSelected: true + onClicked: myRallyPointController.currentRallyPoint = rallyPointObject } } } diff --git a/src/PlanView/SimpleItemMapVisual.qml b/src/PlanView/SimpleItemMapVisual.qml index 2ff9eaf6e..b10939428 100644 --- a/src/PlanView/SimpleItemMapVisual.qml +++ b/src/PlanView/SimpleItemMapVisual.qml @@ -108,25 +108,20 @@ Item { z: QGroundControl.zOrderMapItems missionItem: _missionItem sequenceNumber: _missionItem.sequenceNumber - - onClicked: _root.clicked(_missionItem.sequenceNumber) - + onClicked: _root.clicked(_missionItem.sequenceNumber) // These are the non-coordinate child mission items attached to this item Row { anchors.top: parent.top anchors.left: parent.right - Repeater { model: _missionItem.childItems - delegate: MissionItemIndexLabel { z: 2 label: object.abbreviation.length === 0 ? object.sequenceNumber : object.abbreviation.charAt(0) checked: object.isCurrentItem child: true specifiesCoordinate: false - - onClicked: _root.clicked(object.sequenceNumber) + onClicked: _root.clicked(object.sequenceNumber) } } } diff --git a/src/QGCPalette.cc b/src/QGCPalette.cc index e74574679..97c0bf4e5 100644 --- a/src/QGCPalette.cc +++ b/src/QGCPalette.cc @@ -56,7 +56,7 @@ void QGCPalette::_buildMap() DECLARE_QGC_COLOR(text, "#9d9d9d", "#000000", "#707070", "#ffffff") DECLARE_QGC_COLOR(warningText, "#cc0808", "#cc0808", "#f85761", "#f85761") DECLARE_QGC_COLOR(button, "#ffffff", "#ffffff", "#707070", "#626270") - DECLARE_QGC_COLOR(buttonText, "#9d9d9d", "#000000", "#202020", "#ffffff") + DECLARE_QGC_COLOR(buttonText, "#9d9d9d", "#000000", "#A6A6A6", "#ffffff") DECLARE_QGC_COLOR(buttonHighlight, "#e4e4e4", "#946120", "#3a3a3a", "#fff291") DECLARE_QGC_COLOR(buttonHighlightText, "#2c2c2c", "#ffffff", "#2c2c2c", "#000000") DECLARE_QGC_COLOR(primaryButton, "#585858", "#8cb3be", "#585858", "#8cb3be") diff --git a/src/QmlControls/MissionItemIndexLabel.qml b/src/QmlControls/MissionItemIndexLabel.qml index 28a8eed3a..18ea19c5a 100644 --- a/src/QmlControls/MissionItemIndexLabel.qml +++ b/src/QmlControls/MissionItemIndexLabel.qml @@ -17,6 +17,7 @@ Canvas { property bool checked: false property bool small: false property bool child: false + property bool highlightSelected: false property var color: checked ? "green" : (child ? qgcPal.mapIndicatorChild : qgcPal.mapIndicator) property real anchorPointX: _height / 2 property real anchorPointY: _height / 2 @@ -114,6 +115,17 @@ Canvas { } } + Rectangle { + width: indicator.width * 2 + height: width + radius: width * 0.5 + color: Qt.rgba(0,0,0,0) + border.color: Qt.rgba(1,1,1,0.5) + border.width: 1 + visible: checked && highlightSelected + anchors.centerIn: indicator + } + QGCMouseArea { fillItem: parent onClicked: { diff --git a/src/QmlControls/QGCHoverButton.qml b/src/QmlControls/QGCHoverButton.qml index 43d1d8f92..134b83a3a 100644 --- a/src/QmlControls/QGCHoverButton.qml +++ b/src/QmlControls/QGCHoverButton.qml @@ -30,10 +30,8 @@ Button { QGCPalette { id: qgcPalDisabled; colorGroupEnabled: false } // Initial state - state: "Default" + state: "Default" // Update state on status changed - onEnabledChanged: state = "Default" - // Content Icon + Text contentItem: Item { id: contentLayoutItem @@ -79,8 +77,8 @@ Button { name: "Hovering" PropertyChanges { target: button; - _currentColor: (checked || pressed) ? qgcPal.buttonHighlight : qgcPal.hoverColor - _currentContentColor: qgcPal.buttonHighlightText + _currentColor: (checked || pressed) ? qgcPal.buttonHighlight : qgcPal.hoverColor + _currentContentColor: qgcPal.buttonHighlightText } PropertyChanges { target: buttonBkRect @@ -91,8 +89,8 @@ Button { name: "Default" PropertyChanges { target: button; - _currentColor: enabled ? ((checked || pressed) ? qgcPal.buttonHighlight : qgcPal.button) : qgcPalDisabled.button - _currentContentColor: enabled ? ((checked || pressed) ? qgcPal.buttonHighlightText : qgcPal.buttonText) : qgcPalDisabled.buttonText + _currentColor: enabled ? ((checked || pressed) ? qgcPal.buttonHighlight : qgcPal.button) : qgcPalDisabled.button + _currentContentColor: enabled ? ((checked || pressed) ? qgcPal.buttonHighlightText : qgcPal.buttonText) : qgcPalDisabled.buttonText } PropertyChanges { target: buttonBkRect @@ -114,19 +112,19 @@ Button { // Process hover events MouseArea { - enabled: !ScreenTools.isMobile - hoverEnabled: true + enabled: !ScreenTools.isMobile propagateComposedEvents: true - preventStealing: true - anchors.fill: button - onEntered: { button.state = 'Hovering'; } - onExited: { button.state = 'Default'; } + hoverEnabled: true + preventStealing: true + anchors.fill: button + onEntered: button.state = 'Hovering' + onExited: button.state = 'Default' // Propagate events down - onClicked: { mouse.accepted = false; } - onDoubleClicked: { mouse.accepted = false; } - onPositionChanged: { mouse.accepted = false; } - onPressAndHold: { mouse.accepted = false; } - onPressed: { mouse.accepted = false } - onReleased: { mouse.accepted = false } + onClicked: { mouse.accepted = false; } + onDoubleClicked: { mouse.accepted = false; } + onPositionChanged: { mouse.accepted = false; } + onPressAndHold: { mouse.accepted = false; } + onPressed: { mouse.accepted = false } + onReleased: { mouse.accepted = false } } } diff --git a/src/QmlControls/QGCTabButton.qml b/src/QmlControls/QGCTabButton.qml index da72e0e28..68562d865 100644 --- a/src/QmlControls/QGCTabButton.qml +++ b/src/QmlControls/QGCTabButton.qml @@ -9,12 +9,13 @@ import QGroundControl.ScreenTools 1.0 TabButton { id: control property bool _showHighlight: (pressed | hovered | checked) + QGCPalette { id: qgcPalDisabled; colorGroupEnabled: false } background: Rectangle { - color: _showHighlight ? qgcPal.buttonHighlight : qgcPal.button + color: enabled ? (_showHighlight ? qgcPal.buttonHighlight : qgcPal.button) : qgcPalDisabled.button } contentItem: QGCLabel { text: control.text - color: _showHighlight ? qgcPal.buttonHighlightText : qgcPal.buttonText + color: enabled ? (_showHighlight ? qgcPal.buttonHighlightText : qgcPal.buttonText) : qgcPalDisabled.buttonText horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight diff --git a/src/QmlControls/ToolStrip.qml b/src/QmlControls/ToolStrip.qml index 6cf9b3e46..5c09c5252 100644 --- a/src/QmlControls/ToolStrip.qml +++ b/src/QmlControls/ToolStrip.qml @@ -23,12 +23,7 @@ Rectangle { radius: ScreenTools.defaultFontPixelWidth / 2 property alias model: repeater.model - property var rotateImage ///< List of bool values, one for each button in strip - true: animation rotation, false: static image - property var animateImage ///< List of bool values, one for each button in strip - true: animate image, false: static image - 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 - property var showAlternateIcon ///< List of bool values, one for each button in strip - true: show alternate icon, false: show normal icon property AbstractButton lastClickedButton: null @@ -37,9 +32,17 @@ Rectangle { signal clicked(int index, bool checked) + function setChecked(idx, check) { + repeater.itemAt(idx).checked = check + } + + function getChecked(idx) { + return repeater.itemAt(idx).checked + } + ButtonGroup { - id: buttonGroup - exclusive: false + id: buttonGroup + buttons: toolStripColumn.children } Column { @@ -54,21 +57,20 @@ Rectangle { id: repeater QGCHoverButton { - id: buttonTemplate + id: buttonTemplate anchors.left: toolStripColumn.left anchors.right: toolStripColumn.right height: width radius: ScreenTools.defaultFontPixelWidth / 2 fontPointSize: ScreenTools.smallFontPointSize + autoExclusive: true - enabled: _root.buttonEnabled ? _root.buttonEnabled[index] : true - visible: _root.buttonVisible ? _root.buttonVisible[index] : true - imageSource: (_root.showAlternateIcon && _root.showAlternateIcon[index]) ? _alternateIconSource : _iconSource + enabled: modelData.buttonEnabled + visible: modelData.buttonVisible + imageSource: modelData.showAlternateIcon ? modelData.alternateIconSource : modelData.iconSource text: modelData.name - - property var _iconSource: modelData.iconSource - property var _alternateIconSource: modelData.alternateIconSource + checked: modelData.checked !== undefined ? modelData.checked : checked ButtonGroup.group: buttonGroup // Only drop pannel and toggleable are checkable @@ -76,23 +78,14 @@ Rectangle { onClicked: { dropPanel.hide() // DropPanel will call hide on "lastClickedButton" - - // Uncheck other checked buttons - // TODO: Implement ButtonGroup exclusive with checkable and uncheckable and get rid of this workaround - for(var i = 0; i < buttonGroup.buttons.length; i++) { - var b = buttonGroup.buttons[i] - if(b !== buttonTemplate) { - b.checked = false; - } - } - if (modelData.dropPanelComponent === undefined) { _root.clicked(index, checked) } else if (checked) { var panelEdgeTopPoint = mapToItem(_root, width, 0) dropPanel.show(panelEdgeTopPoint, height, modelData.dropPanelComponent) } - lastClickedButton = buttonTemplate + if(_root && buttonTemplate) + _root.lastClickedButton = buttonTemplate } } } -- 2.22.0