diff --git a/meshroom/ui/qml/Viewer3D/Inspector3D.qml b/meshroom/ui/qml/Viewer3D/Inspector3D.qml index cd28b7bd..93cb1bad 100644 --- a/meshroom/ui/qml/Viewer3D/Inspector3D.qml +++ b/meshroom/ui/qml/Viewer3D/Inspector3D.qml @@ -19,6 +19,7 @@ FloatingPane { property Grid3D grid: null property MediaLibrary mediaLibrary property Camera camera + property var uigraph: null signal mediaFocusRequest(var index) signal mediaRemoveRequest(var index) @@ -128,6 +129,13 @@ FloatingPane { } } + currentIndex: -1 + + Connections { + target: uigraph + onSelectedNodeChanged: mediaListView.currentIndex = -1 + } + Connections { target: mediaLibrary onLoadRequest: { @@ -136,6 +144,7 @@ FloatingPane { } delegate: RowLayout { + id: mediaDelegate // add mediaLibrary.count in the binding to ensure 'entity' // is re-evaluated when mediaLibrary delegates are modified property bool loading: model.status === SceneLoader.Loading @@ -145,12 +154,37 @@ FloatingPane { property string src: model.source onSrcChanged: focusAnim.restart() - RowLayout { - Layout.alignment: Qt.AlignTop - spacing: 0 + property bool hovered: model.attribute ? uigraph.hoveredNode === model.attribute.node : mouseArea.containsMouse + property bool isSelectedNode: model.attribute ? uigraph.selectedNode === model.attribute.node : false - MaterialToolButton { - text: model.visible ? MaterialIcons.visibility : MaterialIcons.visibility_off + function updateCurrentIndex() { + if(isSelectedNode) { mediaListView.currentIndex = index } + } + + onIsSelectedNodeChanged: updateCurrentIndex() + + Connections { + target: mediaListView + onCountChanged: mediaDelegate.updateCurrentIndex() + } + + // Current/selected element indicator + Rectangle { + Layout.fillHeight: true + width: 2 + color: { + if(mediaListView.currentIndex == index || mediaDelegate.isSelectedNode) + return label.palette.highlight; + if(mediaDelegate.hovered) + return Qt.darker(label.palette.highlight, 1.5); + return "transparent"; + } + } + + // Media visibility/loading control + MaterialToolButton { + Layout.alignment: Qt.AlignTop + text: model.visible ? MaterialIcons.visibility : MaterialIcons.visibility_off font.pointSize: 10 ToolTip.text: model.visible ? "Hide" : "Show" flat: true @@ -173,47 +207,42 @@ FloatingPane { modifiers = mouse.modifiers; mouse.accepted = false; } - } - } - MaterialToolButton { - text: MaterialIcons.filter_center_focus - font.pointSize: 10 - ToolTip.text: "Frame" - onClicked: camera.viewEntity(mediaLibrary.entityAt(index)) - flat: true } } - ColumnLayout { + // Media label and info + Item { + implicitHeight: childrenRect.height Layout.fillWidth: true - spacing: 1 Layout.alignment: Qt.AlignTop + ColumnLayout { + id: centralLayout + width: parent.width + spacing: 1 - Label { - id: label - leftPadding: 0 - rightPadding: 0 - topPadding: 3 - bottomPadding: topPadding - Layout.fillWidth: true - text: model.label - elide: Text.ElideMiddle - background: Rectangle { - Connections { - target: mediaLibrary - onLoadRequest: if(idx == index) focusAnim.restart() + Label { + id: label + Layout.fillWidth: true + leftPadding: 0 + rightPadding: 0 + topPadding: 3 + bottomPadding: topPadding + text: model.label + opacity: model.valid ? 1.0 : 0.6 + elide: Text.ElideMiddle + font.weight: mediaListView.currentIndex == index ? Font.DemiBold : Font.Normal + background: Rectangle { + Connections { + target: mediaLibrary + onLoadRequest: if(idx == index) focusAnim.restart() + } + ColorAnimation on color { + id: focusAnim + from: label.palette.highlight + to: "transparent" + duration: 2000 + } } - ColorAnimation on color { - id: focusAnim - from: label.palette.highlight - to: "transparent" - duration: 2000 - } - MouseArea { - anchors.fill: parent - onDoubleClicked: camera.viewEntity(mediaLibrary.entityAt(index)) - } - } } Item { Layout.fillWidth: true @@ -230,6 +259,25 @@ FloatingPane { Label { visible: model.textureCount; text: model.textureCount } } } + } + MouseArea { + id: mouseArea + anchors.fill: centralLayout + hoverEnabled: true + onEntered: { if(model.attribute) uigraph.hoveredNode = model.attribute.node } + onExited: { if(model.attribute) uigraph.hoveredNode = null } + onClicked: { + if(model.attribute) + uigraph.selectedNode = model.attribute.node; + else + uigraph.selectedNode = null; + mediaListView.currentIndex = index; + } + onDoubleClicked: { + model.visible = true; + camera.viewEntity(mediaLibrary.entityAt(index)); + } + } } // Media unavailability indicator diff --git a/meshroom/ui/qml/Viewer3D/Viewer3D.qml b/meshroom/ui/qml/Viewer3D/Viewer3D.qml index fcbd5e3d..9a1c4763 100644 --- a/meshroom/ui/qml/Viewer3D/Viewer3D.qml +++ b/meshroom/ui/qml/Viewer3D/Viewer3D.qml @@ -19,6 +19,7 @@ FocusScope { property int renderMode: 2 property alias library: mediaLibrary + property alias inspector: inspector3d // functions function resetCameraCenter() { @@ -218,7 +219,7 @@ FocusScope { Item { Layout.fillWidth: true; Layout.minimumWidth: parent.width * 0.5 } Inspector3D { - id: inspector + id: inspector3d width: 220 Layout.minimumWidth: 5 diff --git a/meshroom/ui/qml/WorkspaceView.qml b/meshroom/ui/qml/WorkspaceView.qml index 63e2a3a6..692f12ef 100644 --- a/meshroom/ui/qml/WorkspaceView.qml +++ b/meshroom/ui/qml/WorkspaceView.qml @@ -124,6 +124,8 @@ Item { readonly property int outputMediaIndex: library.find(outputAttribute) anchors.fill: parent + inspector.uigraph: reconstruction + DropArea { anchors.fill: parent keys: ["text/uri-list"]