diff --git a/meshroom/ui/qml/Controls/SearchBar.qml b/meshroom/ui/qml/Controls/SearchBar.qml new file mode 100644 index 00000000..2fffc71b --- /dev/null +++ b/meshroom/ui/qml/Controls/SearchBar.qml @@ -0,0 +1,41 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import MaterialIcons 2.2 + + +/** + * Basic SearchBar component with an appropriate icon and a TextField. + */ +FocusScope { + property alias textField: field + property alias text: field.text + + implicitHeight: childrenRect.height + Keys.forwardTo: [field] + + function forceActiveFocus() { + field.forceActiveFocus() + } + + function clear() { + field.clear() + } + + RowLayout { + width: parent.width + + MaterialLabel { + text: MaterialIcons.search + } + + TextField { + id: field + focus: true + Layout.fillWidth: true + selectByMouse: true + } + } +} + + diff --git a/meshroom/ui/qml/Controls/qmldir b/meshroom/ui/qml/Controls/qmldir index aac7ce36..2efd461a 100644 --- a/meshroom/ui/qml/Controls/qmldir +++ b/meshroom/ui/qml/Controls/qmldir @@ -4,3 +4,4 @@ FloatingPane 1.0 FloatingPane.qml Group 1.0 Group.qml MessageDialog 1.0 MessageDialog.qml Panel 1.0 Panel.qml +SearchBar 1.0 SearchBar.qml diff --git a/meshroom/ui/qml/GraphEditor/GraphEditor.qml b/meshroom/ui/qml/GraphEditor/GraphEditor.qml index 83e4a0c9..bed47410 100755 --- a/meshroom/ui/qml/GraphEditor/GraphEditor.qml +++ b/meshroom/ui/qml/GraphEditor/GraphEditor.qml @@ -142,18 +142,14 @@ Item { if(visible) { // when menu is shown, // clear and give focus to the TextField filter - filterTextField.clear() - filterTextField.forceActiveFocus() + searchBar.clear() + searchBar.forceActiveFocus() } } - TextField { - id: filterTextField - selectByMouse: true + SearchBar { + id: searchBar width: parent.width - // ensure down arrow give focus to the first MenuItem - // (without this, we have to pressed the down key twice to do so) - Keys.onDownPressed: nextItemInFocusChain().forceActiveFocus() } Repeater { @@ -164,24 +160,28 @@ Item { id: menuItemDelegate font.pointSize: 8 padding: 3 + // Hide items that does not match the filter text - visible: modelData.toLowerCase().indexOf(filterTextField.text.toLocaleLowerCase()) > -1 + visible: modelData.toLowerCase().indexOf(searchBar.text.toLowerCase()) > -1 + // Reset menu currentIndex if highlighted items gets filtered out + onVisibleChanged: if(highlighted) newNodeMenu.currentIndex = 0 text: modelData + // Forward key events to the search bar to continue typing seamlessly + // even if this delegate took the activeFocus due to mouse hovering + Keys.forwardTo: [searchBar.textField] Keys.onPressed: { + event.accepted = false; switch(event.key) { case Qt.Key_Return: case Qt.Key_Enter: // create node on validation (Enter/Return keys) - newNodeMenu.createNode(modelData) - newNodeMenu.dismiss() - break; - case Qt.Key_Home: - // give focus back to filter - filterTextField.forceActiveFocus() + newNodeMenu.createNode(modelData); + newNodeMenu.close(); + event.accepted = true; break; default: - break; + searchBar.textField.forceActiveFocus(); } } // Create node on mouse click diff --git a/meshroom/ui/qml/Viewer/ImageMetadataView.qml b/meshroom/ui/qml/Viewer/ImageMetadataView.qml index 91bf5e45..44659bfc 100644 --- a/meshroom/ui/qml/Viewer/ImageMetadataView.qml +++ b/meshroom/ui/qml/Viewer/ImageMetadataView.qml @@ -121,17 +121,9 @@ FloatingPane { ColumnLayout { anchors.fill: parent - // Search toolbar - RowLayout { - Label { - text: MaterialIcons.search - font.family: MaterialIcons.fontFamily - } - TextField { - id: filter - Layout.fillWidth: true - z: 2 - } + SearchBar { + id: searchBar + Layout.fillWidth: true } // Metadata ListView @@ -148,7 +140,7 @@ FloatingPane { model: metadataModel sortRole: "raw" filterRole: "raw" - filterValue: filter.text + filterValue: searchBar.text delegate: RowLayout { width: parent.width Label {