Skip to content
Snippets Groups Projects
MainRootWindow.qml 25.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • /****************************************************************************
     *
    
    Gus Grubba's avatar
    Gus Grubba committed
     * (c) 2009-2020 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.
     *
     ****************************************************************************/
    
    
    Gus Grubba's avatar
    Gus Grubba committed
    import QtQuick          2.11
    
    import QtQuick.Controls 2.4
    import QtQuick.Dialogs  1.3
    
    Gus Grubba's avatar
    Gus Grubba committed
    import QtQuick.Layouts  1.11
    
    import QtQuick.Window   2.11
    
    
    import QGroundControl               1.0
    import QGroundControl.Palette       1.0
    import QGroundControl.Controls      1.0
    import QGroundControl.ScreenTools   1.0
    import QGroundControl.FlightDisplay 1.0
    import QGroundControl.FlightMap     1.0
    
    
    Gus Grubba's avatar
    Gus Grubba committed
    /// @brief Native QML top level window
    /// All properties defined here are visible to all QML pages.
    
        id:             mainWindow
    
        minimumWidth:   ScreenTools.isMobile ? Screen.width  : Math.min(ScreenTools.defaultFontPixelWidth * 100, Screen.width)
        minimumHeight:  ScreenTools.isMobile ? Screen.height : Math.min(ScreenTools.defaultFontPixelWidth * 50, Screen.height)
    
        visible:        true
    
    
        Component.onCompleted: {
    
            //-- Full screen on mobile or tiny screens
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
            if (ScreenTools.isMobile || Screen.height / ScreenTools.realPixelDensity < 120) {
    
                mainWindow.showFullScreen()
    
    Gus Grubba's avatar
    Gus Grubba committed
            } else {
                width   = ScreenTools.isMobile ? Screen.width  : Math.min(250 * Screen.pixelDensity, Screen.width)
                height  = ScreenTools.isMobile ? Screen.height : Math.min(150 * Screen.pixelDensity, Screen.height)
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
            // Start the sequence of first run prompt(s)
            firstRunPromptManager.nextPrompt()
        }
    
        QtObject {
            id: firstRunPromptManager
    
            property var currentDialog:     null
            property var rgPromptIds:       QGroundControl.corePlugin.firstRunPromptsToShow()
            property int nextPromptIdIndex: 0
    
            onRgPromptIdsChanged: console.log(QGroundControl.corePlugin, QGroundControl.corePlugin.firstRunPromptsToShow())
    
            function clearNextPromptSignal() {
                if (currentDialog) {
                    currentDialog.closed.disconnect(nextPrompt)
                }
            }
    
            function nextPrompt() {
                if (nextPromptIdIndex < rgPromptIds.length) {
                    currentDialog = showPopupDialogFromSource(QGroundControl.corePlugin.firstRunPromptResource(rgPromptIds[nextPromptIdIndex]))
                    currentDialog.closed.connect(nextPrompt)
                    nextPromptIdIndex++
                } else {
                    currentDialog = null
                    showPreFlightChecklistIfNeeded()
                }
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
        property var                _rgPreventViewSwitch:       [ false ]
    
    
    Gus Grubba's avatar
    Gus Grubba committed
        readonly property real      _topBottomMargins:          ScreenTools.defaultFontPixelHeight * 0.5
    
        //-------------------------------------------------------------------------
        //-- Global Scope Variables
    
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Current active Vehicle
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        property var                activeVehicle:                  QGroundControl.multiVehicleManager.activeVehicle
        property string             formatedMessage:                activeVehicle ? activeVehicle.formatedMessage : ""
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Indicates usable height between toolbar and footer
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        property real               availableHeight:                mainWindow.height - mainWindow.header.height - mainWindow.footer.height
    
    Gus Grubba's avatar
    Gus Grubba committed
    
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        property var                currentPlanMissionItem:         planMasterControllerPlanView ? planMasterControllerPlanView.missionController.currentPlanViewItem : null
        property var                planMasterControllerPlanView:   null
        property var                planMasterControllerFlyView:    null
    
    Gus Grubba's avatar
    Gus Grubba committed
    
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        readonly property string    navButtonWidth:                 ScreenTools.defaultFontPixelWidth * 24
        readonly property real      defaultTextHeight:              ScreenTools.defaultFontPixelHeight
        readonly property real      defaultTextWidth:               ScreenTools.defaultFontPixelWidth
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Default color palette used throughout the UI
    
        QGCPalette { id: qgcPal; colorGroupEnabled: true }
    
    
        //-------------------------------------------------------------------------
        //-- Actions
    
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        signal armVehicleRequest
        signal disarmVehicleRequest
        signal vtolTransitionToFwdFlightRequest
        signal vtolTransitionToMRFlightRequest
        signal showPreFlightChecklistIfNeeded
    
        //-------------------------------------------------------------------------
        //-- Global Scope Functions
    
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
        /// Prevent view switching
        function pushPreventViewSwitch() {
            _rgPreventViewSwitch.push(true)
        }
    
        /// Allow view switching
        function popPreventViewSwitch() {
            if (_rgPreventViewSwitch.length == 1) {
    
    Don Gagne's avatar
     
    Don Gagne committed
                console.warn("mainWindow.popPreventViewSwitch called when nothing pushed")
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
                return
            }
            _rgPreventViewSwitch.pop()
        }
    
        /// @return true: View switches are not currently allowed
        function preventViewSwitch() {
            return _rgPreventViewSwitch[_rgPreventViewSwitch.length - 1]
        }
    
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
        function viewSwitch(currentToolbar) {
    
            settingsWindow.visible  = false
            setupWindow.visible     = false
            analyzeWindow.visible   = false
    
            planViewLoader.visible  = false
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            toolbar.currentToolbar  = currentToolbar
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
                mainWindow.showPreFlightChecklistIfNeeded()
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            viewSwitch(toolbar.flyViewToolbar)
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            viewSwitch(toolbar.planViewToolbar)
    
            planViewLoader.visible = true
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            viewSwitch(toolbar.simpleToolbar)
    
            analyzeWindow.visible = true
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            viewSwitch(toolbar.simpleToolbar)
    
            setupWindow.visible = true
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            viewSwitch(toolbar.simpleToolbar)
    
            settingsWindow.visible = true
    
        }
    
        //-------------------------------------------------------------------------
        //-- Global simple message dialog
    
        function showMessageDialog(title, text) {
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
            var dialog = simpleMessageDialog.createObject(mainWindow, { title: title, text: text })
            dialog.open()
        }
    
        Component {
            id: simpleMessageDialog
    
            MessageDialog {
                standardButtons:    StandardButton.Ok
                modality:           Qt.ApplicationModal
                visible:            false
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Saves main window position and size
    
    Don Gagne's avatar
     
    Don Gagne committed
        MainWindowSavedState {
            window: mainWindow
        }
    
    
        //-------------------------------------------------------------------------
        //-- Global complex dialog
    
    
        /// Shows a QGCViewDialogContainer based dialog
        ///     @param component The dialog contents
    
        ///     @param title Title for dialog
        ///     @param charWidth Width of dialog in characters
        ///     @param buttons Buttons to show in dialog using StandardButton enum
    
        readonly property int showDialogFullWidth:      -1  ///< Use for full width dialog
        readonly property int showDialogDefaultWidth:   40  ///< Use for default dialog width
    
    
        function showComponentDialog(component, title, charWidth, buttons) {
    
            if (mainWindowDialog.visible) {
                console.warn(("showComponentDialog called while dialog is already visible"))
                return
            }
    
            var dialogWidth = charWidth === showDialogFullWidth ? mainWindow.width : ScreenTools.defaultFontPixelWidth * charWidth
            mainWindowDialog.width = dialogWidth
            mainWindowDialog.dialogComponent = component
            mainWindowDialog.dialogTitle = title
            mainWindowDialog.dialogButtons = buttons
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            mainWindow.pushPreventViewSwitch()
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            if (buttons & StandardButton.Cancel || buttons & StandardButton.Close || buttons & StandardButton.Discard || buttons & StandardButton.Abort || buttons & StandardButton.Ignore) {
    
                mainWindowDialog.closePolicy = Popup.NoAutoClose;
                mainWindowDialog.interactive = false;
            } else {
    
                mainWindowDialog.closePolicy = Popup.CloseOnEscape | Popup.CloseOnPressOutside;
                mainWindowDialog.interactive = true;
            }
    
        }
    
        Drawer {
            id:             mainWindowDialog
            y:              mainWindow.header.height
            height:         mainWindow.height - mainWindow.header.height
            edge:           Qt.RightEdge
            interactive:    false
            background: Rectangle {
                color:  qgcPal.windowShadeDark
            }
            property var    dialogComponent: null
            property var    dialogButtons: null
            property string dialogTitle: ""
            Loader {
                id:             dlgLoader
                anchors.fill:   parent
                onLoaded: {
                    item.setupDialogButtons()
                }
            }
            onOpened: {
                dlgLoader.source = "QGCViewDialogContainer.qml"
            }
            onClosed: {
    
                //console.log("View switch ok")
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
                mainWindow.popPreventViewSwitch()
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        // Dialogs based on QGCPopupDialog
    
        function showPopupDialogFromComponent(component, properties) {
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
            var dialog = popupDialogContainerComponent.createObject(mainWindow, { dialogComponent: component, dialogProperties: properties })
            dialog.open()
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
            return dialog
        }
    
        function showPopupDialogFromSource(source, properties) {
            var dialog = popupDialogContainerComponent.createObject(mainWindow, { dialogSource: source, dialogProperties: properties })
            dialog.open()
            return dialog
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        }
    
        Component {
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
            id: popupDialogContainerComponent
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
            QGCPopupDialogContainer { }
        }
    
    
        property bool _forceClose: false
    
        function finishCloseProcess() {
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
            _forceClose = true
            // For some reason on the Qml side Qt doesn't automatically disconnect a signal when an object is destroyed.
            // So we have to do it ourselves otherwise the signal flows through on app shutdown to an object which no longer exists.
            firstRunPromptManager.clearNextPromptSignal()
    
            QGroundControl.videoManager.stopVideo();
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
        // On attempting an application close we check for:
        //  Unsaved missions - then
        //  Pending parameter writes - then
        //  Active connections
        onClosing: {
            if (!_forceClose) {
                unsavedMissionCloseDialog.check()
                close.accepted = false
            }
        }
    
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            id:                 unsavedMissionCloseDialog
    
            title:              qsTr("%1 close").arg(QGroundControl.appName)
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            text:               qsTr("You have a mission edit in progress which has not been saved/sent. If you close you will lose changes. Are you sure you want to close?")
            standardButtons:    StandardButton.Yes | StandardButton.No
    
            modality:           Qt.ApplicationModal
            visible:            false
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            onYes:              pendingParameterWritesCloseDialog.check()
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
                if (planMasterControllerPlanView && planMasterControllerPlanView.dirty) {
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
                    unsavedMissionCloseDialog.open()
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
                    pendingParameterWritesCloseDialog.check()
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
        MessageDialog {
            id:                 pendingParameterWritesCloseDialog
            title:              qsTr("%1 close").arg(QGroundControl.appName)
            text:               qsTr("You have pending parameter updates to a vehicle. If you close you will lose changes. Are you sure you want to close?")
            standardButtons:    StandardButton.Yes | StandardButton.No
            modality:           Qt.ApplicationModal
            visible:            false
            onYes:              activeConnectionsCloseDialog.check()
            function check() {
                for (var index=0; index<QGroundControl.multiVehicleManager.vehicles.count; index++) {
                    if (QGroundControl.multiVehicleManager.vehicles.get(index).parameterManager.pendingWrites) {
                        pendingParameterWritesCloseDialog.open()
                        return
                    }
                }
                activeConnectionsCloseDialog.check()
    
    Gus Grubba's avatar
    Gus Grubba committed
            }
        }
    
        MessageDialog {
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            id:                 activeConnectionsCloseDialog
    
    Gus Grubba's avatar
    Gus Grubba committed
            title:              qsTr("%1 close").arg(QGroundControl.appName)
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            text:               qsTr("There are still active connections to vehicles. Are you sure you want to exit?")
            standardButtons:    StandardButton.Yes | StandardButton.Cancel
    
    Gus Grubba's avatar
    Gus Grubba committed
            modality:           Qt.ApplicationModal
            visible:            false
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
            onYes:              finishCloseProcess()
    
    Gus Grubba's avatar
    Gus Grubba committed
            function check() {
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
                if (QGroundControl.multiVehicleManager.activeVehicle) {
                    activeConnectionsCloseDialog.open()
    
    Gus Grubba's avatar
    Gus Grubba committed
                } else {
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
                    finishCloseProcess()
    
    Gus Grubba's avatar
    Gus Grubba committed
                }
            }
        }
    
        //-------------------------------------------------------------------------
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Main, full window background (Fly View)
    
        background: Item {
            id:             rootBackground
            anchors.fill:   parent
        }
    
        //-------------------------------------------------------------------------
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Toolbar
    
    DonLakeFlyer's avatar
     
    DonLakeFlyer committed
        header: MainToolBar {
            id:         toolbar
            height:     ScreenTools.toolbarHeight
            visible:    !QGroundControl.videoManager.fullScreen
    
    Don Gagne's avatar
     
    Don Gagne committed
        footer: LogReplayStatusBar {
            visible: QGroundControl.settingsManager.flyViewSettings.showLogReplayStatusBar.rawValue
        }
    
    
        //-------------------------------------------------------------------------
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Fly View
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        FlyView {
    
        //-------------------------------------------------------------------------
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Plan View
    
            id:             planViewLoader
            anchors.fill:   parent
            visible:        false
            source:         "PlanView.qml"
        }
    
        //-------------------------------------------------------------------------
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Settings
    
        Loader {
            id:             settingsWindow
            anchors.fill:   parent
            visible:        false
            source:         "AppSettings.qml"
        }
    
        //-------------------------------------------------------------------------
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Setup
    
        Loader {
            id:             setupWindow
            anchors.fill:   parent
            visible:        false
            source:         "SetupView.qml"
    
        //-------------------------------------------------------------------------
    
    Gus Grubba's avatar
    Gus Grubba committed
        /// Analyze
    
            visible:        false
            source:         "AnalyzeView.qml"
    
        }
    
        //-------------------------------------------------------------------------
    
    Gus Grubba's avatar
    Gus Grubba committed
        //   @brief Loader helper for any child, no matter how deep, to display elements
    
        //   on top of the main window.
    
        //   This is DEPRECATED. Use Popup instead.
    
    Gus Grubba's avatar
    Gus Grubba committed
            id: rootLoader
    
            anchors.centerIn: parent
        }
    
        //-------------------------------------------------------------------------
    
        //-- Vehicle Messages
    
    
        function formatMessage(message) {
            message = message.replace(new RegExp("<#E>", "g"), "color: " + qgcPal.warningText + "; font: " + (ScreenTools.defaultFontPointSize.toFixed(0) - 1) + "pt monospace;");
            message = message.replace(new RegExp("<#I>", "g"), "color: " + qgcPal.warningText + "; font: " + (ScreenTools.defaultFontPointSize.toFixed(0) - 1) + "pt monospace;");
            message = message.replace(new RegExp("<#N>", "g"), "color: " + qgcPal.text + "; font: " + (ScreenTools.defaultFontPointSize.toFixed(0) - 1) + "pt monospace;");
            return message;
        }
    
    
        function showVehicleMessages() {
            if(!vehicleMessageArea.visible) {
    
                if(QGroundControl.multiVehicleManager.activeVehicleAvailable) {
                    messageText.text = formatMessage(activeVehicle.formatedMessages)
                    //-- Hack to scroll to last message
                    for (var i = 0; i < activeVehicle.messageCount; i++)
                        messageFlick.flick(0,-5000)
                    activeVehicle.resetMessages()
                } else {
                    messageText.text = qsTr("No Messages")
                }
    
                vehicleMessageArea.open()
    
            if(vehicleMessageArea.visible) {
    
                messageText.append(formatMessage(formatedMessage))
                //-- Hack to scroll down
                messageFlick.flick(0,-500)
            }
        }
    
        Popup {
    
            id:                 vehicleMessageArea
    
            width:              mainWindow.width  * 0.666
            height:             mainWindow.height * 0.666
            modal:              true
            focus:              true
    
    Gus Grubba's avatar
    Gus Grubba committed
            x:                  Math.round((mainWindow.width  - width)  * 0.5)
            y:                  Math.round((mainWindow.height - height) * 0.5)
    
            closePolicy:        Popup.CloseOnEscape | Popup.CloseOnPressOutside
            background: Rectangle {
                anchors.fill:   parent
                color:          qgcPal.window
                border.color:   qgcPal.text
                radius:         ScreenTools.defaultFontPixelHeight * 0.5
            }
            QGCFlickable {
                id:                 messageFlick
                anchors.margins:    ScreenTools.defaultFontPixelHeight
                anchors.fill:       parent
                contentHeight:      messageText.height
                contentWidth:       messageText.width
                pixelAligned:       true
                clip:               true
                TextEdit {
                    id:             messageText
                    readOnly:       true
                    textFormat:     TextEdit.RichText
                    color:          qgcPal.text
                }
            }
    
            //-- Dismiss Vehicle Messages
    
            QGCColoredImage {
                anchors.margins:    ScreenTools.defaultFontPixelHeight * 0.5
                anchors.top:        parent.top
                anchors.right:      parent.right
                width:              ScreenTools.isMobile ? ScreenTools.defaultFontPixelHeight * 1.5 : ScreenTools.defaultFontPixelHeight
                height:             width
                sourceSize.height:  width
                source:             "/res/XDelete.svg"
                fillMode:           Image.PreserveAspectFit
                mipmap:             true
                smooth:             true
                color:              qgcPal.text
                MouseArea {
                    anchors.fill:       parent
                    anchors.margins:    ScreenTools.isMobile ? -ScreenTools.defaultFontPixelHeight : 0
                    onClicked: {
    
                        vehicleMessageArea.close()
    
                    }
                }
            }
            //-- Clear Messages
            QGCColoredImage {
                anchors.bottom:     parent.bottom
                anchors.right:      parent.right
                anchors.margins:    ScreenTools.defaultFontPixelHeight * 0.5
                height:             ScreenTools.isMobile ? ScreenTools.defaultFontPixelHeight * 1.5 : ScreenTools.defaultFontPixelHeight
                width:              height
                sourceSize.height:   height
                source:             "/res/TrashDelete.svg"
                fillMode:           Image.PreserveAspectFit
                mipmap:             true
                smooth:             true
                color:              qgcPal.text
                MouseArea {
                    anchors.fill:   parent
                    onClicked: {
                        if(QGroundControl.multiVehicleManager.activeVehicleAvailable) {
                            activeVehicle.clearMessages();
    
                            vehicleMessageArea.close()
    
                        }
                    }
                }
            }
        }
    
        //-------------------------------------------------------------------------
    
        //-- System Messages
    
    Gus Grubba's avatar
    Gus Grubba committed
        property string _systemMessage:     ""
    
    DoinLakeFlyer's avatar
     
    DoinLakeFlyer committed
        function showVehicleMessage(message) {
    
            vehicleMessageArea.close()
            if(systemMessageArea.visible || QGroundControl.videoManager.fullScreen) {
    
                _systemMessage = message
                systemMessageArea.open()
    
            id:                 systemMessageArea
    
    Gus Grubba's avatar
    Gus Grubba committed
            x:                  Math.round((mainWindow.width - width) * 0.5)
    
    Gus Grubba's avatar
    Gus Grubba committed
            height:             ScreenTools.defaultFontPixelHeight * 6
    
            modal:              false
            focus:              true
            closePolicy:        Popup.CloseOnEscape
    
            background: Rectangle {
                anchors.fill:   parent
                color:          qgcPal.alertBackground
                radius:         ScreenTools.defaultFontPixelHeight * 0.5
                border.color:   qgcPal.alertBorder
                border.width:   2
            }
    
            onOpened: {
    
                systemMessageText.text = mainWindow._systemMessage
    
            }
    
            onClosed: {
                //-- Are there messages in the waiting queue?
                if(mainWindow._messageQueue.length) {
    
                    mainWindow._systemMessage = ""
    
                    //-- Show all messages in queue
                    for (var i = 0; i < mainWindow._messageQueue.length; i++) {
                        var text = mainWindow._messageQueue[i]
    
    Gus Grubba's avatar
    Gus Grubba committed
                        if(i) mainWindow._systemMessage += "<br>"
                        mainWindow._systemMessage += text
    
                    systemMessageArea.open()
    
                    mainWindow._systemMessage = ""
    
                id:                 systemMessageFlick
    
    Gus Grubba's avatar
    Gus Grubba committed
                anchors.margins:    ScreenTools.defaultFontPixelHeight * 0.5
    
                contentHeight:      systemMessageText.height
                contentWidth:       systemMessageText.width
    
                boundsBehavior:     Flickable.StopAtBounds
                pixelAligned:       true
                clip:               true
                TextEdit {
    
                    id:             systemMessageText
                    width:          systemMessageArea.width - systemMessageClose.width - (ScreenTools.defaultFontPixelHeight * 2)
                    anchors.centerIn: parent
    
                    readOnly:       true
                    textFormat:     TextEdit.RichText
                    font.pointSize: ScreenTools.defaultFontPointSize
                    font.family:    ScreenTools.demiboldFontFamily
                    wrapMode:       TextEdit.WordWrap
                    color:          qgcPal.alertText
                }
            }
    
            //-- Dismiss Critical Message
            QGCColoredImage {
    
                id:                 systemMessageClose
    
                anchors.margins:    ScreenTools.defaultFontPixelHeight * 0.5
                anchors.top:        parent.top
                anchors.right:      parent.right
                width:              ScreenTools.isMobile ? ScreenTools.defaultFontPixelHeight * 1.5 : ScreenTools.defaultFontPixelHeight
                height:             width
                sourceSize.height:  width
                source:             "/res/XDelete.svg"
                fillMode:           Image.PreserveAspectFit
                color:              qgcPal.alertText
                MouseArea {
                    anchors.fill:       parent
    
    Gus Grubba's avatar
    Gus Grubba committed
                    anchors.margins:    -ScreenTools.defaultFontPixelHeight
    
                        systemMessageArea.close()
    
                    }
                }
            }
    
            //-- More text below indicator
            QGCColoredImage {
                anchors.margins:    ScreenTools.defaultFontPixelHeight * 0.5
                anchors.bottom:     parent.bottom
                anchors.right:      parent.right
                width:              ScreenTools.isMobile ? ScreenTools.defaultFontPixelHeight * 1.5 : ScreenTools.defaultFontPixelHeight
                height:             width
                sourceSize.height:  width
                source:             "/res/ArrowDown.svg"
                fillMode:           Image.PreserveAspectFit
    
                visible:            systemMessageText.lineCount > 5
    
                color:              qgcPal.alertText
                MouseArea {
                    anchors.fill:   parent
                    onClicked: {
    
                        systemMessageFlick.flick(0,-500)
    
                    }
                }
            }
        }
    
        //-------------------------------------------------------------------------
        //-- Indicator Popups
    
    
        function showPopUp(item, dropItem) {
    
            indicatorDropdown.currentIndicator = dropItem
    
            indicatorDropdown.currentItem = item
    
        function hidePopUp() {
            indicatorDropdown.close()
            indicatorDropdown.currentItem = null
            indicatorDropdown.currentIndicator = null
        }
    
    
        Popup {
            id:             indicatorDropdown
            y:              ScreenTools.defaultFontPixelHeight
            modal:          true
            focus:          true
            closePolicy:    Popup.CloseOnEscape | Popup.CloseOnPressOutside
    
            property var    currentItem:        null
            property var    currentIndicator:   null
    
            background: Rectangle {
                width:  loader.width
                height: loader.height
                color:  Qt.rgba(0,0,0,0)
            }
            Loader {
                id:             loader
                onLoaded: {
    
                    var centerX = mainWindow.contentItem.mapFromItem(indicatorDropdown.currentItem, 0, 0).x - (loader.width * 0.5)
                    if((centerX + indicatorDropdown.width) > (mainWindow.width - ScreenTools.defaultFontPixelWidth)) {
                        centerX = mainWindow.width - indicatorDropdown.width - ScreenTools.defaultFontPixelWidth
                    }
                    indicatorDropdown.x = centerX
    
                }
            }
            onOpened: {
                loader.sourceComponent = indicatorDropdown.currentIndicator
            }
            onClosed: {
                loader.sourceComponent = null
                indicatorDropdown.currentIndicator = null
            }
        }
    }