@@ -13,63 +13,110 @@ AbstractButton {
1313 property bool asynchronous: true;
1414 property bool showHeader: true;
1515 implicitWidth: childrenRect.width;
16−onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
17−readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
18−Item {
19− id: artShapeHolder;
20− height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
21− width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
22− anchors { horizontalCenter: parent.horizontalCenter; }
23− Loader {
24− id: artShapeLoader;
25− objectName: "artShapeLoader";
26− active: cardData && cardData["art"] || false;
27− asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
29− sourceComponent: UbuntuShape {
30− id: artShape;
31− objectName: "artShape";
32− radius: "medium";
33− visible: image.status == Image.Ready;
34− readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39− Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40− function updateWidthHeightBindings() {
41− if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42− width = root.fixedArtShapeSize.width;
43− height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47− } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
50− }
16+Loader {
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";
24+ radius: "medium";
25+ color: getColor(0) || "white";
26+ gradientColor: getColor(1) || color;
27+ anchors.fill: parent;
28+ image: backgroundImage.source ? backgroundImage : null;
29+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
30+ property Image backgroundImage: Image {
31+ objectName: "backgroundImage";
32+ source: {
33+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
34+ else if (template && typeof template["card-background"] === "string") return template["card-background"];
35+ else return "";
36+ }
37+ }
38+ function getColor(index) {
39+ if (cardData && typeof cardData["background"] === "object"
40+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
41+ return cardData["background"]["elements"][index];
42+ } else if (template && typeof template["card-background"] === "object"
43+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
44+ return template["card-background"]["elements"][index];
45+ } else return undefined;
46+ }
47+ }
5148 }
52− image: Image {
53− objectName: "artImage";
54− source: cardData && cardData["art"] || "";
55− cache: true;
56− asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59− width: root.width;
60− height: width / artShape.aspect;
61− }
62− }
49+readonly property size artShapeSize: Qt.size(-1, -1);
50+readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
51+Item {
52+ id: headerTitleContainer;
53+ anchors { right: parent.right; left: parent.left;
54+ top: parent.top;
55+ topMargin: units.gu(1);
56+ leftMargin: units.gu(1);
57+ }
58+ width: parent.width - x;
59+ implicitHeight: titleLabel.height + subtitleLabel.height;
60+ data: [
61+ Label {
62+ id: titleLabel;
63+ objectName: "titleLabel";
64+ anchors { right: emblemImage.left;
65+ rightMargin: units.gu(0.5);
66+ left: parent.left;
67+ top: parent.top; }
68+ elide: Text.ElideRight;
69+ fontSize: "small";
70+ wrapMode: Text.Wrap;
71+ maximumLineCount: 2;
72+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
73+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
74+ visible: showHeader ;
75+ text: root.title;
76+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
77+ horizontalAlignment: root.headerAlignment;
6378 }
64− }
65−readonly property int headerHeight: 0;
79+,Label {
80+ id: subtitleLabel;
81+ objectName: "subtitleLabel";
82+ anchors { right: parent.right;
83+ left: parent.left;
84+ rightMargin: units.gu(1);
85+ top: titleLabel.bottom;
86+ }
87+ anchors.topMargin: units.dp(2);
88+ elide: Text.ElideRight;
89+ fontSize: "small";
90+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
91+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
92+ visible: titleLabel.visible && titleLabel.text;
93+ text: cardData && cardData["subtitle"] || "";
94+ font.weight: Font.Light;
95+ horizontalAlignment: root.headerAlignment;
96+ }
97+,Image {
98+ id: emblemImage;
99+ objectName: "emblemImage";
100+ anchors {
101+ bottom: titleLabel.baseline;
102+ right: parent.right;
103+ rightMargin: units.gu(1);
104+ }
105+ source: cardData["emblem"];
106+ width: height;
107+ height: titleLabel.font.pixelSize;
108+ fillMode: Image.PreserveAspectFit;
109+ }
110+
111+ ]
112+ }
66113UbuntuShape {
67114 id: touchdown;
68115 objectName: "touchdown";
69− anchors { fill: artShapeHolder }
116+ anchors { fill: backgroundLoader }
70117 visible: root.pressed;
71118 radius: "medium";
72119 borderSource: "radius_pressed.sci"
73120}
74−implicitHeight: artShapeHolder.height;
121+implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
75122}