From 4d3dd793b5136de5bc889dff780fa078f5b5e702 Mon Sep 17 00:00:00 2001
From: Don Gagne <don@thegagnes.com>
Date: Sun, 10 May 2015 11:16:40 -0700
Subject: [PATCH] ViewWithDialog -> QGCView

- More more on making QGCView real
- Converted Parameter Editor to QGCView
---
 qgroundcontrol.qrc                             |   5 +-
 src/AutoPilotPlugins/PX4/AirframeComponent.qml |  15 +-
 src/QmlControls/ParameterEditor.qml            | 582 ++++++++++++-------------
 src/QmlControls/QGCView.qml                    | 233 ++++++++++
 src/QmlControls/QGCViewDialog.qml              |  47 ++
 src/QmlControls/QGCViewPanel.qml               |  40 ++
 src/QmlControls/ViewWithDialog.qml             | 221 ----------
 src/QmlControls/qmldir                         |   5 +-
 8 files changed, 605 insertions(+), 543 deletions(-)
 create mode 100644 src/QmlControls/QGCView.qml
 create mode 100644 src/QmlControls/QGCViewDialog.qml
 create mode 100644 src/QmlControls/QGCViewPanel.qml
 delete mode 100644 src/QmlControls/ViewWithDialog.qml

diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index ccabc9b..a8df5dd 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -32,7 +32,10 @@
         <file alias="QGroundControl/Controls/VehicleSummaryRow.qml">src/QmlControls/VehicleSummaryRow.qml</file>
         <file alias="QGroundControl/Controls/arrow-down.png">src/QmlControls/arrow-down.png</file>
         <file alias="QGroundControl/Controls/ViewWidget.qml">src/ViewWidgets/ViewWidget.qml</file>
-        <file alias="QGroundControl/Controls/ViewWithDialog.qml">src/QmlControls/ViewWithDialog.qml</file>
+
+        <file alias="QGroundControl/Controls/QGCView.qml">src/QmlControls/QGCView.qml</file>
+        <file alias="QGroundControl/Controls/QGCViewPanel.qml">src/QmlControls/QGCViewPanel.qml</file>
+        <file alias="QGroundControl/Controls/QGCViewDialog.qml">src/QmlControls/QGCViewDialog.qml</file>
 
         <file alias="QGroundControl/Controls/ParameterEditor.qml">src/QmlControls/ParameterEditor.qml</file>
 
diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.qml b/src/AutoPilotPlugins/PX4/AirframeComponent.qml
index 37a58d2..277458b 100644
--- a/src/AutoPilotPlugins/PX4/AirframeComponent.qml
+++ b/src/AutoPilotPlugins/PX4/AirframeComponent.qml
@@ -32,8 +32,9 @@ import QGroundControl.Palette 1.0
 import QGroundControl.Controls 1.0
 import QGroundControl.Controllers 1.0
 
-ViewWithDialog {
-    viewComponent: view
+QGCView {
+    id:             rootQGCView
+    viewComponent:  view
 
     Component {
         id: view
@@ -45,9 +46,13 @@ ViewWithDialog {
             signal showDialog(Component component, string title, int charWidth, int buttons)
             signal hideDialog
 
-            function doWorkAfterComponentCompleted() {
-                if (controller.showCustomConfigPanel) {
-                    panel.showDialog(customConfigDialog, "Custom Airframe Config", 50, StandardButton.Reset)
+            Connections {
+                target: rootQGCView
+
+                onCompleted: {
+                    if (controller.showCustomConfigPanel) {
+                        panel.showDialog(customConfigDialog, "Custom Airframe Config", 50, StandardButton.Reset)
+                    }
                 }
             }
 
diff --git a/src/QmlControls/ParameterEditor.qml b/src/QmlControls/ParameterEditor.qml
index d40f849..0d39e03 100644
--- a/src/QmlControls/ParameterEditor.qml
+++ b/src/QmlControls/ParameterEditor.qml
@@ -36,384 +36,336 @@ import QGroundControl.Controllers 1.0
 import QGroundControl.FactSystem 1.0
 import QGroundControl.FactControls 1.0
 
-Rectangle {
-	/// true: show full information, false: for use in smaller widgets
-	property bool fullMode: true
-
-	QGCPalette { id: __qgcPal; colorGroupEnabled: true }
-	ParameterEditorController { id: __controller }
-	QGCLabel { id: __textControl; text: "X"; visible: false }
-
-	readonly property real __leftMargin: 10
-	readonly property real __rightMargin: 20
-	readonly property int __maxParamChars: 16
-
-    color: __qgcPal.window
-
-    // We use an ExclusiveGroup to maintain the visibility of a single editing control at a time
-    ExclusiveGroup {
-        id: __exclusiveEditorGroup
-    }
-
-    property Fact __editorOverlayFact: Fact { }
-    property real __textHeight: __textControl.contentHeight
-    property real __textWidth:  __textControl.contentWidth
-
-    Item {
-        id: __editorOverlay
-
-        anchors.fill:   parent
-        visible:        false
-        z:              100
-
-        Rectangle {
-            width:          __textWidth * 75
-            height:         parent.height
-            anchors.left:   parent.left
-            anchors.right:  editorDialog.left
-            opacity:        0.80
-            color:          __qgcPal.window
-        }
+QGCView {
+    viewComponent: parameterList
 
-        Rectangle {
-            id:             editorDialog
-            width:          fullMode ? __textWidth * 50 : parent.width
-            height:         parent.height
-            anchors.right:  parent.right
-            color:          __qgcPal.windowShadeDark
+    /// true: show full information, false: for use in smaller widgets
+    property bool fullMode: true
 
-            Column {
-                spacing:        __textHeight
-                anchors.fill:   parent
+    QGCPalette { id: __qgcPal; colorGroupEnabled: true }
+    ParameterEditorController { id: __controller }
+    QGCLabel { id: __textMeasure; text: "X"; visible: false }
+    property Fact __editorDialogFact: Fact { }
 
-                Rectangle {
-                    width:  parent.width
-                    height: saveButton.height
-                    color:  __qgcPal.windowShade
 
-                    QGCLabel {
-                        x:                  __textWidth
-                        height:             parent.height
-                        verticalAlignment:	Text.AlignVCenter
-                        text:               "Edit Parameter"
-                    }
+    readonly property real __leftMargin: 10
+    readonly property real __rightMargin: 20
+    readonly property int __maxParamChars: 16
 
-                    QGCButton {
-                        anchors.right:  saveButton.left
-                        anchors.bottom: parent.bottom
-                        text:           "Cancel"
+    property real __textHeight: __textMeasure.contentHeight
+    property real __textWidth:  __textMeasure.contentWidth
 
-                        onClicked: {
-                            __editorOverlay.visible = false
-                        }
-                    }
+    Component {
+        id: parameterList
 
-                    QGCButton {
-                        id:             saveButton
-                        anchors.right:  parent.right
-                        primary:        true
-                        text:           "Save"
+        QGCViewPanel {
+            id: panel
 
-                        onClicked: {
-                            __editorOverlayFact.value = valueField.text
-                            __editorOverlay.visible = false
-                        }
-                    }
-                }
+            Component {
+                id: factRowsComponent
 
                 Column {
-                    spacing:                __textHeight
-                    anchors.leftMargin:     __textWidth * 2
-                    anchors.rightMargin:    __textWidth
-                    anchors.left:           parent.left
-                    anchors.right:          parent.right
+                    id:     factColumn
+                    x:      __leftMargin
 
                     QGCLabel {
-                        width:      parent.width
-                        wrapMode:   Text.WordWrap
-                        text:       __editorOverlayFact.shortDescription ? __editorOverlayFact.shortDescription : "Description missing"
+                        height:				__textHeight + (ScreenTools.pixelSizeFactor * (9))
+                        text:               group
+                        verticalAlignment:	Text.AlignVCenter
+                        font.pointSize:     ScreenTools.fontPointFactor * (16);
                     }
 
-                    QGCLabel {
-                        width:      parent.width
-                        wrapMode:   Text.WordWrap
-                        visible:    __editorOverlayFact.longDescription
-                        text:       __editorOverlayFact.longDescription
+                    Rectangle {
+                        width:  parent.width
+                        height: 1
+                        color:  __qgcPal.text
                     }
 
-                    QGCTextField {
-                        id:     valueField
-                        text:   __editorOverlayFact.valueString
-                    }
+                    Repeater {
+                        model: __controller.getFactsForGroup(componentId, group)
 
-                    QGCLabel { text: __editorOverlayFact.name }
+                        Column {
+                            Item {
+                                x:			__leftMargin
+                                width:      parent.width
+                                height:		__textHeight + (ScreenTools.pixelSizeFactor * (9))
 
-                    Row {
-                        spacing: __textWidth
+                                Fact {
+                                    id: modelFact
 
-                        QGCLabel { text: "Units:" }
-                        QGCLabel { text: __editorOverlayFact.units ? __editorOverlayFact.units : "none" }
-                    }
+                                    Component.onCompleted: {
+                                        name = modelData + ":" + componentId
+                                    }
+                                }
+
+                                QGCLabel {
+                                    id:                 nameLabel
+                                    width:              __textWidth * (__maxParamChars + 1)
+                                    height:             parent.height
+                                    verticalAlignment:	Text.AlignVCenter
+                                    text:               modelFact.name
+                                }
+
+                                QGCLabel {
+                                    id:                 valueLabel
+                                    width:              __textWidth * 20
+                                    height:             parent.height
+                                    anchors.left:       nameLabel.right
+                                    verticalAlignment:	Text.AlignVCenter
+                                    color:              modelFact.valueEqualsDefault ? __qgcPal.text : "orange"
+                                    text:               modelFact.valueString + " " + modelFact.units
+                                }
+
+                                QGCLabel {
+                                    height:             parent.height
+                                    anchors.left:       valueLabel.right
+                                    verticalAlignment:	Text.AlignVCenter
+                                    visible:            fullMode
+                                    text:               modelFact.shortDescription
+                                }
+
+                                MouseArea {
+                                    anchors.fill:       parent
+                                     acceptedButtons:   Qt.LeftButton
+
+                                    onClicked: {
+                                        __editorDialogFact = modelFact
+                                        panel.showDialog(editorDialogComponent, "Parameter Editor", fullMode ? 50 : -1, StandardButton.Cancel | StandardButton.Save)
+                                    }
+                                }
+                            }
 
-                    Row {
-                        spacing: __textWidth
+                            Rectangle {
+                                x:      __leftMargin
+                                width:  factColumn.width - __leftMargin - __rightMargin
+                                height: 1
+                                color:  __qgcPal.windowShade
+                            }
+                        } // Column - Fact
+                    } // Repeater - Facts
+                } // Column - Facts
+            } // Component - factRowsComponent
 
-                        QGCLabel { text: "Minimum value:" }
-                        QGCLabel { text: __editorOverlayFact.min }
-                    }
+            Column {
+                anchors.fill: parent
 
-                    Row {
-                        spacing: __textWidth
+                Item {
+                    width:  parent.width
+                    height: firstButton.height
 
-                        QGCLabel { text: "Maxmimum value:" }
-                        QGCLabel { text: __editorOverlayFact.max }
+                    QGCLabel {
+                        font.pointSize: ScreenTools.fontPointFactor * (20)
+                        visible:        fullMode
+                        text:           "PARAMETER EDITOR"
                     }
 
                     Row {
-                        spacing: __textWidth
-
-                        QGCLabel { text: "Default value:" }
-                        QGCLabel { text: __editorOverlayFact.defaultValueAvailable ? __editorOverlayFact.defaultValue : "none" }
-                    }
+                        spacing:            10
+                        layoutDirection:    Qt.RightToLeft
+                        width:              parent.width
 
-                    QGCLabel {
-                        width:      parent.width
-                        wrapMode:   Text.WordWrap
-                        text:       "Warning: Modifying parameters while vehicle is in flight can lead to vehicle instability and possible vehicle loss. " +
-                                        "Make sure you know what you are doing and double-check your values before Save!"
+                        QGCButton {
+                            text:		"Clear RC to Param"
+                            onClicked:	__controller.clearRCToParam()
+                        }
+                        QGCButton {
+                            text:		"Save to file"
+                            visible:	fullMode
+                            onClicked:	__controller.saveToFile()
+                        }
+                        QGCButton {
+                            text:		"Load from file"
+                            visible:	fullMode
+                            onClicked:	__controller.loadFromFile()
+                        }
+                        QGCButton {
+                            id:			firstButton
+                            text:		"Refresh"
+                            onClicked:	__controller.refresh()
+                        }
                     }
-                } // Column - Fact information
-            } // Column - Header + Fact information
-
-
-            QGCButton {
-                anchors.rightMargin:    __textWidth
-                anchors.right:          rcButton.left
-                anchors.bottom:         parent.bottom
-                visible:                __editorOverlayFact.defaultValueAvailable
-                text:                   "Reset to default"
+                }
 
-                onClicked: {
-                    __editorOverlayFact.value = __editorOverlayFact.defaultValue
-                    __editorOverlay.visible = false
+                Item {
+                    id:		lastSpacer
+                    height: 10
+                    width:	5
                 }
-            }
 
-            QGCButton {
-                id:             rcButton
-                anchors.right:  parent.right
-                anchors.bottom: parent.bottom
-                visible:        __editorOverlayFact.defaultValueAvailable
-                text:           "Set RC to Param..."
-                onClicked:      __controller.setRCToParam(__editorOverlayFact.name)
-            }
-        } // Rectangle - editorDialog
-    } // Item - editorOverlay
+                Item {
+                    width:  parent.width
+                    height: parent.height - (lastSpacer.y + lastSpacer.height)
 
-    Component {
-        id: factRowsComponent
+                    ScrollView {
+                        id :	groupScroll
+                        width:	__textWidth * 25
+                        height: parent.height
 
-        Column {
-            id:     factColumn
-            x:      __leftMargin
+                        Column {
+                            Repeater {
+                                model: __controller.componentIds
 
-            QGCLabel {
-                height:				__textHeight + (ScreenTools.pixelSizeFactor * (9))
-                text:               group
-                verticalAlignment:	Text.AlignVCenter
-                font.pointSize:     ScreenTools.fontPointFactor * (16);
-            }
+                                Column {
+                                    id: componentColumn
 
-            Rectangle {
-                width:  parent.width
-                height: 1
-                color:  __qgcPal.text
-            }
+                                    readonly property int componentId: parseInt(modelData)
 
-            Repeater {
-                model: __controller.getFactsForGroup(componentId, group)
+                                    QGCLabel {
+                                        height:				contentHeight + (ScreenTools.pixelSizeFactor * (9))
+                                        text:               "Component #: " + componentId.toString()
+                                        verticalAlignment:	Text.AlignVCenter
+                                        font.pointSize:     ScreenTools.fontPointFactor * (16);
+                                    }
 
-                Column {
-                    Item {
-                        x:			__leftMargin
-                        width:      parent.width
-                        height:		__textHeight + (ScreenTools.pixelSizeFactor * (9))
+                                    Repeater {
+                                        model: __controller.getGroupsForComponent(componentColumn.componentId)
+
+                                        Column {
+                                            QGCButton {
+                                                x:		__leftMargin
+                                                width: groupScroll.width - __leftMargin - __rightMargin
+                                                text:	modelData
+
+                                                onClicked: {
+                                                    factRowsLoader.sourceComponent = null
+                                                    factRowsLoader.componentId = componentId
+                                                    factRowsLoader.group = modelData
+                                                    factRowsLoader.sourceComponent = factRowsComponent
+                                                }
+                                            }
+
+                                            Item {
+                                                width:  1
+                                                height: ScreenTools.pixelSizeFactor * (3)
+                                            }
+                                        } // Column - Group
+                                    } // Repeater - Groups
 
-                        Fact {
-                            id: modelFact
+                                    Item {
+                                        height: 10
+                                        width:	10
+                                    }
+                                } // Column - Component
+                            } // Repeater - Components
+                        } // Column - Component
+                    } // ScrollView - Groups
 
-                            Component.onCompleted: {
-                                name = modelData + ":" + componentId
-                            }
-                        }
+                    ScrollView {
+                        id:             factScrollView
+                        anchors.left:   groupScroll.right
+                        anchors.right:  parent.right
+                        height:         parent.height
 
-                        QGCLabel {
-                            id:                 nameLabel
-                            width:              __textWidth * (__maxParamChars + 1)
-                            height:             parent.height
-                            verticalAlignment:	Text.AlignVCenter
-                            text:               modelFact.name
-                        }
+                        Loader {
+                            id:     factRowsLoader
+                            width:  factScrollView.width
 
-                        QGCLabel {
-                            id:                 valueLabel
-                            width:              __textWidth * 20
-                            height:             parent.height
-                            anchors.left:       nameLabel.right
-                            verticalAlignment:	Text.AlignVCenter
-                            color:              modelFact.valueEqualsDefault ? __qgcPal.text : "orange"
-                            text:               modelFact.valueString + " " + modelFact.units
+                            property int componentId:   __controller.componentIds[0]
+                            property string group:      __controller.getGroupsForComponent(__controller.componentIds[0])[0]
+                            sourceComponent:            factRowsComponent
                         }
+                    } // ScrollView - Facts
+                } // Item - Group ScrollView + Facts
+            } // Column - Outer
+        }
+    } // Component - Parameter List
 
-                        QGCLabel {
-                            height:             parent.height
-                            anchors.left:       valueLabel.right
-                            verticalAlignment:	Text.AlignVCenter
-                            visible:            fullMode
-                            text:               modelFact.shortDescription
-                        }
+    Component {
+        id: editorDialogComponent
 
-                        MouseArea {
-                            anchors.fill:       parent
-                             acceptedButtons:   Qt.LeftButton
+        QGCViewDialog {
+            id:             editorDialog
 
-                            onClicked: {
-                                __editorOverlayFact = modelFact
-                                __editorOverlay.visible = true
-                            }
-                        }
-                    }
+            property bool fullMode: true
 
-                    Rectangle {
-                        x:      __leftMargin
-                        width:  factColumn.width - __leftMargin - __rightMargin
-                        height: 1
-                        color:  __qgcPal.windowShade
-                    }
-                } // Column - Fact
-            } // Repeater - Facts
-        } // Column - Facts
-    } // Component - factRowsComponent
-
-    Column {
-        anchors.fill: parent
-
-        Item {
-            width:  parent.width
-            height: firstButton.height
-
-            QGCLabel {
-                font.pointSize: ScreenTools.fontPointFactor * (20)
-                visible:        fullMode
-                text:           "PARAMETER EDITOR"
+            function accept() {
+                __editorDialogFact.value = valueField.text
+                editorDialog.hideDialog()
             }
 
-            Row {
-                spacing:            10
-                layoutDirection:    Qt.RightToLeft
-                width:              parent.width
+            Column {
+                spacing:        __textHeight
+                anchors.left:   parent.left
+                anchors.right:  parent.right
 
-                QGCButton {
-                    text:		"Clear RC to Param"
-                    onClicked:	__controller.clearRCToParam()
+                QGCLabel {
+                    width:      parent.width
+                    wrapMode:   Text.WordWrap
+                    text:       __editorDialogFact.shortDescription ? __editorDialogFact.shortDescription : "Description missing"
                 }
-                QGCButton {
-                    text:		"Save to file"
-                    visible:	fullMode
-                    onClicked:	__controller.saveToFile()
-                }
-                QGCButton {
-                    text:		"Load from file"
-                    visible:	fullMode
-                    onClicked:	__controller.loadFromFile()
-                }
-                QGCButton {
-                    id:			firstButton
-                    text:		"Refresh"
-                    onClicked:	__controller.refresh()
+
+                QGCLabel {
+                    width:      parent.width
+                    wrapMode:   Text.WordWrap
+                    visible:    __editorDialogFact.longDescription
+                    text:       __editorDialogFact.longDescription
                 }
-            }
-        }
 
-        Item {
-            id:		lastSpacer
-            height: 10
-            width:	5
-        }
+                QGCTextField {
+                    id:     valueField
+                    text:   __editorDialogFact.valueString
+                }
 
-        Item {
-            width:  parent.width
-            height: parent.height - (lastSpacer.y + lastSpacer.height)
+                QGCLabel { text: __editorDialogFact.name }
 
-            ScrollView {
-                id :	groupScroll
-                width:	__textWidth * 25
-                height: parent.height
+                Row {
+                    spacing: __textWidth
 
-                Column {
-                    Repeater {
-                        model: __controller.componentIds
+                    QGCLabel { text: "Units:" }
+                    QGCLabel { text: __editorDialogFact.units ? __editorDialogFact.units : "none" }
+                }
 
-                        Column {
-                            id: componentColumn
+                Row {
+                    spacing: __textWidth
 
-                            readonly property int componentId: parseInt(modelData)
+                    QGCLabel { text: "Minimum value:" }
+                    QGCLabel { text: __editorDialogFact.min }
+                }
 
-                            QGCLabel {
-                                height:				contentHeight + (ScreenTools.pixelSizeFactor * (9))
-                                text:               "Component #: " + componentId.toString()
-                                verticalAlignment:	Text.AlignVCenter
-                                font.pointSize:     ScreenTools.fontPointFactor * (16);
-                            }
+                Row {
+                    spacing: __textWidth
 
-                            Repeater {
-                                model: __controller.getGroupsForComponent(componentColumn.componentId)
+                    QGCLabel { text: "Maxmimum value:" }
+                    QGCLabel { text: __editorDialogFact.max }
+                }
 
-                                Column {
-                                    QGCButton {
-                                        x:		__leftMargin
-                                        width: groupScroll.width - __leftMargin - __rightMargin
-                                        text:	modelData
-
-                                        onClicked: {
-                                            factRowsLoader.sourceComponent = null
-                                            factRowsLoader.componentId = componentId
-                                            factRowsLoader.group = modelData
-                                            factRowsLoader.sourceComponent = factRowsComponent
-                                        }
-                                    }
+                Row {
+                    spacing: __textWidth
 
-                                    Item {
-                                        width:  1
-                                        height: ScreenTools.pixelSizeFactor * (3)
-                                    }
-                                } // Column - Group
-                            } // Repeater - Groups
+                    QGCLabel { text: "Default value:" }
+                    QGCLabel { text: __editorDialogFact.defaultValueAvailable ? __editorDialogFact.defaultValue : "none" }
+                }
 
-                            Item {
-                                height: 10
-                                width:	10
-                            }
-                        } // Column - Component
-                    } // Repeater - Components
-                } // Column - Component
-            } // ScrollView - Groups
+                QGCLabel {
+                    width:      parent.width
+                    wrapMode:   Text.WordWrap
+                    text:       "Warning: Modifying parameters while vehicle is in flight can lead to vehicle instability and possible vehicle loss. " +
+                                    "Make sure you know what you are doing and double-check your values before Save!"
+                }
+            } // Column - Fact information
 
-            ScrollView {
-                id:             factScrollView
-                anchors.left:   groupScroll.right
-                anchors.right:  parent.right
-                height:         parent.height
 
-                Loader {
-                    id:     factRowsLoader
-                    width:  factScrollView.width
+            QGCButton {
+                anchors.rightMargin:    __textWidth
+                anchors.right:          rcButton.left
+                anchors.bottom:         parent.bottom
+                visible:                __editorDialogFact.defaultValueAvailable
+                text:                   "Reset to default"
 
-                    property int componentId:   __controller.componentIds[0]
-                    property string group:      __controller.getGroupsForComponent(__controller.componentIds[0])[0]
-                    sourceComponent:            factRowsComponent
+                onClicked: {
+                    __editorDialogFact.value = __editorDialogFact.defaultValue
+                    editorDialog.hideDialog()
                 }
-            } // ScrollView - Facts
-        } // Item - Group ScrollView + Facts
-    } // Column - Outer
-}
+            }
+
+            QGCButton {
+                id:             rcButton
+                anchors.right:  parent.right
+                anchors.bottom: parent.bottom
+                visible:        __editorDialogFact.defaultValueAvailable
+                text:           "Set RC to Param..."
+                onClicked:      __controller.setRCToParam(__editorDialogFact.name)
+            }
+        } // Rectangle - editorDialog
+    } // Component - Editor Dialog
+} // QGCView
\ No newline at end of file
diff --git a/src/QmlControls/QGCView.qml b/src/QmlControls/QGCView.qml
new file mode 100644
index 0000000..001c2e5
--- /dev/null
+++ b/src/QmlControls/QGCView.qml
@@ -0,0 +1,233 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+/// @file
+///     @author Don Gagne <don@thegagnes.com>
+
+import QtQuick 2.3
+import QtQuick.Controls 1.3
+import QtQuick.Dialogs 1.2
+
+import QGroundControl.Controls 1.0
+import QGroundControl.Palette 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.FactSystem 1.0
+import QGroundControl.FactControls 1.0
+
+Item {
+    id: __rootItem
+
+    property Component viewComponent
+
+    /// This is signalled when the top level Item reaches Component.onCompleted. This allows
+    /// the view subcomponent to connect to this signal and do work once the full ui is ready
+    /// to go.
+    signal completed
+
+    function __showDialog(component, title, charWidth, buttons) {
+        __acceptButton.visible = false
+        __rejectButton.visible = false
+        __dialogCharWidth = charWidth
+        __dialogTitle = title
+
+        // Accept role buttons
+        if (buttons & StandardButton.Ok) {
+            __acceptButton.text = "Ok"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.Open) {
+            __acceptButton.text = "Open"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.Save) {
+            __acceptButton.text = "Save"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.Apply) {
+            __acceptButton.text = "Apply"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.Open) {
+            __acceptButton.text = "Open"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.SaveAll) {
+            __acceptButton.text = "Save All"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.Yes) {
+            __acceptButton.text = "Yes"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.YesToAll) {
+            __acceptButton.text = "Yes to All"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.Retry) {
+            __acceptButton.text = "Retry"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.Reset) {
+            __acceptButton.text = "Reset"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.RestoreToDefaults) {
+            __acceptButton.text = "Restore to Defaults"
+            __acceptButton.visible = true
+        } else if (buttons & StandardButton.Ignore) {
+            __acceptButton.text = "Ignore"
+            __acceptButton.visible = true
+        }
+
+        // Reject role buttons
+        if (buttons & StandardButton.Cancel) {
+            __rejectButton.text = "Cancel"
+            __rejectButton.visible = true
+        } else if (buttons & StandardButton.Close) {
+            __rejectButton.text = "Cancel"
+            __rejectButton.visible = true
+        } else if (buttons & StandardButton.No) {
+            __rejectButton.text = "No"
+            __rejectButton.visible = true
+        } else if (buttons & StandardButton.NoToAll) {
+            __rejectButton.text = "No to All"
+            __rejectButton.visible = true
+        } else if (buttons & StandardButton.Abort) {
+            __rejectButton.text = "Abort"
+            __rejectButton.visible = true
+        }
+
+        __dialogComponent = component
+        __viewPanel.enabled = false
+        __dialogOverlay.visible = true
+    }
+
+    function __hideDialog() {
+        __dialogComponent = null
+        __viewPanel.enabled = true
+        __dialogOverlay.visible = false
+    }
+
+    QGCPalette { id: __qgcPal; colorGroupEnabled: true }
+    QGCLabel { id: __textMeasure; text: "X"; visible: false }
+
+    property real __textHeight: __textMeasure.contentHeight
+    property real __textWidth:  __textMeasure.contentWidth
+
+    /// The width of the dialog panel in characters
+    property int __dialogCharWidth: 75
+
+    /// The title for the dialog panel
+    property string __dialogTitle
+
+    property Component __dialogComponent
+
+    Component.onCompleted: completed()
+
+    Connections {
+        target: __viewPanel.item
+
+        onShowDialog: __showDialog(component, title, charWidth, buttons)
+        onHideDialog: __hideDialog()
+    }
+
+    Connections {
+        target: __dialogComponentLoader.item
+
+        onHideDialog: __hideDialog()
+    }
+
+    Loader {
+        id:                 __viewPanel
+        anchors.fill:       parent
+        focus:              true
+        sourceComponent:    viewComponent
+    }
+
+    Item {
+        id:             __dialogOverlay
+        visible:        false
+        anchors.fill:   parent
+        z:              5000
+
+        // This covers the parent with an transparent section
+        Rectangle {
+            anchors.top:    parent.top
+            anchors.bottom: parent.bottom
+            anchors.left:   parent.left
+            anchors.right:  __dialogPanel.left
+            opacity:        0.80
+            color:          __qgcPal.window
+        }
+
+        // This is the main dialog panel which is anchored to the right edge
+        Rectangle {
+            id:             __dialogPanel
+            width:          __dialogCharWidth == -1 ? parent.width : __textWidth * __dialogCharWidth
+            height:         parent.height
+            anchors.right:  parent.right
+            color:          __qgcPal.windowShadeDark
+
+            Rectangle {
+                id:     __header
+                width:  parent.width
+                height: __acceptButton.height
+                color:  __qgcPal.windowShade
+
+                function __hidePanel() {
+                    __fullPanel.visible = false
+                }
+
+                QGCLabel {
+                    x:                  __textWidth
+                    height:             parent.height
+                    verticalAlignment:	Text.AlignVCenter
+                    text:               __dialogTitle
+                }
+
+                QGCButton {
+                    id:             __rejectButton
+                    anchors.right:  __acceptButton.left
+                    anchors.bottom: parent.bottom
+
+                    onClicked: __dialogComponentLoader.item.reject()
+                }
+
+                QGCButton {
+                    id:             __acceptButton
+                    anchors.right:  parent.right
+                    primary:        true
+
+                    onClicked: __dialogComponentLoader.item.accept()
+                }
+            }
+
+            Item {
+                id:             __spacer
+                width:          10
+                height:         10
+                anchors.top:    __header.bottom
+            }
+
+            Loader {
+                id:                 __dialogComponentLoader
+                anchors.margins:    5
+                anchors.left:       parent.left
+                anchors.right:      parent.right
+                anchors.top:        __spacer.bottom
+                anchors.bottom:     parent.bottom
+                sourceComponent:    __dialogComponent
+            }
+        } // Rectangle - Dialog panel
+    } // Item - Dialog overlay
+}
\ No newline at end of file
diff --git a/src/QmlControls/QGCViewDialog.qml b/src/QmlControls/QGCViewDialog.qml
new file mode 100644
index 0000000..f65b9d6
--- /dev/null
+++ b/src/QmlControls/QGCViewDialog.qml
@@ -0,0 +1,47 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+/// @file
+///     @author Don Gagne <don@thegagnes.com>
+
+import QtQuick 2.3
+import QtQuick.Controls 1.3
+
+import QGroundControl.Controls 1.0
+import QGroundControl.Palette 1.0
+
+Rectangle {
+    QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
+
+    signal hideDialog
+
+    function accept() {
+        hideDialog()
+    }
+
+    function reject() {
+        hideDialog()
+    }
+
+    color: qgcPal.windowShadeDark
+}
diff --git a/src/QmlControls/QGCViewPanel.qml b/src/QmlControls/QGCViewPanel.qml
new file mode 100644
index 0000000..3bf89d9
--- /dev/null
+++ b/src/QmlControls/QGCViewPanel.qml
@@ -0,0 +1,40 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+/// @file
+///     @author Don Gagne <don@thegagnes.com>
+
+import QtQuick 2.3
+import QtQuick.Controls 1.3
+
+import QGroundControl.Palette 1.0
+import QGroundControl.Controls 1.0
+
+Rectangle {
+    QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
+
+    signal showDialog(Component component, string title, int charWidth, int buttons)
+    signal hideDialog
+
+    color: qgcPal.window
+}
diff --git a/src/QmlControls/ViewWithDialog.qml b/src/QmlControls/ViewWithDialog.qml
deleted file mode 100644
index 61d64c4..0000000
--- a/src/QmlControls/ViewWithDialog.qml
+++ /dev/null
@@ -1,221 +0,0 @@
-/*=====================================================================
-
- QGroundControl Open Source Ground Control Station
-
- (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
-
- This file is part of the QGROUNDCONTROL project
-
- QGROUNDCONTROL is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- QGROUNDCONTROL is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
-
- ======================================================================*/
-
-/// @file
-///     @author Don Gagne <don@thegagnes.com>
-
-import QtQuick 2.3
-import QtQuick.Controls 1.3
-import QtQuick.Dialogs 1.2
-
-import QGroundControl.Controls 1.0
-import QGroundControl.Palette 1.0
-import QGroundControl.ScreenTools 1.0
-import QGroundControl.FactSystem 1.0
-import QGroundControl.FactControls 1.0
-
-Item {
-    property Component viewComponent
-
-    function __showDialog(component, title, charWidth, buttons) {
-        __acceptButton.visible = false
-        __rejectButton.visible = false
-        __dialogCharWidth = charWidth
-        __dialogTitle = title
-
-        if (buttons & StandardButton.Ok) {
-            __acceptButton.text = "Ok"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.Open) {
-            __acceptButton.text = "Open"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.Save) {
-            __acceptButton.text = "Save"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.Cancel) {
-            __rejectButton.text = "Cancel"
-            __rejectButton.visible = true
-        } else if (buttons & StandardButton.Close) {
-            __rejectButton.text = "Cancel"
-            __rejectButton.visible = true
-        } else if (buttons & StandardButton.Apply) {
-            __acceptButton.text = "Apply"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.Open) {
-            __acceptButton.text = "Open"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.SaveAll) {
-            __acceptButton.text = "Save All"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.Yes) {
-            __acceptButton.text = "Yes"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.YesToAll) {
-            __acceptButton.text = "Yes to All"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.No) {
-            __rejectButton.text = "No"
-            __rejectButton.visible = true
-        } else if (buttons & StandardButton.NoToAll) {
-            __rejectButton.text = "No to All"
-            __rejectButton.visible = true
-        } else if (buttons & StandardButton.Abort) {
-            __rejectButton.text = "Abort"
-            __rejectButton.visible = true
-        } else if (buttons & StandardButton.Retry) {
-            __acceptButton.text = "Retry"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.Reset) {
-            __acceptButton.text = "Reset"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.RestoreToDefaults) {
-            __acceptButton.text = "Restore to Defaults"
-            __acceptButton.visible = true
-        } else if (buttons & StandardButton.Ignore) {
-            __acceptButton.text = "Ignore"
-            __acceptButton.visible = true
-        }
-        __dialogComponent = component
-        __viewPanel.enabled = false
-        __dialogOverlay.visible = true
-    }
-
-    function __hideDialog() {
-        __dialogComponent = null
-        __viewPanel.enabled = true
-        __dialogOverlay.visible = false
-    }
-
-    QGCPalette { id: __qgcPal; colorGroupEnabled: true }
-    QGCLabel { id: __textMeasure; text: "X"; visible: false }
-
-    property real __textHeight: __textMeasure.contentHeight
-    property real __textWidth:  __textMeasure.contentWidth
-
-    /// The width of the dialog panel in characters
-    property int __dialogCharWidth: 75
-
-    /// The title for the dialog panel
-    property string __dialogTitle
-
-    property Component __dialogComponent
-
-    Component.onCompleted: __viewPanel.item.doWorkAfterComponentCompleted()
-
-    Connections {
-        target: __viewPanel.item
-
-        onShowDialog: __showDialog(component, title, charWidth, buttons)
-        onHideDialog: __hideDialog()
-    }
-
-    Connections {
-        target: __dialogComponentLoader.item
-
-        onHideDialog: __hideDialog()
-    }
-
-    Loader {
-        id:                 __viewPanel
-        anchors.fill:       parent
-        focus:              true
-        sourceComponent:    viewComponent
-    }
-
-    Item {
-        id:             __dialogOverlay
-        visible:        false
-        anchors.fill:   parent
-        z:              5000
-
-        // This covers the parent with an transparent section
-        Rectangle {
-            anchors.top:    parent.top
-            anchors.bottom: parent.bottom
-            anchors.left:   parent.left
-            anchors.right:  __dialogPanel.left
-            opacity:        0.80
-            color:          __qgcPal.window
-        }
-
-        // This is the main dialog panel which is anchored to the right edge
-        Rectangle {
-            id:             __dialogPanel
-            width:          __textWidth * __dialogCharWidth
-            height:         parent.height
-            anchors.right:  parent.right
-            color:          __qgcPal.windowShadeDark
-
-            Rectangle {
-                id:     __header
-                width:  parent.width
-                height: __acceptButton.height
-                color:  __qgcPal.windowShade
-
-                function __hidePanel() {
-                    __fullPanel.visible = false
-                }
-
-                QGCLabel {
-                    x:                  __textWidth
-                    height:             parent.height
-                    verticalAlignment:	Text.AlignVCenter
-                    text:               __dialogTitle
-                }
-
-                QGCButton {
-                    id:             __rejectButton
-                    anchors.right:  __acceptButton.left
-                    anchors.bottom: parent.bottom
-
-                    onClicked: __dialogComponentLoader.item.reject()
-                }
-
-                QGCButton {
-                    id:             __acceptButton
-                    anchors.right:  parent.right
-                    primary:        true
-
-                    onClicked: __dialogComponentLoader.item.accept()
-                }
-            }
-
-            Item {
-                id:             __spacer
-                width:          10
-                height:         10
-                anchors.top:    __header.bottom
-            }
-
-            Loader {
-                id:                 __dialogComponentLoader
-                anchors.margins:    5
-                anchors.left:       parent.left
-                anchors.right:      parent.right
-                anchors.top:        __spacer.bottom
-                anchors.bottom:     parent.bottom
-                sourceComponent:    __dialogComponent
-            }
-        } // Rectangle - Dialog panel
-    } // Item - Dialog overlay
-}
\ No newline at end of file
diff --git a/src/QmlControls/qmldir b/src/QmlControls/qmldir
index a588343..5c30f2a 100644
--- a/src/QmlControls/qmldir
+++ b/src/QmlControls/qmldir
@@ -16,5 +16,8 @@ VehicleRotationCal 1.0 VehicleRotationCal.qml
 VehicleSummaryRow 1.0 VehicleSummaryRow.qml
 ParameterEditor 1.0 ParameterEditor.qml
 ViewWidget 1.0 ViewWidget.qml
-ViewWithDialog 1.0 ViewWithDialog.qml
+
+QGCView 1.0 QGCView.qml
+QGCViewPanel 1.0 QGCViewPanel.qml
+QGCViewDialog 1.0 QGCViewDialog.qml