Skip to content

Commit

Permalink
[ui] GraphEditor: single tab group + status table
Browse files Browse the repository at this point in the history
- Use a single tab group for attributes, log, statistics, status
- Use a ListView with key/value to display the node status fields (instead of a file viewer)
  • Loading branch information
fabiencastan committed Sep 14, 2019
1 parent 6e8a6de commit 13d0763
Show file tree
Hide file tree
Showing 5 changed files with 363 additions and 109 deletions.
66 changes: 66 additions & 0 deletions meshroom/ui/qml/GraphEditor/ChunksListView.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import QtQuick 2.11
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4 as Controls1 // SplitView
import QtQuick.Layouts 1.3
import MaterialIcons 2.2
import Controls 1.0

import "common.js" as Common

/**
* ChunkListView
*/
ListView {
id: chunksLV

// model: node.chunks

property variant currentChunk: currentItem ? currentItem.chunk : undefined

width: 60
Layout.fillHeight: true
highlightFollowsCurrentItem: true
keyNavigationEnabled: true
focus: true
currentIndex: 0

signal changeCurrentChunk(int chunkIndex)

header: Component {
Label {
width: chunksLV.width
elide: Label.ElideRight
text: "Chunks"
padding: 4
z: 10
background: Rectangle { color: parent.palette.window }
}
}

highlight: Component {
Rectangle {
color: activePalette.highlight
opacity: 0.3
z: 2
}
}
highlightMoveDuration: 0
highlightResizeDuration: 0

delegate: ItemDelegate {
id: chunkDelegate
property var chunk: object
text: index
width: parent.width
leftPadding: 8
onClicked: {
chunksLV.forceActiveFocus()
chunksLV.changeCurrentChunk(index)
}
Rectangle {
width: 4
height: parent.height
color: Common.getChunkColor(parent.chunk)
}
}
}
39 changes: 36 additions & 3 deletions meshroom/ui/qml/GraphEditor/NodeEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ Panel {
signal attributeDoubleClicked(var mouse, var attribute)
signal upgradeRequest()

Item {
id: m
property int chunkCurrentIndex: 0
}

onNodeChanged: {
m.chunkCurrentIndex = 0 // Needed to avoid invalid state of ChunksListView
}

title: "Node" + (node !== null ? " - <b>" + node.label + "</b>" : "")
icon: MaterialLabel { text: MaterialIcons.tune }

Expand Down Expand Up @@ -113,7 +122,6 @@ Panel {
currentIndex: tabBar.currentIndex

AttributeEditor {
Layout.fillWidth: true
attributes: root.node.attributes
readOnly: root.readOnly || root.isCompatibilityNode
onAttributeDoubleClicked: root.attributeDoubleClicked(mouse, attribute)
Expand All @@ -122,10 +130,23 @@ Panel {

NodeLog {
id: nodeLog
node: root.node
chunkCurrentIndex: m.chunkCurrentIndex
onChangeCurrentChunk: { m.chunkCurrentIndex = chunkIndex }
}

Layout.fillHeight: true
Layout.fillWidth: true
NodeStatistics {
id: nodeStatistics
node: root.node
chunkCurrentIndex: m.chunkCurrentIndex
onChangeCurrentChunk: { m.chunkCurrentIndex = chunkIndex }
}

NodeStatus {
id: nodeStatus
node: root.node
chunkCurrentIndex: m.chunkCurrentIndex
onChangeCurrentChunk: { m.chunkCurrentIndex = chunkIndex }
}
}
}
Expand All @@ -152,6 +173,18 @@ Panel {
leftPadding: 8
rightPadding: leftPadding
}
TabButton {
text: "Statistics"
width: implicitWidth
leftPadding: 8
rightPadding: leftPadding
}
TabButton {
text: "Status"
width: implicitWidth
leftPadding: 8
rightPadding: leftPadding
}
}
}
}
132 changes: 26 additions & 106 deletions meshroom/ui/qml/GraphEditor/NodeLog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,134 +14,54 @@ import "common.js" as Common
* if the related NodeChunk is being computed.
*/
FocusScope {
id: root
property variant node
property alias chunkCurrentIndex: chunksLV.currentIndex
signal changeCurrentChunk(int chunkIndex)

SystemPalette { id: activePalette }

Controls1.SplitView {
anchors.fill: parent

// The list of chunks
ListView {
ChunksListView {
id: chunksLV

property variant currentChunk: currentItem ? currentItem.chunk : undefined

width: 60
Layout.fillHeight: true
model: node.chunks
highlightFollowsCurrentItem: true
keyNavigationEnabled: true
focus: true
currentIndex: 0

header: Component {
Label {
width: chunksLV.width
elide: Label.ElideRight
text: "Chunks"
padding: 4
z: 10
background: Rectangle { color: parent.palette.window }
}
}

highlight: Component {
Rectangle {
color: activePalette.highlight
opacity: 0.3
z: 2
}
}
highlightMoveDuration: 0
highlightResizeDuration: 0

delegate: ItemDelegate {
id: chunkDelegate
property var chunk: object
text: index
width: parent.width
leftPadding: 8
onClicked: {
chunksLV.forceActiveFocus()
chunksLV.currentIndex = index
}
Rectangle {
width: 4
height: parent.height
color: Common.getChunkColor(parent.chunk)
}
}
onChangeCurrentChunk: root.changeCurrentChunk(chunkIndex)
}

ColumnLayout {
Loader {
id: componentLoader
clip: true
Layout.fillWidth: true
Layout.fillHeight: true
Layout.margins: 1

spacing: 1
property url source

TabBar {
id: fileSelector
Layout.fillWidth: true
property string currentFile: chunksLV.currentChunk ? chunksLV.currentChunk[currentItem.fileProperty] : ""
onCurrentFileChanged: {
// only set text file viewer source when ListView is fully ready
// (either empty or fully populated with a valid currentChunk)
// to avoid going through an empty url when switching between two nodes

if(!chunksLV.count || chunksLV.currentChunk)
logComponentLoader.source = Filepath.stringToUrl(currentFile);

}
property string currentFile: chunksLV.currentChunk ? chunksLV.currentChunk["logFile"] : ""
onCurrentFileChanged: {
// only set text file viewer source when ListView is fully ready
// (either empty or fully populated with a valid currentChunk)
// to avoid going through an empty url when switching between two nodes

TabButton {
property string fileProperty: "logFile"
text: "Output"
padding: 4
}
if(!chunksLV.count || chunksLV.currentChunk)
componentLoader.source = Filepath.stringToUrl(currentFile);

TabButton {
property string fileProperty: "statisticsFile"
text: "Statistics"
padding: 4
}
TabButton {
property string fileProperty: "statusFile"
text: "Status"
padding: 4
}
}

Loader {
id: logComponentLoader
clip: true
sourceComponent: textFileViewerComponent
}

Component {
id: textFileViewerComponent
TextFileViewer {
id: textFileViewer
source: componentLoader.source
Layout.fillWidth: true
Layout.fillHeight: true
property url source
sourceComponent: fileSelector.currentItem.fileProperty === "statisticsFile" ? statViewerComponent : textFileViewerComponent
}

Component {
id: textFileViewerComponent
TextFileViewer {
id: textFileViewer
source: logComponentLoader.source
Layout.fillWidth: true
Layout.fillHeight: true
autoReload: chunksLV.currentChunk !== undefined && chunksLV.currentChunk.statusName === "RUNNING"
// source is set in fileSelector
}
}

Component {
id: statViewerComponent
StatViewer {
id: statViewer
Layout.fillWidth: true
Layout.fillHeight: true
source: logComponentLoader.source
}
autoReload: chunksLV.currentChunk !== undefined && chunksLV.currentChunk.statusName === "RUNNING"
// source is set in fileSelector
}
}
}
Expand Down
65 changes: 65 additions & 0 deletions meshroom/ui/qml/GraphEditor/NodeStatistics.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import QtQuick 2.11
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4 as Controls1 // SplitView
import QtQuick.Layouts 1.3
import MaterialIcons 2.2
import Controls 1.0

import "common.js" as Common

/**
* NodeLog displays log and statistics data of Node's chunks (NodeChunks)
*
* To ease monitoring, it provides periodic auto-reload of the opened file
* if the related NodeChunk is being computed.
*/
FocusScope {
id: root
property variant node
property alias chunkCurrentIndex: chunksLV.currentIndex
signal changeCurrentChunk(int chunkIndex)

SystemPalette { id: activePalette }

Controls1.SplitView {
anchors.fill: parent

// The list of chunks
ChunksListView {
id: chunksLV
Layout.fillHeight: true
model: node.chunks
onChangeCurrentChunk: root.changeCurrentChunk(chunkIndex)
}

Loader {
id: componentLoader
clip: true
Layout.fillWidth: true
Layout.fillHeight: true
property url source

property string currentFile: chunksLV.currentChunk ? chunksLV.currentChunk["statisticsFile"] : ""
onCurrentFileChanged: {
// only set text file viewer source when ListView is fully ready
// (either empty or fully populated with a valid currentChunk)
// to avoid going through an empty url when switching between two nodes

if(!chunksLV.count || chunksLV.currentChunk)
componentLoader.source = Filepath.stringToUrl(currentFile);
}

sourceComponent: statViewerComponent
}

Component {
id: statViewerComponent
StatViewer {
id: statViewer
Layout.fillWidth: true
Layout.fillHeight: true
source: componentLoader.source
}
}
}
}
Loading

0 comments on commit 13d0763

Please sign in to comment.