@@ -0,0 +1,213 @@
3+ property var cardData;
4+ property string artShapeStyle: "inset";
5+ property string backgroundShapeStyle: "inset";
6+ property real fontScale: 1.0;
7+ property var scopeStyle: null;
8+ property int fixedHeaderHeight: -1;
9+ property size fixedArtShapeSize: Qt.size(-1, -1);
10+ readonly property string title: cardData && cardData["title"] || "";
11+ property bool asynchronous: true;
12+ property bool showHeader: true;
13+ implicitWidth: childrenRect.width;
17+ id: backgroundLoader;
18+ objectName: "backgroundLoader";
19+ anchors.fill: parent;
20+ asynchronous: root.asynchronous;
21+ visible: status == Loader.Ready;
22+ sourceComponent: UbuntuShape {
23+ objectName: "background";
26+ switch (root.backgroundShapeStyle) {
27+ case "inset": return UbuntuShape.Inset;
28+ case "shadow": return UbuntuShape.DropShadow;
30+ case "flat": return UbuntuShape.Flat;
33+ backgroundColor: getColor(0) || "white";
34+ secondaryBackgroundColor: getColor(1) || backgroundColor;
35+ backgroundMode: UbuntuShape.VerticalGradient;
36+ anchors.fill: parent;
37+ source: backgroundImage.source ? backgroundImage : null;
38+ property real luminance: Style.luminance(backgroundColor);
39+ property Image backgroundImage: Image {
40+ objectName: "backgroundImage";
42+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
46+ function getColor(index) {
47+ if (cardData && typeof cardData["background"] === "object"
48+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
49+ return cardData["background"]["elements"][index];
50+ } else return index === 0 ? "#E9E9E9" : undefined;
54+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
57+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
58+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
59+ anchors { horizontalCenter: parent.horizontalCenter; }
62+ objectName: "artShapeLoader";
63+ readonly property string cardArt: cardData && cardData["art"] || "";
64+ active: cardArt != "";
65+ asynchronous: root.asynchronous;
66+ visible: status == Loader.Ready;
67+ sourceComponent: Item {
69+ objectName: "artShape";
70+ visible: image.status == Image.Ready;
71+ readonly property alias image: artImage;
74+ sourceItem: artImage;
75+ anchors.centerIn: parent;
81+ anchors.fill: parent;
83+ sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
85+ id: artShapeShapeComponent;
87+ source: artShapeSource;
88+ sourceFillMode: UbuntuShape.PreserveAspectCrop;
91+ switch (root.artShapeStyle) {
92+ case "inset": return UbuntuShape.Inset;
93+ case "shadow": return UbuntuShape.DropShadow;
95+ case "flat": return UbuntuShape.Flat;
101+ id: artShapeIconComponent;
102+ ProportionalShape { source: artShapeSource; aspect: UbuntuShape.DropShadow; }
105+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
106+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 1;
107+ Component.onCompleted: { updateWidthHeightBindings(); }
108+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
109+ function updateWidthHeightBindings() {
110+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
111+ width = root.fixedArtShapeSize.width;
112+ height = root.fixedArtShapeSize.height;
114+ width = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.width });
115+ height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });
118+ CroppedImageMinimumSourceSize {
120+ objectName: "artImage";
121+ source: artShapeLoader.cardArt;
122+ asynchronous: root.asynchronous;
124+ height: width / artShape.aspect;
129+readonly property int headerHeight: row.height;
132+ objectName: "outerRow";
133+ property real margins: units.gu(1);
135+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
136+ anchors { top: artShapeHolder.bottom;
137+ topMargin: units.gu(1);
140+ anchors.right: parent.right;
141+ anchors.margins: margins;
142+ anchors.rightMargin: 0;
144+ CroppedImageMinimumSourceSize {
146+ objectName: "mascotImage";
147+ anchors { verticalCenter: parent.verticalCenter; }
148+ source: cardData && cardData["mascot"] || "";
150+ height: units.gu(5.625);
151+ horizontalAlignment: Image.AlignHCenter;
152+ verticalAlignment: Image.AlignVCenter;
153+ visible: showHeader;
156+ id: headerTitleContainer;
157+ anchors { verticalCenter: parent.verticalCenter; }
158+ width: parent.width - x;
159+ implicitHeight: titleLabel.height + subtitleLabel.height;
163+ objectName: "titleLabel";
164+ anchors { right: parent.right;
165+rightMargin: units.gu(1);
168+ elide: Text.ElideRight;
170+ wrapMode: Text.Wrap;
171+ maximumLineCount: 2;
172+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
173+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
174+ visible: showHeader ;
177+ font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal;
178+ horizontalAlignment: Text.AlignLeft;
182+ objectName: "subtitleLabel";
183+ anchors { right: parent.right;
185+rightMargin: units.gu(1);
186+top: titleLabel.bottom;
188+ anchors.topMargin: units.dp(2);
189+ elide: Text.ElideRight;
190+ maximumLineCount: 1;
191+ fontSize: "x-small";
192+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
193+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
194+ visible: titleLabel.visible && titleLabel.text;
195+ text: cardData && cardData["subtitle"] || "";
196+ font.weight: Font.Light;
206+ objectName: "touchdown";
207+ anchors { fill: backgroundLoader }
208+ visible: root.artShapeStyle != "shadow" && root.artShapeStyle != "icon" && root.pressed;
210+ borderSource: "radius_pressed.sci"
212+implicitHeight: row.y + row.height + units.gu(1);