mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-04-30 15:54:32 +08:00
Merge pull request #4976 from Ultimaker/CURA-6013-rate-packages
Cura 6013 rate packages
This commit is contained in:
commit
efb832702b
104
plugins/Toolbox/resources/qml/RatingWidget.qml
Normal file
104
plugins/Toolbox/resources/qml/RatingWidget.qml
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 2.1
|
||||||
|
import UM 1.0 as UM
|
||||||
|
import Cura 1.1 as Cura
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: ratingWidget
|
||||||
|
|
||||||
|
property real rating: 0
|
||||||
|
property int indexHovered: -1
|
||||||
|
property string packageId: ""
|
||||||
|
|
||||||
|
property int userRating: 0
|
||||||
|
property bool canRate: false
|
||||||
|
|
||||||
|
signal rated(int rating)
|
||||||
|
|
||||||
|
width: contentRow.width
|
||||||
|
height: contentRow.height
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: ratingWidget.canRate
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
onExited:
|
||||||
|
{
|
||||||
|
if(ratingWidget.canRate)
|
||||||
|
{
|
||||||
|
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 && 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.
|
||||||
|
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(!ratingWidget.canRate)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("rating_star")
|
||||||
|
}
|
||||||
|
if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("primary")
|
||||||
|
}
|
||||||
|
return UM.Theme.getColor("rating_star")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
if(ratingWidget.canRate)
|
||||||
|
{
|
||||||
|
rated(index + 1) // Notify anyone who cares about this.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
plugins/Toolbox/resources/qml/SmallRatingWidget.qml
Normal file
34
plugins/Toolbox/resources/qml/SmallRatingWidget.qml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
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
|
||||||
|
width: starIcon.width + spacing + numRatingsLabel.width
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
id: starIcon
|
||||||
|
source: UM.Theme.getIcon("star_filled")
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: numRatingsLabel
|
||||||
|
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
|
||||||
|
anchors.verticalCenter: starIcon.verticalCenter
|
||||||
|
color: starIcon.color
|
||||||
|
font: UM.Theme.getFont("small")
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,8 @@ import QtQuick.Controls 1.4
|
|||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import UM 1.1 as UM
|
import UM 1.1 as UM
|
||||||
|
|
||||||
|
import Cura 1.1 as Cura
|
||||||
|
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
id: page
|
id: page
|
||||||
@ -24,7 +26,7 @@ Item
|
|||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: UM.Theme.getSize("wide_margin").width
|
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
|
Rectangle
|
||||||
{
|
{
|
||||||
id: thumbnail
|
id: thumbnail
|
||||||
@ -37,7 +39,7 @@ Item
|
|||||||
leftMargin: UM.Theme.getSize("wide_margin").width
|
leftMargin: UM.Theme.getSize("wide_margin").width
|
||||||
topMargin: UM.Theme.getSize("wide_margin").height
|
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
|
Image
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@ -55,19 +57,23 @@ Item
|
|||||||
top: thumbnail.top
|
top: thumbnail.top
|
||||||
left: thumbnail.right
|
left: thumbnail.right
|
||||||
leftMargin: UM.Theme.getSize("default_margin").width
|
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 || "")
|
text: details === null ? "" : (details.name || "")
|
||||||
font: UM.Theme.getFont("large")
|
font: UM.Theme.getFont("large")
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
wrapMode: Text.WordWrap
|
width: contentWidth
|
||||||
width: parent.width
|
height: contentHeight
|
||||||
height: UM.Theme.getSize("toolbox_property_label").height
|
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SmallRatingWidget
|
||||||
|
{
|
||||||
|
anchors.left: title.right
|
||||||
|
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
anchors.verticalCenter: title.verticalCenter
|
||||||
|
property var model: details
|
||||||
|
}
|
||||||
|
|
||||||
Column
|
Column
|
||||||
{
|
{
|
||||||
id: properties
|
id: properties
|
||||||
@ -81,6 +87,13 @@ Item
|
|||||||
width: childrenRect.width
|
width: childrenRect.width
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
Label
|
Label
|
||||||
|
{
|
||||||
|
text: catalog.i18nc("@label", "Rating") + ":"
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
color: UM.Theme.getColor("text_medium")
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
}
|
||||||
|
Label
|
||||||
{
|
{
|
||||||
text: catalog.i18nc("@label", "Version") + ":"
|
text: catalog.i18nc("@label", "Version") + ":"
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
@ -121,6 +134,48 @@ Item
|
|||||||
}
|
}
|
||||||
spacing: Math.floor(UM.Theme.getSize("narrow_margin").height)
|
spacing: Math.floor(UM.Theme.getSize("narrow_margin").height)
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
RatingWidget
|
||||||
|
{
|
||||||
|
id: rating
|
||||||
|
visible: details.type == "plugin"
|
||||||
|
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:
|
||||||
|
{
|
||||||
|
toolbox.ratePackage(details.id, rating)
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
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.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown"))
|
text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown"))
|
||||||
@ -170,13 +225,6 @@ Item
|
|||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
color: UM.Theme.getColor("lining")
|
|
||||||
width: parent.width
|
|
||||||
height: UM.Theme.getSize("default_lining").height
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ToolboxDetailList
|
ToolboxDetailList
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ import QtQuick.Controls 1.4
|
|||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import UM 1.1 as UM
|
import UM 1.1 as UM
|
||||||
|
import Cura 1.1 as Cura
|
||||||
|
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
@ -14,94 +15,13 @@ Item
|
|||||||
property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
|
property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
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
|
|
||||||
{
|
|
||||||
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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: name
|
|
||||||
text: model.name
|
|
||||||
width: parent.width
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: UM.Theme.getColor("text")
|
|
||||||
font: UM.Theme.getFont("default_bold")
|
|
||||||
renderType: Text.NativeRendering
|
|
||||||
}
|
|
||||||
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")
|
|
||||||
renderType: Text.NativeRendering
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MouseArea
|
MouseArea
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onEntered:
|
onEntered: thumbnail.border.color = UM.Theme.getColor("primary")
|
||||||
{
|
onExited: thumbnail.border.color = UM.Theme.getColor("lining")
|
||||||
thumbnail.border.color = UM.Theme.getColor("primary")
|
|
||||||
highlight.opacity = 0.1
|
|
||||||
}
|
|
||||||
onExited:
|
|
||||||
{
|
|
||||||
thumbnail.border.color = UM.Theme.getColor("lining")
|
|
||||||
highlight.opacity = 0.0
|
|
||||||
}
|
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
base.selection = model
|
base.selection = model
|
||||||
@ -131,4 +51,83 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: thumbnail
|
||||||
|
width: UM.Theme.getSize("toolbox_thumbnail_small").width
|
||||||
|
height: UM.Theme.getSize("toolbox_thumbnail_small").height
|
||||||
|
color: UM.Theme.getColor("main_background")
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: thumbnail.right
|
||||||
|
leftMargin: Math.floor(UM.Theme.getSize("narrow_margin").width)
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
maximumLineCount: 2
|
||||||
|
}
|
||||||
|
SmallRatingWidget
|
||||||
|
{
|
||||||
|
id: rating
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,57 +13,25 @@ Rectangle
|
|||||||
property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
|
property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
|
||||||
id: tileBase
|
id: tileBase
|
||||||
width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width)
|
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.width: UM.Theme.getSize("default_lining").width
|
||||||
border.color: UM.Theme.getColor("lining")
|
border.color: UM.Theme.getColor("lining")
|
||||||
color: "transparent"
|
color: UM.Theme.getColor("main_background")
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: thumbnail
|
|
||||||
color: "white"
|
|
||||||
width: UM.Theme.getSize("toolbox_thumbnail_large").width
|
|
||||||
height: UM.Theme.getSize("toolbox_thumbnail_large").height
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
top: parent.top
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
topMargin: UM.Theme.getSize("default_lining").width
|
|
||||||
}
|
|
||||||
Image
|
Image
|
||||||
{
|
{
|
||||||
anchors.centerIn: parent
|
id: thumbnail
|
||||||
width: UM.Theme.getSize("toolbox_thumbnail_large").width - 2 * UM.Theme.getSize("default_margin").width
|
height: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height
|
||||||
height: UM.Theme.getSize("toolbox_thumbnail_large").height - 2 * UM.Theme.getSize("default_margin").height
|
width: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: model.icon_url || "../images/logobot.svg"
|
source: model.icon_url || "../images/logobot.svg"
|
||||||
mipmap: true
|
mipmap: true
|
||||||
}
|
|
||||||
UM.RecolorImage
|
|
||||||
{
|
|
||||||
width: (parent.width * 0.3) | 0
|
|
||||||
height: (parent.height * 0.3) | 0
|
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
bottom: parent.bottom
|
top: parent.top
|
||||||
right: parent.right
|
topMargin: UM.Theme.getSize("default_margin").height
|
||||||
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
|
|
||||||
{
|
|
||||||
id: packageNameBackground
|
|
||||||
color: UM.Theme.getColor("primary")
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
top: thumbnail.bottom
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
height: UM.Theme.getSize("toolbox_heading_label").height
|
}
|
||||||
width: parent.width
|
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: packageName
|
id: packageName
|
||||||
@ -71,33 +39,52 @@ Rectangle
|
|||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
top: thumbnail.bottom
|
||||||
}
|
}
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
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")
|
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
|
height: UM.Theme.getSize("toolbox_heading_label").height
|
||||||
|
width: parent.width - UM.Theme.getSize("default_margin").width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
font: UM.Theme.getFont("medium_bold")
|
||||||
}
|
}
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
width: (parent.width * 0.20) | 0
|
||||||
|
height: width
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
bottom: bottomBorder.top
|
||||||
|
right: parent.right
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: bottomBorder
|
||||||
|
color: UM.Theme.getColor("primary")
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
width: parent.width
|
||||||
|
height: UM.Theme.getSize("toolbox_header_highlight").height
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea
|
MouseArea
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onEntered:
|
onEntered: tileBase.border.color = UM.Theme.getColor("primary")
|
||||||
{
|
onExited: tileBase.border.color = UM.Theme.getColor("lining")
|
||||||
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:
|
onClicked:
|
||||||
{
|
{
|
||||||
base.selection = model
|
base.selection = model
|
||||||
|
@ -41,6 +41,9 @@ class PackagesModel(ListModel):
|
|||||||
self.addRoleName(Qt.UserRole + 20, "links")
|
self.addRoleName(Qt.UserRole + 20, "links")
|
||||||
self.addRoleName(Qt.UserRole + 21, "website")
|
self.addRoleName(Qt.UserRole + 21, "website")
|
||||||
self.addRoleName(Qt.UserRole + 22, "login_required")
|
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.
|
# List of filters for queries. The result is the union of the each list of results.
|
||||||
self._filter = {} # type: Dict[str, str]
|
self._filter = {} # type: Dict[str, str]
|
||||||
@ -101,7 +104,10 @@ class PackagesModel(ListModel):
|
|||||||
"tags": package["tags"] if "tags" in package else [],
|
"tags": package["tags"] if "tags" in package else [],
|
||||||
"links": links_dict,
|
"links": links_dict,
|
||||||
"website": package["website"] if "website" in package else None,
|
"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": float(package.get("rating", {}).get("average", 0)),
|
||||||
|
"num_ratings": package.get("rating", {}).get("count", 0),
|
||||||
|
"user_rating": package.get("rating", {}).get("user_rating", 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
# Filter on all the key-word arguments.
|
# Filter on all the key-word arguments.
|
||||||
|
@ -13,7 +13,6 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkRepl
|
|||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.Extension import Extension
|
from UM.Extension import Extension
|
||||||
from UM.Qt.ListModel import ListModel
|
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
from UM.Version import Version
|
from UM.Version import Version
|
||||||
|
|
||||||
@ -50,17 +49,10 @@ class Toolbox(QObject, Extension):
|
|||||||
self._download_progress = 0 # type: float
|
self._download_progress = 0 # type: float
|
||||||
self._is_downloading = False # type: bool
|
self._is_downloading = False # type: bool
|
||||||
self._network_manager = None # type: Optional[QNetworkAccessManager]
|
self._network_manager = None # type: Optional[QNetworkAccessManager]
|
||||||
self._request_header = [
|
self._request_headers = [] # type: List[Tuple[bytes, bytes]]
|
||||||
b"User-Agent",
|
self._updateRequestHeader()
|
||||||
str.encode(
|
|
||||||
"%s/%s (%s %s)" % (
|
|
||||||
self._application.getApplicationName(),
|
|
||||||
self._application.getVersion(),
|
|
||||||
platform.system(),
|
|
||||||
platform.machine(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
self._request_urls = {} # type: Dict[str, QUrl]
|
self._request_urls = {} # type: Dict[str, QUrl]
|
||||||
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
|
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
|
||||||
self._old_plugin_ids = set() # type: Set[str]
|
self._old_plugin_ids = set() # type: Set[str]
|
||||||
@ -115,6 +107,7 @@ class Toolbox(QObject, Extension):
|
|||||||
self._restart_dialog_message = "" # type: str
|
self._restart_dialog_message = "" # type: str
|
||||||
|
|
||||||
self._application.initializationFinished.connect(self._onAppInitialized)
|
self._application.initializationFinished.connect(self._onAppInitialized)
|
||||||
|
self._application.getCuraAPI().account.loginStateChanged.connect(self._updateRequestHeader)
|
||||||
|
|
||||||
# Signals:
|
# Signals:
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@ -134,12 +127,38 @@ class Toolbox(QObject, Extension):
|
|||||||
showLicenseDialog = pyqtSignal()
|
showLicenseDialog = pyqtSignal()
|
||||||
uninstallVariablesChanged = 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:
|
def _resetUninstallVariables(self) -> None:
|
||||||
self._package_id_to_uninstall = None # type: Optional[str]
|
self._package_id_to_uninstall = None # type: Optional[str]
|
||||||
self._package_name_to_uninstall = ""
|
self._package_name_to_uninstall = ""
|
||||||
self._package_used_materials = [] # type: List[Tuple[GlobalStack, str, str]]
|
self._package_used_materials = [] # type: List[Tuple[GlobalStack, str, str]]
|
||||||
self._package_used_qualities = [] # 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(self._application.getVersion()), rating)
|
||||||
|
self._rate_reply = cast(QNetworkAccessManager, self._network_manager).put(self._rate_request, data.encode())
|
||||||
|
|
||||||
@pyqtSlot(result = str)
|
@pyqtSlot(result = str)
|
||||||
def getLicenseDialogPluginName(self) -> str:
|
def getLicenseDialogPluginName(self) -> str:
|
||||||
return self._license_dialog_plugin_name
|
return self._license_dialog_plugin_name
|
||||||
@ -563,7 +582,8 @@ class Toolbox(QObject, Extension):
|
|||||||
def _makeRequestByType(self, request_type: str) -> None:
|
def _makeRequestByType(self, request_type: str) -> None:
|
||||||
Logger.log("i", "Requesting %s metadata from server.", request_type)
|
Logger.log("i", "Requesting %s metadata from server.", request_type)
|
||||||
request = QNetworkRequest(self._request_urls[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:
|
if self._network_manager:
|
||||||
self._network_manager.get(request)
|
self._network_manager.get(request)
|
||||||
|
|
||||||
@ -578,7 +598,8 @@ class Toolbox(QObject, Extension):
|
|||||||
if hasattr(QNetworkRequest, "RedirectPolicyAttribute"):
|
if hasattr(QNetworkRequest, "RedirectPolicyAttribute"):
|
||||||
# Patch for Qt 5.9+
|
# Patch for Qt 5.9+
|
||||||
cast(QNetworkRequest, self._download_request).setAttribute(QNetworkRequest.RedirectPolicyAttribute, True)
|
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._download_reply = cast(QNetworkAccessManager, self._network_manager).get(self._download_request)
|
||||||
self.setDownloadProgress(0)
|
self.setDownloadProgress(0)
|
||||||
self.setIsDownloading(True)
|
self.setIsDownloading(True)
|
||||||
@ -660,7 +681,7 @@ class Toolbox(QObject, Extension):
|
|||||||
else:
|
else:
|
||||||
self.setViewPage("errored")
|
self.setViewPage("errored")
|
||||||
self.resetDownload()
|
self.resetDownload()
|
||||||
else:
|
elif reply.operation() == QNetworkAccessManager.PutOperation:
|
||||||
# Ignore any operation that is not a get operation
|
# Ignore any operation that is not a get operation
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
11
resources/themes/cura-light/icons/star_empty.svg
Normal file
11
resources/themes/cura-light/icons/star_empty.svg
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="14px" height="13px" viewBox="0 0 14 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Star Copy 8</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<g id="Toolbox-VIP-material" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="Marketplace-hover-" transform="translate(-140.000000, -457.000000)" stroke="#666666">
|
||||||
|
<path d="M150.450431,468.749111 L149.791458,464.907 L152.582915,462.186001 L148.725216,461.625444 L147,458.129776 L145.274784,461.625444 L141.417085,462.186001 L144.208542,464.907 L143.549569,468.749111 L147,466.935112 L150.450431,468.749111 Z" id="Star-Copy-8"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 844 B |
11
resources/themes/cura-light/icons/star_filled.svg
Normal file
11
resources/themes/cura-light/icons/star_filled.svg
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="14px" height="13px" viewBox="0 0 14 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Star Copy 7</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<g id="Toolbox-VIP-material" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="Marketplace-hover-" transform="translate(-127.000000, -457.000000)" fill="#666666" stroke="#666666">
|
||||||
|
<path d="M137.450431,468.749111 L136.791458,464.907 L139.582915,462.186001 L135.725216,461.625444 L134,458.129776 L132.274784,461.625444 L128.417085,462.186001 L131.208542,464.907 L130.549569,468.749111 L134,466.935112 L137.450431,468.749111 Z" id="Star-Copy-7"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 859 B |
@ -147,6 +147,8 @@
|
|||||||
|
|
||||||
"extruder_button_material_border": [255, 255, 255, 255],
|
"extruder_button_material_border": [255, 255, 255, 255],
|
||||||
|
|
||||||
|
"rating_star": [90, 90, 90, 255],
|
||||||
|
|
||||||
"sync_button_text": [120, 120, 120, 255],
|
"sync_button_text": [120, 120, 120, 255],
|
||||||
"sync_button_text_hovered": [0, 0, 0, 255],
|
"sync_button_text_hovered": [0, 0, 0, 255],
|
||||||
|
|
||||||
@ -390,6 +392,7 @@
|
|||||||
"section": [0.0, 2],
|
"section": [0.0, 2],
|
||||||
"section_icon": [1.6, 1.6],
|
"section_icon": [1.6, 1.6],
|
||||||
"section_icon_column": [2.8, 0.0],
|
"section_icon_column": [2.8, 0.0],
|
||||||
|
"rating_star": [1.0, 1.0],
|
||||||
|
|
||||||
"setting": [25.0, 1.8],
|
"setting": [25.0, 1.8],
|
||||||
"setting_control": [11.0, 2.0],
|
"setting_control": [11.0, 2.0],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user