From 977a12c989895072e8ca1ceed812000c8c2d1962 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 12 Nov 2021 09:52:24 +0100 Subject: [PATCH 1/9] Steal search-bar from DigitalFactory. Make 'SearchBar' into a reusable component, so it can be used in the (new) Marketplace search. Also now at least the word 'Search' can be translated ;-) part of CURA-8559 --- .../resources/qml/SelectProjectPage.qml | 26 ++------------ resources/qml/SearchBar.qml | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 resources/qml/SearchBar.qml diff --git a/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml b/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml index 50d3cb61c5..1114900c04 100644 --- a/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml +++ b/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml @@ -9,7 +9,7 @@ import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.1 import UM 1.2 as UM -import Cura 1.6 as Cura +import Cura 1.7 as Cura import DigitalFactory 1.0 as DF @@ -44,32 +44,10 @@ Item height: childrenRect.height spacing: UM.Theme.getSize("default_margin").width - Cura.TextField + Cura.SearchBar { id: searchBar - Layout.fillWidth: true - implicitHeight: createNewProjectButton.height - leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2 - onTextEdited: manager.projectFilter = text //Update the search filter when editing this text field. - - placeholderText: "Search" - - UM.RecolorImage - { - id: searchIcon - - anchors - { - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - } - source: UM.Theme.getIcon("search") - height: UM.Theme.getSize("small_button_icon").height - width: height - color: UM.Theme.getColor("text") - } } Cura.SecondaryButton diff --git a/resources/qml/SearchBar.qml b/resources/qml/SearchBar.qml new file mode 100644 index 0000000000..de723d1c84 --- /dev/null +++ b/resources/qml/SearchBar.qml @@ -0,0 +1,36 @@ +// Copyright (C) 2021 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.1 + +import UM 1.6 as UM +import Cura 1.7 as Cura + +Cura.TextField +{ + UM.I18nCatalog { id: catalog; name: "cura" } + + Layout.fillWidth: true + implicitHeight: createNewProjectButton.height + leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2 + + placeholderText: catalog.i18nc("@placeholder", "Search") + + UM.RecolorImage + { + id: searchIcon + + anchors + { + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + } + source: UM.Theme.getIcon("search") + height: UM.Theme.getSize("small_button_icon").height + width: height + color: UM.Theme.getColor("text") + } +} From b5d58f78d7a5ab32cbf9a399b9faf3c303b2d3a1 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 12 Nov 2021 11:49:37 +0100 Subject: [PATCH 2/9] Fix: Actually make SearchBar-component independant. It still depended on the Digital Library 'parent'. part of CURA-8559 --- plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml | 2 ++ resources/qml/SearchBar.qml | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml b/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml index 1114900c04..9ebf264e0f 100644 --- a/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml +++ b/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml @@ -47,6 +47,8 @@ Item Cura.SearchBar { id: searchBar + Layout.fillWidth: true + implicitHeight: createNewProjectButton.height onTextEdited: manager.projectFilter = text //Update the search filter when editing this text field. } diff --git a/resources/qml/SearchBar.qml b/resources/qml/SearchBar.qml index de723d1c84..ce1808252e 100644 --- a/resources/qml/SearchBar.qml +++ b/resources/qml/SearchBar.qml @@ -12,8 +12,6 @@ Cura.TextField { UM.I18nCatalog { id: catalog; name: "cura" } - Layout.fillWidth: true - implicitHeight: createNewProjectButton.height leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2 placeholderText: catalog.i18nc("@placeholder", "Search") @@ -28,7 +26,7 @@ Cura.TextField left: parent.left leftMargin: UM.Theme.getSize("default_margin").width } - source: UM.Theme.getIcon("search") + source: UM.Theme.getIcon("Magnifier") height: UM.Theme.getSize("small_button_icon").height width: height color: UM.Theme.getColor("text") From 7432c0d8f01e6783036a7de532de096b0e28bf3d Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 12 Nov 2021 12:11:45 +0100 Subject: [PATCH 3/9] Add (not yet operational) search-bar to new Marketplace. part of CURA-8559 --- .../Marketplace/resources/qml/Marketplace.qml | 89 +++++++++++++------ 1 file changed, 61 insertions(+), 28 deletions(-) diff --git a/plugins/Marketplace/resources/qml/Marketplace.qml b/plugins/Marketplace/resources/qml/Marketplace.qml index 430c237252..1422a0eece 100644 --- a/plugins/Marketplace/resources/qml/Marketplace.qml +++ b/plugins/Marketplace/resources/qml/Marketplace.qml @@ -70,46 +70,79 @@ Window } } + // Search & Top-Level Tabs Item { - Layout.preferredWidth: parent.width Layout.preferredHeight: childrenRect.height - - ManagePackagesButton + Layout.preferredWidth: parent.width - 2 * UM.Theme.getSize("thin_margin").width + RowLayout { - id: managePackagesButton + width: parent.width + height: UM.Theme.getSize("button_icon").height + UM.Theme.getSize("default_margin").height + spacing: UM.Theme.getSize("thin_margin").width - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - - onClicked: + Rectangle { - content.source = "ManagedPackages.qml" + Layout.preferredHeight: parent.height + Layout.preferredWidth: UM.Theme.getSize("thin_margin").width } - } - // Page selection. - TabBar - { - id: pageSelectionTabBar - anchors.right: managePackagesButton.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("button_icon").height - spacing: 0 - - PackageTypeTab + Cura.SearchBar { - width: implicitWidth - padding: UM.Theme.getSize("default_margin").width/2 - text: catalog.i18nc("@button", "Plugins") - onClicked: content.source = "Plugins.qml" + id: searchBar + Layout.preferredHeight: parent.height + Layout.fillWidth: true + //onTextEdited: // TODO! } - PackageTypeTab + + // Page selection. + TabBar { + id: pageSelectionTabBar + height: parent.height width: implicitWidth - padding: Math.round(UM.Theme.getSize("default_margin").width / 2) - text: catalog.i18nc("@button", "Materials") - onClicked: content.source = "Materials.qml" + spacing: 0 + + PackageTypeTab + { + id: pluginTabText + width: implicitWidth + padding: UM.Theme.getSize("thin_margin").width + text: catalog.i18nc("@button", "Plugins") + onClicked: content.source = "Plugins.qml" + } + PackageTypeTab + { + id: materialsTabText + width: implicitWidth + padding: UM.Theme.getSize("thin_margin").width + text: catalog.i18nc("@button", "Materials") + onClicked: content.source = "Materials.qml" + } + } + TextMetrics + { + id: pluginTabTextMetrics + text: pluginTabText.text + font: pluginTabText.font + } + TextMetrics + { + id: materialsTabTextMetrics + text: materialsTabText.text + font: materialsTabText.font + } + + ManagePackagesButton + { + id: managePackagesButton + height: parent.height + width: UM.Theme.getSize("button_icon").width + + onClicked: + { + content.source = "ManagedPackages.qml" + } } } } From d7ac307ace75917882386c9cf4244013a4e5a319 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 12 Nov 2021 14:01:05 +0100 Subject: [PATCH 4/9] Type in the search-bar and the remote package list reacts. It doesn't do any actual searching yet though. Also switching between page doesn't work like it's supposed to yet (and probalby more of that sort of cases). part of CURA-8559 --- plugins/Marketplace/RemotePackageList.py | 24 +++++++++++++++++-- .../Marketplace/resources/qml/Marketplace.qml | 9 ++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/plugins/Marketplace/RemotePackageList.py b/plugins/Marketplace/RemotePackageList.py index 8fa75453c1..150d9901f1 100644 --- a/plugins/Marketplace/RemotePackageList.py +++ b/plugins/Marketplace/RemotePackageList.py @@ -32,6 +32,7 @@ class RemotePackageList(PackageList): self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance())) self._package_type_filter = "" + self._search_string = "" self._request_url = self._initialRequestUrl() self.isLoadingChanged.emit() @@ -69,6 +70,7 @@ class RemotePackageList(PackageList): self._request_url = self._initialRequestUrl() packageTypeFilterChanged = pyqtSignal() + searchStringChanged = pyqtSignal() def setPackageTypeFilter(self, new_filter: str) -> None: if new_filter != self._package_type_filter: @@ -76,6 +78,12 @@ class RemotePackageList(PackageList): self.reset() self.packageTypeFilterChanged.emit() + def setSearchString(self, new_search: str) -> None: + if new_search != self._search_string: + self._search_string = new_search + self.reset() + self.searchStringChanged.emit() + @pyqtProperty(str, fset = setPackageTypeFilter, notify = packageTypeFilterChanged) def packageTypeFilter(self) -> str: """ @@ -84,14 +92,26 @@ class RemotePackageList(PackageList): """ return self._package_type_filter + @pyqtProperty(str, fset = setSearchString, notify = searchStringChanged) + def searchString(self) -> str: + """ + Get the string the user is currently searching for within the packages, or an empty string if no extra search + filter has to be applied. Does not override package-type filter! + :return: String the user is searching for. Empty denotes 'no search filter'. + """ + return self._search_string + def _initialRequestUrl(self) -> str: """ Get the URL to request the first paginated page with. :return: A URL to request. """ + request_url = f"{Marketplace.PACKAGES_URL}?limit={self.ITEMS_PER_PAGE}" if self._package_type_filter != "": - return f"{Marketplace.PACKAGES_URL}?package_type={self._package_type_filter}&limit={self.ITEMS_PER_PAGE}" - return f"{Marketplace.PACKAGES_URL}?limit={self.ITEMS_PER_PAGE}" + request_url += f"&package_type={self._package_type_filter}" + if self._search_string != "": + request_url += f"" # TODO + return request_url def _parseResponse(self, reply: "QNetworkReply") -> None: """ diff --git a/plugins/Marketplace/resources/qml/Marketplace.qml b/plugins/Marketplace/resources/qml/Marketplace.qml index 1422a0eece..e92ac44c1d 100644 --- a/plugins/Marketplace/resources/qml/Marketplace.qml +++ b/plugins/Marketplace/resources/qml/Marketplace.qml @@ -14,6 +14,8 @@ Window id: marketplaceDialog property variant catalog: UM.I18nCatalog { name: "cura" } + signal searchStringChanged(string new_search) + minimumWidth: UM.Theme.getSize("modal_window_minimum").width minimumHeight: UM.Theme.getSize("modal_window_minimum").height width: minimumWidth @@ -92,7 +94,7 @@ Window id: searchBar Layout.preferredHeight: parent.height Layout.fillWidth: true - //onTextEdited: // TODO! + onTextEdited: marketplaceDialog.searchStringChanged(text) } // Page selection. @@ -168,6 +170,11 @@ Window function onLoaded() { pageTitle.text = content.item.pageTitle + searchStringChanged.connect(onSearchStringChanged) + } + function onSearchStringChanged(new_search) + { + content.item.model.searchString = new_search } } } From 79f7724923198e8ac17bd409507a6d2ad9de013c Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 12 Nov 2021 14:30:09 +0100 Subject: [PATCH 5/9] Actually set search string + fix code style warnings. It now works! Sort of. Turns out you have to manually click 'Load More' each time now :-) This is also at least partially explains the 'cases' mentioned in previous commit (when switching tabs). part of CURA-8559 --- plugins/Marketplace/RemotePackageList.py | 2 +- plugins/Marketplace/resources/qml/ManagePackagesButton.qml | 2 +- plugins/Marketplace/resources/qml/Marketplace.qml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/Marketplace/RemotePackageList.py b/plugins/Marketplace/RemotePackageList.py index 150d9901f1..156e7bbf0f 100644 --- a/plugins/Marketplace/RemotePackageList.py +++ b/plugins/Marketplace/RemotePackageList.py @@ -110,7 +110,7 @@ class RemotePackageList(PackageList): if self._package_type_filter != "": request_url += f"&package_type={self._package_type_filter}" if self._search_string != "": - request_url += f"" # TODO + request_url += f"&search={self._search_string}" return request_url def _parseResponse(self, reply: "QNetworkReply") -> None: diff --git a/plugins/Marketplace/resources/qml/ManagePackagesButton.qml b/plugins/Marketplace/resources/qml/ManagePackagesButton.qml index 31b97d89ed..a2ebfe0df7 100644 --- a/plugins/Marketplace/resources/qml/ManagePackagesButton.qml +++ b/plugins/Marketplace/resources/qml/ManagePackagesButton.qml @@ -18,7 +18,7 @@ Button background: Rectangle { color: backgroundColor - border.color: transparent + border.color: "transparent" radius: Math.round(width * 0.5) } diff --git a/plugins/Marketplace/resources/qml/Marketplace.qml b/plugins/Marketplace/resources/qml/Marketplace.qml index e92ac44c1d..7cfb68883f 100644 --- a/plugins/Marketplace/resources/qml/Marketplace.qml +++ b/plugins/Marketplace/resources/qml/Marketplace.qml @@ -170,9 +170,9 @@ Window function onLoaded() { pageTitle.text = content.item.pageTitle - searchStringChanged.connect(onSearchStringChanged) + searchStringChanged.connect(handleSearchStringChanged) } - function onSearchStringChanged(new_search) + function handleSearchStringChanged(new_search) { content.item.model.searchString = new_search } From 44242dcd02d37e01a2c1ebefab48b5c8bd0c7992 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 12 Nov 2021 15:20:46 +0100 Subject: [PATCH 6/9] Auto-load next batch with searched-for text in Marketplace. part of CURA-8559 --- plugins/Marketplace/RemotePackageList.py | 27 +++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/plugins/Marketplace/RemotePackageList.py b/plugins/Marketplace/RemotePackageList.py index 156e7bbf0f..e7df498fbf 100644 --- a/plugins/Marketplace/RemotePackageList.py +++ b/plugins/Marketplace/RemotePackageList.py @@ -32,8 +32,10 @@ class RemotePackageList(PackageList): self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance())) self._package_type_filter = "" - self._search_string = "" + self._requested_search_string = "" + self._current_search_string = "" self._request_url = self._initialRequestUrl() + self.isLoadingChanged.connect(self._onLoadingChanged) self.isLoadingChanged.emit() def __del__(self) -> None: @@ -79,10 +81,8 @@ class RemotePackageList(PackageList): self.packageTypeFilterChanged.emit() def setSearchString(self, new_search: str) -> None: - if new_search != self._search_string: - self._search_string = new_search - self.reset() - self.searchStringChanged.emit() + self._requested_search_string = new_search + self._onLoadingChanged() @pyqtProperty(str, fset = setPackageTypeFilter, notify = packageTypeFilterChanged) def packageTypeFilter(self) -> str: @@ -95,11 +95,18 @@ class RemotePackageList(PackageList): @pyqtProperty(str, fset = setSearchString, notify = searchStringChanged) def searchString(self) -> str: """ - Get the string the user is currently searching for within the packages, or an empty string if no extra search - filter has to be applied. Does not override package-type filter! + Get the string the user is currently searching for (as in: the list is updating) within the packages, + or an empty string if no extra search filter has to be applied. Does not override package-type filter! :return: String the user is searching for. Empty denotes 'no search filter'. """ - return self._search_string + return self._current_search_string + + def _onLoadingChanged(self) -> None: + if self._requested_search_string != self._current_search_string and not self._is_loading: + self._current_search_string = self._requested_search_string + self.reset() + self.updatePackages() + self.searchStringChanged.emit() def _initialRequestUrl(self) -> str: """ @@ -109,8 +116,8 @@ class RemotePackageList(PackageList): request_url = f"{Marketplace.PACKAGES_URL}?limit={self.ITEMS_PER_PAGE}" if self._package_type_filter != "": request_url += f"&package_type={self._package_type_filter}" - if self._search_string != "": - request_url += f"&search={self._search_string}" + if self._current_search_string != "": + request_url += f"&search={self._current_search_string}" return request_url def _parseResponse(self, reply: "QNetworkReply") -> None: From 24eaad4c6d87889b3d47ae21dfdcd6d714d11029 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 12 Nov 2021 15:37:59 +0100 Subject: [PATCH 7/9] Make switching Marketplace-tabs work with search-bar. Reset search-bar (text) when switching tabs. Also hide search-bar (at least for now) when dealing with the managed packages tab. part of CURA-8559 --- .../Marketplace/resources/qml/Marketplace.qml | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/plugins/Marketplace/resources/qml/Marketplace.qml b/plugins/Marketplace/resources/qml/Marketplace.qml index 7cfb68883f..ea60bf0c7e 100644 --- a/plugins/Marketplace/resources/qml/Marketplace.qml +++ b/plugins/Marketplace/resources/qml/Marketplace.qml @@ -86,7 +86,8 @@ Window Rectangle { Layout.preferredHeight: parent.height - Layout.preferredWidth: UM.Theme.getSize("thin_margin").width + Layout.preferredWidth: searchBar.visible ? UM.Theme.getSize("thin_margin").width : 0 + Layout.fillWidth: ! searchBar.visible } Cura.SearchBar @@ -94,7 +95,7 @@ Window id: searchBar Layout.preferredHeight: parent.height Layout.fillWidth: true - onTextEdited: marketplaceDialog.searchStringChanged(text) + onTextEdited: searchStringChanged(text) } // Page selection. @@ -111,7 +112,12 @@ Window width: implicitWidth padding: UM.Theme.getSize("thin_margin").width text: catalog.i18nc("@button", "Plugins") - onClicked: content.source = "Plugins.qml" + onClicked: + { + searchBar.text = "" + searchBar.visible = true + content.source = "Plugins.qml" + } } PackageTypeTab { @@ -119,7 +125,12 @@ Window width: implicitWidth padding: UM.Theme.getSize("thin_margin").width text: catalog.i18nc("@button", "Materials") - onClicked: content.source = "Materials.qml" + onClicked: + { + searchBar.text = "" + searchBar.visible = true + content.source = "Materials.qml" + } } } TextMetrics @@ -143,6 +154,8 @@ Window onClicked: { + searchBar.text = "" + searchBar.visible = false content.source = "ManagedPackages.qml" } } From 87f94e680bf0da3f96d03e2a72c6848cf7451c3c Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 16 Nov 2021 10:20:08 +0100 Subject: [PATCH 8/9] Use re-usable search-bar for Settings search as well. done as part of CURA-8559 --- resources/qml/SearchBar.qml | 1 + resources/qml/Settings/SettingView.qml | 33 ++++---------------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/resources/qml/SearchBar.qml b/resources/qml/SearchBar.qml index ce1808252e..4d9c003653 100644 --- a/resources/qml/SearchBar.qml +++ b/resources/qml/SearchBar.qml @@ -15,6 +15,7 @@ Cura.TextField leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2 placeholderText: catalog.i18nc("@placeholder", "Search") + font.italic: true UM.RecolorImage { diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 074946c6bd..5fc0b60381 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -41,39 +41,19 @@ Item repeat: false } - Cura.TextField + Cura.SearchBar { id: filter height: parent.height anchors.left: parent.left anchors.right: parent.right - leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2 - placeholderText: catalog.i18nc("@label:textbox", "Search settings") - font.italic: true + + placeholderText: catalog.i18nc("@label:textbox", "Search settings") // Overwrite property var expandedCategories property bool lastFindingSettings: false - UM.RecolorImage - { - id: searchIcon - - anchors - { - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - } - source: UM.Theme.getIcon("search") - height: UM.Theme.getSize("small_button_icon").height - width: height - color: UM.Theme.getColor("text") - } - - onTextChanged: - { - settingsSearchTimer.restart() - } + onTextChanged: settingsSearchTimer.restart() onEditingFinished: { @@ -86,10 +66,7 @@ Item } } - Keys.onEscapePressed: - { - filter.text = "" - } + Keys.onEscapePressed: filter.text = "" function updateDefinitionModel() { From 6df6dab6f01db427a9b73f1012a2d5f28fd9c3fb Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 16 Nov 2021 10:38:00 +0100 Subject: [PATCH 9/9] Remove explicit transparent border on button. done as part of CURA-8559 --- plugins/Marketplace/resources/qml/ManagePackagesButton.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/Marketplace/resources/qml/ManagePackagesButton.qml b/plugins/Marketplace/resources/qml/ManagePackagesButton.qml index a2ebfe0df7..bf122140a7 100644 --- a/plugins/Marketplace/resources/qml/ManagePackagesButton.qml +++ b/plugins/Marketplace/resources/qml/ManagePackagesButton.qml @@ -18,9 +18,7 @@ Button background: Rectangle { color: backgroundColor - border.color: "transparent" radius: Math.round(width * 0.5) - } Cura.ToolTip