Browse Source

Merge pull request #8127 from mavlink/pr-analyze-float

Allow analyze panels to be detached into their own windows
QGC4.4
Gus Grubba 6 years ago committed by GitHub
parent
commit
9f6ea7e106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      qgcimages.qrc
  2. 84
      src/AnalyzeView/AnalyzePage.qml
  3. 47
      src/AnalyzeView/AnalyzeView.qml
  4. 10
      src/AnalyzeView/FloatingWindow.svg
  5. 275
      src/AnalyzeView/MAVLinkInspectorPage.qml

1
qgcimages.qrc

@ -80,6 +80,7 @@ @@ -80,6 +80,7 @@
<file alias="FirmwareUpgradeIcon.png">src/VehicleSetup/FirmwareUpgradeIcon.png</file>
<file alias="FollowComponentIcon.png">src/AutoPilotPlugins/Common/Images/FlightModesComponentIcon.png</file>
<file alias="FlightModesComponentIcon.png">src/AutoPilotPlugins/Common/Images/FlightModesComponentIcon.png</file>
<file alias="FloatingWindow.svg">src/AnalyzeView/FloatingWindow.svg</file>
<file alias="Frames/BlueROV1.png">src/AutoPilotPlugins/APM/Images/bluerov-frame.png</file>
<file alias="Frames/SimpleROV-3.png">src/AutoPilotPlugins/APM/Images/simple3-frame.png</file>
<file alias="Frames/SimpleROV-4.png">src/AutoPilotPlugins/APM/Images/simple4-frame.png</file>

84
src/AnalyzeView/AnalyzePage.qml

@ -23,36 +23,78 @@ Item { @@ -23,36 +23,78 @@ Item {
property alias pageComponent: pageLoader.sourceComponent
property alias pageName: pageNameLabel.text
property alias pageDescription: pageDescriptionLabel.text
property alias headerComponent: headerLoader.sourceComponent
property real availableWidth: width - pageLoader.x
property real availableHeight: height - pageLoader.y
property real availableHeight: height - mainContent.y
property bool poped: false
property real _margins: ScreenTools.defaultFontPixelHeight * 0.5
signal popout()
Loader {
id: headerLoader
anchors.topMargin: _margins
anchors.top: parent.top
anchors.left: parent.left
anchors.rightMargin: _margins
anchors.right: floatIcon.left
visible: !ScreenTools.isShortScreen && headerLoader.sourceComponent !== null
}
Column {
id: headingColumn
anchors.topMargin: _margins
anchors.top: parent.top
anchors.left: parent.left
anchors.rightMargin: _margins
anchors.right: floatIcon.left
spacing: _margins
visible: !ScreenTools.isShortScreen && headerLoader.sourceComponent === null
QGCLabel {
id: pageNameLabel
font.pointSize: ScreenTools.largeFontPointSize
visible: !poped
}
QGCLabel {
id: pageDescriptionLabel
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
}
}
QGCFlickable {
anchors.fill: parent
id: mainContent
anchors.topMargin: ScreenTools.defaultFontPixelHeight
anchors.top: headerLoader.sourceComponent === null ? (headingColumn.visible ? headingColumn.bottom : parent.top) : headerLoader.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
contentWidth: pageLoader.x + pageLoader.item.width
contentHeight: pageLoader.y + pageLoader.item.height
clip: true
Column {
id: headingColumn
width: parent.width
spacing: _margins
QGCLabel {
id: pageNameLabel
font.pointSize: ScreenTools.largeFontPointSize
visible: !ScreenTools.isShortScreen
}
QGCLabel {
id: pageDescriptionLabel
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
visible: !ScreenTools.isShortScreen
}
}
Loader {
id: pageLoader
anchors.topMargin: _margins
anchors.top: headingColumn.bottom
}
}
QGCColoredImage {
id: floatIcon
anchors.verticalCenter: headerLoader.visible ? headerLoader.verticalCenter : headingColumn.verticalCenter
anchors.right: parent.right
width: ScreenTools.defaultFontPixelHeight * 2
height: width
sourceSize.width: width
source: "/qmlimages/FloatingWindow.svg"
fillMode: Image.PreserveAspectFit
color: qgcPal.text
visible: !poped && !ScreenTools.isMobile
MouseArea {
anchors.fill: parent
onClicked: {
popout()
}
}
}
}

47
src/AnalyzeView/AnalyzeView.qml

@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
/// @author Don Gagne <don@thegagnes.com>
import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import QGroundControl 1.0
@ -34,6 +35,8 @@ Rectangle { @@ -34,6 +35,8 @@ Rectangle {
readonly property real _verticalMargin: _defaultTextHeight / 2
readonly property real _buttonWidth: _defaultTextWidth * 18
property int _curIndex: 0
GeoTagController {
id: geoController
}
@ -136,11 +139,41 @@ Rectangle { @@ -136,11 +139,41 @@ Rectangle {
model: ScreenTools.isMobile ? mobileModel : desktopModel
Component.onCompleted: itemAt(0).checked = true
SubMenuButton {
id: subMenu
imageResource: buttonImage
setupIndicator: false
exclusiveGroup: setupButtonGroup
text: buttonText
onClicked: { panelLoader.source = pageSource; checked = true; }
property var window: analyzeWidgetWindow
property var loader: analyzeWidgetLoader
onClicked: {
_curIndex = index
panelLoader.source = pageSource
checked = true
}
Window {
id: analyzeWidgetWindow
width: mainWindow.width * 0.5
height: mainWindow.height * 0.5
visible: false
title: buttonText
Rectangle {
color: qgcPal.window
anchors.fill: parent
Loader {
id: analyzeWidgetLoader
anchors.fill: parent
}
}
onClosing: {
analyzeWidgetWindow.visible = false
analyzeWidgetLoader.source = ""
_curIndex = index
panelLoader.source = pageSource
subMenu.visible = true
subMenu.checked = true
}
}
}
}
}
@ -158,6 +191,18 @@ Rectangle { @@ -158,6 +191,18 @@ Rectangle {
color: qgcPal.windowShade
}
Connections {
target: panelLoader.item
onPopout: {
buttonRepeater.itemAt(_curIndex).window.visible = true
var source = panelLoader.source
panelLoader.source = ""
buttonRepeater.itemAt(_curIndex).loader.source = source
buttonRepeater.itemAt(_curIndex).visible = false
buttonRepeater.itemAt(_curIndex).loader.item.poped = true
}
}
Loader {
id: panelLoader
anchors.topMargin: _verticalMargin

10
src/AnalyzeView/FloatingWindow.svg

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<path d="M218.7,16.6H69.3C31,16.6,0,47.6,0,85.9v116.2c0,38.3,31,69.3,69.3,69.3h149.4c38.3,0,69.3-31,69.3-69.3V85.9
C288,47.6,257,16.6,218.7,16.6z M139.5,215.9c0,14.7-11.9,26.6-26.6,26.6H55.5c-14.7,0-26.6-11.9-26.6-26.6v-44.7
c0-14.7,11.9-26.6,26.6-26.6h57.4c14.7,0,26.6,11.9,26.6,26.6L139.5,215.9L139.5,215.9z M246.9,71.6l-15.7,58.8
c-2.8,10.5-11.4,12.8-19.1,5.1l-6.8-6.8l-22.8,22.8c-5.9,5.9-15.6,5.9-21.5,0l-7.9-7.9c-5.9-5.9-5.9-15.5,0-21.5l22.8-22.8l-6.8-6.8
c-7.7-7.7-5.4-16.2,5.1-19.1L233,57.7C243.4,54.9,249.7,61.2,246.9,71.6z"/>
</svg>

After

Width:  |  Height:  |  Size: 895 B

275
src/AnalyzeView/MAVLinkInspectorPage.qml

@ -18,9 +18,9 @@ import QGroundControl.Controls 1.0 @@ -18,9 +18,9 @@ import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.ScreenTools 1.0
Item {
anchors.fill: parent
anchors.margins: ScreenTools.defaultFontPixelWidth
AnalyzePage {
headerComponent: headerComponent
pageComponent: pageComponent
property var curVehicle: controller ? controller.activeVehicle : null
property int curMessageIndex: 0
@ -33,154 +33,155 @@ Item { @@ -33,154 +33,155 @@ Item {
id: controller
}
DeadMouseArea {
anchors.fill: parent
}
//-- Header
RowLayout {
id: header
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
QGCLabel {
text: qsTr("Inspect real time MAVLink messages.")
}
Component {
id: headerComponent
//-- Header
RowLayout {
Layout.alignment: Qt.AlignRight
visible: curVehicle ? curVehicle.compIDsStr.length > 2 : false
id: header
anchors.left: parent.left
anchors.right: parent.right
QGCLabel {
text: qsTr("Component ID:")
text: qsTr("Inspect real time MAVLink messages.")
}
QGCComboBox {
id: cidCombo
model: curVehicle ? curVehicle.compIDsStr : []
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 10
currentIndex: 0
onActivated: {
if(curVehicle && curVehicle.compIDsStr.length > 1) {
selectionValid = false
if(index < 1)
curCompID = 0
else
curCompID = curVehicle.compIDs[index - 1]
RowLayout {
Layout.alignment: Qt.AlignRight
visible: curVehicle ? curVehicle.compIDsStr.length > 2 : false
QGCLabel {
text: qsTr("Component ID:")
}
QGCComboBox {
id: cidCombo
model: curVehicle ? curVehicle.compIDsStr : []
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 10
currentIndex: 0
onActivated: {
if(curVehicle && curVehicle.compIDsStr.length > 1) {
selectionValid = false
if(index < 1)
curCompID = 0
else
curCompID = curVehicle.compIDs[index - 1]
}
}
}
}
}
}
//-- Messages (Buttons)
QGCFlickable {
id: buttonGrid
anchors.top: header.bottom
anchors.topMargin: ScreenTools.defaultFontPixelHeight
anchors.bottom: parent.bottom
anchors.left: parent.left
width: maxButtonWidth
contentWidth: width
contentHeight: buttonCol.height
ColumnLayout {
id: buttonCol
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater {
model: curVehicle ? curVehicle.messages : []
delegate: MAVLinkMessageButton {
text: object.name
compID: object.cid
checked: curMessageIndex === index
messageHz: object.messageHz
visible: curCompID === 0 || curCompID === compID
onClicked: {
selectionValid = true
curMessageIndex = index
Component {
id: pageComponent
RowLayout {
width: availableWidth
height: availableHeight
//-- Messages (Buttons)
QGCFlickable {
id: buttonGrid
width: maxButtonWidth
Layout.maximumWidth:maxButtonWidth
Layout.fillHeight: true
Layout.fillWidth: true
contentWidth: width
contentHeight: buttonCol.height
ColumnLayout {
id: buttonCol
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater {
model: curVehicle ? curVehicle.messages : []
delegate: MAVLinkMessageButton {
text: object.name
compID: object.cid
checked: curMessageIndex === index
messageHz: object.messageHz
visible: curCompID === 0 || curCompID === compID
onClicked: {
selectionValid = true
curMessageIndex = index
}
Layout.fillWidth: true
}
}
Layout.fillWidth: true
}
}
}
}
//-- Message Data
QGCFlickable {
id: messageGrid
visible: curMessage !== null && selectionValid
anchors.top: buttonGrid.top
anchors.bottom: parent.bottom
anchors.left: buttonGrid.right
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
anchors.right: parent.right
contentWidth: messageCol.width
contentHeight: messageCol.height
ColumnLayout {
id: messageCol
spacing: ScreenTools.defaultFontPixelHeight * 0.25
GridLayout {
columns: 2
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
QGCLabel {
text: qsTr("Message:")
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 20
}
QGCLabel {
color: qgcPal.buttonHighlight
text: curMessage ? curMessage.name + ' (' + curMessage.id + ') ' + curMessage.messageHz.toFixed(1) + 'Hz' : ""
}
QGCLabel {
text: qsTr("Component:")
}
QGCLabel {
text: curMessage ? curMessage.cid : ""
}
QGCLabel {
text: qsTr("Count:")
}
QGCLabel {
text: curMessage ? curMessage.count : ""
}
}
Item { height: ScreenTools.defaultFontPixelHeight; width: 1 }
QGCLabel {
text: qsTr("Message Fields:")
}
Rectangle {
Layout.fillWidth: true
height: 1
color: qgcPal.text
}
Item { height: ScreenTools.defaultFontPixelHeight * 0.25; width: 1 }
GridLayout {
columns: 3
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 0
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 20
text: object.name
//-- Message Data
QGCFlickable {
id: messageGrid
visible: curMessage !== null && selectionValid
Layout.fillHeight: true
Layout.fillWidth: true
contentWidth: messageCol.width
contentHeight: messageCol.height
ColumnLayout {
id: messageCol
spacing: ScreenTools.defaultFontPixelHeight * 0.25
GridLayout {
columns: 2
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
QGCLabel {
text: qsTr("Message:")
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 20
}
QGCLabel {
color: qgcPal.buttonHighlight
text: curMessage ? curMessage.name + ' (' + curMessage.id + ') ' + curMessage.messageHz.toFixed(1) + 'Hz' : ""
}
QGCLabel {
text: qsTr("Component:")
}
QGCLabel {
text: curMessage ? curMessage.cid : ""
}
QGCLabel {
text: qsTr("Count:")
}
QGCLabel {
text: curMessage ? curMessage.count : ""
}
}
}
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 1
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 30
Layout.maximumWidth: ScreenTools.defaultFontPixelWidth * 30
wrapMode: Text.WordWrap
text: object.value
Item { height: ScreenTools.defaultFontPixelHeight; width: 1 }
QGCLabel {
text: qsTr("Message Fields:")
}
}
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 2
text: object.type
Rectangle {
Layout.fillWidth: true
height: 1
color: qgcPal.text
}
Item { height: ScreenTools.defaultFontPixelHeight * 0.25; width: 1 }
GridLayout {
columns: 3
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 0
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 20
text: object.name
}
}
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 1
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 30
Layout.maximumWidth: ScreenTools.defaultFontPixelWidth * 30
wrapMode: Text.WordWrap
text: object.value
}
}
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCLabel {
Layout.row: index
Layout.column: 2
text: object.type
}
}
}
}
}

Loading…
Cancel
Save