Merge remote-tracking branch 'origin/marketplace_redesign' into CURA-8559_add_marketplace_search

This commit is contained in:
Remco Burema 2021-11-12 13:10:20 +01:00
commit bc0b7301e5
No known key found for this signature in database
GPG Key ID: 215C49431D43F98C
7 changed files with 415 additions and 20 deletions

View File

@ -4,10 +4,12 @@
from PyQt5.QtCore import pyqtProperty, QObject
from typing import Any, Dict, Optional
from UM.i18n import i18nCatalog # To translate placeholder names if data is not present.
from UM.Util import parseBool
from UM.i18n import i18nCatalog # To translate placeholder names if data is not present.
catalog = i18nCatalog("cura")
class PackageModel(QObject):
"""
Represents a package, containing all the relevant information to be displayed about a package.
@ -25,17 +27,65 @@ class PackageModel(QObject):
"""
super().__init__(parent)
self._package_id = package_data.get("package_id", "UnknownPackageId")
self._icon_url = package_data.get("icon_url", "")
self._display_name = package_data.get("display_name", catalog.i18nc("@label:property", "Unknown Package"))
self._is_verified = "verified" in package_data.get("tags", [])
self._package_version = package_data.get("package_version", "") # Display purpose, no need for 'UM.Version'.
self._package_info_url = package_data.get("website", "") # Not to be confused with 'download_url'.
self._download_count = package_data.get("download_count", 0)
self._description = package_data.get("description", "")
self._download_url = package_data.get("download_url", "") # Not used yet, will be.
self._release_notes = package_data.get("release_notes", "") # Not used yet, propose to add to description?
author_data = package_data.get("author", {})
self._author_name = author_data.get("display_name", catalog.i18nc("@label:property", "Unknown Author"))
self._author_info_url = author_data.get("website", "")
self._section_title = section_title
# Note that there's a lot more info in the package_data than just these specified here.
@pyqtProperty(str, constant = True)
def packageId(self) -> str:
return self._package_id
@pyqtProperty(str, constant=True)
def iconUrl(self):
return self._icon_url
@pyqtProperty(str, constant = True)
def displayName(self) -> str:
return self._display_name
@pyqtProperty(bool, constant=True)
def isVerified(self):
return self._is_verified
@pyqtProperty(str, constant=True)
def packageVersion(self):
return self._package_version
@pyqtProperty(str, constant=True)
def packageInfoUrl(self):
return self._package_info_url
@pyqtProperty(int, constant=True)
def downloadCount(self):
return self._download_count
@pyqtProperty(str, constant=True)
def description(self):
return self._description
@pyqtProperty(str, constant=True)
def authorName(self):
return self._author_name
@pyqtProperty(str, constant=True)
def authorInfoUrl(self):
return self._author_info_url
@pyqtProperty(str, constant = True)
def sectionTitle(self) -> Optional[str]:
return self._section_title

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
<path d="M24,44,7,33.4V14.6L24,4,41,14.6V33.4ZM9,32.3l15,9.3,15-9.3V15.7L24,6.4,9,15.7Z"/>
</svg>

After

Width:  |  Height:  |  Size: 184 B

View File

@ -0,0 +1,351 @@
// Copyright (c) 2021 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.1
import UM 1.6 as UM
import Cura 1.6 as Cura
Rectangle
{
property var packageData
width: parent ? parent.width - UM.Theme.getSize("default_margin").width : 0
height: childrenRect.height
color: UM.Theme.getColor("main_background")
radius: UM.Theme.getSize("default_radius").width
states:
[
State
{
name: "Folded"
when: true // TODO
PropertyChanges
{
target: downloadCountRow
visible: false
}
PropertyChanges
{
target: descriptionArea
visible: true
}
},
State
{
name: "Header"
when: false // TODO
PropertyChanges
{
target: downloadCountRow
visible: true
}
PropertyChanges
{
target: descriptionArea
visible: false
}
}
]
RowLayout
{
width: parent.width - UM.Theme.getSize("thin_margin").width * 2
height: childrenRect.height + UM.Theme.getSize("thin_margin").height * 2
x: UM.Theme.getSize("thin_margin").width
y: UM.Theme.getSize("thin_margin").height
spacing: UM.Theme.getSize("default_margin").width
Image //Separate column for icon on the left.
{
Layout.preferredWidth: UM.Theme.getSize("card_icon").width
Layout.preferredHeight: UM.Theme.getSize("card_icon").height
Layout.alignment: Qt.AlignTop
source: packageData.iconUrl != "" ? packageData.iconUrl : "../images/placeholder.svg"
}
Column
{
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
RowLayout //Title row.
{
Layout.alignment: Qt.AlignTop
width: parent.width
Label
{
Layout.alignment: Qt.AlignTop
text: packageData.displayName
font: UM.Theme.getFont("medium_bold")
color: UM.Theme.getColor("text")
}
Row //Row inside row, but the non-layout version skips invisible elements.
{
spacing: parent.spacing
Layout.alignment: Qt.AlignTop
Control
{
width: UM.Theme.getSize("card_tiny_icon").width
height: UM.Theme.getSize("card_tiny_icon").height
Layout.alignment: Qt.AlignTop
enabled: packageData.isVerified
visible: packageData.isVerified
Cura.ToolTip
{
tooltipText: catalog.i18nc("@info", "Verified")
visible: parent.hovered
}
UM.RecolorImage
{
anchors.fill: parent
color: UM.Theme.getColor("primary")
source: UM.Theme.getIcon("CheckCircle")
}
//NOTE: Can we link to something here? (Probably a static link explaining what verified is):
// onClicked: Qt.openUrlExternally( XXXXXX )
}
Control
{
width: UM.Theme.getSize("card_tiny_icon").width
height: UM.Theme.getSize("card_tiny_icon").height
Layout.alignment: Qt.AlignTop
enabled: false // remove!
visible: false // replace packageInfo.XXXXXX
// TODO: waiting for materials card implementation
Cura.ToolTip
{
tooltipText: "" // TODO
visible: parent.hovered
}
UM.RecolorImage
{
anchors.fill: parent
color: UM.Theme.getColor("primary")
source: UM.Theme.getIcon("CheckCircle") // TODO
}
// onClicked: Qt.openUrlExternally( XXXXXX ) // TODO
}
}
Label
{
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
text: packageData.packageVersion
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
}
Button
{
id: externalLinkButton
Layout.preferredWidth: UM.Theme.getSize("card_tiny_icon").width
Layout.preferredHeight: UM.Theme.getSize("card_tiny_icon").height
Layout.alignment: Qt.AlignTop
Rectangle
{
anchors.fill: parent
color: externalLinkButton.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("detail_background")
UM.RecolorImage
{
anchors.fill: parent
color: externalLinkButton.hovered ? UM.Theme.getColor("text_link") : UM.Theme.getColor("text")
source: UM.Theme.getIcon("LinkExternal")
}
}
onClicked: Qt.openUrlExternally(packageData.packageInfoUrl)
}
}
RowLayout
{
id: downloadCountRow
width: childrenRect.width
height: childrenRect.height
x: UM.Theme.getSize("thin_margin").width
y: UM.Theme.getSize("thin_margin").height
spacing: UM.Theme.getSize("thin_margin").width
UM.RecolorImage
{
id: downloadCountIcon
width: UM.Theme.getSize("card_tiny_icon").width
height: UM.Theme.getSize("card_tiny_icon").height
color: UM.Theme.getColor("icon")
source: UM.Theme.getIcon("Download")
}
Label
{
id: downloadCountLabel
text: packageData.downloadCount
}
}
Item
{
id: descriptionArea
width: parent.width
height: descriptionLabel.height
Label
{
id: descriptionLabel
width: parent.width
property real lastLineWidth: 0; //Store the width of the last line, to properly position the elision.
text: packageData.description
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Text.ElideRight
onLineLaidOut:
{
if(truncated && line.isLast)
{
let max_line_width = parent.width - readMoreButton.width - fontMetrics.advanceWidth("… ") - UM.Theme.getSize("default_margin").width;
if(line.implicitWidth > max_line_width)
{
line.width = max_line_width;
}
else
{
line.width = line.implicitWidth - fontMetrics.advanceWidth("…"); //Truncate the ellipsis. We're adding this ourselves.
}
descriptionLabel.lastLineWidth = line.implicitWidth;
}
}
}
Cura.TertiaryButton
{
id: readMoreButton
anchors.right: parent.right
anchors.bottom: parent.bottom
height: fontMetrics.height //Height of a single line.
text: catalog.i18nc("@info", "Read more")
iconSource: UM.Theme.getIcon("LinkExternal")
visible: descriptionLabel.truncated
enabled: visible
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("wide_margin").width
textFont: descriptionLabel.font
isIconOnRightSide: true
// NOTE: Is this the right URL for this action?
onClicked: Qt.openUrlExternally(packageData.packageInfoUrl)
}
Label
{
anchors.left: parent.left
anchors.leftMargin: descriptionLabel.lastLineWidth
anchors.bottom: readMoreButton.bottom
text: "… "
font: descriptionLabel.font
color: descriptionLabel.color
visible: descriptionLabel.truncated
}
}
RowLayout //Author and action buttons.
{
width: parent.width
Layout.alignment: Qt.AlignTop
spacing: UM.Theme.getSize("thin_margin").width
Label
{
id: authorBy
Layout.alignment: Qt.AlignTop
text: catalog.i18nc("@label", "By")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
}
Cura.TertiaryButton
{
Layout.fillWidth: true
Layout.preferredHeight: authorBy.height
Layout.alignment: Qt.AlignTop
text: packageData.authorName
textFont: UM.Theme.getFont("default_bold")
textColor: UM.Theme.getColor("text") // override normal link color
leftPadding: 0
rightPadding: 0
iconSource: UM.Theme.getIcon("LinkExternal")
isIconOnRightSide: true
onClicked: Qt.openUrlExternally(packageData.authorInfoUrl)
}
Cura.SecondaryButton
{
id: disableButton
Layout.alignment: Qt.AlignTop
text: catalog.i18nc("@button", "Disable")
visible: false // not functional right now, also only when unfolding and required
}
Cura.SecondaryButton
{
id: uninstallButton
Layout.alignment: Qt.AlignTop
text: catalog.i18nc("@button", "Uninstall")
visible: false // not functional right now, also only when unfolding and required
}
Cura.PrimaryButton
{
id: installButton
Layout.alignment: Qt.AlignTop
text: catalog.i18nc("@button", "Update") // OR Download, if new!
visible: false // not functional right now, also only when unfolding and required
}
}
}
}
FontMetrics
{
id: fontMetrics
font: UM.Theme.getFont("medium")
}
}

View File

@ -46,24 +46,9 @@ ScrollView
}
}
delegate: Rectangle
delegate: PackageCard
{
width: packagesListview.width
height: UM.Theme.getSize("card").height
color: UM.Theme.getColor("main_background")
radius: UM.Theme.getSize("default_radius").width
Label
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: Math.round((parent.height - height) / 2)
text: model.package.displayName
font: UM.Theme.getFont("medium_bold")
color: UM.Theme.getColor("text")
}
packageData: model.package
}
//Wrapper item to add spacing between content and footer.

View File

@ -38,7 +38,7 @@ ToolTip
onAboutToHide: hide()
// If the text is not set, just set the height to 0 to prevent it from showing
height: text != "" ? label.contentHeight + 2 * UM.Theme.getSize("thin_margin").width: 0
height: label.contentHeight + 2 * UM.Theme.getSize("thin_margin").width
x:
{
@ -74,7 +74,7 @@ ToolTip
}
function show() {
opacity = 1
opacity = text != "" ? 1 : 0
}
function hide() {

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.707 10.293L12 17L5.293 10.293L6.707 8.8789L11 13.1719V3H13V13.1719L17.293 8.8789L18.707 10.293ZM21 19H3V21H21V19Z" fill="#000E1A"/>
</svg>

After

Width:  |  Height:  |  Size: 248 B

View File

@ -553,7 +553,10 @@
"standard_list_lineheight": [1.5, 1.5],
"standard_arrow": [1.0, 1.0],
"card": [25.0, 8.75],
"card_icon": [6.0, 6.0],
"card_tiny_icon": [1.2, 1.2],
"button": [4, 4],
"button_icon": [2.5, 2.5],