diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml
deleted file mode 100644
index e146b17f0..000000000
--- a/bitbucket-pipelines.yml
+++ /dev/null
@@ -1,85 +0,0 @@
-image: ubuntu:bionic
-
-pipelines:
- default:
- - step:
- script:
- # Install dependencies
- - apt update
- - apt -y install wget lsb-release gnupg
- - sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list'
- - sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-prerelease `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-prerelease.list'
- - wget http://packages.osrfoundation.org/gazebo.key -O - | apt-key add -
- - apt update
- - apt install -y
- build-essential wget cmake cppcheck git g++-8
- qtbase5-dev libtinyxml2-dev libprotoc-dev libprotobuf-dev
- qtdeclarative5-dev
- qtquickcontrols2-5-dev
- qml-module-qtquick2
- qml-module-qtquick-controls
- qml-module-qtquick-controls2
- qml-module-qtquick-dialogs
- qml-module-qtquick-layouts
- qml-module-qt-labs-folderlistmodel
- qml-module-qt-labs-settings
- qml-module-qtgraphicaleffects
- - update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8 --slave /usr/bin/gcov gcov /usr/bin/gcov-8
- - gcc -v
- - g++ -v
- - gcov -v
- # lcov
- - git clone https://github.com/linux-test-project/lcov.git
- - cd lcov
- - make install
- - cd ..
- # Dependency: Ignition packages
- - apt-get -y install
- libignition-cmake2-dev
- libignition-common3-dev
- libignition-math6-dev
- libignition-msgs5-dev
- libignition-plugin-dev
- libignition-tools-dev
- libignition-transport8-dev
- # libignition-rendering3-dev
- # # Ignition msgs (uncomment if a specific branch is needed)
- # - apt install -y
- # libprotobuf-dev protobuf-compiler libprotoc-dev
- # - git clone http://github.com/ignitionrobotics/ign-msgs
- # - cd ign-msgs
- # - mkdir build
- # - cd build
- # - cmake ..
- # - make -j4 install
- # - cd ../..
- # # Ignition transport (uncomment if a specific branch is needed)
- # - apt install -y
- # libzmq3-dev uuid-dev libsqlite3-dev
- # - git clone http://github.com/ignitionrobotics/ign-transport
- # - cd ign-transport
- # - mkdir build
- # - cd build
- # - cmake ..
- # - make -j4 install
- # - cd ../..
- # # Ignition rendering (uncomment if a specific branch is needed)
- # - apt install -y
- # libogre-1.9-dev
- # libogre-2.1-dev
- # libglew-dev libfreeimage-dev freeglut3-dev libxmu-dev libxi-dev
- # - git clone http://github.com/ignitionrobotics/ign-rendering
- # - cd ign-rendering
- # - mkdir build
- # - cd build
- # - cmake ..
- # - make -j4 install
- # - cd ../..
- # Ignition GUI
- - mkdir build
- - cd build
- - cmake ..
- - make -j4 install
- - make codecheck
- # Tests currently fail, graphics issue?
- # - make test
diff --git a/include/ignition/gui/qml/IgnSortFilterModel.qml b/include/ignition/gui/qml/IgnSortFilterModel.qml
new file mode 100644
index 000000000..f127d27ab
--- /dev/null
+++ b/include/ignition/gui/qml/IgnSortFilterModel.qml
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 Open Source Robotics Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+// Borrowed from
+// https://martin.rpdev.net/2019/01/15/using-delegatemodel-in-qml-for-sorting-and-filtering.html
+
+import QtQuick 2.9
+import QtQml.Models 2.3
+
+DelegateModel {
+ /**
+ * Used by sorting. Override it to create custom sort behaviour.
+ */
+ property var lessThan: function(_left, _right)
+ {
+ return true;
+ }
+
+ /**
+ * Override this function to define what items should be accepted or not.
+ */
+ property var filterAcceptsItem: function(_item)
+ {
+ return true;
+ }
+
+ /**
+ * Update the item list
+ */
+ function update() {
+ if (items.count > 0) {
+ items.setGroups(0, items.count, "items");
+ }
+
+ // Step 1: Filter items
+ var visible = [];
+ for (var i = 0; i < items.count; ++i) {
+ var item = items.get(i);
+ if (filterAcceptsItem(item.model)) {
+ visible.push(item);
+ }
+ }
+
+ // Step 2: Sort the list of visible items
+ visible.sort(function(_a, _b) {
+ return lessThan(_a.model, _b.model) ? -1 : 1;
+ });
+
+ // Step 3: Add all items to the visible group:
+ for (i = 0; i < visible.length; ++i) {
+ item = visible[i];
+ item.inVisible = true;
+ if (item.visibleIndex !== i) {
+ visibleItems.move(item.visibleIndex, i, 1);
+ }
+ }
+ }
+
+ items.onChanged: update()
+ onLessThanChanged: update()
+ onFilterAcceptsItemChanged: update()
+
+ groups: DelegateModelGroup {
+ id: visibleItems
+
+ name: "visible"
+ includeByDefault: false
+ }
+
+ filterOnGroup: "visible"
+}
+
diff --git a/include/ignition/gui/qml/Main.qml b/include/ignition/gui/qml/Main.qml
index ec75de916..0f1f3c00a 100644
--- a/include/ignition/gui/qml/Main.qml
+++ b/include/ignition/gui/qml/Main.qml
@@ -201,9 +201,10 @@ ApplicationWindow
PluginMenu {
id: pluginMenu
+ width: 200
x: parent.width - width
height: window.height * 0.3
- transformOrigin: Menu.TopRight
+ transformOrigin: Popup.TopRight
}
}
}
diff --git a/include/ignition/gui/qml/PluginMenu.qml b/include/ignition/gui/qml/PluginMenu.qml
index 413dcb860..68de63a7c 100644
--- a/include/ignition/gui/qml/PluginMenu.qml
+++ b/include/ignition/gui/qml/PluginMenu.qml
@@ -16,20 +16,92 @@
*/
import QtQuick 2.9
import QtQuick.Controls 2.2
+import QtQuick.Controls.Material 2.2
+import QtQuick.Controls.Material.impl 2.2
+import QtQuick.Layouts 1.3
-Menu {
+Popup {
id: pluginMenu
+ padding: 0
Connections {
target: MainWindow
onConfigChanged: {
- pluginMenuListView.model = MainWindow.PluginListModel()
+ filteredModel.model = MainWindow.PluginListModel()
}
}
- ListView {
- id: pluginMenuListView
- height: pluginMenu.height
+ /**
+ * Color for search bar
+ */
+ property color searchColor: (Material.theme == Material.Light) ?
+ Material.color(Material.Grey, Material.Shade200):
+ Material.color(Material.Grey, Material.Shade900);
+
+ onOpened: searchField.forceActiveFocus()
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: 0
+
+ Rectangle {
+ id: searchSortBar
+ color: searchColor
+ height: 50
+ width: parent.width
+ RowLayout {
+ id: rowLayout
+ anchors.fill: parent
+ spacing: 0
+ Rectangle {
+ color: "transparent"
+ height: 25
+ width: 25
+ Layout.leftMargin: 5
+ Image {
+ id: searchIcon
+ source: "images/search.svg"
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+ TextField {
+ id: searchField
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.width - 50
+ selectByMouse: true
+ onTextEdited: {
+ filteredModel.update();
+ }
+ }
+ }
+ }
+
+ ListView {
+ id: pluginMenuListView
+ Layout.fillHeight: true
+ width: parent.width
+ clip: true
+
+ model: filteredModel
+
+ ScrollBar.vertical: ScrollBar {
+ active: true
+ width: 8
+ policy: ScrollBar.AlwaysOn
+ }
+ }
+ }
+
+ IgnSortFilterModel {
+ id: filteredModel
+
+ filterAcceptsItem: function(item) {
+ var itemStr = item.modelData.toLowerCase();
+ var filterStr = searchField.text.toLowerCase();
+ return itemStr.includes(filterStr);
+ }
+
+ model: MainWindow.PluginListModel()
delegate: ItemDelegate {
width: parent.width
@@ -41,14 +113,6 @@ Menu {
pluginMenu.close()
}
}
-
- model: MainWindow.PluginListModel()
-
- ScrollBar.vertical: ScrollBar {
- active: true
- width: 8
- policy: ScrollBar.AlwaysOn
- }
}
}
diff --git a/include/ignition/gui/qml/images/search.svg b/include/ignition/gui/qml/images/search.svg
new file mode 100644
index 000000000..40ab947b2
--- /dev/null
+++ b/include/ignition/gui/qml/images/search.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/include/ignition/gui/resources.qrc b/include/ignition/gui/resources.qrc
index a3cacdc29..6d54c9f0c 100644
--- a/include/ignition/gui/resources.qrc
+++ b/include/ignition/gui/resources.qrc
@@ -7,6 +7,7 @@
qml/IgnCardSettings.qml
qml/IgnHelpers.qml
qml/IgnRulers.qml
+ qml/IgnSortFilterModel.qml
qml/IgnSpinBox.qml
qml/IgnSplit.qml
qml/Main.qml
@@ -20,5 +21,6 @@
qml/images/drawer.png
qml/images/menu.png
qml/images/export_icon.png
+ qml/images/search.svg