@@ -18,19 +18,19 @@
1818
1919function cardString(template, components) {
2020 var code;
21− code = 'AbstractButton { \
22− id: root; \
23− property var template; \
24− property var components; \
25− property var cardData; \
26− property real fontScale: 1.0; \
27− property int headerAlignment: Text.AlignLeft; \
28− property int fixedHeaderHeight: -1; \
29− property size fixedArtShapeSize: Qt.size(-1, -1); \
30− readonly property string title: cardData && cardData["title"] || ""; \
31− property bool asynchronous: true; \
32− property bool showHeader: true; \
33− implicitWidth: childrenRect.width; ';
21+ code = 'AbstractButton { \n\
22+ id: root; \n\
23+ property var template; \n\
24+ property var components; \n\
25+ property var cardData; \n\
26+ property real fontScale: 1.0; \n\
27+ property int headerAlignment: Text.AlignLeft; \n\
28+ property int fixedHeaderHeight: -1; \n\
29+ property size fixedArtShapeSize: Qt.size(-1, -1); \n\
30+ readonly property string title: cardData && cardData["title"] || ""; \n\
31+ property bool asynchronous: true; \n\
32+ property bool showHeader: true; \n\
33+ implicitWidth: childrenRect.width; \n';
3434
3535 var hasArt = components["art"] && components["art"]["field"] || false;
3636 var hasSummary = components["summary"] || false;
@@ -44,194 +44,194 @@ function cardString(template, components) {
4444 var hasHeaderRow = hasMascot && hasTitle;
4545
4646 if (hasBackground) {
47− code += 'Loader {\
48− id: backgroundLoader; \
49− objectName: "backgroundLoader"; \
50− anchors.fill: parent; \
51− asynchronous: root.asynchronous; \
52− visible: status == Loader.Ready; \
53− sourceComponent: UbuntuShape { \
54− objectName: "background"; \
55− radius: "medium"; \
56− color: getColor(0) || "white"; \
57− gradientColor: getColor(1) || color; \
58− anchors.fill: parent; \
59− image: backgroundImage.source ? backgroundImage : null; \
60− property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; \
61− property Image backgroundImage: Image { \
62− objectName: "backgroundImage"; \
63− source: { \
64− if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \
65− else if (template && typeof template["card-background"] === "string") return template["card-background"]; \
66− else return ""; \
67− } \
68− } \
69− function getColor(index) { \
70− if (cardData && typeof cardData["background"] === "object" \
71− && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \
72− return cardData["background"]["elements"][index]; \
73− } else if (template && typeof template["card-background"] === "object" \
74− && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) { \
75− return template["card-background"]["elements"][index]; \
76− } else return undefined; \
77− } \
78− } \
79− }';
47+ code += 'Loader {\n\
48+ id: backgroundLoader; \n\
49+ objectName: "backgroundLoader"; \n\
50+ anchors.fill: parent; \n\
51+ asynchronous: root.asynchronous; \n\
52+ visible: status == Loader.Ready; \n\
53+ sourceComponent: UbuntuShape { \n\
54+ objectName: "background"; \n\
55+ radius: "medium"; \n\
56+ color: getColor(0) || "white"; \n\
57+ gradientColor: getColor(1) || color; \n\
58+ anchors.fill: parent; \n\
59+ image: backgroundImage.source ? backgroundImage : null; \n\
60+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; \n\
61+ property Image backgroundImage: Image { \n\
62+ objectName: "backgroundImage"; \n\
63+ source: { \n\
64+ if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
65+ else if (template && typeof template["card-background"] === "string") return template["card-background"]; \n\
66+ else return ""; \n\
67+ } \n\
68+ } \n\
69+ function getColor(index) { \n\
70+ if (cardData && typeof cardData["background"] === "object" \n\
71+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
72+ return cardData["background"]["elements"][index]; \n\
73+ } else if (template && typeof template["card-background"] === "object" \n\
74+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) { \n\
75+ return template["card-background"]["elements"][index]; \n\
76+ } else return undefined; \n\
77+ } \n\
78+ } \n\
79+ }\n';
8080 }
8181
8282 if (hasArt) {
83− code += 'readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);'
83+ code += 'readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);\n'
8484 var imageWidthHeight;
8585 if (isHorizontal) {
8686 if (hasMascot || hasTitle) {
87− imageWidthHeight = 'width: height * artShape.aspect; \
88− height: headerHeight;'
87+ imageWidthHeight = 'width: height * artShape.aspect; \n\
88+ height: headerHeight;\n'
8989 } else {
9090 // This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
9191 // So we define a "random" height of the image height + 2 gu for the margins
92− imageWidthHeight = 'width: height * artShape.aspect; \
92+ imageWidthHeight = 'width: height * artShape.aspect; \n\
9393 height: units.gu(7.625)';
9494 }
9595 } else {
96− imageWidthHeight = 'width: root.width; \
97− height: width / artShape.aspect;'
96+ imageWidthHeight = 'width: root.width; \n\
97+ height: width / artShape.aspect;\n'
9898 }
99− code += 'Item { \
100− id: artShapeHolder; \
101− height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; \
102− width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; \
103− ' + (isHorizontal ? 'anchors.left: parent.left;' : 'anchors.horizontalCenter: parent.horizontalCenter;' ) + '\
104− Loader { \
105− id: artShapeLoader; \
106− objectName: "artShapeLoader"; \
107− active: cardData && cardData["art"] || false; \
108− asynchronous: root.asynchronous; \
109− visible: status == Loader.Ready; \
110− sourceComponent: UbuntuShape { \
111− id: artShape; \
112− objectName: "artShape"; \
113− radius: "medium"; \
114− readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; \
115− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \
116− Component.onCompleted: updateWidthHeightBindings(); \
117− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \
118− visible: image.status == Image.Ready; \
119− function updateWidthHeightBindings() { \
120− if (aspectSmallerThanImageAspect) { \
121− width = Qt.binding(function() { return !visible ? 0 : image.width }); \
122− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); \
123− } else { \
124− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); \
125− height = Qt.binding(function() { return !visible ? 0 : image.height }); \
126− } \
127− } \
128− image: Image { \
129− objectName: "artImage"; \
130− source: cardData && cardData["art"] || ""; \
131− cache: true; \
132− asynchronous: root.asynchronous; \
133− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; \
134− readonly property real aspect: implicitWidth / implicitHeight; \
135− ' + imageWidthHeight + '\
136− } \
137− } \
138− } \
139− }'
99+ code += 'Item { \n\
100+ id: artShapeHolder; \n\
101+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
102+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; \n\
103+ ' + (isHorizontal ? 'anchors.left: parent.left;' : 'anchors.horizontalCenter: parent.horizontalCenter;\n' ) + '\n\
104+ Loader { \n\
105+ id: artShapeLoader; \n\
106+ objectName: "artShapeLoader"; \n\
107+ active: cardData && cardData["art"] || false; \n\
108+ asynchronous: root.asynchronous; \n\
109+ visible: status == Loader.Ready; \n\
110+ sourceComponent: UbuntuShape { \n\
111+ id: artShape; \n\
112+ objectName: "artShape"; \n\
113+ radius: "medium"; \n\
114+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
115+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \n\
116+ Component.onCompleted: updateWidthHeightBindings(); \n\
117+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \n\
118+ visible: image.status == Image.Ready; \n\
119+ function updateWidthHeightBindings() { \n\
120+ if (aspectSmallerThanImageAspect) { \n\
121+ width = Qt.binding(function() { return !visible ? 0 : image.width }); \n\
122+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); \n\
123+ } else { \n\
124+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); \n\
125+ height = Qt.binding(function() { return !visible ? 0 : image.height }); \n\
126+ } \n\
127+ } \n\
128+ image: Image { \n\
129+ objectName: "artImage"; \n\
130+ source: cardData && cardData["art"] || ""; \n\
131+ cache: true; \n\
132+ asynchronous: root.asynchronous; \n\
133+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; \n\
134+ readonly property real aspect: implicitWidth / implicitHeight; \n\
135+ ' + imageWidthHeight + '\n\
136+ } \n\
137+ } \n\
138+ } \n\
139+ }\n'
140140 } else {
141− code += 'readonly property size artShapeSize: Qt.size(-1, -1);'
141+ code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
142142 }
143143
144144 if (inOverlay) {
145− var height = 'fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight;';
146− code += 'Loader { \
147− id: overlayLoader; \
148− anchors { \
149− left: artShapeHolder.left; \
150− right: artShapeHolder.right; \
151− bottom: artShapeHolder.bottom; \
152− } \
153− active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \
154− asynchronous: root.asynchronous; \
155− visible: showHeader && status == Loader.Ready; \
156− sourceComponent: ShaderEffect { \
157− id: overlay; \
158− height: ' + height + ' \
159− opacity: 0.6; \
160− property var source: ShaderEffectSource { \
161− id: shaderSource; \
162− sourceItem: artShapeLoader.item; \
163− onVisibleChanged: if (visible) scheduleUpdate(); \
164− live: false; \
165− sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height); \
166− } \
167− vertexShader: " \
168− uniform highp mat4 qt_Matrix; \
169− attribute highp vec4 qt_Vertex; \
170− attribute highp vec2 qt_MultiTexCoord0; \
171− varying highp vec2 coord; \
172− void main() { \
173− coord = qt_MultiTexCoord0; \
174− gl_Position = qt_Matrix * qt_Vertex; \
175− }"; \
176− fragmentShader: " \
177− varying highp vec2 coord; \
178− uniform sampler2D source; \
179− uniform lowp float qt_Opacity; \
180− void main() { \
181− lowp vec4 tex = texture2D(source, coord); \
182− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; \
183− }"; \
184− } \
185− }';
145+ var height = 'fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight;\n';
146+ code += 'Loader { \n\
147+ id: overlayLoader; \n\
148+ anchors { \n\
149+ left: artShapeHolder.left; \n\
150+ right: artShapeHolder.right; \n\
151+ bottom: artShapeHolder.bottom; \n\
152+ } \n\
153+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \n\
154+ asynchronous: root.asynchronous; \n\
155+ visible: showHeader && status == Loader.Ready; \n\
156+ sourceComponent: ShaderEffect { \n\
157+ id: overlay; \n\
158+ height: ' + height + ' \n\
159+ opacity: 0.6; \n\
160+ property var source: ShaderEffectSource { \n\
161+ id: shaderSource; \n\
162+ sourceItem: artShapeLoader.item; \n\
163+ onVisibleChanged: if (visible) scheduleUpdate(); \n\
164+ live: false; \n\
165+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height); \n\
166+ } \n\
167+ vertexShader: " \n\
168+ uniform highp mat4 qt_Matrix; \n\
169+ attribute highp vec4 qt_Vertex; \n\
170+ attribute highp vec2 qt_MultiTexCoord0; \n\
171+ varying highp vec2 coord; \n\
172+ void main() { \n\
173+ coord = qt_MultiTexCoord0; \n\
174+ gl_Position = qt_Matrix * qt_Vertex; \n\
175+ }"; \n\
176+ fragmentShader: " \n\
177+ varying highp vec2 coord; \n\
178+ uniform sampler2D source; \n\
179+ uniform lowp float qt_Opacity; \n\
180+ void main() { \n\
181+ lowp vec4 tex = texture2D(source, coord); \n\
182+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; \n\
183+ }"; \n\
184+ } \n\
185+ }\n';
186186 }
187187
188188 var headerVerticalAnchors;
189189 if (inOverlay) {
190− headerVerticalAnchors = 'anchors.bottom: artShapeHolder.bottom; \
191− anchors.bottomMargin: units.gu(1);';
190+ headerVerticalAnchors = 'anchors.bottom: artShapeHolder.bottom; \n\
191+ anchors.bottomMargin: units.gu(1);\n';
192192 } else {
193193 if (hasArt) {
194194 if (isHorizontal) {
195− headerVerticalAnchors = 'anchors.top: artShapeHolder.top; \
196− anchors.topMargin: units.gu(1);';
195+ headerVerticalAnchors = 'anchors.top: artShapeHolder.top; \n\
196+ anchors.topMargin: units.gu(1);\n';
197197 } else {
198− headerVerticalAnchors = 'anchors.top: artShapeHolder.bottom; \
199− anchors.topMargin: units.gu(1);';
198+ headerVerticalAnchors = 'anchors.top: artShapeHolder.bottom; \n\
199+ anchors.topMargin: units.gu(1);\n';
200200 }
201201 } else {
202− headerVerticalAnchors = 'anchors.top: parent.top; \
203− anchors.topMargin: units.gu(1);';
202+ headerVerticalAnchors = 'anchors.top: parent.top; \n\
203+ anchors.topMargin: units.gu(1);\n';
204204 }
205205 }
206206 var headerLeftAnchor;
207207 var headerLeftAnchorHasMagin = false;
208208 if (isHorizontal && hasArt) {
209− headerLeftAnchor = 'anchors.left: artShapeHolder.right; \
210− anchors.leftMargin: units.gu(1);';
209+ headerLeftAnchor = 'anchors.left: artShapeHolder.right; \n\
210+ anchors.leftMargin: units.gu(1);\n';
211211 headerLeftAnchorHasMagin = true;
212212 } else {
213− headerLeftAnchor = 'anchors.left: parent.left;';
213+ headerLeftAnchor = 'anchors.left: parent.left;\n';
214214 }
215215
216216 if (hasHeaderRow) {
217− code += 'readonly property int headerHeight: row.height + row.margins * 2;'
218− code += 'Row { \
219− id: row; \
220− objectName: "outerRow"; \
221− property real margins: units.gu(1); \
222− spacing: margins; \
223− ' + headerVerticalAnchors + '\
224− ' + headerLeftAnchor + '\
225− anchors.right: parent.right; \
226− anchors.margins: margins;';
217+ code += 'readonly property int headerHeight: row.height + row.margins * 2;\n'
218+ code += 'Row { \n\
219+ id: row; \n\
220+ objectName: "outerRow"; \n\
221+ property real margins: units.gu(1); \n\
222+ spacing: margins; \n\
223+ ' + headerVerticalAnchors + '\n\
224+ ' + headerLeftAnchor + '\n\
225+ anchors.right: parent.right; \n\
226+ anchors.margins: margins;\n';
227227 } else if (hasMascot) {
228− code += 'readonly property int headerHeight: mascotImage.height + units.gu(1) * 2;'
228+ code += 'readonly property int headerHeight: mascotImage.height + units.gu(1) * 2;\n'
229229 } else if (hasSubtitle) {
230− code += 'readonly property int headerHeight: subtitleLabel.y + subtitleLabel.height - titleLabel.y + titleLabel.anchors.topMargin * 2 + subtitleLabel.anchors.topMargin;'
230+ code += 'readonly property int headerHeight: subtitleLabel.y + subtitleLabel.height - titleLabel.y + titleLabel.anchors.topMargin * 2 + subtitleLabel.anchors.topMargin;\n'
231231 } else if (hasTitle) {
232− code += 'readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;'
232+ code += 'readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;\n'
233233 } else {
234− code += 'readonly property int headerHeight: 0;'
234+ code += 'readonly property int headerHeight: 0;\n'
235235 }
236236
237237 if (hasMascot) {
@@ -241,40 +241,40 @@ function cardString(template, components) {
241241 anchors += headerLeftAnchor;
242242 anchors += headerVerticalAnchors;
243243 if (!headerLeftAnchorHasMagin) {
244− anchors += 'anchors.leftMargin: units.gu(1);'
244+ anchors += 'anchors.leftMargin: units.gu(1);\n'
245245 }
246246 } else {
247247 anchors = "anchors.verticalCenter: parent.verticalCenter;"
248248 }
249249
250250 if (useMascotShape) {
251− code += 'Loader { \
252− id: mascotShapeLoader; \
253− objectName: "mascotShapeLoader"; \
254− asynchronous: root.asynchronous; \
255− active: mascotImage.status === Image.Ready; \
256− visible: showHeader && active && status == Loader.Ready; \
257− width: units.gu(6); \
258− height: units.gu(5.625); \
259− sourceComponent: UbuntuShape { image: mascotImage } \
260− ' + anchors + '\
261− }';
251+ code += 'Loader { \n\
252+ id: mascotShapeLoader; \n\
253+ objectName: "mascotShapeLoader"; \n\
254+ asynchronous: root.asynchronous; \n\
255+ active: mascotImage.status === Image.Ready; \n\
256+ visible: showHeader && active && status == Loader.Ready; \n\
257+ width: units.gu(6); \n\
258+ height: units.gu(5.625); \n\
259+ sourceComponent: UbuntuShape { image: mascotImage } \n\
260+ ' + anchors + '\n\
261+ }\n';
262262 }
263263
264− code += 'Image { \
265− id: mascotImage; \
266− objectName: "mascotImage"; \
267− ' + anchors + '\
268− readonly property int maxSize: Math.max(width, height) * 4; \
269− source: cardData && cardData["mascot"]; \
270− width: units.gu(6); \
271− height: units.gu(5.625); \
272− sourceSize { width: maxSize; height: maxSize } \
273− fillMode: Image.PreserveAspectCrop; \
274− horizontalAlignment: Image.AlignHCenter; \
275− verticalAlignment: Image.AlignVCenter; \
276− visible: showHeader && ' + (useMascotShape ? 'false' : 'true') + '; \
277− }';
264+ code += 'Image { \n\
265+ id: mascotImage; \n\
266+ objectName: "mascotImage"; \n\
267+ ' + anchors + '\n\
268+ readonly property int maxSize: Math.max(width, height) * 4; \n\
269+ source: cardData && cardData["mascot"]; \n\
270+ width: units.gu(6); \n\
271+ height: units.gu(5.625); \n\
272+ sourceSize { width: maxSize; height: maxSize } \n\
273+ fillMode: Image.PreserveAspectCrop; \n\
274+ horizontalAlignment: Image.AlignHCenter; \n\
275+ verticalAlignment: Image.AlignVCenter; \n\
276+ visible: showHeader && ' + (useMascotShape ? 'false' : 'true') + '; \n\
277+ }\n';
278278 }
279279
280280 var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey"';
@@ -294,81 +294,81 @@ function cardString(template, components) {
294294 var titleAnchors = "";
295295 var subtitleAnchors = "";
296296 if (hasMascot && hasSubtitle) {
297− titleAnchors = 'anchors { left: parent.left; right: parent.right }';
297+ titleAnchors = 'anchors { left: parent.left; right: parent.right }\n';
298298 subtitleAnchors = titleAnchors;
299− code += 'Column { \
300− anchors.verticalCenter: parent.verticalCenter; \
301− spacing: units.dp(2); \
302− width: parent.width - x;';
299+ code += 'Column { \n\
300+ anchors.verticalCenter: parent.verticalCenter; \n\
301+ spacing: units.dp(2); \n\
302+ width: parent.width - x;\n';
303303 } else if (hasMascot) {
304− titleAnchors = 'anchors.verticalCenter: parent.verticalCenter;'
304+ titleAnchors = 'anchors.verticalCenter: parent.verticalCenter;\n'
305305 } else if (inOverlay) {
306− titleAnchors = 'anchors.left: parent.left; \
307− anchors.leftMargin: units.gu(1); \
308− anchors.right: parent.right; \
309− anchors.top: overlayLoader.top; \
310− anchors.topMargin: units.gu(1);';
311− subtitleAnchors = 'anchors.left: titleLabel.left; \
312− anchors.leftMargin: titleLabel.leftMargin; \
313− anchors.right: titleLabel.right; \
314− anchors.top: titleLabel.bottom; \
315− anchors.topMargin: units.dp(2);';
306+ titleAnchors = 'anchors.left: parent.left; \n\
307+ anchors.leftMargin: units.gu(1); \n\
308+ anchors.right: parent.right; \n\
309+ anchors.top: overlayLoader.top; \n\
310+ anchors.topMargin: units.gu(1);\n';
311+ subtitleAnchors = 'anchors.left: titleLabel.left; \n\
312+ anchors.leftMargin: titleLabel.leftMargin; \n\
313+ anchors.right: titleLabel.right; \n\
314+ anchors.top: titleLabel.bottom; \n\
315+ anchors.topMargin: units.dp(2);\n';
316316 } else {
317317 titleAnchors = "anchors.right: parent.right;";
318318 if (hasMascot) {
319− titleAnchors += 'anchors.left: mascotImage.right; \
320− anchors.leftMargin: units.gu(1);';
319+ titleAnchors += 'anchors.left: mascotImage.right; \n\
320+ anchors.leftMargin: units.gu(1);\n';
321321 } else {
322322 titleAnchors += headerLeftAnchor;
323323 }
324324 titleAnchors += headerVerticalAnchors;
325− subtitleAnchors = 'anchors.left: titleLabel.left; \
326− anchors.leftMargin: titleLabel.leftMargin; \
327− anchors.right: titleLabel.right; \
328− anchors.top: titleLabel.bottom; \
329− anchors.topMargin: units.dp(2);';
325+ subtitleAnchors = 'anchors.left: titleLabel.left; \n\
326+ anchors.leftMargin: titleLabel.leftMargin; \n\
327+ anchors.right: titleLabel.right; \n\
328+ anchors.top: titleLabel.bottom; \n\
329+ anchors.topMargin: units.dp(2);\n';
330330 }
331331
332− code += 'Label { \
333− id: titleLabel; \
334− objectName: "titleLabel"; \
335− ' + titleAnchors + '\
336− elide: Text.ElideRight; \
337− fontSize: "small"; \
338− wrapMode: Text.Wrap; \
339− maximumLineCount: 2; \
340− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \
341− color: ' + color + '; \
342− visible: showHeader ' + (inOverlay ? '&& overlayLoader.active': '') + '; \
343− text: root.title; \
344− font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; \
345− horizontalAlignment: root.headerAlignment; \
346− }';
332+ code += 'Label { \n\
333+ id: titleLabel; \n\
334+ objectName: "titleLabel"; \n\
335+ ' + titleAnchors + '\n\
336+ elide: Text.ElideRight; \n\
337+ fontSize: "small"; \n\
338+ wrapMode: Text.Wrap; \n\
339+ maximumLineCount: 2; \n\
340+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\
341+ color: ' + color + '; \n\
342+ visible: showHeader ' + (inOverlay ? '&& overlayLoader.active': '') + '; \n\
343+ text: root.title; \n\
344+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; \n\
345+ horizontalAlignment: root.headerAlignment; \n\
346+ }\n';
347347
348348 if (hasSubtitle) {
349− code += 'Label { \
350− id: subtitleLabel; \
351− objectName: "subtitleLabel"; \
352− ' + subtitleAnchors + '\
353− elide: Text.ElideRight; \
354− fontSize: "small"; \
355− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \
356− color: ' + color + '; \
357− visible: titleLabel.visible && titleLabel.text; \
358− text: cardData && cardData["subtitle"] || ""; \
359− font.weight: Font.Light; \
360− horizontalAlignment: root.headerAlignment; \
361− }';
349+ code += 'Label { \n\
350+ id: subtitleLabel; \n\
351+ objectName: "subtitleLabel"; \n\
352+ ' + subtitleAnchors + '\n\
353+ elide: Text.ElideRight; \n\
354+ fontSize: "small"; \n\
355+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\
356+ color: ' + color + '; \n\
357+ visible: titleLabel.visible && titleLabel.text; \n\
358+ text: cardData && cardData["subtitle"] || ""; \n\
359+ font.weight: Font.Light; \n\
360+ horizontalAlignment: root.headerAlignment; \n\
361+ }\n';
362362
363363 // Close Column
364364 if (hasMascot)
365− code += '}';
365+ code += '}\n';
366366 }
367367 }
368368
369369 if (hasHeaderRow) {
370370 // Close Row
371− code += '}';
371+ code += '}\n';
372372 }
373373
374374 if (hasSummary) {
@@ -387,48 +387,48 @@ function cardString(template, components) {
387387 } else {
388388 color = '"grey"';
389389 }
390− code += 'Label { \
391− id: summary; \
392− objectName: "summaryLabel"; \
393− anchors { \
394− top: ' + summaryTopAnchor + '; \
395− left: parent.left; \
396− right: parent.right; \
397− margins: units.gu(1); \
398− topMargin: ' + (hasMascot || hasSubtitle ? 'anchors.margins' : 0) + '; \
399− } \
400− wrapMode: Text.Wrap; \
401− maximumLineCount: 5; \
402− elide: Text.ElideRight; \
403− text: cardData && cardData["summary"] || ""; \
404− height: text ? implicitHeight : 0; \
405− fontSize: "small"; \
406− color: ' + color + '; \
407− }';
390+ code += 'Label { \n\
391+ id: summary; \n\
392+ objectName: "summaryLabel"; \n\
393+ anchors { \n\
394+ top: ' + summaryTopAnchor + '; \n\
395+ left: parent.left; \n\
396+ right: parent.right; \n\
397+ margins: units.gu(1); \n\
398+ topMargin: ' + (hasMascot || hasSubtitle ? 'anchors.margins' : 0) + '; \n\
399+ } \n\
400+ wrapMode: Text.Wrap; \n\
401+ maximumLineCount: 5; \n\
402+ elide: Text.ElideRight; \n\
403+ text: cardData && cardData["summary"] || ""; \n\
404+ height: text ? implicitHeight : 0; \n\
405+ fontSize: "small"; \n\
406+ color: ' + color + '; \n\
407+ }\n';
408408 }
409409
410410 // Close the AbstractButton
411411 if (hasSummary) {
412− code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);';
412+ code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n';
413413 } else if (hasHeaderRow) {
414− code += 'implicitHeight: row.y + row.height + units.gu(1);';
414+ code += 'implicitHeight: row.y + row.height + units.gu(1);\n';
415415 } else if (hasMascot) {
416− code += 'implicitHeight: mascotImage.y + mascotImage.height;';
416+ code += 'implicitHeight: mascotImage.y + mascotImage.height;\n';
417417 } else if (hasSubtitle) {
418− code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);';
418+ code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
419419 } else if (hasTitle) {
420− code += 'implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);';
420+ code += 'implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);\n';
421421 }
422− code += '}';
422+ code += '}\n';
423423
424424 return code;
425425}
426426
427427function createCardComponent(parent, template, components) {
428− var imports = 'import QtQuick 2.2; \
429− import Ubuntu.Components 0.1; \
430− import Ubuntu.Thumbnailer 0.1;';
428+ var imports = 'import QtQuick 2.2; \n\
429+ import Ubuntu.Components 0.1; \n\
430+ import Ubuntu.Thumbnailer 0.1;\n';
431431 var card = cardString(template, components);
432− var code = imports + 'Component {' + card + '}';
432+ var code = imports + 'Component {\n' + card + '}\n';
433433 return Qt.createQmlObject(code, parent, "createCardComponent");
434434}