diff --git a/meshroom/ui/qml/GraphEditor/GraphEditor.qml b/meshroom/ui/qml/GraphEditor/GraphEditor.qml index e73b1383..a780573f 100755 --- a/meshroom/ui/qml/GraphEditor/GraphEditor.qml +++ b/meshroom/ui/qml/GraphEditor/GraphEditor.qml @@ -772,6 +772,86 @@ Item { } } + // Graph Nodes Search + FloatingPane { + id: navigation + padding: 2 + anchors.top: parent.top + + property int currentIndex: -1 + + RowLayout { + spacing: 0 + + SearchBar { + id: graphSearchBar + Layout.minimumWidth: 150 + width: 150 + textField.background.opacity: 0.5 + textField.onTextChanged: navigation.currentIndex = -1 + } + + MaterialToolButton { + text: MaterialIcons.arrow_left + padding: 0 + enabled: graphSearchBar.text !== "" + onClicked: { + navigation.currentIndex--; + if (navigation.currentIndex === -1) + navigation.currentIndex = filteredNodes.count - 1; + navigation.nextItem(); + } + } + + MaterialToolButton { + text: MaterialIcons.arrow_right + padding: 0 + enabled: graphSearchBar.text !== "" + onClicked: { + navigation.currentIndex++; + if (navigation.currentIndex === filteredNodes.count) + navigation.currentIndex = 0; + navigation.nextItem(); + } + } + + Label { + id: currentSearchLabel + text: " " + (navigation.currentIndex + 1) + "/" + filteredNodes.count + padding: 0 + visible: graphSearchBar.text !== "" + } + + } + + Repeater { + id: filteredNodes + model: SortFilterDelegateModel { + model: root.graph ? root.graph.nodes : undefined + sortRole: "label" + filters: [{role: "label", value: graphSearchBar.text}] + delegate: Item { + property var index_: index + } + function modelData(item, roleName_) { + return item.model.object[roleName_] + } + } + } + + function nextItem() + { + // compute bounding box + var node = nodeRepeater.itemAt(filteredNodes.itemAt(navigation.currentIndex).index_) + var bbox = Qt.rect(node.x, node.y, node.width, node.height) + // rescale to fit the bounding box in the view, zoom is limited to prevent huge text + draggable.scale = Math.min(Math.min(root.width/bbox.width, root.height/bbox.height),maxZoom) + // recenter + draggable.x = bbox.x*draggable.scale*-1 + (root.width-bbox.width*draggable.scale)*0.5 + draggable.y = bbox.y*draggable.scale*-1 + (root.height-bbox.height*draggable.scale)*0.5 + } + } + function registerAttributePin(attribute, pin) { root._attributeToDelegate[attribute] = pin