From f4220da550ff4f5c65787b54f413415ac4dce73e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 15:31:33 +0100 Subject: [PATCH 01/29] Adds rough first version of rating stars It's not fully polished just yet CURA-6013 --- cura/API/Account.py | 2 +- .../Toolbox/resources/qml/RatingWidget.qml | 101 ++++++++++++++++++ .../qml/ToolboxDownloadsGridTile.qml | 10 ++ plugins/Toolbox/src/PackagesModel.py | 8 +- plugins/Toolbox/src/Toolbox.py | 53 ++++++--- .../themes/cura-light/icons/star_empty.svg | 11 ++ .../themes/cura-light/icons/star_filled.svg | 11 ++ resources/themes/cura-light/theme.json | 1 + 8 files changed, 180 insertions(+), 17 deletions(-) create mode 100644 plugins/Toolbox/resources/qml/RatingWidget.qml create mode 100644 resources/themes/cura-light/icons/star_empty.svg create mode 100644 resources/themes/cura-light/icons/star_filled.svg diff --git a/cura/API/Account.py b/cura/API/Account.py index 397e220478..be77a6307b 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -44,7 +44,7 @@ class Account(QObject): OAUTH_SERVER_URL= self._oauth_root, CALLBACK_PORT=self._callback_port, CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port), - CLIENT_ID="um---------------ultimaker_cura_drive_plugin", + CLIENT_ID="um----------------------------ultimaker_cura", CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write", AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data", AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root), diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml new file mode 100644 index 0000000000..424f6c91c4 --- /dev/null +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -0,0 +1,101 @@ +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.0 as UM + +Item +{ + id: ratingWidget + + property real rating: 0 + property int indexHovered: -1 + property string packageId: "" + property int numRatings: 0 + property int userRating: 0 + width: contentRow.width + height: contentRow.height + MouseArea + { + id: mouseArea + anchors.fill: parent + hoverEnabled: ratingWidget.enabled + acceptedButtons: Qt.NoButton + onExited: + { + ratingWidget.indexHovered = -1 + } + + Row + { + id: contentRow + height: childrenRect.height + Repeater + { + model: 5 // We need to get 5 stars + Button + { + id: control + hoverEnabled: true + onHoveredChanged: + { + if(hovered) + { + indexHovered = index + } + } + + property bool isStarFilled: + { + // If the entire widget is hovered, override the actual rating. + if(ratingWidget.indexHovered >= 0) + { + return indexHovered >= index + } + + if(ratingWidget.userRating > 0) + { + return userRating >= index +1 + } + + return rating >= index + 1 + } + + contentItem: Item {} + height: UM.Theme.getSize("rating_star").height + width: UM.Theme.getSize("rating_star").width + background: UM.RecolorImage + { + source: UM.Theme.getIcon(control.isStarFilled ? "star_filled" : "star_empty") + + // Unfilled stars should always have the default color. Only filled stars should change on hover + color: + { + if(!enabled) + { + return "#5a5a5a" + } + if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) + { + return UM.Theme.getColor("primary") + } + return "#5a5a5a" + } + } + onClicked: + { + if(userRating == 0) + { + //User didn't vote yet, locally fake it + numRatings += 1 + } + userRating = index + 1 // Fake local data + toolbox.ratePackage(ratingWidget.packageId, index + 1) + } + } + } + Label + { + text: "(" + numRatings + ")" + } + } + } +} \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index cee3f0fd20..a72411ef4b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -84,6 +84,16 @@ Item color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("default") } + + RatingWidget + { + visible: model.type == "plugin" + packageId: model.id + rating: model.average_rating != undefined ? model.average_rating : 0 + numRatings: model.num_ratings != undefined ? model.num_ratings : 0 + userRating: model.user_rating + enabled: installedPackages != 0 + } } } MouseArea diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index bcc02955a2..b3c388bc7c 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -41,6 +41,9 @@ class PackagesModel(ListModel): self.addRoleName(Qt.UserRole + 20, "links") self.addRoleName(Qt.UserRole + 21, "website") self.addRoleName(Qt.UserRole + 22, "login_required") + self.addRoleName(Qt.UserRole + 23, "average_rating") + self.addRoleName(Qt.UserRole + 24, "num_ratings") + self.addRoleName(Qt.UserRole + 25, "user_rating") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str, str] @@ -101,7 +104,10 @@ class PackagesModel(ListModel): "tags": package["tags"] if "tags" in package else [], "links": links_dict, "website": package["website"] if "website" in package else None, - "login_required": "login-required" in package.get("tags", []) + "login_required": "login-required" in package.get("tags", []), + "average_rating": package.get("rating", {}).get("average", 0), + "num_ratings": package.get("rating", {}).get("count", 0), + "user_rating": package.get("rating", {}).get("user", 0) }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index ab975548ce..7e35f5d1f4 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -22,7 +22,8 @@ from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel from .PackagesModel import PackagesModel - +from cura.CuraVersion import CuraVersion +from cura.API import CuraAPI if TYPE_CHECKING: from cura.Settings.GlobalStack import GlobalStack @@ -50,17 +51,10 @@ class Toolbox(QObject, Extension): self._download_progress = 0 # type: float self._is_downloading = False # type: bool self._network_manager = None # type: Optional[QNetworkAccessManager] - self._request_header = [ - b"User-Agent", - str.encode( - "%s/%s (%s %s)" % ( - self._application.getApplicationName(), - self._application.getVersion(), - platform.system(), - platform.machine(), - ) - ) - ] + self._request_headers = [] # type: List[Tuple(bytes, bytes)] + self._updateRequestHeader() + + self._request_urls = {} # type: Dict[str, QUrl] self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated self._old_plugin_ids = set() # type: Set[str] @@ -115,6 +109,7 @@ class Toolbox(QObject, Extension): self._restart_dialog_message = "" # type: str self._application.initializationFinished.connect(self._onAppInitialized) + self._application.getCuraAPI().account.loginStateChanged.connect(self._updateRequestHeader) # Signals: # -------------------------------------------------------------------------- @@ -134,12 +129,38 @@ class Toolbox(QObject, Extension): showLicenseDialog = pyqtSignal() uninstallVariablesChanged = pyqtSignal() + def _updateRequestHeader(self): + self._request_headers = [ + (b"User-Agent", + str.encode( + "%s/%s (%s %s)" % ( + self._application.getApplicationName(), + self._application.getVersion(), + platform.system(), + platform.machine(), + ) + )) + ] + access_token = self._application.getCuraAPI().account.accessToken + if access_token: + self._request_headers.append((b"Authorization", "Bearer {}".format(access_token).encode())) + def _resetUninstallVariables(self) -> None: self._package_id_to_uninstall = None # type: Optional[str] self._package_name_to_uninstall = "" self._package_used_materials = [] # type: List[Tuple[GlobalStack, str, str]] self._package_used_qualities = [] # type: List[Tuple[GlobalStack, str, str]] + @pyqtSlot(str, int) + def ratePackage(self, package_id: str, rating: int) -> None: + url = QUrl("{base_url}/packages/{package_id}/ratings".format(base_url=self._api_url, package_id = package_id)) + + self._rate_request = QNetworkRequest(url) + for header_name, header_value in self._request_headers: + cast(QNetworkRequest, self._rate_request).setRawHeader(header_name, header_value) + data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(CuraVersion), rating) + self._rate_reply = cast(QNetworkAccessManager, self._network_manager).put(self._rate_request, data.encode()) + @pyqtSlot(result = str) def getLicenseDialogPluginName(self) -> str: return self._license_dialog_plugin_name @@ -563,7 +584,8 @@ class Toolbox(QObject, Extension): def _makeRequestByType(self, request_type: str) -> None: Logger.log("i", "Requesting %s metadata from server.", request_type) request = QNetworkRequest(self._request_urls[request_type]) - request.setRawHeader(*self._request_header) + for header_name, header_value in self._request_headers: + request.setRawHeader(header_name, header_value) if self._network_manager: self._network_manager.get(request) @@ -578,7 +600,8 @@ class Toolbox(QObject, Extension): if hasattr(QNetworkRequest, "RedirectPolicyAttribute"): # Patch for Qt 5.9+ cast(QNetworkRequest, self._download_request).setAttribute(QNetworkRequest.RedirectPolicyAttribute, True) - cast(QNetworkRequest, self._download_request).setRawHeader(*self._request_header) + for header_name, header_value in self._request_headers: + cast(QNetworkRequest, self._download_request).setRawHeader(header_name, header_value) self._download_reply = cast(QNetworkAccessManager, self._network_manager).get(self._download_request) self.setDownloadProgress(0) self.setIsDownloading(True) @@ -660,7 +683,7 @@ class Toolbox(QObject, Extension): else: self.setViewPage("errored") self.resetDownload() - else: + elif reply.operation() == QNetworkAccessManager.PutOperation: # Ignore any operation that is not a get operation pass diff --git a/resources/themes/cura-light/icons/star_empty.svg b/resources/themes/cura-light/icons/star_empty.svg new file mode 100644 index 0000000000..39b5791e91 --- /dev/null +++ b/resources/themes/cura-light/icons/star_empty.svg @@ -0,0 +1,11 @@ + + + + Star Copy 8 + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/icons/star_filled.svg b/resources/themes/cura-light/icons/star_filled.svg new file mode 100644 index 0000000000..d4e161f6c6 --- /dev/null +++ b/resources/themes/cura-light/icons/star_filled.svg @@ -0,0 +1,11 @@ + + + + Star Copy 7 + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2d7e92be4d..8d8f5dd718 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -394,6 +394,7 @@ "section": [0.0, 2.2], "section_icon": [1.6, 1.6], "section_icon_column": [2.8, 0.0], + "rating_star": [1.0, 1.0], "setting": [25.0, 1.8], "setting_control": [10.0, 2.0], From 8b25e6946adb3ea763fc25f22c3226e557d4c8bd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 15:33:44 +0100 Subject: [PATCH 02/29] Prevent attempting to rate when not logged in CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index a72411ef4b..283d9bc0aa 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -6,6 +6,7 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 import UM 1.1 as UM +import Cura 1.1 as Cura Item { @@ -92,7 +93,7 @@ Item rating: model.average_rating != undefined ? model.average_rating : 0 numRatings: model.num_ratings != undefined ? model.num_ratings : 0 userRating: model.user_rating - enabled: installedPackages != 0 + enabled: installedPackages != 0 && Cura.API.account.isLoggedIn } } } From fed9e2b623fcc2085a8343c479946cc4edc43c2c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 15:42:46 +0100 Subject: [PATCH 03/29] Move the click area of the download tile to just the icon CURA-6013 --- .../qml/ToolboxDownloadsGridTile.qml | 81 +++++++++---------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 283d9bc0aa..472f273817 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -58,13 +58,49 @@ Item color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") source: "../images/installed_check.svg" } + + MouseArea + { + anchors.fill: thumbnail + hoverEnabled: true + onEntered: thumbnail.border.color = UM.Theme.getColor("primary") + onExited: thumbnail.border.color = UM.Theme.getColor("lining") + onClicked: + { + base.selection = model + switch(toolbox.viewCategory) + { + case "material": + + // If model has a type, it must be a package + if (model.type !== undefined) + { + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + } + else + { + toolbox.viewPage = "author" + toolbox.setFilters("packages", { + "author_id": model.id, + "type": "material" + }) + } + break + default: + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + break + } + } + } } Column { width: parent.width - thumbnail.width - parent.spacing spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("default_margin").height + //anchors.topMargin: UM.Theme.getSize("default_margin").height Label { id: name @@ -97,47 +133,4 @@ Item } } } - MouseArea - { - anchors.fill: parent - hoverEnabled: true - onEntered: - { - thumbnail.border.color = UM.Theme.getColor("primary") - highlight.opacity = 0.1 - } - onExited: - { - thumbnail.border.color = UM.Theme.getColor("lining") - highlight.opacity = 0.0 - } - onClicked: - { - base.selection = model - switch(toolbox.viewCategory) - { - case "material": - - // If model has a type, it must be a package - if (model.type !== undefined) - { - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - } - else - { - toolbox.viewPage = "author" - toolbox.setFilters("packages", { - "author_id": model.id, - "type": "material" - }) - } - break - default: - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - break - } - } - } } From 4742db6fec2a82aa5e8d5bc95c764d0ce9d69e0b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 15:57:52 +0100 Subject: [PATCH 04/29] Cleanup gridTile CURA-6013 --- .../qml/ToolboxDownloadsGridTile.qml | 209 +++++++++--------- 1 file changed, 104 insertions(+), 105 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 472f273817..7ced23aee9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -13,124 +13,123 @@ Item id: toolboxDownloadsGridTile property int packageCount: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getTotalNumberOfMaterialPackagesByAuthor(model.id) : 1 property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0) - height: childrenRect.height + height: UM.Theme.getSize("toolbox_thumbnail_small").height Layout.alignment: Qt.AlignTop | Qt.AlignLeft + Rectangle { - id: highlight - anchors.fill: parent - opacity: 0.0 - color: UM.Theme.getColor("primary") - } - Row - { - width: parent.width - height: childrenRect.height - spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) - Rectangle + id: thumbnail + width: UM.Theme.getSize("toolbox_thumbnail_small").width + height: UM.Theme.getSize("toolbox_thumbnail_small").height + color: "white" + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + + Image { - id: thumbnail - width: UM.Theme.getSize("toolbox_thumbnail_small").width - height: UM.Theme.getSize("toolbox_thumbnail_small").height - color: "white" - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - Image - { - anchors.centerIn: parent - width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width - height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width - fillMode: Image.PreserveAspectFit - source: model.icon_url || "../images/logobot.svg" - mipmap: true - } - UM.RecolorImage - { - width: (parent.width * 0.4) | 0 - height: (parent.height * 0.4) | 0 - anchors - { - bottom: parent.bottom - right: parent.right - } - sourceSize.height: height - visible: installedPackages != 0 - color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") - source: "../images/installed_check.svg" - } + anchors.centerIn: parent + width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width + height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width + fillMode: Image.PreserveAspectFit + source: model.icon_url || "../images/logobot.svg" + mipmap: true - MouseArea - { - anchors.fill: thumbnail - hoverEnabled: true - onEntered: thumbnail.border.color = UM.Theme.getColor("primary") - onExited: thumbnail.border.color = UM.Theme.getColor("lining") - onClicked: - { - base.selection = model - switch(toolbox.viewCategory) - { - case "material": - // If model has a type, it must be a package - if (model.type !== undefined) - { - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - } - else - { - toolbox.viewPage = "author" - toolbox.setFilters("packages", { - "author_id": model.id, - "type": "material" - }) - } - break - default: + } + UM.RecolorImage + { + width: (parent.width * 0.4) | 0 + height: (parent.height * 0.4) | 0 + anchors + { + bottom: parent.bottom + right: parent.right + } + sourceSize.height: height + visible: installedPackages != 0 + color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") + source: "../images/installed_check.svg" + } + + MouseArea + { + anchors.fill: thumbnail + hoverEnabled: true + onEntered: thumbnail.border.color = UM.Theme.getColor("primary") + onExited: thumbnail.border.color = UM.Theme.getColor("lining") + onClicked: + { + base.selection = model + switch(toolbox.viewCategory) + { + case "material": + + // If model has a type, it must be a package + if (model.type !== undefined) + { toolbox.viewPage = "detail" toolbox.filterModelByProp("packages", "id", model.id) - break - } + } + else + { + toolbox.viewPage = "author" + toolbox.setFilters("packages", { + "author_id": model.id, + "type": "material" + }) + } + break + default: + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + break } } } - Column + } + Item + { + anchors { - width: parent.width - thumbnail.width - parent.spacing - spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) - anchors.top: parent.top - //anchors.topMargin: UM.Theme.getSize("default_margin").height - Label - { - id: name - text: model.name - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default_bold") - } - Label - { - id: info - text: model.description - maximumLineCount: 2 - elide: Text.ElideRight - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("default") - } + left: thumbnail.right + leftMargin: Math.floor(UM.Theme.getSize("narrow_margin").width) + right: parent.right + top: parent.top + bottom: parent.bottom + } - RatingWidget - { - visible: model.type == "plugin" - packageId: model.id - rating: model.average_rating != undefined ? model.average_rating : 0 - numRatings: model.num_ratings != undefined ? model.num_ratings : 0 - userRating: model.user_rating - enabled: installedPackages != 0 && Cura.API.account.isLoggedIn - } + Label + { + id: name + text: model.name + width: parent.width + elide: Text.ElideRight + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default_bold") + } + Label + { + id: info + text: model.description + elide: Text.ElideRight + width: parent.width + wrapMode: Text.WordWrap + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("default") + anchors.top: name.bottom + anchors.bottom: rating.top + verticalAlignment: Text.AlignVCenter + } + RatingWidget + { + id: rating + visible: model.type == "plugin" + packageId: model.id + rating: model.average_rating != undefined ? model.average_rating : 0 + numRatings: model.num_ratings != undefined ? model.num_ratings : 0 + userRating: model.user_rating + enabled: installedPackages != 0 && Cura.API.account.isLoggedIn + anchors.bottom: parent.bottom } } } From 50099ab7530da3d307426c4b069ef621fd9654b6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 16:02:21 +0100 Subject: [PATCH 05/29] Make a few missed items themeable as well CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 2 +- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 9e2e178b71..4e0bf67544 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -37,7 +37,7 @@ Item leftMargin: UM.Theme.getSize("wide_margin").width topMargin: UM.Theme.getSize("wide_margin").height } - color: "white" //Always a white background for image (regardless of theme). + color: UM.Theme.getColor("main_background") Image { anchors.fill: parent diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 7ced23aee9..70edee7449 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -21,7 +21,7 @@ Item id: thumbnail width: UM.Theme.getSize("toolbox_thumbnail_small").width height: UM.Theme.getSize("toolbox_thumbnail_small").height - color: "white" + color: UM.Theme.getColor("main_background") border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") From e92bd01fb28d460facdd5f0e7883267a25379aeb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 17:28:42 +0100 Subject: [PATCH 06/29] Removed the rating from the download grid It felt a bit weird to already have it in the grid layout CURA-6013 --- .../qml/ToolboxDownloadsGridTile.qml | 112 +++++++++++------- plugins/Toolbox/src/PackagesModel.py | 2 +- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 70edee7449..677e532827 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -16,6 +16,42 @@ Item height: UM.Theme.getSize("toolbox_thumbnail_small").height Layout.alignment: Qt.AlignTop | Qt.AlignLeft + MouseArea + { + anchors.fill: parent + hoverEnabled: true + onEntered: thumbnail.border.color = UM.Theme.getColor("primary") + onExited: thumbnail.border.color = UM.Theme.getColor("lining") + onClicked: + { + base.selection = model + switch(toolbox.viewCategory) + { + case "material": + + // If model has a type, it must be a package + if (model.type !== undefined) + { + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + } + else + { + toolbox.viewPage = "author" + toolbox.setFilters("packages", { + "author_id": model.id, + "type": "material" + }) + } + break + default: + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + break + } + } + } + Rectangle { id: thumbnail @@ -33,8 +69,6 @@ Item fillMode: Image.PreserveAspectFit source: model.icon_url || "../images/logobot.svg" mipmap: true - - } UM.RecolorImage { @@ -50,42 +84,6 @@ Item color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") source: "../images/installed_check.svg" } - - MouseArea - { - anchors.fill: thumbnail - hoverEnabled: true - onEntered: thumbnail.border.color = UM.Theme.getColor("primary") - onExited: thumbnail.border.color = UM.Theme.getColor("lining") - onClicked: - { - base.selection = model - switch(toolbox.viewCategory) - { - case "material": - - // If model has a type, it must be a package - if (model.type !== undefined) - { - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - } - else - { - toolbox.viewPage = "author" - toolbox.setFilters("packages", { - "author_id": model.id, - "type": "material" - }) - } - break - default: - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - break - } - } - } } Item { @@ -119,17 +117,39 @@ Item anchors.top: name.bottom anchors.bottom: rating.top verticalAlignment: Text.AlignVCenter + maximumLineCount: 2 } - RatingWidget + Row { id: rating - visible: model.type == "plugin" - packageId: model.id - rating: model.average_rating != undefined ? model.average_rating : 0 - numRatings: model.num_ratings != undefined ? model.num_ratings : 0 - userRating: model.user_rating - enabled: installedPackages != 0 && Cura.API.account.isLoggedIn - anchors.bottom: parent.bottom + height: UM.Theme.getSize("rating_star").height + visible: model.average_rating > 0 //Has a rating at all. + spacing: UM.Theme.getSize("thick_lining").width + anchors + { + bottom: parent.bottom + left: parent.left + right: parent.right + } + + UM.RecolorImage + { + id: starIcon + source: UM.Theme.getIcon("star_filled") + color: "#5a5a5a" + height: UM.Theme.getSize("rating_star").height + width: UM.Theme.getSize("rating_star").width + } + + Label + { + text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + verticalAlignment: Text.AlignVCenter + height: starIcon.height + anchors.verticalCenter: starIcon.verticalCenter + color: starIcon.color + font: UM.Theme.getFont("small") + } } } } diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index b3c388bc7c..3f5be3bc37 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -105,7 +105,7 @@ class PackagesModel(ListModel): "links": links_dict, "website": package["website"] if "website" in package else None, "login_required": "login-required" in package.get("tags", []), - "average_rating": package.get("rating", {}).get("average", 0), + "average_rating": float(package.get("rating", {}).get("average", 0)), "num_ratings": package.get("rating", {}).get("count", 0), "user_rating": package.get("rating", {}).get("user", 0) }) From 04f3601c2711426ac5b363ad51e03d468492506f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 09:54:26 +0100 Subject: [PATCH 07/29] Ensure that local votes are displayed right away So even before an update is received, ensure that the data is updated CURA-6013 --- .../Toolbox/resources/qml/RatingWidget.qml | 29 +++++++++++++------ .../resources/qml/ToolboxDetailPage.qml | 18 ++++++++++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 424f6c91c4..b7d07835e8 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -9,8 +9,16 @@ Item property real rating: 0 property int indexHovered: -1 property string packageId: "" + property int numRatings: 0 + + // If the widget was used to vote, but the vote isn't sent to remote yet, we do want to fake some things. + property int _numRatings: _localRating != 0 ? numRatings + 1 : numRatings + property int _localRating: 0 + onVisibleChanged: _localRating = 0 // Reset the _localRating + property int userRating: 0 + width: contentRow.width height: contentRow.height MouseArea @@ -50,7 +58,10 @@ Item { return indexHovered >= index } - + if(ratingWidget._localRating > 0) + { + return _localRating >= index +1 + } if(ratingWidget.userRating > 0) { return userRating >= index +1 @@ -73,7 +84,7 @@ Item { return "#5a5a5a" } - if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) + if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0 || ratingWidget._localRating > 0) && isStarFilled) { return UM.Theme.getColor("primary") } @@ -82,19 +93,19 @@ Item } onClicked: { - if(userRating == 0) - { - //User didn't vote yet, locally fake it - numRatings += 1 - } - userRating = index + 1 // Fake local data + // Ensure that the local rating is updated (even though it's not on the server just yet) + _localRating = index + 1 toolbox.ratePackage(ratingWidget.packageId, index + 1) } } } Label { - text: "(" + numRatings + ")" + text: "(" + _numRatings + ")" + verticalAlignment: Text.AlignVCenter + height: parent.height + color: "#5a5a5a" + font: UM.Theme.getFont("small") } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 4e0bf67544..dd3f0a6c84 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -6,6 +6,8 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM +import Cura 1.1 as Cura + Item { id: page @@ -103,6 +105,12 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } + Label + { + text: catalog.i18nc("@label", "Rating") + ":" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_medium") + } } Column { @@ -160,6 +168,16 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } + RatingWidget + { + id: rating + visible: details.type == "plugin" + packageId: details.id + rating: details.average_rating + numRatings: details.num_ratings + userRating: details.user_rating + enabled: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn + } } Rectangle { From 098adc45ff6464f14e6ba8c2be2deec2df17bb75 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 10:40:54 +0100 Subject: [PATCH 08/29] Move the rating logic outside of the rating widget That way it's easier to re-use the component if that's ever required. CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 7 +++++-- .../Toolbox/resources/qml/ToolboxDetailPage.qml | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index b7d07835e8..f1499b61a7 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -19,6 +19,8 @@ Item property int userRating: 0 + signal rated(int rating) + width: contentRow.width height: contentRow.height MouseArea @@ -94,8 +96,9 @@ Item onClicked: { // Ensure that the local rating is updated (even though it's not on the server just yet) - _localRating = index + 1 - toolbox.ratePackage(ratingWidget.packageId, index + 1) + //_localRating = index + 1 + rated(index + 1) + } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index dd3f0a6c84..a503a9d519 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -177,6 +177,21 @@ Item numRatings: details.num_ratings userRating: details.user_rating enabled: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn + + onRated: + { + toolbox.ratePackage(details.id, rating) + var index = toolbox.packagesModel.find("id", details.id) + if(index != -1) + { + // Found the package + toolbox.packagesModel.setProperty(index, "user_rating", rating) + toolbox.packagesModel.setProperty(index, "num_ratings", details.num_ratings + 1) + + // Hack; This is because the current selection is an outdated copy, so we need to re-copy it. + base.selection = toolbox.packagesModel.getItem(index) + } + } } } Rectangle From 99f0e9613144ceebb30159cc8fc73c6bff25f0e3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 11:01:55 +0100 Subject: [PATCH 09/29] Ensure that the local model is updated correctly on local vote CURA-6013 --- .../Toolbox/resources/qml/RatingWidget.qml | 22 +++----------- .../resources/qml/ToolboxDetailPage.qml | 29 +++++++++++++++---- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index f1499b61a7..fbe782b2e2 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -12,11 +12,6 @@ Item property int numRatings: 0 - // If the widget was used to vote, but the vote isn't sent to remote yet, we do want to fake some things. - property int _numRatings: _localRating != 0 ? numRatings + 1 : numRatings - property int _localRating: 0 - onVisibleChanged: _localRating = 0 // Reset the _localRating - property int userRating: 0 signal rated(int rating) @@ -60,10 +55,7 @@ Item { return indexHovered >= index } - if(ratingWidget._localRating > 0) - { - return _localRating >= index +1 - } + if(ratingWidget.userRating > 0) { return userRating >= index +1 @@ -86,25 +78,19 @@ Item { return "#5a5a5a" } - if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0 || ratingWidget._localRating > 0) && isStarFilled) + if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) { return UM.Theme.getColor("primary") } return "#5a5a5a" } } - onClicked: - { - // Ensure that the local rating is updated (even though it's not on the server just yet) - //_localRating = index + 1 - rated(index + 1) - - } + onClicked: rated(index + 1) // Notify anyone who cares about this. } } Label { - text: "(" + _numRatings + ")" + text: "(" + numRatings + ")" verticalAlignment: Text.AlignVCenter height: parent.height color: "#5a5a5a" diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index a503a9d519..51bb218293 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -181,15 +181,34 @@ Item onRated: { toolbox.ratePackage(details.id, rating) - var index = toolbox.packagesModel.find("id", details.id) + // HACK: This is a far from optimal solution, but without major refactoring, this is the best we can + // do. Since a rework of this is scheduled, it shouldn't live that long... + var index = toolbox.pluginsAvailableModel.find("id", details.id) if(index != -1) { - // Found the package - toolbox.packagesModel.setProperty(index, "user_rating", rating) - toolbox.packagesModel.setProperty(index, "num_ratings", details.num_ratings + 1) + if(details.user_rating == 0) // User never rated before. + { + toolbox.pluginsAvailableModel.setProperty(index, "num_ratings", details.num_ratings + 1) + } + + toolbox.pluginsAvailableModel.setProperty(index, "user_rating", rating) + // Hack; This is because the current selection is an outdated copy, so we need to re-copy it. - base.selection = toolbox.packagesModel.getItem(index) + base.selection = toolbox.pluginsAvailableModel.getItem(index) + return + } + index = toolbox.pluginsShowcaseModel.find("id", details.id) + if(index != -1) + { + if(details.user_rating == 0) // User never rated before. + { + toolbox.pluginsShowcaseModel.setProperty(index, "user_rating", rating) + } + toolbox.pluginsShowcaseModel.setProperty(index, "num_ratings", details.num_ratings + 1) + + // Hack; This is because the current selection is an outdated copy, so we need to re-copy it. + base.selection = toolbox.pluginsShowcaseModel.getItem(index) } } } From 82322d857554b3685394dbee40485c59a973cf02 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 11:12:25 +0100 Subject: [PATCH 10/29] Show that a downloaded plugin has a user rating or not CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 677e532827..f34d982cfb 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -136,14 +136,16 @@ Item { id: starIcon source: UM.Theme.getIcon("star_filled") - color: "#5a5a5a" + color: model.user_rating == 0 ? "#5a5a5a" : UM.Theme.getColor("primary") height: UM.Theme.getSize("rating_star").height width: UM.Theme.getSize("rating_star").width } Label { - text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + // If the user voted, show that value. Otherwsie show the average rating. + property real ratingtoUse: model.user_rating == 0 ? model.average_rating: model.user_rating + text: ratingtoUse.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" verticalAlignment: Text.AlignVCenter height: starIcon.height anchors.verticalCenter: starIcon.verticalCenter From 70b9a44ae42de5ae7a796285338f7abad673f984 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 13:04:02 +0100 Subject: [PATCH 11/29] Removed import of CuraVersion CURA-6013 --- plugins/Toolbox/src/Toolbox.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 7e35f5d1f4..b88e1aa973 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -13,7 +13,6 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkRepl from UM.Logger import Logger from UM.PluginRegistry import PluginRegistry from UM.Extension import Extension -from UM.Qt.ListModel import ListModel from UM.i18n import i18nCatalog from UM.Version import Version @@ -22,8 +21,7 @@ from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel from .PackagesModel import PackagesModel -from cura.CuraVersion import CuraVersion -from cura.API import CuraAPI + if TYPE_CHECKING: from cura.Settings.GlobalStack import GlobalStack @@ -158,7 +156,7 @@ class Toolbox(QObject, Extension): self._rate_request = QNetworkRequest(url) for header_name, header_value in self._request_headers: cast(QNetworkRequest, self._rate_request).setRawHeader(header_name, header_value) - data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(CuraVersion), rating) + data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(self._application.getVersion()), rating) self._rate_reply = cast(QNetworkAccessManager, self._network_manager).put(self._rate_request, data.encode()) @pyqtSlot(result = str) From 9d1701aacbef8273f3225f26c158ceb2d6b6b8f3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 13:29:58 +0100 Subject: [PATCH 12/29] Removed hardcoded color CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 8a2fdc8bc8..ceaadc110d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -20,7 +20,7 @@ Rectangle Rectangle { id: thumbnail - color: "white" + color: UM.Theme.getColor("main_background") width: UM.Theme.getSize("toolbox_thumbnail_large").width height: UM.Theme.getSize("toolbox_thumbnail_large").height anchors From 4baf0d1bdb8c9aeab709cde37f400ae7db304543 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 13:49:20 +0100 Subject: [PATCH 13/29] Always show average rating CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index f34d982cfb..f217d901b8 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -143,9 +143,7 @@ Item Label { - // If the user voted, show that value. Otherwsie show the average rating. - property real ratingtoUse: model.user_rating == 0 ? model.average_rating: model.user_rating - text: ratingtoUse.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" verticalAlignment: Text.AlignVCenter height: starIcon.height anchors.verticalCenter: starIcon.verticalCenter From 30057e2fcd4c1b6370178d24db903d84e83b0619 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 13:49:45 +0100 Subject: [PATCH 14/29] Use user_rating instead of user In the end it was implemented as user_rating (and not as user) CURA-6013 --- plugins/Toolbox/src/PackagesModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index 3f5be3bc37..d94fdf6bb7 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -107,7 +107,7 @@ class PackagesModel(ListModel): "login_required": "login-required" in package.get("tags", []), "average_rating": float(package.get("rating", {}).get("average", 0)), "num_ratings": package.get("rating", {}).get("count", 0), - "user_rating": package.get("rating", {}).get("user", 0) + "user_rating": package.get("rating", {}).get("user_rating", 0) }) # Filter on all the key-word arguments. From 7a5701b00121e3a481e6f7dbd496c3250a299018 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 14:12:34 +0100 Subject: [PATCH 15/29] Made smallrating widget re-usable Also added it to the details page CURA-6013 --- .../resources/qml/SmallRatingWidget.qml | 33 +++++ .../resources/qml/ToolboxDetailPage.qml | 114 +++++++++--------- .../qml/ToolboxDownloadsGridTile.qml | 24 +--- 3 files changed, 94 insertions(+), 77 deletions(-) create mode 100644 plugins/Toolbox/resources/qml/SmallRatingWidget.qml diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml new file mode 100644 index 0000000000..f69e9349cf --- /dev/null +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -0,0 +1,33 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.4 +import UM 1.1 as UM +import Cura 1.1 as Cura + + + +Row +{ + id: rating + height: UM.Theme.getSize("rating_star").height + visible: model.average_rating > 0 //Has a rating at all. + spacing: UM.Theme.getSize("thick_lining").width + + UM.RecolorImage + { + id: starIcon + source: UM.Theme.getIcon("star_filled") + color: model.user_rating == 0 ? "#5a5a5a" : UM.Theme.getColor("primary") + height: UM.Theme.getSize("rating_star").height + width: UM.Theme.getSize("rating_star").width + } + + Label + { + text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + verticalAlignment: Text.AlignVCenter + height: starIcon.height + anchors.verticalCenter: starIcon.verticalCenter + color: starIcon.color + font: UM.Theme.getFont("small") + } +} \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 51bb218293..4adbaa2435 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -57,16 +57,22 @@ Item top: thumbnail.top left: thumbnail.right leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("wide_margin").width bottomMargin: UM.Theme.getSize("default_margin").height } text: details === null ? "" : (details.name || "") font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") wrapMode: Text.WordWrap - width: parent.width - height: UM.Theme.getSize("toolbox_property_label").height + width: properties.width + values.width + height: contentHeight + } + + SmallRatingWidget + { + anchors.left: title.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: title.verticalCenter + property var model: details } Column @@ -82,6 +88,12 @@ Item width: childrenRect.width height: childrenRect.height Label + { + text: catalog.i18nc("@label", "Rating") + ":" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_medium") + } + Label { text: catalog.i18nc("@label", "Version") + ":" font: UM.Theme.getFont("default") @@ -105,12 +117,6 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } - Label - { - text: catalog.i18nc("@label", "Rating") + ":" - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text_medium") - } } Column { @@ -124,50 +130,6 @@ Item } spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) height: childrenRect.height - Label - { - text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - Label - { - text: - { - if (details === null) - { - return "" - } - var date = new Date(details.last_updated) - return date.toLocaleString(UM.Preferences.getValue("general/language")) - } - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - Label - { - text: - { - if (details === null) - { - return "" - } - else - { - return "" + details.author_name + "" - } - } - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - linkColor: UM.Theme.getColor("text_link") - onLinkActivated: Qt.openUrlExternally(link) - } - Label - { - text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } RatingWidget { id: rating @@ -212,6 +174,50 @@ Item } } } + Label + { + text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + Label + { + text: + { + if (details === null) + { + return "" + } + var date = new Date(details.last_updated) + return date.toLocaleString(UM.Preferences.getValue("general/language")) + } + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + Label + { + text: + { + if (details === null) + { + return "" + } + else + { + return "" + details.author_name + "" + } + } + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + linkColor: UM.Theme.getColor("text_link") + onLinkActivated: Qt.openUrlExternally(link) + } + Label + { + text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown")) + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } } Rectangle { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index f217d901b8..8cd8f2ffef 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -119,37 +119,15 @@ Item verticalAlignment: Text.AlignVCenter maximumLineCount: 2 } - Row + SmallRatingWidget { id: rating - height: UM.Theme.getSize("rating_star").height - visible: model.average_rating > 0 //Has a rating at all. - spacing: UM.Theme.getSize("thick_lining").width anchors { bottom: parent.bottom left: parent.left right: parent.right } - - UM.RecolorImage - { - id: starIcon - source: UM.Theme.getIcon("star_filled") - color: model.user_rating == 0 ? "#5a5a5a" : UM.Theme.getColor("primary") - height: UM.Theme.getSize("rating_star").height - width: UM.Theme.getSize("rating_star").width - } - - Label - { - text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" - verticalAlignment: Text.AlignVCenter - height: starIcon.height - anchors.verticalCenter: starIcon.verticalCenter - color: starIcon.color - font: UM.Theme.getFont("small") - } } } } From fcaa23ed0ae2c168ff405ce7d9a66acf1ae19351 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 15:16:21 +0100 Subject: [PATCH 16/29] Added smallRating widget to featured plugins CURA-6013 --- .../resources/qml/SmallRatingWidget.qml | 4 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 103 +++++++----------- 2 files changed, 43 insertions(+), 64 deletions(-) diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index f69e9349cf..0b93131cfd 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -11,7 +11,7 @@ Row height: UM.Theme.getSize("rating_star").height visible: model.average_rating > 0 //Has a rating at all. spacing: UM.Theme.getSize("thick_lining").width - + width: starIcon.width + spacing + numRatingsLabel.width UM.RecolorImage { id: starIcon @@ -23,9 +23,11 @@ Row Label { + id: numRatingsLabel text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" verticalAlignment: Text.AlignVCenter height: starIcon.height + width: contentWidth anchors.verticalCenter: starIcon.verticalCenter color: starIcon.color font: UM.Theme.getFont("small") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index ceaadc110d..3e09654173 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -13,90 +13,67 @@ Rectangle property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0) id: tileBase width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width) - height: thumbnail.height + packageNameBackground.height + (2 * UM.Theme.getSize("default_lining").width) + height: thumbnail.height + packageName.height + rating.height + UM.Theme.getSize("default_margin").width border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - color: "transparent" - Rectangle + color: UM.Theme.getColor("main_background") + Image { id: thumbnail - color: UM.Theme.getColor("main_background") - width: UM.Theme.getSize("toolbox_thumbnail_large").width - height: UM.Theme.getSize("toolbox_thumbnail_large").height + height: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height + fillMode: Image.PreserveAspectFit + source: model.icon_url || "../images/logobot.svg" + mipmap: true anchors { top: parent.top + topMargin: UM.Theme.getSize("default_margin").height horizontalCenter: parent.horizontalCenter - topMargin: UM.Theme.getSize("default_lining").width - } - Image - { - anchors.centerIn: parent - width: UM.Theme.getSize("toolbox_thumbnail_large").width - 2 * UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("toolbox_thumbnail_large").height - 2 * UM.Theme.getSize("default_margin").height - fillMode: Image.PreserveAspectFit - source: model.icon_url || "../images/logobot.svg" - mipmap: true - } - UM.RecolorImage - { - width: (parent.width * 0.3) | 0 - height: (parent.height * 0.3) | 0 - anchors - { - bottom: parent.bottom - right: parent.right - bottomMargin: UM.Theme.getSize("default_lining").width - } - visible: installedPackages != 0 - color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") - source: "../images/installed_check.svg" } } - Rectangle + Label { - id: packageNameBackground - color: UM.Theme.getColor("primary") + id: packageName + text: model.name anchors { - top: thumbnail.bottom horizontalCenter: parent.horizontalCenter + top: thumbnail.bottom } + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter height: UM.Theme.getSize("toolbox_heading_label").height width: parent.width - Label - { - id: packageName - text: model.name - anchors - { - horizontalCenter: parent.horizontalCenter - } - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - height: UM.Theme.getSize("toolbox_heading_label").height - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("button_text") - font: UM.Theme.getFont("medium_bold") - } + wrapMode: Text.WordWrap + font: UM.Theme.getFont("medium_bold") } + UM.RecolorImage + { + width: (parent.width * 0.20) | 0 + height: (parent.height * 0.20) | 0 + anchors + { + bottom: parent.bottom + right: parent.right + bottomMargin: UM.Theme.getSize("default_lining").width + } + visible: installedPackages != 0 + color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") + source: "../images/installed_check.svg" + } + + SmallRatingWidget + { + id: rating + anchors.bottom: parent.bottom + anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height + anchors.horizontalCenter: parent.horizontalCenter + } + MouseArea { anchors.fill: parent - hoverEnabled: true - onEntered: - { - packageName.color = UM.Theme.getColor("button_text_hover") - packageNameBackground.color = UM.Theme.getColor("primary_hover") - tileBase.border.color = UM.Theme.getColor("primary_hover") - } - onExited: - { - packageName.color = UM.Theme.getColor("button_text") - packageNameBackground.color = UM.Theme.getColor("primary") - tileBase.border.color = UM.Theme.getColor("lining") - } onClicked: { base.selection = model From 4d57aa8ea42096dde3ef1db3f370e672ebd89b2b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 09:28:15 +0100 Subject: [PATCH 17/29] Simplify the rating widget CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 10 ---------- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 2 -- 2 files changed, 12 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index fbe782b2e2..355b99c0c4 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -10,8 +10,6 @@ Item property int indexHovered: -1 property string packageId: "" - property int numRatings: 0 - property int userRating: 0 signal rated(int rating) @@ -88,14 +86,6 @@ Item onClicked: rated(index + 1) // Notify anyone who cares about this. } } - Label - { - text: "(" + numRatings + ")" - verticalAlignment: Text.AlignVCenter - height: parent.height - color: "#5a5a5a" - font: UM.Theme.getFont("small") - } } } } \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 4adbaa2435..52af1d6ddf 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -135,8 +135,6 @@ Item id: rating visible: details.type == "plugin" packageId: details.id - rating: details.average_rating - numRatings: details.num_ratings userRating: details.user_rating enabled: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn From a6dbba709088c93b110abd874b82785eb612f4f7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 09:41:35 +0100 Subject: [PATCH 18/29] Minor UI tweaks CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 52af1d6ddf..1d977883f9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -26,7 +26,7 @@ Item right: parent.right rightMargin: UM.Theme.getSize("wide_margin").width } - height: UM.Theme.getSize("toolbox_detail_header").height + height: childrenRect.height + 3 * UM.Theme.getSize("default_margin").width Rectangle { id: thumbnail @@ -62,8 +62,7 @@ Item text: details === null ? "" : (details.name || "") font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") - wrapMode: Text.WordWrap - width: properties.width + values.width + width: contentWidth height: contentHeight } From 95f70a75d8629663dd42b2fdac148407cc993ed9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 10:39:56 +0100 Subject: [PATCH 19/29] Ensure that package name has margins in showcase tile CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 3e09654173..ca0226b39d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -44,7 +44,7 @@ Rectangle verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter height: UM.Theme.getSize("toolbox_heading_label").height - width: parent.width + width: parent.width - UM.Theme.getSize("default_margin").width wrapMode: Text.WordWrap font: UM.Theme.getFont("medium_bold") } From 5fd0f2b5f69e8f0597b4550a828a88da16eb8621 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 11:09:58 +0100 Subject: [PATCH 20/29] Add tooltip to rating if the rating is disabled This makes it clearer what the user needs to do in order to rate (install package or login) CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 16 ++++++++++------ .../Toolbox/resources/qml/ToolboxDetailPage.qml | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 355b99c0c4..9d9eb8bca8 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -1,7 +1,7 @@ -import QtQuick 2.2 -import QtQuick.Controls 2.0 +import QtQuick 2.7 +import QtQuick.Controls 2.1 import UM 1.0 as UM - +import Cura 1.1 as Cura Item { id: ratingWidget @@ -11,6 +11,7 @@ Item property string packageId: "" property int userRating: 0 + property bool canRate: false signal rated(int rating) @@ -20,7 +21,7 @@ Item { id: mouseArea anchors.fill: parent - hoverEnabled: ratingWidget.enabled + hoverEnabled: ratingWidget.canRate acceptedButtons: Qt.NoButton onExited: { @@ -40,12 +41,15 @@ Item hoverEnabled: true onHoveredChanged: { - if(hovered) + if(hovered && ratingWidget.canRate) { indexHovered = index } } + ToolTip.visible: control.hovered && !ratingWidget.canRate + ToolTip.text: !Cura.API.account.isLoggedIn ? catalog.i18nc("@label", "You need to login first before you can rate"): catalog.i18nc("@label", "You need to install the package before you can rate") + property bool isStarFilled: { // If the entire widget is hovered, override the actual rating. @@ -72,7 +76,7 @@ Item // Unfilled stars should always have the default color. Only filled stars should change on hover color: { - if(!enabled) + if(!ratingWidget.canRate) { return "#5a5a5a" } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 1d977883f9..d0608be4de 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -135,7 +135,7 @@ Item visible: details.type == "plugin" packageId: details.id userRating: details.user_rating - enabled: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn + canRate: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn onRated: { From dbf91fca7f42e34111134d5e794267c1f917ee09 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 11:40:51 +0100 Subject: [PATCH 21/29] Re-added hover on showcase tiles CURA-6013 --- .../qml/ToolboxDownloadsShowcaseTile.qml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index ca0226b39d..73d3acc76f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -51,12 +51,11 @@ Rectangle UM.RecolorImage { width: (parent.width * 0.20) | 0 - height: (parent.height * 0.20) | 0 + height: width anchors { - bottom: parent.bottom + bottom: bottomBorder.top right: parent.right - bottomMargin: UM.Theme.getSize("default_lining").width } visible: installedPackages != 0 color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") @@ -70,10 +69,21 @@ Rectangle anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height anchors.horizontalCenter: parent.horizontalCenter } + Rectangle + { + id: bottomBorder + color: UM.Theme.getColor("primary") + anchors.bottom: parent.bottom + width: parent.width + height: UM.Theme.getSize("toolbox_header_highlight").height + } MouseArea { anchors.fill: parent + hoverEnabled: true + onEntered: tileBase.border.color = UM.Theme.getColor("primary") + onExited: tileBase.border.color = UM.Theme.getColor("lining") onClicked: { base.selection = model From 901c19e270e3c3258e734b14c1f2433135f99695 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 11:52:04 +0100 Subject: [PATCH 22/29] Prevent QML warning CURA-6013 --- plugins/Toolbox/resources/qml/SmallRatingWidget.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index 0b93131cfd..439a7baec0 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -3,8 +3,6 @@ import QtQuick.Controls 1.4 import UM 1.1 as UM import Cura 1.1 as Cura - - Row { id: rating @@ -24,7 +22,7 @@ Row Label { id: numRatingsLabel - text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + text: model.average_rating != undefined ? model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")": "" verticalAlignment: Text.AlignVCenter height: starIcon.height width: contentWidth From 3225512851f61f0ac9f18ae6322f8eeb2c3bfd79 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 13 Dec 2018 15:48:03 +0100 Subject: [PATCH 23/29] Fix typing CURA-6013 --- plugins/Toolbox/src/Toolbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 715c105bad..05669e55d8 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -49,7 +49,7 @@ class Toolbox(QObject, Extension): self._download_progress = 0 # type: float self._is_downloading = False # type: bool self._network_manager = None # type: Optional[QNetworkAccessManager] - self._request_headers = [] # type: List[Tuple(bytes, bytes)] + self._request_headers = [] # type: List[Tuple[bytes, bytes]] self._updateRequestHeader() From bb1bf14a0182710ebb5c08fcbc8248e8d67c711e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 10:46:31 +0100 Subject: [PATCH 24/29] Prevent rating when user is not logged in CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 9d9eb8bca8..2623d13c0e 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -25,7 +25,10 @@ Item acceptedButtons: Qt.NoButton onExited: { - ratingWidget.indexHovered = -1 + if(ratingWidget.canRate) + { + ratingWidget.indexHovered = -1 + } } Row @@ -87,7 +90,13 @@ Item return "#5a5a5a" } } - onClicked: rated(index + 1) // Notify anyone who cares about this. + onClicked: + { + if(ratingWidget.canRate) + { + rated(index + 1) // Notify anyone who cares about this. + } + } } } } From 450f301c8c1211684db866eee9e1d8573a4d8665 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 10:56:13 +0100 Subject: [PATCH 25/29] Fix binding loop CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 0e183c2860..95c3a20e1e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -57,7 +57,6 @@ Item top: thumbnail.top left: thumbnail.right leftMargin: UM.Theme.getSize("default_margin").width - bottomMargin: UM.Theme.getSize("default_margin").height } text: details === null ? "" : (details.name || "") font: UM.Theme.getFont("large") @@ -226,13 +225,6 @@ Item renderType: Text.NativeRendering } } - Rectangle - { - color: UM.Theme.getColor("lining") - width: parent.width - height: UM.Theme.getSize("default_lining").height - anchors.bottom: parent.bottom - } } ToolboxDetailList { From 7616f9c97db92a7b213bd45232bb419e51581436 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 10:59:59 +0100 Subject: [PATCH 26/29] Make hardcoded color themeable CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 4 ++-- plugins/Toolbox/resources/qml/SmallRatingWidget.qml | 2 +- resources/themes/cura-light/theme.json | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 2623d13c0e..3dcae6d602 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -81,13 +81,13 @@ Item { if(!ratingWidget.canRate) { - return "#5a5a5a" + return UM.Theme.getColor("rating_star") } if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) { return UM.Theme.getColor("primary") } - return "#5a5a5a" + return UM.Theme.getColor("rating_star") } } onClicked: diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index 439a7baec0..bab219d294 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -14,7 +14,7 @@ Row { id: starIcon source: UM.Theme.getIcon("star_filled") - color: model.user_rating == 0 ? "#5a5a5a" : UM.Theme.getColor("primary") + color: model.user_rating == 0 ? UM.Theme.getColor("rating_star") : UM.Theme.getColor("primary") height: UM.Theme.getSize("rating_star").height width: UM.Theme.getSize("rating_star").width } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 969f5666a6..16f885c0b5 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -160,6 +160,8 @@ "extruder_button_material_border": [255, 255, 255, 255], + "rating_star": [90, 90, 90, 255], + "sync_button_text": [120, 120, 120, 255], "sync_button_text_hovered": [0, 0, 0, 255], From edd4f6e1faa7062299d832ceac2e412a3aec23b6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 11:02:10 +0100 Subject: [PATCH 27/29] Fix some minor QML warnings CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 95c3a20e1e..92b9fb1198 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -138,8 +138,8 @@ Item { id: rating visible: details.type == "plugin" - packageId: details.id - userRating: details.user_rating + packageId: details.id != undefined ? details.id: "" + userRating: details.user_rating != undefined ? details.user_rating: 0 canRate: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn onRated: From ae695b77e6ad8e9ea882c2b20e6ec4922fa6603a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 15:23:56 +0100 Subject: [PATCH 28/29] Add native rendering for QML Label CURA-6013 --- plugins/Toolbox/resources/qml/SmallRatingWidget.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index bab219d294..686058f4e8 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -29,5 +29,6 @@ Row anchors.verticalCenter: starIcon.verticalCenter color: starIcon.color font: UM.Theme.getFont("small") + renderType: Text.NativeRendering } } \ No newline at end of file From 9146a775a4c3ae4b83cd7f62d2bf0d945e9caab1 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 14 Dec 2018 16:17:05 +0100 Subject: [PATCH 29/29] After resetting the custom settings the quality slider did not update selected value CURA-6028 --- cura/Settings/SimpleModeSettingsManager.py | 11 ++++++----- .../RecommendedQualityProfileSelector.qml | 12 +++++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index fce43243bd..210a5794d4 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty +from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot from UM.Application import Application @@ -16,12 +16,12 @@ class SimpleModeSettingsManager(QObject): self._is_profile_user_created = False # True when profile was custom created by user self._machine_manager.activeStackValueChanged.connect(self._updateIsProfileCustomized) - self._machine_manager.activeQualityGroupChanged.connect(self._updateIsProfileUserCreated) - self._machine_manager.activeQualityChangesGroupChanged.connect(self._updateIsProfileUserCreated) + self._machine_manager.activeQualityGroupChanged.connect(self.updateIsProfileUserCreated) + self._machine_manager.activeQualityChangesGroupChanged.connect(self.updateIsProfileUserCreated) # update on create as the activeQualityChanged signal is emitted before this manager is created when Cura starts self._updateIsProfileCustomized() - self._updateIsProfileUserCreated() + self.updateIsProfileUserCreated() isProfileCustomizedChanged = pyqtSignal() isProfileUserCreatedChanged = pyqtSignal() @@ -61,7 +61,8 @@ class SimpleModeSettingsManager(QObject): def isProfileUserCreated(self): return self._is_profile_user_created - def _updateIsProfileUserCreated(self): + @pyqtSlot() + def updateIsProfileUserCreated(self) -> None: quality_changes_keys = set() if not self._machine_manager.activeMachine: diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 349c6dbb57..e6b3f1b9eb 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -39,7 +39,17 @@ Item { target: Cura.QualityProfilesDropDownMenuModel onItemsChanged: qualityModel.update() - onDataChanged: qualityModel.update() + onDataChanged: + { + // If a custom profile is selected and then a user decides to change any of setting the slider should show + // the reset button. After clicking the reset button the QualityProfilesDropDownMenuModel(ListModel) is + // updated before the property isProfileCustomized is called to update. + if (Cura.SimpleModeSettingsManager.isProfileCustomized) + { + Cura.SimpleModeSettingsManager.updateIsProfileUserCreated() + } + qualityModel.update() + } } Connections {