Merge pull request #10812 from Ultimaker/CURA-8559_add_marketplace_search

[CURA-8559] Add new-marketplace search
This commit is contained in:
Jaime van Kessel 2021-11-16 15:57:27 +01:00 committed by GitHub
commit 5c875a1394
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 152 additions and 82 deletions

View File

@ -9,7 +9,7 @@ import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import UM 1.2 as UM import UM 1.2 as UM
import Cura 1.6 as Cura import Cura 1.7 as Cura
import DigitalFactory 1.0 as DF import DigitalFactory 1.0 as DF
@ -44,32 +44,12 @@ Item
height: childrenRect.height height: childrenRect.height
spacing: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width
Cura.TextField Cura.SearchBar
{ {
id: searchBar id: searchBar
Layout.fillWidth: true Layout.fillWidth: true
implicitHeight: createNewProjectButton.height 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. 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 Cura.SecondaryButton

View File

@ -32,7 +32,10 @@ class RemotePackageList(PackageList):
self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance())) self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance()))
self._package_type_filter = "" self._package_type_filter = ""
self._requested_search_string = ""
self._current_search_string = ""
self._request_url = self._initialRequestUrl() self._request_url = self._initialRequestUrl()
self.isLoadingChanged.connect(self._onLoadingChanged)
self.isLoadingChanged.emit() self.isLoadingChanged.emit()
def __del__(self) -> None: def __del__(self) -> None:
@ -69,6 +72,7 @@ class RemotePackageList(PackageList):
self._request_url = self._initialRequestUrl() self._request_url = self._initialRequestUrl()
packageTypeFilterChanged = pyqtSignal() packageTypeFilterChanged = pyqtSignal()
searchStringChanged = pyqtSignal()
def setPackageTypeFilter(self, new_filter: str) -> None: def setPackageTypeFilter(self, new_filter: str) -> None:
if new_filter != self._package_type_filter: if new_filter != self._package_type_filter:
@ -76,6 +80,10 @@ class RemotePackageList(PackageList):
self.reset() self.reset()
self.packageTypeFilterChanged.emit() self.packageTypeFilterChanged.emit()
def setSearchString(self, new_search: str) -> None:
self._requested_search_string = new_search
self._onLoadingChanged()
@pyqtProperty(str, fset = setPackageTypeFilter, notify = packageTypeFilterChanged) @pyqtProperty(str, fset = setPackageTypeFilter, notify = packageTypeFilterChanged)
def packageTypeFilter(self) -> str: def packageTypeFilter(self) -> str:
""" """
@ -84,14 +92,33 @@ class RemotePackageList(PackageList):
""" """
return self._package_type_filter return self._package_type_filter
@pyqtProperty(str, fset = setSearchString, notify = searchStringChanged)
def searchString(self) -> str:
"""
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._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: def _initialRequestUrl(self) -> str:
""" """
Get the URL to request the first paginated page with. Get the URL to request the first paginated page with.
:return: A URL to request. :return: A URL to request.
""" """
request_url = f"{Marketplace.PACKAGES_URL}?limit={self.ITEMS_PER_PAGE}"
if self._package_type_filter != "": if self._package_type_filter != "":
return f"{Marketplace.PACKAGES_URL}?package_type={self._package_type_filter}&limit={self.ITEMS_PER_PAGE}" request_url += f"&package_type={self._package_type_filter}"
return f"{Marketplace.PACKAGES_URL}?limit={self.ITEMS_PER_PAGE}" if self._current_search_string != "":
request_url += f"&search={self._current_search_string}"
return request_url
def _parseResponse(self, reply: "QNetworkReply") -> None: def _parseResponse(self, reply: "QNetworkReply") -> None:
""" """

View File

@ -18,9 +18,7 @@ Button
background: Rectangle background: Rectangle
{ {
color: backgroundColor color: backgroundColor
border.color: transparent
radius: Math.round(width * 0.5) radius: Math.round(width * 0.5)
} }
Cura.ToolTip Cura.ToolTip

View File

@ -14,6 +14,8 @@ Window
id: marketplaceDialog id: marketplaceDialog
property variant catalog: UM.I18nCatalog { name: "cura" } property variant catalog: UM.I18nCatalog { name: "cura" }
signal searchStringChanged(string new_search)
minimumWidth: UM.Theme.getSize("modal_window_minimum").width minimumWidth: UM.Theme.getSize("modal_window_minimum").width
minimumHeight: UM.Theme.getSize("modal_window_minimum").height minimumHeight: UM.Theme.getSize("modal_window_minimum").height
width: minimumWidth width: minimumWidth
@ -70,46 +72,92 @@ Window
} }
} }
// Search & Top-Level Tabs
Item Item
{ {
Layout.preferredWidth: parent.width
Layout.preferredHeight: childrenRect.height Layout.preferredHeight: childrenRect.height
Layout.preferredWidth: parent.width - 2 * UM.Theme.getSize("thin_margin").width
ManagePackagesButton 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 Rectangle
anchors.rightMargin: UM.Theme.getSize("default_margin").width
onClicked:
{ {
content.source = "ManagedPackages.qml" Layout.preferredHeight: parent.height
Layout.preferredWidth: searchBar.visible ? UM.Theme.getSize("thin_margin").width : 0
Layout.fillWidth: ! searchBar.visible
} }
}
// Page selection. Cura.SearchBar
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
{ {
width: implicitWidth id: searchBar
padding: UM.Theme.getSize("default_margin").width/2 Layout.preferredHeight: parent.height
text: catalog.i18nc("@button", "Plugins") Layout.fillWidth: true
onClicked: content.source = "Plugins.qml" onTextEdited: searchStringChanged(text)
} }
PackageTypeTab
// Page selection.
TabBar
{ {
id: pageSelectionTabBar
height: parent.height
width: implicitWidth width: implicitWidth
padding: Math.round(UM.Theme.getSize("default_margin").width / 2) spacing: 0
text: catalog.i18nc("@button", "Materials")
onClicked: content.source = "Materials.qml" PackageTypeTab
{
id: pluginTabText
width: implicitWidth
padding: UM.Theme.getSize("thin_margin").width
text: catalog.i18nc("@button", "Plugins")
onClicked:
{
searchBar.text = ""
searchBar.visible = true
content.source = "Plugins.qml"
}
}
PackageTypeTab
{
id: materialsTabText
width: implicitWidth
padding: UM.Theme.getSize("thin_margin").width
text: catalog.i18nc("@button", "Materials")
onClicked:
{
searchBar.text = ""
searchBar.visible = true
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:
{
searchBar.text = ""
searchBar.visible = false
content.source = "ManagedPackages.qml"
}
} }
} }
} }
@ -135,6 +183,11 @@ Window
function onLoaded() function onLoaded()
{ {
pageTitle.text = content.item.pageTitle pageTitle.text = content.item.pageTitle
searchStringChanged.connect(handleSearchStringChanged)
}
function handleSearchStringChanged(new_search)
{
content.item.model.searchString = new_search
} }
} }
} }

View File

@ -0,0 +1,35 @@
// 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" }
leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2
placeholderText: catalog.i18nc("@placeholder", "Search")
font.italic: true
UM.RecolorImage
{
id: searchIcon
anchors
{
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: UM.Theme.getSize("default_margin").width
}
source: UM.Theme.getIcon("Magnifier")
height: UM.Theme.getSize("small_button_icon").height
width: height
color: UM.Theme.getColor("text")
}
}

View File

@ -41,39 +41,19 @@ Item
repeat: false repeat: false
} }
Cura.TextField Cura.SearchBar
{ {
id: filter id: filter
height: parent.height height: parent.height
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2
placeholderText: catalog.i18nc("@label:textbox", "Search settings") placeholderText: catalog.i18nc("@label:textbox", "Search settings") // Overwrite
font.italic: true
property var expandedCategories property var expandedCategories
property bool lastFindingSettings: false property bool lastFindingSettings: false
UM.RecolorImage onTextChanged: settingsSearchTimer.restart()
{
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()
}
onEditingFinished: onEditingFinished:
{ {
@ -86,10 +66,7 @@ Item
} }
} }
Keys.onEscapePressed: Keys.onEscapePressed: filter.text = ""
{
filter.text = ""
}
function updateDefinitionModel() function updateDefinitionModel()
{ {