Cura/plugins/Marketplace/resources/qml/Packages.qml
Ghostkeeper 61fdd5dc72
Restore check for parent before getting its width
Delegates that are outside of the viewport may have no parent any more. Don't attempt to find their parents' width.

Contributes to issue CURA-8565.
2021-11-29 16:32:55 +01:00

225 lines
7.5 KiB
QML

// 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 UM 1.4 as UM
ListView
{
id: packages
width: parent.width
property string pageTitle
property var selectedPackage
clip: true
Component.onCompleted: model.updatePackages()
Component.onDestruction: model.abortUpdating()
//ScrollBar.vertical.policy: ScrollBar.AlwaysOff
spacing: UM.Theme.getSize("default_margin").height
section.property: "package.sectionTitle"
section.delegate: Rectangle
{
width: packages.width
height: sectionHeaderText.height + UM.Theme.getSize("default_margin").height
color: UM.Theme.getColor("detail_background")
required property string section
Label
{
id: sectionHeaderText
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
text: parent.section
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
}
}
ScrollBar.vertical: ScrollBar
{
// Vertical ScrollBar, styled similarly to the scrollBar in the settings panel
id: verticalScrollBar
visible: packages.contentHeight > packages.height
background: Item{}
contentItem: Rectangle
{
id: scrollViewHandle
implicitWidth: UM.Theme.getSize("scrollbar").width
radius: Math.round(implicitWidth / 2)
color: verticalScrollBar.pressed ? UM.Theme.getColor("scrollbar_handle_down") : verticalScrollBar.hovered ? UM.Theme.getColor("scrollbar_handle_hover") : UM.Theme.getColor("scrollbar_handle")
Behavior on color { ColorAnimation { duration: 50; } }
}
}
delegate: MouseArea
{
width: parent ? parent.width : 0
height: childrenRect.height
onClicked:
{
packages.selectedPackage = model.package;
contextStack.push(packageDetailsComponent);
}
PackageCard
{
packageData: model.package
width: parent.width - UM.Theme.getSize("default_margin").width - UM.Theme.getSize("narrow_margin").width
}
}
Component
{
id: packageDetailsComponent
PackageDetails
{
packageData: packages.selectedPackage
}
}
//Wrapper item to add spacing between content and footer.
footer: Item
{
width: parent.width - UM.Theme.getSize("default_margin").width - UM.Theme.getSize("narrow_margin").width
height: model.hasFooter || packages.model.errorMessage != "" ? UM.Theme.getSize("card").height + packages.spacing : 0
visible: model.hasFooter || packages.model.errorMessage != ""
Button
{
id: loadMoreButton
width: parent.width
height: UM.Theme.getSize("card").height
anchors.bottom: parent.bottom
enabled: packages.model.hasMore && !packages.model.isLoading || packages.model.errorMessage != ""
onClicked: packages.model.updatePackages() //Load next page in plug-in list.
background: Rectangle
{
anchors.fill: parent
radius: UM.Theme.getSize("default_radius").width
color: UM.Theme.getColor("main_background")
}
Row
{
anchors.centerIn: parent
spacing: UM.Theme.getSize("thin_margin").width
states:
[
State
{
name: "Error"
when: packages.model.errorMessage != ""
PropertyChanges
{
target: errorIcon
visible: true
}
PropertyChanges
{
target: loadMoreIcon
visible: false
}
PropertyChanges
{
target: loadMoreLabel
text: catalog.i18nc("@button", "Failed to load packages:") + " " + packages.model.errorMessage + "\n" + catalog.i18nc("@button", "Retry?")
}
},
State
{
name: "Loading"
when: packages.model.isLoading
PropertyChanges
{
target: loadMoreIcon
source: UM.Theme.getIcon("ArrowDoubleCircleRight")
color: UM.Theme.getColor("action_button_disabled_text")
}
PropertyChanges
{
target: loadMoreLabel
text: catalog.i18nc("@button", "Loading")
color: UM.Theme.getColor("action_button_disabled_text")
}
},
State
{
name: "LastPage"
when: !packages.model.hasMore
PropertyChanges
{
target: loadMoreIcon
visible: false
}
PropertyChanges
{
target: loadMoreLabel
text: packages.model.count > 0 ? catalog.i18nc("@message", "No more results to load") : catalog.i18nc("@message", "No results found with current filter")
color: UM.Theme.getColor("action_button_disabled_text")
}
}
]
Item
{
width: (errorIcon.visible || loadMoreIcon.visible) ? UM.Theme.getSize("small_button_icon").width : 0
height: UM.Theme.getSize("small_button_icon").height
anchors.verticalCenter: loadMoreLabel.verticalCenter
UM.StatusIcon
{
id: errorIcon
anchors.fill: parent
status: UM.StatusIcon.Status.ERROR
visible: false
}
UM.RecolorImage
{
id: loadMoreIcon
anchors.fill: parent
source: UM.Theme.getIcon("ArrowDown")
color: UM.Theme.getColor("secondary_button_text")
RotationAnimator
{
target: loadMoreIcon
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
running: packages.model.isLoading
alwaysRunToEnd: true
}
}
}
Label
{
id: loadMoreLabel
text: catalog.i18nc("@button", "Load more")
font: UM.Theme.getFont("medium_bold")
color: UM.Theme.getColor("secondary_button_text")
}
}
}
}
}