diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 44fb871fffebc3dda3aa01aff5de7e92ada82940..f2cc59db892e1ebb86f97097132e679aa9066abe 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -127,6 +127,7 @@ src/QmlControls/QGCButton.qml src/QmlControls/QGCCheckBox.qml src/QmlControls/QGCColoredImage.qml + src/QmlControls/QGCControlDebug.qml src/QmlControls/QGCComboBox.qml src/QmlControls/QGCFileDialog.qml src/QmlControls/QGCFlickable.qml @@ -147,7 +148,8 @@ src/QmlControls/QGCMovableItem.qml src/QmlControls/QGCPopupDialog.qml src/QmlControls/QGCPopupDialogContainer.qml - src/QmlControls/QGCPipable.qml + src/QmlControls/QGCPipOverlay.qml + src/QmlControls/QGCPipState.qml src/QmlControls/QGCRadioButton.qml src/QmlControls/QGCSlider.qml src/QmlControls/QGCSwitch.qml diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml index e16dae0504a6ccae0ab30e47bfc4e0b20c56f9b0..5e3ec2246b559498adeef87f1895313a9c666cd0 100644 --- a/src/FlightDisplay/FlightDisplayView.qml +++ b/src/FlightDisplay/FlightDisplayView.qml @@ -39,40 +39,20 @@ Item { } } - property bool mainIsMap: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey, true) : true - property bool isBackgroundDark: mainIsMap ? (mainWindow.flightDisplayMap ? mainWindow.flightDisplayMap.isSatelliteMap : true) : true - - property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle - property var _missionController: _planController.missionController - property var _geoFenceController: _planController.geoFenceController - property var _rallyPointController: _planController.rallyPointController - property bool _isPipVisible: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false - property real _margins: ScreenTools.defaultFontPixelWidth / 2 - property real _pipSize: mainWindow.width * 0.2 - property alias _guidedController: guidedActionsController - property alias _guidedConfirm: guidedActionConfirm - property alias _guidedList: guidedActionList - property alias _guidedSlider: altitudeSlider - property real _guidedZOrder: _flightVideoPipControl.z + 1 - property real _toolsMargin: ScreenTools.defaultFontPixelWidth * 0.75 + property bool _mainWindowIsMap: mapControl.pipState.state === mapControl.pipState.fullState + property bool _isMapDark: _mainWindowIsMap ? mapControl.isSatelliteMap : true + property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle + property var _missionController: _planController.missionController + property var _geoFenceController: _planController.geoFenceController + property var _rallyPointController: _planController.rallyPointController + property real _margins: ScreenTools.defaultFontPixelWidth / 2 + property alias _guidedController: guidedActionsController + property alias _guidedConfirm: guidedActionConfirm + property alias _guidedList: guidedActionList + property alias _guidedSlider: altitudeSlider + property real _toolsMargin: ScreenTools.defaultFontPixelWidth * 0.75 readonly property string _mapName: "FlightDisplayView" - readonly property string _showMapBackgroundKey: "/showMapBackground" - readonly property string _mainIsMapKey: "MainFlyWindowIsMap" - readonly property string _PIPVisibleKey: "IsPIPVisible" - - function setStates() { - QGroundControl.saveBoolGlobalSetting(_mainIsMapKey, mainIsMap) - if(mainIsMap) { - //-- Adjust Margins - _flightMapContainer.state = "fullMode" - _flightVideo.state = "pipMode" - } else { - //-- Adjust Margins - _flightMapContainer.state = "pipMode" - _flightVideo.state = "fullMode" - } - } function setPipVisibility(state) { _isPipVisible = state; @@ -93,12 +73,6 @@ Item { return true; } - // Signal routing - Connections { - target: mainWindow - onFlightDisplayMapChanged: setStates() - } - Component.onCompleted: { if(QGroundControl.corePlugin.options.flyViewOverlay.toString().length) { flyViewOverlay.source = QGroundControl.corePlugin.options.flyViewOverlay @@ -112,180 +86,66 @@ Item { guidedController: _guidedController } - Window { - id: videoWindow - width: !mainIsMap ? _mapAndVideo.width : _pipSize - height: !mainIsMap ? _mapAndVideo.height : _pipSize * (9/16) - visible: false - - Item { - id: videoItem - anchors.fill: parent - } - - onClosing: { - _flightVideo.state = "unpopup" - videoWindow.visible = false - } - } - - /* This timer will startVideo again after the popup window appears and is loaded. - * Such approach was the only one to avoid a crash for windows users - */ - Timer { - id: videoPopUpTimer - interval: 2000; - running: false; - repeat: false - onTriggered: { - // If state is popup, the next one will be popup-finished - if (_flightVideo.state == "popup") { - _flightVideo.state = "popup-finished" - } - QGroundControl.videoManager.startVideo() - } - } - - QGCMapPalette { id: mapPal; lightColors: mainIsMap ? mainWindow.flightDisplayMap.isSatelliteMap : true } + QGCMapPalette { id: mapPal; lightColors: _mainWindowIsMap ? mapControl.isSatelliteMap : true } Item { id: _mapAndVideo anchors.fill: parent - //-- Map View - Item { - id: _flightMapContainer - z: mainIsMap ? _mapAndVideo.z + 1 : _mapAndVideo.z + 2 - anchors.left: _mapAndVideo.left - anchors.bottom: _mapAndVideo.bottom - visible: mainIsMap || _isPipVisible && !QGroundControl.videoManager.fullScreen - width: mainIsMap ? _mapAndVideo.width : _pipSize - height: mainIsMap ? _mapAndVideo.height : _pipSize * (9/16) - states: [ - State { - name: "pipMode" - PropertyChanges { - target: _flightMapContainer - anchors.margins: ScreenTools.defaultFontPixelHeight - } - }, - State { - name: "fullMode" - PropertyChanges { - target: _flightMapContainer - anchors.margins: 0 - } - } - ] - FlightDisplayViewMap { - id: _fMap - anchors.fill: parent - guidedActionsController: _guidedController - planMasterController: _planController - flightWidgets: flightDisplayViewWidgets - rightPanelWidth: ScreenTools.defaultFontPixelHeight * 9 - scaleState: (mainIsMap && flyViewOverlay.item) ? (flyViewOverlay.item.scaleState ? flyViewOverlay.item.scaleState : "bottomMode") : "bottomMode" - Component.onCompleted: { - mainWindow.flightDisplayMap = _fMap - _fMap.adjustMapSize() - } + FlightDisplayViewMap { + id: mapControl + guidedActionsController: _guidedController + planMasterController: _planController + flightWidgets: flightDisplayViewWidgets + rightPanelWidth: ScreenTools.defaultFontPixelHeight * 9 + scaleState: (_mainWindowIsMap && flyViewOverlay.item) ? (flyViewOverlay.item.scaleState ? flyViewOverlay.item.scaleState : "bottomMode") : "bottomMode" + mainWindowIsMap: _mainWindowIsMap + + property var pipState: mapPipState + QGCPipState { + id: mapPipState + pipOverlay: _pipOverlay + isDark: _isMapDark } } //-- Video View Item { - id: _flightVideo - z: mainIsMap ? _mapAndVideo.z + 2 : _mapAndVideo.z + 1 - width: !mainIsMap ? _mapAndVideo.width : _pipSize - height: !mainIsMap ? _mapAndVideo.height : _pipSize * (9/16) - anchors.left: _mapAndVideo.left - anchors.bottom: _mapAndVideo.bottom - visible: QGroundControl.videoManager.hasVideo && (!mainIsMap || _isPipVisible) - - onParentChanged: { - /* If video comes back from popup - * correct anchors. - * Such thing is not possible with ParentChange. - */ - if(parent == _mapAndVideo) { - // Do anchors again after popup - anchors.left = _mapAndVideo.left - anchors.bottom = _mapAndVideo.bottom - anchors.margins = _toolsMargin + id: videoControl + visible: QGroundControl.videoManager.hasVideo + + property var pipState: videoPipState + QGCPipState { + id: videoPipState + pipOverlay: _pipOverlay + isDark: true + + onWindowAboutToOpen: { + console.log("about to open") + QGroundControl.videoManager.stopVideo() + videoStartDelay.start() } - } - states: [ - State { - name: "pipMode" - PropertyChanges { - target: _flightVideo - anchors.margins: ScreenTools.defaultFontPixelHeight - } - PropertyChanges { - target: _flightVideoPipControl - inPopup: false - } - }, - State { - name: "fullMode" - PropertyChanges { - target: _flightVideo - anchors.margins: 0 - } - PropertyChanges { - target: _flightVideoPipControl - inPopup: false - } - }, - State { - name: "popup" - StateChangeScript { - script: { - // Stop video, restart it again with Timer - // Avoiding crashes if ParentChange is not yet done - QGroundControl.videoManager.stopVideo() - videoPopUpTimer.running = true - } - } - PropertyChanges { - target: _flightVideoPipControl - inPopup: true - } - }, - State { - name: "popup-finished" - ParentChange { - target: _flightVideo - parent: videoItem - x: 0 - y: 0 - width: videoItem.width - height: videoItem.height - } - }, - State { - name: "unpopup" - StateChangeScript { - script: { - QGroundControl.videoManager.stopVideo() - videoPopUpTimer.running = true - } - } - ParentChange { - target: _flightVideo - parent: _mapAndVideo - } - PropertyChanges { - target: _flightVideoPipControl - inPopup: false - } + onWindowAboutToClose: { + console.log("about to close") + QGroundControl.videoManager.stopVideo() + videoStartDelay.start() } - ] + } + + Timer { + id: videoStartDelay + interval: 2000; + running: false + repeat: false + onTriggered: QGroundControl.videoManager.startVideo() + } + //-- Video Streaming FlightDisplayViewVideo { id: videoStreaming anchors.fill: parent + useSmallFont: videoControl.pipState.state !== videoControl.pipState.fullState visible: QGroundControl.videoManager.isGStreamer } //-- UVC Video (USB Camera or Video Device) @@ -297,33 +157,16 @@ Item { } } - QGCPipable { - id: _flightVideoPipControl - z: _flightVideo.z + 3 - width: _pipSize - height: _pipSize * (9/16) - anchors.left: _mapAndVideo.left - anchors.bottom: _mapAndVideo.bottom - anchors.margins: ScreenTools.defaultFontPixelHeight - visible: QGroundControl.videoManager.hasVideo && !QGroundControl.videoManager.fullScreen && _flightVideo.state != "popup" - isHidden: !_isPipVisible - isDark: isBackgroundDark - enablePopup: mainIsMap - onActivated: { - mainIsMap = !mainIsMap - setStates() - _fMap.adjustMapSize() - } - onHideIt: { - setPipVisibility(!state) - } - onPopup: { - videoWindow.visible = true - _flightVideo.state = "popup" - } - onNewWidth: { - _pipSize = newWidth - } + QGCPipOverlay { + id: _pipOverlay + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: ScreenTools.defaultFontPixelHeight + item1IsFullSettingsKey: "MainFlyWindowIsMap" + item1: mapControl + item2: QGroundControl.videoManager.hasVideo ? videoControl : null + fullZOrder: 0 + pipZOrder: QGroundControl.zOrderWidgets } MultiVehiclePanel { @@ -331,20 +174,20 @@ Item { anchors.margins: _toolsMargin anchors.top: parent.top anchors.right: parent.right - z: _mapAndVideo.z + 4 + z: QGroundControl.zOrderWidgets availableHeight: mainWindow.availableHeight - (anchors.margins * 2) guidedActionsController: _guidedController } FlightDisplayViewWidgets { id: flightDisplayViewWidgets - z: _mapAndVideo.z + 4 + z: QGroundControl.zOrderWidgets height: availableHeight - (singleMultiSelector.visible ? singleMultiSelector.height + _toolsMargin : 0) - _toolsMargin anchors.left: parent.left anchors.right: altitudeSlider.visible ? altitudeSlider.left : parent.right anchors.bottom: parent.bottom anchors.top: singleMultiSelector.visible? singleMultiSelector.bottom : undefined - useLightColors: isBackgroundDark + useLightColors: _isMapDark missionController: _missionController visible: singleMultiSelector.singleVehiclePanel && !QGroundControl.videoManager.fullScreen } @@ -353,7 +196,7 @@ Item { //-- Loader helper for plugins to overlay elements over the fly view Loader { id: flyViewOverlay - z: flightDisplayViewWidgets.z + 1 + z: QGroundControl.zOrderWidgets visible: !QGroundControl.videoManager.fullScreen height: mainWindow.height - mainWindow.header.height anchors.left: parent.left @@ -364,17 +207,17 @@ Item { //-- Virtual Joystick Loader { id: virtualJoystickMultiTouch - z: _mapAndVideo.z + 5 - width: parent.width - (_flightVideoPipControl.width / 2) + z: QGroundControl.zOrderTopMost + 1 + width: parent.width - (_pipOverlay.width / 2) height: Math.min(mainWindow.height * 0.25, ScreenTools.defaultFontPixelWidth * 16) visible: (_virtualJoystick ? _virtualJoystick.value : false) && !QGroundControl.videoManager.fullScreen && !(_activeVehicle ? _activeVehicle.highLatencyLink : false) - anchors.bottom: _flightVideoPipControl.top + anchors.bottom: _pipOverlay.top anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 2 anchors.horizontalCenter: flightDisplayViewWidgets.horizontalCenter source: "qrc:/qml/VirtualJoystick.qml" active: (_virtualJoystick ? _virtualJoystick.value : false) && !(_activeVehicle ? _activeVehicle.highLatencyLink : false) - property bool useLightColors: isBackgroundDark + property bool useLightColors: _isMapDark // The default behaviour is not centralized throttle property bool centralizeThrottle: _virtualJoystickCentralized ? _virtualJoystickCentralized.value : false @@ -390,8 +233,8 @@ Item { anchors.right: isInstrumentRight() ? undefined : _mapAndVideo.right anchors.topMargin: _toolsMargin anchors.top: parent.top - z: _mapAndVideo.z + 4 - maxHeight: parent.height - toolStrip.y + (_flightVideo.visible ? (_flightVideo.y - parent.height) : 0) + z: QGroundControl.zOrderWidgets + maxHeight: parent.height - toolStrip.y + (_pipOverlay.visible ? (_pipOverlay.y - parent.height) : 0) guidedActionsController: _guidedController guidedActionList: _guidedList usePreFlightChecklist: preFlightChecklistPopup.useChecklist @@ -413,7 +256,7 @@ Item { anchors.margins: _margins anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter - z: _guidedZOrder + z: QGroundControl.zOrderTopMost guidedController: _guidedController altitudeSlider: _guidedSlider } @@ -423,7 +266,7 @@ Item { anchors.margins: _margins anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter - z: _guidedZOrder + z: QGroundControl.zOrderTopMost guidedController: _guidedController } @@ -435,7 +278,7 @@ Item { anchors.topMargin: ScreenTools.toolbarHeight + _margins anchors.top: parent.top anchors.bottom: parent.bottom - z: _guidedZOrder + z: QGroundControl.zOrderTopMost radius: ScreenTools.defaultFontPixelWidth / 2 width: ScreenTools.defaultFontPixelWidth * 10 color: qgcPal.window @@ -447,7 +290,7 @@ Item { anchors.top: parent.top anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 anchors.horizontalCenter: parent.horizontalCenter - show: mainIsMap + show: _mainWindowIsMap } FlyViewPreFlightChecklistPopup { diff --git a/src/FlightDisplay/FlightDisplayViewMap.qml b/src/FlightDisplay/FlightDisplayViewMap.qml index 458ead5cc32e2a397270e149db4a554c176fba82..248a50b5f72a3070f85fa8a63c7699babef51d57 100644 --- a/src/FlightDisplay/FlightDisplayViewMap.qml +++ b/src/FlightDisplay/FlightDisplayViewMap.qml @@ -33,15 +33,13 @@ FlightMap { zoomLevel: QGroundControl.flightMapZoom center: QGroundControl.flightMapPosition - property alias scaleState: mapScale.state - - // The following properties must be set by the consumer property var guidedActionsController property var flightWidgets property var rightPanelWidth property var planMasterController - + property alias scaleState: mapScale.state property rect centerViewport: Qt.rect(0, 0, width, height) + property bool mainWindowIsMap: true property var _planMasterController: planMasterController property var _geoFenceController: planMasterController.geoFenceController @@ -53,7 +51,7 @@ FlightMap { property bool _keepMapCenteredOnVehicle: _flyViewSettings.keepMapCenteredOnVehicle.rawValue property bool _disableVehicleTracking: false - property bool _keepVehicleCentered: mainIsMap ? false : true + property bool _keepVehicleCentered: mainWindowIsMap ? false : true property bool _pipping: false function updateAirspace(reset) { @@ -81,7 +79,7 @@ FlightMap { } function adjustMapSize() { - if(mainIsMap) + if(mainWindowIsMap) pipOut() else pipIn() @@ -213,7 +211,7 @@ FlightMap { MapFitFunctions { id: mapFitFunctions // The name for this id cannot be changed without breaking references outside of this code. Beware! - map: mainWindow.flightDisplayMap + map: flightMap usePlannedHomePosition: false planMasterController: _planMasterController property real leftToolWidth: toolStrip.x + toolStrip.width @@ -225,7 +223,7 @@ FlightMap { line.width: 3 line.color: "red" z: QGroundControl.zOrderTrajectoryLines - visible: mainIsMap + visible: mainWindowIsMap Connections { target: QGroundControl.multiVehicleManager @@ -247,7 +245,7 @@ FlightMap { vehicle: object coordinate: object.coordinate map: flightMap - size: mainIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight + size: mainWindowIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight z: QGroundControl.zOrderVehicles } } @@ -272,7 +270,7 @@ FlightMap { PlanMapItems { map: flightMap - largeMapView: mainIsMap + largeMapView: mainWindowIsMap planMasterController: _planMasterController vehicle: _vehicle @@ -286,7 +284,7 @@ FlightMap { } MapItemView { - model: mainIsMap ? _missionController.directionArrows : undefined + model: mainWindowIsMap ? _missionController.directionArrows : undefined delegate: MapLineArrow { fromCoord: object ? object.coordinate1 : undefined @@ -299,7 +297,7 @@ FlightMap { // Allow custom builds to add map items CustomMapItems { map: flightMap - largeMapView: mainIsMap + largeMapView: mainWindowIsMap } GeoFenceMapVisuals { @@ -556,7 +554,7 @@ FlightMap { anchors.topMargin: _toolsMargin + state === "bottomMode" ? 0 : ScreenTools.toolbarHeight mapControl: flightMap buttonsOnLeft: false - visible: !ScreenTools.isTinyScreen && QGroundControl.corePlugin.options.enableMapScale && mainIsMap + visible: !ScreenTools.isTinyScreen && QGroundControl.corePlugin.options.enableMapScale && mainWindowIsMap state: "bottomMode" states: [ State { diff --git a/src/FlightDisplay/FlightDisplayViewVideo.qml b/src/FlightDisplay/FlightDisplayViewVideo.qml index 3e71ed2efc5bac7133925716bb8aa3e4c01edffd..4ce95246de72ddfb04cc475d86bb0454815e5381 100644 --- a/src/FlightDisplay/FlightDisplayViewVideo.qml +++ b/src/FlightDisplay/FlightDisplayViewVideo.qml @@ -23,6 +23,9 @@ import QGroundControl.Controllers 1.0 Item { id: root clip: true + + property bool useSmallFont: true + property double _ar: QGroundControl.videoManager.aspectRatio property bool _showGrid: QGroundControl.settingsManager.videoSettings.gridLines.rawValue > 0 property var _dynamicCameras: activeVehicle ? activeVehicle.dynamicCameras : null @@ -44,7 +47,7 @@ Item { text: QGroundControl.settingsManager.videoSettings.streamEnabled.rawValue ? qsTr("WAITING FOR VIDEO") : qsTr("VIDEO DISABLED") font.family: ScreenTools.demiboldFontFamily color: "white" - font.pointSize: mainIsMap ? ScreenTools.smallFontPointSize : ScreenTools.largeFontPointSize + font.pointSize: useSmallFont ? ScreenTools.smallFontPointSize : ScreenTools.largeFontPointSize anchors.centerIn: parent } MouseArea { diff --git a/src/FlightDisplay/FlightDisplayViewWidgets.qml b/src/FlightDisplay/FlightDisplayViewWidgets.qml index 3a6ccc87e9f62a990cbc2e8c616c8e7343f5a092..27c4f1834f5e899b5c9105da419927bde1c73684 100644 --- a/src/FlightDisplay/FlightDisplayViewWidgets.qml +++ b/src/FlightDisplay/FlightDisplayViewWidgets.qml @@ -33,15 +33,12 @@ Item { property var missionController property bool showValues: !QGroundControl.airspaceManager.airspaceVisible - property bool _isSatellite: mainIsMap ? (mainWindow.flightDisplayMap ? mainWindow.flightDisplayMap.isSatelliteMap : true) : true - property bool _lightWidgetBorders: _isSatellite + property bool _lightWidgetBorders: true property bool _airspaceEnabled: QGroundControl.airmapSupported ? QGroundControl.settingsManager.airMapSettings.enableAirMap.rawValue : false readonly property real _margins: ScreenTools.defaultFontPixelHeight * 0.5 readonly property bool _useAlternateInstrumentPanel: QGroundControl.settingsManager.flyViewSettings.alternateInstrumentPanel.value - QGCMapPalette { id: mapPal; lightColors: useLightColors } - function getPreferredInstrumentWidth() { // Don't allow instrument panel to chew more than 1/4 of full window var defaultWidth = ScreenTools.defaultFontPixelWidth * 30 diff --git a/src/FlightMap/Widgets/QGCInstrumentWidget.qml b/src/FlightMap/Widgets/QGCInstrumentWidget.qml index 2e8b5eb69389d091348c76b1d7a691a4f25d60ce..4d6f8ce01aa4fa0622f807c9a9ebbff53905df3a 100644 --- a/src/FlightMap/Widgets/QGCInstrumentWidget.qml +++ b/src/FlightMap/Widgets/QGCInstrumentWidget.qml @@ -43,7 +43,7 @@ ColumnLayout { radius: _outerRadius color: qgcPal.window border.width: 1 - border.color: _isSatellite ? qgcPal.mapWidgetBorderLight : qgcPal.mapWidgetBorderDark + border.color: qgcPal.mapWidgetBorderLight DeadMouseArea { anchors.fill: parent } diff --git a/src/QmlControls/QGCControlDebug.qml b/src/QmlControls/QGCControlDebug.qml new file mode 100644 index 0000000000000000000000000000000000000000..5e665613f5d6af7b64c32ab93c08b0a165ef1bb3 --- /dev/null +++ b/src/QmlControls/QGCControlDebug.qml @@ -0,0 +1,25 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.12 + +Item { + property string name: "control" + + Connections { + target: parent + onXChanged: console.log(name, "xChanged", parent.x) + onYChanged: console.log(name, "yChanged", parent.y) + onWidthChanged: console.log(name, "widthChanged", parent.width) + onHeightChanged: console.log(name, "heightChanged", parent.height) + onVisibleChanged: console.log(name, "visibleChanged", parent.visible) + onZChanged: console.log(name, "zChanged", parent.z) + onParentChanged: console.log(name, "parentChanged", parent.parent) + } +} diff --git a/src/QmlControls/QGCPipOverlay.qml b/src/QmlControls/QGCPipOverlay.qml new file mode 100644 index 0000000000000000000000000000000000000000..cf435c3d36a8648e7d1c47179be0c45e0028b9e4 --- /dev/null +++ b/src/QmlControls/QGCPipOverlay.qml @@ -0,0 +1,243 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Window 2.12 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.Palette 1.0 + +Item { + id: _root + width: _pipSize + height: _pipSize * (9/16) + z: pipZOrder + 1 + visible: item2 && item2.pipState !== item2.pipState.window + + property var item1: null // Required + property var item2: null // Optional, may come and go + property string item1IsFullSettingsKey // Settings key to save whether item1 was saved in full mode + property real fullZOrder: 0 // zOrder for items in full mode + property real pipZOrder: 1 // zOrder for items in pip mode + + readonly property string _pipExpandedSettingsKey: "IsPIPVisible" + + property var _fullItem + property var _pipOrWindowItem + property alias _windowContentItem: window.contentItem + property bool _isExpanded: true + property real _pipSize: parent.width * 0.2 + property real _maxSize: 0.75 // Percentage of parent control size + property real _minSize: 0.10 + property bool _componentComplete: false + + Component.onCompleted: { + _initForItems() + _componentComplete = true + } + + onItem2Changed: _initForItems() + + function showWindow() { + window.width = _root.width + window.height = _root.height + window.show() + } + + function _initForItems() { + var item1IsFull = QGroundControl.loadBoolGlobalSetting(item1IsFullSettingsKey, true) + if (item1 && item2) { + item1.pipState.state = item1IsFull ? item1.pipState.fullState : item1.pipState.pipState + item2.pipState.state = item1IsFull ? item2.pipState.pipState : item2.pipState.fullState + _fullItem = item1IsFull ? item1 : item2 + _pipOrWindowItem = item1IsFull ? item2 : item1 + } else { + item1.pipState.state = item1.pipState.fullState + _fullItem = item1 + _pipOrWindowItem = null + } + _setPipIsExpanded(QGroundControl.loadBoolGlobalSetting(_pipExpandedSettingsKey, true)) + } + + function _swapPip() { + var item1IsFull = false + if (item1.pipState.state === item1.pipState.fullState) { + item1.pipState.state = item1.pipState.pipState + item2.pipState.state = item2.pipState.fullState + _fullItem = item2 + _pipOrWindowItem = item1 + item1IsFull = false + } else { + item1.pipState.state = item1.pipState.fullState + item2.pipState.state = item2.pipState.pipState + _fullItem = item1 + _pipOrWindowItem = item2 + item1IsFull = true + } + QGroundControl.saveBoolGlobalSetting(item1IsFullSettingsKey, item1IsFull) + } + + function _setPipIsExpanded(isExpanded) { + QGroundControl.saveBoolGlobalSetting(_pipExpandedSettingsKey, isExpanded) + _isExpanded = isExpanded + if (_pipOrWindowItem) { + _pipOrWindowItem.visible = isExpanded + } + } + + Window { + id: window + visible: false + onClosing: { + var item = contentItem.children[0] + item.pipState.windowAboutToClose() + item.pipState.state = item.pipState.windowClosingState + item.pipState.state = item.pipState.pipState + } + } + + MouseArea { + id: pipMouseArea + anchors.fill: parent + enabled: _isExpanded + hoverEnabled: true + onClicked: _swapPip() + } + + // MouseArea to drag in order to resize the PiP area + MouseArea { + id: pipResize + anchors.top: parent.top + anchors.right: parent.right + height: ScreenTools.minTouchPixels + width: height + + property real initialX: 0 + property real initialWidth: 0 + + // When we push the mouse button down, we un-anchor the mouse area to prevent a resizing loop + onPressed: { + pipResize.anchors.top = undefined // Top doesn't seem to 'detach' + pipResize.anchors.right = undefined // This one works right, which is what we really need + pipResize.initialX = mouse.x + pipResize.initialWidth = _root.width + } + + // When we let go of the mouse button, we re-anchor the mouse area in the correct position + onReleased: { + pipResize.anchors.top = _root.top + pipResize.anchors.right = _root.right + } + + // Drag + onPositionChanged: { + if (pipResize.pressed) { + var parentWidth = _root.parent.width + var newWidth = pipResize.initialWidth + mouse.x - pipResize.initialX + if (newWidth < parentWidth * _maxSize && newWidth > parentWidth * _minSize) { + _pipSize = newWidth + } + } + } + } + + // Resize icon + Image { + source: "/qmlimages/pipResize.svg" + fillMode: Image.PreserveAspectFit + mipmap: true + anchors.right: parent.right + anchors.top: parent.top + visible: _isExpanded && (ScreenTools.isMobile || pipMouseArea.containsMouse) + height: ScreenTools.defaultFontPixelHeight * 2.5 + width: ScreenTools.defaultFontPixelHeight * 2.5 + sourceSize.height: height + } + + // Check min/max constraints on pip size when when parent is resized + Connections { + target: _root.parent + + onWidthChanged: { + if (!_componentComplete) { + // Wait until first time setup is done + return + } + var parentWidth = _root.parent.width + if (_root.width > parentWidth * _maxSize) { + _pipSize = parentWidth * _maxSize + } else if (_root.width < parentWidth * _minSize) { + _pipSize = parentWidth * _minSize + } + } + } + + // Pip to Window + Image { + id: popupPIP + source: "/qmlimages/PiP.svg" + mipmap: true + fillMode: Image.PreserveAspectFit + anchors.left: parent.left + anchors.top: parent.top + visible: _isExpanded && !ScreenTools.isMobile && pipMouseArea.containsMouse + height: ScreenTools.defaultFontPixelHeight * 2.5 + width: ScreenTools.defaultFontPixelHeight * 2.5 + sourceSize.height: height + + MouseArea { + anchors.fill: parent + onClicked: _pipOrWindowItem.pipState.state = _pipOrWindowItem.pipState.windowState + } + } + + Image { + id: hidePIP + source: "/qmlimages/pipHide.svg" + mipmap: true + fillMode: Image.PreserveAspectFit + anchors.left: parent.left + anchors.bottom: parent.bottom + visible: _isExpanded && (ScreenTools.isMobile || pipMouseArea.containsMouse) + height: ScreenTools.defaultFontPixelHeight * 2.5 + width: ScreenTools.defaultFontPixelHeight * 2.5 + sourceSize.height: height + MouseArea { + anchors.fill: parent + onClicked: _root._setPipIsExpanded(false) + } + } + + Rectangle { + id: showPip + anchors.left : parent.left + anchors.bottom: parent.bottom + height: ScreenTools.defaultFontPixelHeight * 2 + width: ScreenTools.defaultFontPixelHeight * 2 + radius: ScreenTools.defaultFontPixelHeight / 3 + visible: !_isExpanded + color: _fullItem.pipState.isDark ? Qt.rgba(0,0,0,0.75) : Qt.rgba(0,0,0,0.5) + Image { + width: parent.width * 0.75 + height: parent.height * 0.75 + sourceSize.height: height + source: "/res/buttonRight.svg" + mipmap: true + fillMode: Image.PreserveAspectFit + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } + MouseArea { + anchors.fill: parent + onClicked: _root._setPipIsExpanded(true) + } + } +} diff --git a/src/QmlControls/QGCPipState.qml b/src/QmlControls/QGCPipState.qml new file mode 100644 index 0000000000000000000000000000000000000000..c143ec18f2c50549b1603d7d40b4bb9035b7cbd9 --- /dev/null +++ b/src/QmlControls/QGCPipState.qml @@ -0,0 +1,96 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.12 + +// Used to manage state for itesm using with QGCPipOveral +Item { + id: _root + state: initState + + readonly property string initState: "init" + readonly property string pipState: "pip" + readonly property string fullState: "full" + readonly property string windowState: "window" + readonly property string windowClosingState: "windowClosing" + + property var pipOverlay // QGCPipOverlay control + property bool isDark: true // true: Use dark overlay visuals + + signal windowAboutToOpen // Catch this signal to do something special prior to the item transition to windowed mode + signal windowAboutToClose // Catch this signal to do special processing prior to the item transition back to pip mode + + property var _clientControl: _root.parent + + states: [ + State { + name: pipState + + AnchorChanges { + target: _clientControl + anchors.top: pipOverlay.top + anchors.bottom: pipOverlay.bottom + anchors.left: pipOverlay.left + anchors.right: pipOverlay.right + } + + PropertyChanges { + target: _clientControl + z: pipOverlay.pipZOrder + } + }, + State { + name: fullState + + AnchorChanges { + target: _clientControl + anchors.top: pipOverlay.parent.top + anchors.bottom: pipOverlay.parent.bottom + anchors.left: pipOverlay.parent.left + anchors.right: pipOverlay.parent.right + } + + PropertyChanges { + target: _clientControl + z: pipOverlay.fullZOrder + } + }, + State { + name: windowState + + AnchorChanges { + target: _root.parent + anchors.top: pipOverlay._windowContentItem.top + anchors.bottom: pipOverlay._windowContentItem.bottom + anchors.left: pipOverlay._windowContentItem.left + anchors.right: pipOverlay._windowContentItem.right + } + + ParentChange { + target: _root.parent + parent: pipOverlay._windowContentItem + } + + StateChangeScript { + script: { + _root.windowAboutToOpen() + pipOverlay.showWindow() + } + } + }, + State { + name: windowClosingState + + ParentChange { + target: _root.parent + parent: pipOverlay.parent + } + } + ] +} diff --git a/src/QmlControls/QGCPipable.qml b/src/QmlControls/QGCPipable.qml deleted file mode 100644 index 292324e6a25611b8be0e4dc27f930e52e10768d6..0000000000000000000000000000000000000000 --- a/src/QmlControls/QGCPipable.qml +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -import QtQuick 2.3 -import QtQuick.Controls 1.2 - -import QGroundControl 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.Palette 1.0 - -Item { - id: pip - - property bool isHidden: false - property bool isDark: false - - // As a percentage of the window width - property real maxSize: 0.75 - property real minSize: 0.10 - - property bool inPopup: false - property bool enablePopup: true - - signal activated() - signal hideIt(bool state) - signal newWidth(real newWidth) - signal popup() - - MouseArea { - id: pipMouseArea - anchors.fill: parent - enabled: !isHidden - hoverEnabled: true - onClicked: { - pip.activated() - } - } - - // MouseArea to drag in order to resize the PiP area - MouseArea { - id: pipResize - anchors.top: parent.top - anchors.right: parent.right - height: ScreenTools.minTouchPixels - width: height - property real initialX: 0 - property real initialWidth: 0 - - onClicked: { - // TODO propagate - } - - // When we push the mouse button down, we un-anchor the mouse area to prevent a resizing loop - onPressed: { - pipResize.anchors.top = undefined // Top doesn't seem to 'detach' - pipResize.anchors.right = undefined // This one works right, which is what we really need - pipResize.initialX = mouse.x - pipResize.initialWidth = pip.width - } - - // When we let go of the mouse button, we re-anchor the mouse area in the correct position - onReleased: { - pipResize.anchors.top = pip.top - pipResize.anchors.right = pip.right - } - - // Drag - onPositionChanged: { - if (pipResize.pressed) { - var parentW = pip.parent.width // flightView - var newW = pipResize.initialWidth + mouse.x - pipResize.initialX - if (newW < parentW * maxSize && newW > parentW * minSize) { - newWidth(newW) - } - } - } - } - - // Resize icon - Image { - source: "/qmlimages/pipResize.svg" - fillMode: Image.PreserveAspectFit - mipmap: true - anchors.right: parent.right - anchors.top: parent.top - visible: !isHidden && (ScreenTools.isMobile || pipMouseArea.containsMouse) && !inPopup - height: ScreenTools.defaultFontPixelHeight * 2.5 - width: ScreenTools.defaultFontPixelHeight * 2.5 - sourceSize.height: height - } - - // Resize pip window if necessary when main window is resized - property int pipLock: 2 - - Connections { - target: pip.parent - onWidthChanged: { - // hackity hack... - // don't fire this while app is loading/initializing (it happens twice) - if (pipLock) { - pipLock-- - return - } - - var parentW = pip.parent.width - - if (pip.width > parentW * maxSize) { - newWidth(parentW * maxSize) - } else if (pip.width < parentW * minSize) { - newWidth(parentW * minSize) - } - } - } - - //-- PIP Popup Indicator - Image { - id: popupPIP - source: "/qmlimages/PiP.svg" - mipmap: true - fillMode: Image.PreserveAspectFit - anchors.left: parent.left - anchors.top: parent.top - visible: !isHidden && !inPopup && !ScreenTools.isMobile && enablePopup && pipMouseArea.containsMouse - height: ScreenTools.defaultFontPixelHeight * 2.5 - width: ScreenTools.defaultFontPixelHeight * 2.5 - sourceSize.height: height - MouseArea { - anchors.fill: parent - onClicked: { - inPopup = true - pip.popup() - } - } - } - - //-- PIP Corner Indicator - Image { - id: closePIP - source: "/qmlimages/pipHide.svg" - mipmap: true - fillMode: Image.PreserveAspectFit - anchors.left: parent.left - anchors.bottom: parent.bottom - visible: !isHidden && (ScreenTools.isMobile || pipMouseArea.containsMouse) - height: ScreenTools.defaultFontPixelHeight * 2.5 - width: ScreenTools.defaultFontPixelHeight * 2.5 - sourceSize.height: height - MouseArea { - anchors.fill: parent - onClicked: { - pip.hideIt(true) - } - } - } - - //-- Show PIP - Rectangle { - id: openPIP - anchors.left : parent.left - anchors.bottom: parent.bottom - height: ScreenTools.defaultFontPixelHeight * 2 - width: ScreenTools.defaultFontPixelHeight * 2 - radius: ScreenTools.defaultFontPixelHeight / 3 - visible: isHidden - color: isDark ? Qt.rgba(0,0,0,0.75) : Qt.rgba(0,0,0,0.5) - Image { - width: parent.width * 0.75 - height: parent.height * 0.75 - sourceSize.height: height - source: "/res/buttonRight.svg" - mipmap: true - fillMode: Image.PreserveAspectFit - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - } - MouseArea { - anchors.fill: parent - onClicked: { - pip.hideIt(false) - } - } - } -} diff --git a/src/QmlControls/QGroundControl/Controls/qmldir b/src/QmlControls/QGroundControl/Controls/qmldir index 7391942986384d1439de2b9ce09ac77f0abf3390..444ec058035d8e33c552f96ddabe42b9475c3840 100644 --- a/src/QmlControls/QGroundControl/Controls/qmldir +++ b/src/QmlControls/QGroundControl/Controls/qmldir @@ -50,6 +50,7 @@ QGCButton 1.0 QGCButton.qml QGCCheckBox 1.0 QGCCheckBox.qml QGCColoredImage 1.0 QGCColoredImage.qml QGCComboBox 1.0 QGCComboBox.qml +QGCControlDebug 1.0 QGCControlDebug.qml QGCDynamicObjectManager 1.0 QGCDynamicObjectManager.qml QGCFileDialog 1.0 QGCFileDialog.qml QGCFlickable 1.0 QGCFlickable.qml @@ -66,7 +67,8 @@ QGCMenuSeparator 1.0 QGCMenuSeparator.qml QGCMouseArea 1.0 QGCMouseArea.qml QGCMovableItem 1.0 QGCMovableItem.qml QGCOptionsComboBox 1.0 QGCOptionsComboBox.qml -QGCPipable 1.0 QGCPipable.qml +QGCPipOverlay 1.0 QGCPipOverlay.qml +QGCPipState 1.0 QGCPipState.qml QGCPopupDialog 1.0 QGCPopupDialog.qml QGCPopupDialogContainer 1.0 QGCPopupDialogContainer.qml QGCRadioButton 1.0 QGCRadioButton.qml diff --git a/src/ui/MainRootWindow.qml b/src/ui/MainRootWindow.qml index 6e295cb72c0019ec08b34903bb5cd19e923194f8..862caa3313ec6b8c0d4799bfe480d4a368493d54 100644 --- a/src/ui/MainRootWindow.qml +++ b/src/ui/MainRootWindow.qml @@ -68,7 +68,6 @@ ApplicationWindow { property var currentPlanMissionItem: planMasterControllerPlan ? planMasterControllerPlan.missionController.currentPlanViewItem : null property var planMasterControllerPlan: null property var planMasterControllerView: null - property var flightDisplayMap: null readonly property string navButtonWidth: ScreenTools.defaultFontPixelWidth * 24 readonly property real defaultTextHeight: ScreenTools.defaultFontPixelHeight