Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion meshroom/ui/qml/Controls/SearchBar.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,24 @@ import MaterialIcons 2.2
*/

FocusScope {
id: root
property alias textField: field
property alias text: field.text

// Enables hiding and showing of the text field on Search button click
property bool toggle: false
property bool isVisible: false

// Size properties
property int maxWidth: 150
property int minWidth: 30

// The default width is computed based on whether toggling is enabled and if the visibility is true
width: toggle && isVisible ? maxWidth : minWidth

// Keyboard interaction related signals
signal accepted()

implicitHeight: childrenRect.height
Keys.forwardTo: [field]

Expand All @@ -24,10 +39,17 @@ FocusScope {
}

RowLayout {
spacing: 0
width: parent.width

MaterialLabel {
MaterialToolButton {
text: MaterialIcons.search

onClicked: {
isVisible = !root.isVisible
// Set Focus on the Text Field
field.focus = field.visible
}
}

TextField {
Expand All @@ -36,10 +58,46 @@ FocusScope {
Layout.fillWidth: true
selectByMouse: true

rightPadding: clear.width

// The text field is visible either when toggle is not activated or the visible property is set
visible: root.toggle ? root.isVisible : true

// Ensure the field has focus when the text is modified
onTextChanged: {
forceActiveFocus()
}

// Handle enter Key press and forward it to the parent
Keys.onPressed: (event)=> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be using the more semantic onAccepted slot to have both Return and Enter key considered
(to work with Enter key on numpad).
The root signal for the search bar could be accepted to match that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core signal from the class is updated to be called accepted but using onAccepted instead of Keys.onPressed currently is emitting the signal twice so keeping it same at the moment,
Have updated the event to consider both Return and Number Pad Enter key though.

if ((event.key == Qt.Key_Return || event.key == Qt.Key_Enter)) {
event.accepted = true
root.accepted()
}
}

MaterialToolButton {
id: clear

// Anchors
anchors.right: parent.right
anchors.rightMargin: 2 // Leave a tiny bit of space so that its highlight does not overlap with the boundary of the parent
anchors.verticalCenter: parent.verticalCenter

// Style
font.pointSize: 8
text: MaterialIcons.close
ToolTip.text: "Clears text."

// States
visible: field.text

// Signals -> Slots
onClicked: {
field.text = ""
parent.focus = true
}
}
}
}
}
Expand Down
128 changes: 76 additions & 52 deletions meshroom/ui/qml/GraphEditor/GraphEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,11 @@ Item {
padding: 2
anchors.bottom: parent.bottom
RowLayout {
id: navigation
spacing: 4

// Default index for search
property int currentIndex: -1
// Fit
MaterialToolButton {
text: MaterialIcons.fullscreen
Expand Down Expand Up @@ -1044,7 +1048,7 @@ Item {
ComboBox {
flat: true
model: ['Minimum', 'Maximum']
implicitWidth: 80
implicitWidth: 85
currentIndex: uigraph ? uigraph.layout.depthMode : -1
onActivated: {
uigraph.layout.depthMode = currentIndex
Expand All @@ -1071,50 +1075,44 @@ Item {
uigraph.setSelectedNodesColor(color)
}
}
}
}

// Graph Nodes Search
FloatingPane {
id: navigation
padding: 2
anchors.top: parent.top

property int currentIndex: -1

RowLayout {
spacing: 0
// Separator
Rectangle {
Layout.fillHeight: true
Layout.margins: 2
implicitWidth: 1
color: activePalette.window
}

// Search nodes in the graph
SearchBar {
id: graphSearchBar
Layout.minimumWidth: 150
width: 150

toggle: true // enable toggling the actual text field by the search button
Layout.minimumWidth: graphSearchBar.width
maxWidth: 150

textField.background.opacity: 0.5
textField.onTextChanged: navigation.currentIndex = -1

onAccepted: {
navigation.navigateForward()
}
}

MaterialToolButton {
text: MaterialIcons.arrow_left
padding: 0
enabled: graphSearchBar.text !== ""
onClicked: {
navigation.currentIndex--
if (navigation.currentIndex === -1)
navigation.currentIndex = filteredNodes.count - 1
navigation.nextItem()
}
visible: graphSearchBar.text !== ""
onClicked: navigation.navigateBackward()
}

MaterialToolButton {
id: nextArrow
text: MaterialIcons.arrow_right
padding: 0
enabled: graphSearchBar.text !== ""
onClicked: {
navigation.currentIndex++
if (navigation.currentIndex === filteredNodes.count)
navigation.currentIndex = 0
navigation.nextItem()
}
visible: graphSearchBar.text !== ""
onClicked: navigation.navigateForward()
}

Label {
Expand All @@ -1124,32 +1122,58 @@ Item {
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_]
Repeater {
id: filteredNodes
model: SortFilterDelegateModel {
model: root.graph ? root.graph.nodes : undefined
sortRole: "label"
filters: [{role: "label", value: graphSearchBar.text}]
delegate: Item {
visible: false // Hide the items to not affect the layout as the nodes model gets changes
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 navigateForward() {
/**
* Moves the navigation index forwards and focuses on the next node as per index.
*/
if (!filteredNodes.count)
return

navigation.currentIndex++
if (navigation.currentIndex === filteredNodes.count)
navigation.currentIndex = 0
navigation.nextItem()
}

function navigateBackward() {
/**
* Moves the navigation index backwards and focuses on the previous node as per index.
*/
if (!filteredNodes.count)
return

navigation.currentIndex--
if (navigation.currentIndex === -1)
navigation.currentIndex = filteredNodes.count - 1
navigation.nextItem()
}

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
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion meshroom/ui/qml/GraphEditor/NodeEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ Panel {

SearchBar {
id: searchBar
width: 150
toggle: true // Enable toggling the actual text field by the search button
Layout.minimumWidth: searchBar.width
maxWidth: 150
enabled: tabBar.currentIndex === 0 || tabBar.currentIndex === 5
}

Expand Down
4 changes: 3 additions & 1 deletion meshroom/ui/qml/ImageGallery/ImageGallery.qml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ Panel {
headerBar: RowLayout {
SearchBar {
id: searchBar
width: 150
toggle: true // Enable toggling the actual text field by the search button
Layout.minimumWidth: searchBar.width
maxWidth: 150
}

MaterialToolButton {
Expand Down