on xenial help sign in
Add newlines, makes debugging the code when it fails easier
01b778cAlbert Astals
plugins/Dash/CardCreator.js+267−267
@@ -18,19 +18,19 @@
18
18
19function cardString(template, components) {
19function cardString(template, components) {
20 var code;
20 var code;
21− code = 'AbstractButton { \
21+ code = 'AbstractButton { \n\
22− id: root; \
22+ id: root; \n\
23− property var template; \
23+ property var template; \n\
24− property var components; \
24+ property var components; \n\
25− property var cardData; \
25+ property var cardData; \n\
26− property real fontScale: 1.0; \
26+ property real fontScale: 1.0; \n\
27− property int headerAlignment: Text.AlignLeft; \
27+ property int headerAlignment: Text.AlignLeft; \n\
28− property int fixedHeaderHeight: -1; \
28+ property int fixedHeaderHeight: -1; \n\
29− property size fixedArtShapeSize: Qt.size(-1, -1); \
29+ property size fixedArtShapeSize: Qt.size(-1, -1); \n\
30− readonly property string title: cardData && cardData["title"] || ""; \
30+ readonly property string title: cardData && cardData["title"] || ""; \n\
31− property bool asynchronous: true; \
31+ property bool asynchronous: true; \n\
32− property bool showHeader: true; \
32+ property bool showHeader: true; \n\
33− implicitWidth: childrenRect.width; ';
33+ implicitWidth: childrenRect.width; \n';
34
34
35 var hasArt = components["art"] && components["art"]["field"] || false;
35 var hasArt = components["art"] && components["art"]["field"] || false;
36 var hasSummary = components["summary"] || false;
36 var hasSummary = components["summary"] || false;
@@ -44,194 +44,194 @@ function cardString(template, components) {
44 var hasHeaderRow = hasMascot && hasTitle;
44 var hasHeaderRow = hasMascot && hasTitle;
45
45
46 if (hasBackground) {
46 if (hasBackground) {
47− code += 'Loader {\
47+ code += 'Loader {\n\
48− id: backgroundLoader; \
48+ id: backgroundLoader; \n\
49− objectName: "backgroundLoader"; \
49+ objectName: "backgroundLoader"; \n\
50− anchors.fill: parent; \
50+ anchors.fill: parent; \n\
51− asynchronous: root.asynchronous; \
51+ asynchronous: root.asynchronous; \n\
52− visible: status == Loader.Ready; \
52+ visible: status == Loader.Ready; \n\
53− sourceComponent: UbuntuShape { \
53+ sourceComponent: UbuntuShape { \n\
54− objectName: "background"; \
54+ objectName: "background"; \n\
55− radius: "medium"; \
55+ radius: "medium"; \n\
56− color: getColor(0) || "white"; \
56+ color: getColor(0) || "white"; \n\
57− gradientColor: getColor(1) || color; \
57+ gradientColor: getColor(1) || color; \n\
58− anchors.fill: parent; \
58+ anchors.fill: parent; \n\
59− image: backgroundImage.source ? backgroundImage : null; \
59+ image: backgroundImage.source ? backgroundImage : null; \n\
60− property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; \
60+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; \n\
61− property Image backgroundImage: Image { \
61+ property Image backgroundImage: Image { \n\
62− objectName: "backgroundImage"; \
62+ objectName: "backgroundImage"; \n\
63− source: { \
63+ source: { \n\
64− if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \
64+ if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
65− else if (template && typeof template["card-background"] === "string") return template["card-background"]; \
65+ else if (template && typeof template["card-background"] === "string") return template["card-background"]; \n\
66− else return ""; \
66+ else return ""; \n\
67− } \
67+ } \n\
68− } \
68+ } \n\
69− function getColor(index) { \
69+ function getColor(index) { \n\
70− if (cardData && typeof cardData["background"] === "object" \
70+ if (cardData && typeof cardData["background"] === "object" \n\
71− && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \
71+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
72− return cardData["background"]["elements"][index]; \
72+ return cardData["background"]["elements"][index]; \n\
73− } else if (template && typeof template["card-background"] === "object" \
73+ } else if (template && typeof template["card-background"] === "object" \n\
74− && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) { \
74+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) { \n\
75− return template["card-background"]["elements"][index]; \
75+ return template["card-background"]["elements"][index]; \n\
76− } else return undefined; \
76+ } else return undefined; \n\
77− } \
77+ } \n\
78− } \
78+ } \n\
79− }';
79+ }\n';
80 }
80 }
81
81
82 if (hasArt) {
82 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'
84 var imageWidthHeight;
84 var imageWidthHeight;
85 if (isHorizontal) {
85 if (isHorizontal) {
86 if (hasMascot || hasTitle) {
86 if (hasMascot || hasTitle) {
87− imageWidthHeight = 'width: height * artShape.aspect; \
87+ imageWidthHeight = 'width: height * artShape.aspect; \n\
88− height: headerHeight;'
88+ height: headerHeight;\n'
89 } else {
89 } else {
90 // This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
90 // This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
91 // So we define a "random" height of the image height + 2 gu for the margins
91 // 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\
93 height: units.gu(7.625)';
93 height: units.gu(7.625)';
94 }
94 }
95 } else {
95 } else {
96− imageWidthHeight = 'width: root.width; \
96+ imageWidthHeight = 'width: root.width; \n\
97− height: width / artShape.aspect;'
97+ height: width / artShape.aspect;\n'
98 }
98 }
99− code += 'Item { \
99+ code += 'Item { \n\
100− id: artShapeHolder; \
100+ id: artShapeHolder; \n\
101− height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; \
101+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
102− width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; \
102+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; \n\
103− ' + (isHorizontal ? 'anchors.left: parent.left;' : 'anchors.horizontalCenter: parent.horizontalCenter;' ) + '\
103+ ' + (isHorizontal ? 'anchors.left: parent.left;' : 'anchors.horizontalCenter: parent.horizontalCenter;\n' ) + '\n\
104− Loader { \
104+ Loader { \n\
105− id: artShapeLoader; \
105+ id: artShapeLoader; \n\
106− objectName: "artShapeLoader"; \
106+ objectName: "artShapeLoader"; \n\
107− active: cardData && cardData["art"] || false; \
107+ active: cardData && cardData["art"] || false; \n\
108− asynchronous: root.asynchronous; \
108+ asynchronous: root.asynchronous; \n\
109− visible: status == Loader.Ready; \
109+ visible: status == Loader.Ready; \n\
110− sourceComponent: UbuntuShape { \
110+ sourceComponent: UbuntuShape { \n\
111− id: artShape; \
111+ id: artShape; \n\
112− objectName: "artShape"; \
112+ objectName: "artShape"; \n\
113− radius: "medium"; \
113+ radius: "medium"; \n\
114− readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; \
114+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
115− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \
115+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \n\
116− Component.onCompleted: updateWidthHeightBindings(); \
116+ Component.onCompleted: updateWidthHeightBindings(); \n\
117− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \
117+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \n\
118− visible: image.status == Image.Ready; \
118+ visible: image.status == Image.Ready; \n\
119− function updateWidthHeightBindings() { \
119+ function updateWidthHeightBindings() { \n\
120− if (aspectSmallerThanImageAspect) { \
120+ if (aspectSmallerThanImageAspect) { \n\
121− width = Qt.binding(function() { return !visible ? 0 : image.width }); \
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 }); \
122+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); \n\
123− } else { \
123+ } else { \n\
124− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); \
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 }); \
125+ height = Qt.binding(function() { return !visible ? 0 : image.height }); \n\
126− } \
126+ } \n\
127− } \
127+ } \n\
128− image: Image { \
128+ image: Image { \n\
129− objectName: "artImage"; \
129+ objectName: "artImage"; \n\
130− source: cardData && cardData["art"] || ""; \
130+ source: cardData && cardData["art"] || ""; \n\
131− cache: true; \
131+ cache: true; \n\
132− asynchronous: root.asynchronous; \
132+ asynchronous: root.asynchronous; \n\
133− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; \
133+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; \n\
134− readonly property real aspect: implicitWidth / implicitHeight; \
134+ readonly property real aspect: implicitWidth / implicitHeight; \n\
135− ' + imageWidthHeight + '\
135+ ' + imageWidthHeight + '\n\
136− } \
136+ } \n\
137− } \
137+ } \n\
138− } \
138+ } \n\
139− }'
139+ }\n'
140 } else {
140 } else {
141− code += 'readonly property size artShapeSize: Qt.size(-1, -1);'
141+ code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
142 }
142 }
143
143
144 if (inOverlay) {
144 if (inOverlay) {
145− var height = 'fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight;';
145+ var height = 'fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight;\n';
146− code += 'Loader { \
146+ code += 'Loader { \n\
147− id: overlayLoader; \
147+ id: overlayLoader; \n\
148− anchors { \
148+ anchors { \n\
149− left: artShapeHolder.left; \
149+ left: artShapeHolder.left; \n\
150− right: artShapeHolder.right; \
150+ right: artShapeHolder.right; \n\
151− bottom: artShapeHolder.bottom; \
151+ bottom: artShapeHolder.bottom; \n\
152− } \
152+ } \n\
153− active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \
153+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \n\
154− asynchronous: root.asynchronous; \
154+ asynchronous: root.asynchronous; \n\
155− visible: showHeader && status == Loader.Ready; \
155+ visible: showHeader && status == Loader.Ready; \n\
156− sourceComponent: ShaderEffect { \
156+ sourceComponent: ShaderEffect { \n\
157− id: overlay; \
157+ id: overlay; \n\
158− height: ' + height + ' \
158+ height: ' + height + ' \n\
159− opacity: 0.6; \
159+ opacity: 0.6; \n\
160− property var source: ShaderEffectSource { \
160+ property var source: ShaderEffectSource { \n\
161− id: shaderSource; \
161+ id: shaderSource; \n\
162− sourceItem: artShapeLoader.item; \
162+ sourceItem: artShapeLoader.item; \n\
163− onVisibleChanged: if (visible) scheduleUpdate(); \
163+ onVisibleChanged: if (visible) scheduleUpdate(); \n\
164− live: false; \
164+ live: false; \n\
165− sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height); \
165+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height); \n\
166− } \
166+ } \n\
167− vertexShader: " \
167+ vertexShader: " \n\
168− uniform highp mat4 qt_Matrix; \
168+ uniform highp mat4 qt_Matrix; \n\
169− attribute highp vec4 qt_Vertex; \
169+ attribute highp vec4 qt_Vertex; \n\
170− attribute highp vec2 qt_MultiTexCoord0; \
170+ attribute highp vec2 qt_MultiTexCoord0; \n\
171− varying highp vec2 coord; \
171+ varying highp vec2 coord; \n\
172− void main() { \
172+ void main() { \n\
173− coord = qt_MultiTexCoord0; \
173+ coord = qt_MultiTexCoord0; \n\
174− gl_Position = qt_Matrix * qt_Vertex; \
174+ gl_Position = qt_Matrix * qt_Vertex; \n\
175− }"; \
175+ }"; \n\
176− fragmentShader: " \
176+ fragmentShader: " \n\
177− varying highp vec2 coord; \
177+ varying highp vec2 coord; \n\
178− uniform sampler2D source; \
178+ uniform sampler2D source; \n\
179− uniform lowp float qt_Opacity; \
179+ uniform lowp float qt_Opacity; \n\
180− void main() { \
180+ void main() { \n\
181− lowp vec4 tex = texture2D(source, coord); \
181+ lowp vec4 tex = texture2D(source, coord); \n\
182− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; \
182+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; \n\
183− }"; \
183+ }"; \n\
184− } \
184+ } \n\
185− }';
185+ }\n';
186 }
186 }
187
187
188 var headerVerticalAnchors;
188 var headerVerticalAnchors;
189 if (inOverlay) {
189 if (inOverlay) {
190− headerVerticalAnchors = 'anchors.bottom: artShapeHolder.bottom; \
190+ headerVerticalAnchors = 'anchors.bottom: artShapeHolder.bottom; \n\
191− anchors.bottomMargin: units.gu(1);';
191+ anchors.bottomMargin: units.gu(1);\n';
192 } else {
192 } else {
193 if (hasArt) {
193 if (hasArt) {
194 if (isHorizontal) {
194 if (isHorizontal) {
195− headerVerticalAnchors = 'anchors.top: artShapeHolder.top; \
195+ headerVerticalAnchors = 'anchors.top: artShapeHolder.top; \n\
196− anchors.topMargin: units.gu(1);';
196+ anchors.topMargin: units.gu(1);\n';
197 } else {
197 } else {
198− headerVerticalAnchors = 'anchors.top: artShapeHolder.bottom; \
198+ headerVerticalAnchors = 'anchors.top: artShapeHolder.bottom; \n\
199− anchors.topMargin: units.gu(1);';
199+ anchors.topMargin: units.gu(1);\n';
200 }
200 }
201 } else {
201 } else {
202− headerVerticalAnchors = 'anchors.top: parent.top; \
202+ headerVerticalAnchors = 'anchors.top: parent.top; \n\
203− anchors.topMargin: units.gu(1);';
203+ anchors.topMargin: units.gu(1);\n';
204 }
204 }
205 }
205 }
206 var headerLeftAnchor;
206 var headerLeftAnchor;
207 var headerLeftAnchorHasMagin = false;
207 var headerLeftAnchorHasMagin = false;
208 if (isHorizontal && hasArt) {
208 if (isHorizontal && hasArt) {
209− headerLeftAnchor = 'anchors.left: artShapeHolder.right; \
209+ headerLeftAnchor = 'anchors.left: artShapeHolder.right; \n\
210− anchors.leftMargin: units.gu(1);';
210+ anchors.leftMargin: units.gu(1);\n';
211 headerLeftAnchorHasMagin = true;
211 headerLeftAnchorHasMagin = true;
212 } else {
212 } else {
213− headerLeftAnchor = 'anchors.left: parent.left;';
213+ headerLeftAnchor = 'anchors.left: parent.left;\n';
214 }
214 }
215
215
216 if (hasHeaderRow) {
216 if (hasHeaderRow) {
217− code += 'readonly property int headerHeight: row.height + row.margins * 2;'
217+ code += 'readonly property int headerHeight: row.height + row.margins * 2;\n'
218− code += 'Row { \
218+ code += 'Row { \n\
219− id: row; \
219+ id: row; \n\
220− objectName: "outerRow"; \
220+ objectName: "outerRow"; \n\
221− property real margins: units.gu(1); \
221+ property real margins: units.gu(1); \n\
222− spacing: margins; \
222+ spacing: margins; \n\
223− ' + headerVerticalAnchors + '\
223+ ' + headerVerticalAnchors + '\n\
224− ' + headerLeftAnchor + '\
224+ ' + headerLeftAnchor + '\n\
225− anchors.right: parent.right; \
225+ anchors.right: parent.right; \n\
226− anchors.margins: margins;';
226+ anchors.margins: margins;\n';
227 } else if (hasMascot) {
227 } 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'
229 } else if (hasSubtitle) {
229 } 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'
231 } else if (hasTitle) {
231 } 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'
233 } else {
233 } else {
234− code += 'readonly property int headerHeight: 0;'
234+ code += 'readonly property int headerHeight: 0;\n'
235 }
235 }
236
236
237 if (hasMascot) {
237 if (hasMascot) {
@@ -241,40 +241,40 @@ function cardString(template, components) {
241 anchors += headerLeftAnchor;
241 anchors += headerLeftAnchor;
242 anchors += headerVerticalAnchors;
242 anchors += headerVerticalAnchors;
243 if (!headerLeftAnchorHasMagin) {
243 if (!headerLeftAnchorHasMagin) {
244− anchors += 'anchors.leftMargin: units.gu(1);'
244+ anchors += 'anchors.leftMargin: units.gu(1);\n'
245 }
245 }
246 } else {
246 } else {
247 anchors = "anchors.verticalCenter: parent.verticalCenter;"
247 anchors = "anchors.verticalCenter: parent.verticalCenter;"
248 }
248 }
249
249
250 if (useMascotShape) {
250 if (useMascotShape) {
251− code += 'Loader { \
251+ code += 'Loader { \n\
252− id: mascotShapeLoader; \
252+ id: mascotShapeLoader; \n\
253− objectName: "mascotShapeLoader"; \
253+ objectName: "mascotShapeLoader"; \n\
254− asynchronous: root.asynchronous; \
254+ asynchronous: root.asynchronous; \n\
255− active: mascotImage.status === Image.Ready; \
255+ active: mascotImage.status === Image.Ready; \n\
256− visible: showHeader && active && status == Loader.Ready; \
256+ visible: showHeader && active && status == Loader.Ready; \n\
257− width: units.gu(6); \
257+ width: units.gu(6); \n\
258− height: units.gu(5.625); \
258+ height: units.gu(5.625); \n\
259− sourceComponent: UbuntuShape { image: mascotImage } \
259+ sourceComponent: UbuntuShape { image: mascotImage } \n\
260− ' + anchors + '\
260+ ' + anchors + '\n\
261− }';
261+ }\n';
262 }
262 }
263
263
264− code += 'Image { \
264+ code += 'Image { \n\
265− id: mascotImage; \
265+ id: mascotImage; \n\
266− objectName: "mascotImage"; \
266+ objectName: "mascotImage"; \n\
267− ' + anchors + '\
267+ ' + anchors + '\n\
268− readonly property int maxSize: Math.max(width, height) * 4; \
268+ readonly property int maxSize: Math.max(width, height) * 4; \n\
269− source: cardData && cardData["mascot"]; \
269+ source: cardData && cardData["mascot"]; \n\
270− width: units.gu(6); \
270+ width: units.gu(6); \n\
271− height: units.gu(5.625); \
271+ height: units.gu(5.625); \n\
272− sourceSize { width: maxSize; height: maxSize } \
272+ sourceSize { width: maxSize; height: maxSize } \n\
273− fillMode: Image.PreserveAspectCrop; \
273+ fillMode: Image.PreserveAspectCrop; \n\
274− horizontalAlignment: Image.AlignHCenter; \
274+ horizontalAlignment: Image.AlignHCenter; \n\
275− verticalAlignment: Image.AlignVCenter; \
275+ verticalAlignment: Image.AlignVCenter; \n\
276− visible: showHeader && ' + (useMascotShape ? 'false' : 'true') + '; \
276+ visible: showHeader && ' + (useMascotShape ? 'false' : 'true') + '; \n\
277− }';
277+ }\n';
278 }
278 }
279
279
280 var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey"';
280 var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey"';
@@ -294,81 +294,81 @@ function cardString(template, components) {
294 var titleAnchors = "";
294 var titleAnchors = "";
295 var subtitleAnchors = "";
295 var subtitleAnchors = "";
296 if (hasMascot && hasSubtitle) {
296 if (hasMascot && hasSubtitle) {
297− titleAnchors = 'anchors { left: parent.left; right: parent.right }';
297+ titleAnchors = 'anchors { left: parent.left; right: parent.right }\n';
298 subtitleAnchors = titleAnchors;
298 subtitleAnchors = titleAnchors;
299− code += 'Column { \
299+ code += 'Column { \n\
300− anchors.verticalCenter: parent.verticalCenter; \
300+ anchors.verticalCenter: parent.verticalCenter; \n\
301− spacing: units.dp(2); \
301+ spacing: units.dp(2); \n\
302− width: parent.width - x;';
302+ width: parent.width - x;\n';
303 } else if (hasMascot) {
303 } else if (hasMascot) {
304− titleAnchors = 'anchors.verticalCenter: parent.verticalCenter;'
304+ titleAnchors = 'anchors.verticalCenter: parent.verticalCenter;\n'
305 } else if (inOverlay) {
305 } else if (inOverlay) {
306− titleAnchors = 'anchors.left: parent.left; \
306+ titleAnchors = 'anchors.left: parent.left; \n\
307− anchors.leftMargin: units.gu(1); \
307+ anchors.leftMargin: units.gu(1); \n\
308− anchors.right: parent.right; \
308+ anchors.right: parent.right; \n\
309− anchors.top: overlayLoader.top; \
309+ anchors.top: overlayLoader.top; \n\
310− anchors.topMargin: units.gu(1);';
310+ anchors.topMargin: units.gu(1);\n';
311− subtitleAnchors = 'anchors.left: titleLabel.left; \
311+ subtitleAnchors = 'anchors.left: titleLabel.left; \n\
312− anchors.leftMargin: titleLabel.leftMargin; \
312+ anchors.leftMargin: titleLabel.leftMargin; \n\
313− anchors.right: titleLabel.right; \
313+ anchors.right: titleLabel.right; \n\
314− anchors.top: titleLabel.bottom; \
314+ anchors.top: titleLabel.bottom; \n\
315− anchors.topMargin: units.dp(2);';
315+ anchors.topMargin: units.dp(2);\n';
316 } else {
316 } else {
317 titleAnchors = "anchors.right: parent.right;";
317 titleAnchors = "anchors.right: parent.right;";
318 if (hasMascot) {
318 if (hasMascot) {
319− titleAnchors += 'anchors.left: mascotImage.right; \
319+ titleAnchors += 'anchors.left: mascotImage.right; \n\
320− anchors.leftMargin: units.gu(1);';
320+ anchors.leftMargin: units.gu(1);\n';
321 } else {
321 } else {
322 titleAnchors += headerLeftAnchor;
322 titleAnchors += headerLeftAnchor;
323 }
323 }
324 titleAnchors += headerVerticalAnchors;
324 titleAnchors += headerVerticalAnchors;
325− subtitleAnchors = 'anchors.left: titleLabel.left; \
325+ subtitleAnchors = 'anchors.left: titleLabel.left; \n\
326− anchors.leftMargin: titleLabel.leftMargin; \
326+ anchors.leftMargin: titleLabel.leftMargin; \n\
327− anchors.right: titleLabel.right; \
327+ anchors.right: titleLabel.right; \n\
328− anchors.top: titleLabel.bottom; \
328+ anchors.top: titleLabel.bottom; \n\
329− anchors.topMargin: units.dp(2);';
329+ anchors.topMargin: units.dp(2);\n';
330 }
330 }
331
331
332− code += 'Label { \
332+ code += 'Label { \n\
333− id: titleLabel; \
333+ id: titleLabel; \n\
334− objectName: "titleLabel"; \
334+ objectName: "titleLabel"; \n\
335− ' + titleAnchors + '\
335+ ' + titleAnchors + '\n\
336− elide: Text.ElideRight; \
336+ elide: Text.ElideRight; \n\
337− fontSize: "small"; \
337+ fontSize: "small"; \n\
338− wrapMode: Text.Wrap; \
338+ wrapMode: Text.Wrap; \n\
339− maximumLineCount: 2; \
339+ maximumLineCount: 2; \n\
340− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \
340+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\
341− color: ' + color + '; \
341+ color: ' + color + '; \n\
342− visible: showHeader ' + (inOverlay ? '&& overlayLoader.active': '') + '; \
342+ visible: showHeader ' + (inOverlay ? '&& overlayLoader.active': '') + '; \n\
343− text: root.title; \
343+ text: root.title; \n\
344− font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; \
344+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; \n\
345− horizontalAlignment: root.headerAlignment; \
345+ horizontalAlignment: root.headerAlignment; \n\
346− }';
346+ }\n';
347
347
348 if (hasSubtitle) {
348 if (hasSubtitle) {
349− code += 'Label { \
349+ code += 'Label { \n\
350− id: subtitleLabel; \
350+ id: subtitleLabel; \n\
351− objectName: "subtitleLabel"; \
351+ objectName: "subtitleLabel"; \n\
352− ' + subtitleAnchors + '\
352+ ' + subtitleAnchors + '\n\
353− elide: Text.ElideRight; \
353+ elide: Text.ElideRight; \n\
354− fontSize: "small"; \
354+ fontSize: "small"; \n\
355− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \
355+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\
356− color: ' + color + '; \
356+ color: ' + color + '; \n\
357− visible: titleLabel.visible && titleLabel.text; \
357+ visible: titleLabel.visible && titleLabel.text; \n\
358− text: cardData && cardData["subtitle"] || ""; \
358+ text: cardData && cardData["subtitle"] || ""; \n\
359− font.weight: Font.Light; \
359+ font.weight: Font.Light; \n\
360− horizontalAlignment: root.headerAlignment; \
360+ horizontalAlignment: root.headerAlignment; \n\
361− }';
361+ }\n';
362
362
363 // Close Column
363 // Close Column
364 if (hasMascot)
364 if (hasMascot)
365− code += '}';
365+ code += '}\n';
366 }
366 }
367 }
367 }
368
368
369 if (hasHeaderRow) {
369 if (hasHeaderRow) {
370 // Close Row
370 // Close Row
371− code += '}';
371+ code += '}\n';
372 }
372 }
373
373
374 if (hasSummary) {
374 if (hasSummary) {
@@ -387,48 +387,48 @@ function cardString(template, components) {
387 } else {
387 } else {
388 color = '"grey"';
388 color = '"grey"';
389 }
389 }
390− code += 'Label { \
390+ code += 'Label { \n\
391− id: summary; \
391+ id: summary; \n\
392− objectName: "summaryLabel"; \
392+ objectName: "summaryLabel"; \n\
393− anchors { \
393+ anchors { \n\
394− top: ' + summaryTopAnchor + '; \
394+ top: ' + summaryTopAnchor + '; \n\
395− left: parent.left; \
395+ left: parent.left; \n\
396− right: parent.right; \
396+ right: parent.right; \n\
397− margins: units.gu(1); \
397+ margins: units.gu(1); \n\
398− topMargin: ' + (hasMascot || hasSubtitle ? 'anchors.margins' : 0) + '; \
398+ topMargin: ' + (hasMascot || hasSubtitle ? 'anchors.margins' : 0) + '; \n\
399− } \
399+ } \n\
400− wrapMode: Text.Wrap; \
400+ wrapMode: Text.Wrap; \n\
401− maximumLineCount: 5; \
401+ maximumLineCount: 5; \n\
402− elide: Text.ElideRight; \
402+ elide: Text.ElideRight; \n\
403− text: cardData && cardData["summary"] || ""; \
403+ text: cardData && cardData["summary"] || ""; \n\
404− height: text ? implicitHeight : 0; \
404+ height: text ? implicitHeight : 0; \n\
405− fontSize: "small"; \
405+ fontSize: "small"; \n\
406− color: ' + color + '; \
406+ color: ' + color + '; \n\
407− }';
407+ }\n';
408 }
408 }
409
409
410 // Close the AbstractButton
410 // Close the AbstractButton
411 if (hasSummary) {
411 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';
413 } else if (hasHeaderRow) {
413 } else if (hasHeaderRow) {
414− code += 'implicitHeight: row.y + row.height + units.gu(1);';
414+ code += 'implicitHeight: row.y + row.height + units.gu(1);\n';
415 } else if (hasMascot) {
415 } else if (hasMascot) {
416− code += 'implicitHeight: mascotImage.y + mascotImage.height;';
416+ code += 'implicitHeight: mascotImage.y + mascotImage.height;\n';
417 } else if (hasSubtitle) {
417 } else if (hasSubtitle) {
418− code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);';
418+ code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
419 } else if (hasTitle) {
419 } else if (hasTitle) {
420− code += 'implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);';
420+ code += 'implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);\n';
421 }
421 }
422− code += '}';
422+ code += '}\n';
423
423
424 return code;
424 return code;
425}
425}
426
426
427function createCardComponent(parent, template, components) {
427function createCardComponent(parent, template, components) {
428− var imports = 'import QtQuick 2.2; \
428+ var imports = 'import QtQuick 2.2; \n\
429− import Ubuntu.Components 0.1; \
429+ import Ubuntu.Components 0.1; \n\
430− import Ubuntu.Thumbnailer 0.1;';
430+ import Ubuntu.Thumbnailer 0.1;\n';
431 var card = cardString(template, components);
431 var card = cardString(template, components);
432− var code = imports + 'Component {' + card + '}';
432+ var code = imports + 'Component {\n' + card + '}\n';
433 return Qt.createQmlObject(code, parent, "createCardComponent");
433 return Qt.createQmlObject(code, parent, "createCardComponent");
434}
434}
tests/plugins/Dash/cardcreator/1.res+79−1
@@ -1 +1,79 @@
1−AbstractButton { id: root; property var template; property var components; property var cardData; property real fontScale: 1.0; property int headerAlignment: Text.AlignLeft; property int fixedHeaderHeight: -1; property size fixedArtShapeSize: Qt.size(-1, -1); readonly property string title: cardData && cardData["title"] || ""; property bool asynchronous: true; property bool showHeader: true; implicitWidth: childrenRect.width; readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);Item { id: artShapeHolder; height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; anchors.horizontalCenter: parent.horizontalCenter; Loader { id: artShapeLoader; objectName: "artShapeLoader"; active: cardData && cardData["art"] || false; asynchronous: root.asynchronous; visible: status == Loader.Ready; sourceComponent: UbuntuShape { id: artShape; objectName: "artShape"; radius: "medium"; readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; Component.onCompleted: updateWidthHeightBindings(); onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); visible: image.status == Image.Ready; function updateWidthHeightBindings() { if (aspectSmallerThanImageAspect) { width = Qt.binding(function() { return !visible ? 0 : image.width }); height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); } else { width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); height = Qt.binding(function() { return !visible ? 0 : image.height }); } } image: Image { objectName: "artImage"; source: cardData && cardData["art"] || ""; cache: true; asynchronous: root.asynchronous; fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; readonly property real aspect: implicitWidth / implicitHeight; width: root.width; height: width / artShape.aspect; } } } }readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;Label { id: titleLabel; objectName: "titleLabel"; anchors.right: parent.right;anchors.left: parent.left;anchors.top: artShapeHolder.bottom; anchors.topMargin: units.gu(1); elide: Text.ElideRight; fontSize: "small"; wrapMode: Text.Wrap; maximumLineCount: 2; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: "grey"; visible: showHeader ; text: root.title; font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; horizontalAlignment: root.headerAlignment; }implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);}
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property real fontScale: 1.0;
7+ property int headerAlignment: Text.AlignLeft;
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;
14+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
15+Item {
16+ id: artShapeHolder;
17+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
18+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
19+ anchors.horizontalCenter: parent.horizontalCenter;
20+
21+ Loader {
22+ id: artShapeLoader;
23+ objectName: "artShapeLoader";
24+ active: cardData && cardData["art"] || false;
25+ asynchronous: root.asynchronous;
26+ visible: status == Loader.Ready;
27+ sourceComponent: UbuntuShape {
28+ id: artShape;
29+ objectName: "artShape";
30+ radius: "medium";
31+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
32+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
33+ Component.onCompleted: updateWidthHeightBindings();
34+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
35+ visible: image.status == Image.Ready;
36+ function updateWidthHeightBindings() {
37+ if (aspectSmallerThanImageAspect) {
38+ width = Qt.binding(function() { return !visible ? 0 : image.width });
39+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
40+ } else {
41+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
42+ height = Qt.binding(function() { return !visible ? 0 : image.height });
43+ }
44+ }
45+ image: Image {
46+ objectName: "artImage";
47+ source: cardData && cardData["art"] || "";
48+ cache: true;
49+ asynchronous: root.asynchronous;
50+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
51+ readonly property real aspect: implicitWidth / implicitHeight;
52+ width: root.width;
53+ height: width / artShape.aspect;
54+
55+ }
56+ }
57+ }
58+ }
59+readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;
60+Label {
61+ id: titleLabel;
62+ objectName: "titleLabel";
63+ anchors.right: parent.right;anchors.left: parent.left;
64+anchors.top: artShapeHolder.bottom;
65+ anchors.topMargin: units.gu(1);
66+
67+ elide: Text.ElideRight;
68+ fontSize: "small";
69+ wrapMode: Text.Wrap;
70+ maximumLineCount: 2;
71+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
72+ color: "grey";
73+ visible: showHeader ;
74+ text: root.title;
75+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
76+ horizontalAlignment: root.headerAlignment;
77+ }
78+implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
79+}
tests/plugins/Dash/cardcreator/2.res+112−1
@@ -1 +1,112 @@
1−AbstractButton { id: root; property var template; property var components; property var cardData; property real fontScale: 1.0; property int headerAlignment: Text.AlignLeft; property int fixedHeaderHeight: -1; property size fixedArtShapeSize: Qt.size(-1, -1); readonly property string title: cardData && cardData["title"] || ""; property bool asynchronous: true; property bool showHeader: true; implicitWidth: childrenRect.width; Loader { id: backgroundLoader; objectName: "backgroundLoader"; anchors.fill: parent; asynchronous: root.asynchronous; visible: status == Loader.Ready; sourceComponent: UbuntuShape { objectName: "background"; radius: "medium"; color: getColor(0) || "white"; gradientColor: getColor(1) || color; anchors.fill: parent; image: backgroundImage.source ? backgroundImage : null; property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; property Image backgroundImage: Image { objectName: "backgroundImage"; source: { if (cardData && typeof cardData["background"] === "string") return cardData["background"]; else if (template && typeof template["card-background"] === "string") return template["card-background"]; else return ""; } } function getColor(index) { if (cardData && typeof cardData["background"] === "object" && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { return cardData["background"]["elements"][index]; } else if (template && typeof template["card-background"] === "object" && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) { return template["card-background"]["elements"][index]; } else return undefined; } } }readonly property size artShapeSize: Qt.size(-1, -1);readonly property int headerHeight: row.height + row.margins * 2;Row { id: row; objectName: "outerRow"; property real margins: units.gu(1); spacing: margins; anchors.top: parent.top; anchors.topMargin: units.gu(1); anchors.left: parent.left; anchors.right: parent.right; anchors.margins: margins;Image { id: mascotImage; objectName: "mascotImage"; anchors.verticalCenter: parent.verticalCenter; readonly property int maxSize: Math.max(width, height) * 4; source: cardData && cardData["mascot"]; width: units.gu(6); height: units.gu(5.625); sourceSize { width: maxSize; height: maxSize } fillMode: Image.PreserveAspectCrop; horizontalAlignment: Image.AlignHCenter; verticalAlignment: Image.AlignVCenter; visible: showHeader && true; }Column { anchors.verticalCenter: parent.verticalCenter; spacing: units.dp(2); width: parent.width - x;Label { id: titleLabel; objectName: "titleLabel"; anchors { left: parent.left; right: parent.right } elide: Text.ElideRight; fontSize: "small"; wrapMode: Text.Wrap; maximumLineCount: 2; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey"; visible: showHeader ; text: root.title; font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; horizontalAlignment: root.headerAlignment; }Label { id: subtitleLabel; objectName: "subtitleLabel"; anchors { left: parent.left; right: parent.right } elide: Text.ElideRight; fontSize: "small"; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey"; visible: titleLabel.visible && titleLabel.text; text: cardData && cardData["subtitle"] || ""; font.weight: Font.Light; horizontalAlignment: root.headerAlignment; }}}implicitHeight: row.y + row.height + units.gu(1);}
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property real fontScale: 1.0;
7+ property int headerAlignment: Text.AlignLeft;
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;
14+Loader {
15+ id: backgroundLoader;
16+ objectName: "backgroundLoader";
17+ anchors.fill: parent;
18+ asynchronous: root.asynchronous;
19+ visible: status == Loader.Ready;
20+ sourceComponent: UbuntuShape {
21+ objectName: "background";
22+ radius: "medium";
23+ color: getColor(0) || "white";
24+ gradientColor: getColor(1) || color;
25+ anchors.fill: parent;
26+ image: backgroundImage.source ? backgroundImage : null;
27+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
28+ property Image backgroundImage: Image {
29+ objectName: "backgroundImage";
30+ source: {
31+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
32+ else if (template && typeof template["card-background"] === "string") return template["card-background"];
33+ else return "";
34+ }
35+ }
36+ function getColor(index) {
37+ if (cardData && typeof cardData["background"] === "object"
38+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
39+ return cardData["background"]["elements"][index];
40+ } else if (template && typeof template["card-background"] === "object"
41+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
42+ return template["card-background"]["elements"][index];
43+ } else return undefined;
44+ }
45+ }
46+ }
47+readonly property size artShapeSize: Qt.size(-1, -1);
48+readonly property int headerHeight: row.height + row.margins * 2;
49+Row {
50+ id: row;
51+ objectName: "outerRow";
52+ property real margins: units.gu(1);
53+ spacing: margins;
54+ anchors.top: parent.top;
55+ anchors.topMargin: units.gu(1);
56+
57+ anchors.left: parent.left;
58+
59+ anchors.right: parent.right;
60+ anchors.margins: margins;
61+Image {
62+ id: mascotImage;
63+ objectName: "mascotImage";
64+ anchors.verticalCenter: parent.verticalCenter;
65+ readonly property int maxSize: Math.max(width, height) * 4;
66+ source: cardData && cardData["mascot"];
67+ width: units.gu(6);
68+ height: units.gu(5.625);
69+ sourceSize { width: maxSize; height: maxSize }
70+ fillMode: Image.PreserveAspectCrop;
71+ horizontalAlignment: Image.AlignHCenter;
72+ verticalAlignment: Image.AlignVCenter;
73+ visible: showHeader && true;
74+ }
75+Column {
76+ anchors.verticalCenter: parent.verticalCenter;
77+ spacing: units.dp(2);
78+ width: parent.width - x;
79+Label {
80+ id: titleLabel;
81+ objectName: "titleLabel";
82+ anchors { left: parent.left; right: parent.right }
83+
84+ elide: Text.ElideRight;
85+ fontSize: "small";
86+ wrapMode: Text.Wrap;
87+ maximumLineCount: 2;
88+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
89+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey";
90+ visible: showHeader ;
91+ text: root.title;
92+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
93+ horizontalAlignment: root.headerAlignment;
94+ }
95+Label {
96+ id: subtitleLabel;
97+ objectName: "subtitleLabel";
98+ anchors { left: parent.left; right: parent.right }
99+
100+ elide: Text.ElideRight;
101+ fontSize: "small";
102+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
103+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : "grey";
104+ visible: titleLabel.visible && titleLabel.text;
105+ text: cardData && cardData["subtitle"] || "";
106+ font.weight: Font.Light;
107+ horizontalAlignment: root.headerAlignment;
108+ }
109+}
110+}
111+implicitHeight: row.y + row.height + units.gu(1);
112+}
tests/plugins/Dash/cardcreator/3.res+97−1
@@ -1 +1,97 @@
1−AbstractButton { id: root; property var template; property var components; property var cardData; property real fontScale: 1.0; property int headerAlignment: Text.AlignLeft; property int fixedHeaderHeight: -1; property size fixedArtShapeSize: Qt.size(-1, -1); readonly property string title: cardData && cardData["title"] || ""; property bool asynchronous: true; property bool showHeader: true; implicitWidth: childrenRect.width; readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);Item { id: artShapeHolder; height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; anchors.horizontalCenter: parent.horizontalCenter; Loader { id: artShapeLoader; objectName: "artShapeLoader"; active: cardData && cardData["art"] || false; asynchronous: root.asynchronous; visible: status == Loader.Ready; sourceComponent: UbuntuShape { id: artShape; objectName: "artShape"; radius: "medium"; readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; Component.onCompleted: updateWidthHeightBindings(); onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); visible: image.status == Image.Ready; function updateWidthHeightBindings() { if (aspectSmallerThanImageAspect) { width = Qt.binding(function() { return !visible ? 0 : image.width }); height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); } else { width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); height = Qt.binding(function() { return !visible ? 0 : image.height }); } } image: Image { objectName: "artImage"; source: cardData && cardData["art"] || ""; cache: true; asynchronous: root.asynchronous; fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; readonly property real aspect: implicitWidth / implicitHeight; width: root.width; height: width / artShape.aspect; } } } }readonly property int headerHeight: subtitleLabel.y + subtitleLabel.height - titleLabel.y + titleLabel.anchors.topMargin * 2 + subtitleLabel.anchors.topMargin;Label { id: titleLabel; objectName: "titleLabel"; anchors.right: parent.right;anchors.left: parent.left;anchors.top: artShapeHolder.bottom; anchors.topMargin: units.gu(1); elide: Text.ElideRight; fontSize: "small"; wrapMode: Text.Wrap; maximumLineCount: 2; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: "grey"; visible: showHeader ; text: root.title; font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; horizontalAlignment: root.headerAlignment; }Label { id: subtitleLabel; objectName: "subtitleLabel"; anchors.left: titleLabel.left; anchors.leftMargin: titleLabel.leftMargin; anchors.right: titleLabel.right; anchors.top: titleLabel.bottom; anchors.topMargin: units.dp(2); elide: Text.ElideRight; fontSize: "small"; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: "grey"; visible: titleLabel.visible && titleLabel.text; text: cardData && cardData["subtitle"] || ""; font.weight: Font.Light; horizontalAlignment: root.headerAlignment; }implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);}
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property real fontScale: 1.0;
7+ property int headerAlignment: Text.AlignLeft;
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;
14+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
15+Item {
16+ id: artShapeHolder;
17+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
18+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
19+ anchors.horizontalCenter: parent.horizontalCenter;
20+
21+ Loader {
22+ id: artShapeLoader;
23+ objectName: "artShapeLoader";
24+ active: cardData && cardData["art"] || false;
25+ asynchronous: root.asynchronous;
26+ visible: status == Loader.Ready;
27+ sourceComponent: UbuntuShape {
28+ id: artShape;
29+ objectName: "artShape";
30+ radius: "medium";
31+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
32+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
33+ Component.onCompleted: updateWidthHeightBindings();
34+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
35+ visible: image.status == Image.Ready;
36+ function updateWidthHeightBindings() {
37+ if (aspectSmallerThanImageAspect) {
38+ width = Qt.binding(function() { return !visible ? 0 : image.width });
39+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
40+ } else {
41+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
42+ height = Qt.binding(function() { return !visible ? 0 : image.height });
43+ }
44+ }
45+ image: Image {
46+ objectName: "artImage";
47+ source: cardData && cardData["art"] || "";
48+ cache: true;
49+ asynchronous: root.asynchronous;
50+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
51+ readonly property real aspect: implicitWidth / implicitHeight;
52+ width: root.width;
53+ height: width / artShape.aspect;
54+
55+ }
56+ }
57+ }
58+ }
59+readonly property int headerHeight: subtitleLabel.y + subtitleLabel.height - titleLabel.y + titleLabel.anchors.topMargin * 2 + subtitleLabel.anchors.topMargin;
60+Label {
61+ id: titleLabel;
62+ objectName: "titleLabel";
63+ anchors.right: parent.right;anchors.left: parent.left;
64+anchors.top: artShapeHolder.bottom;
65+ anchors.topMargin: units.gu(1);
66+
67+ elide: Text.ElideRight;
68+ fontSize: "small";
69+ wrapMode: Text.Wrap;
70+ maximumLineCount: 2;
71+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
72+ color: "grey";
73+ visible: showHeader ;
74+ text: root.title;
75+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
76+ horizontalAlignment: root.headerAlignment;
77+ }
78+Label {
79+ id: subtitleLabel;
80+ objectName: "subtitleLabel";
81+ anchors.left: titleLabel.left;
82+ anchors.leftMargin: titleLabel.leftMargin;
83+ anchors.right: titleLabel.right;
84+ anchors.top: titleLabel.bottom;
85+ anchors.topMargin: units.dp(2);
86+
87+ elide: Text.ElideRight;
88+ fontSize: "small";
89+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
90+ color: "grey";
91+ visible: titleLabel.visible && titleLabel.text;
92+ text: cardData && cardData["subtitle"] || "";
93+ font.weight: Font.Light;
94+ horizontalAlignment: root.headerAlignment;
95+ }
96+implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
97+}
tests/plugins/Dash/cardcreator/4.res+90−1
@@ -1 +1,90 @@
1−AbstractButton { id: root; property var template; property var components; property var cardData; property real fontScale: 1.0; property int headerAlignment: Text.AlignLeft; property int fixedHeaderHeight: -1; property size fixedArtShapeSize: Qt.size(-1, -1); readonly property string title: cardData && cardData["title"] || ""; property bool asynchronous: true; property bool showHeader: true; implicitWidth: childrenRect.width; readonly property size artShapeSize: Qt.size(-1, -1);readonly property int headerHeight: row.height + row.margins * 2;Row { id: row; objectName: "outerRow"; property real margins: units.gu(1); spacing: margins; anchors.top: parent.top; anchors.topMargin: units.gu(1); anchors.left: parent.left; anchors.right: parent.right; anchors.margins: margins;Loader { id: mascotShapeLoader; objectName: "mascotShapeLoader"; asynchronous: root.asynchronous; active: mascotImage.status === Image.Ready; visible: showHeader && active && status == Loader.Ready; width: units.gu(6); height: units.gu(5.625); sourceComponent: UbuntuShape { image: mascotImage } anchors.verticalCenter: parent.verticalCenter; }Image { id: mascotImage; objectName: "mascotImage"; anchors.verticalCenter: parent.verticalCenter; readonly property int maxSize: Math.max(width, height) * 4; source: cardData && cardData["mascot"]; width: units.gu(6); height: units.gu(5.625); sourceSize { width: maxSize; height: maxSize } fillMode: Image.PreserveAspectCrop; horizontalAlignment: Image.AlignHCenter; verticalAlignment: Image.AlignVCenter; visible: showHeader && false; }Column { anchors.verticalCenter: parent.verticalCenter; spacing: units.dp(2); width: parent.width - x;Label { id: titleLabel; objectName: "titleLabel"; anchors { left: parent.left; right: parent.right } elide: Text.ElideRight; fontSize: "small"; wrapMode: Text.Wrap; maximumLineCount: 2; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: "grey"; visible: showHeader ; text: root.title; font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; horizontalAlignment: root.headerAlignment; }Label { id: subtitleLabel; objectName: "subtitleLabel"; anchors { left: parent.left; right: parent.right } elide: Text.ElideRight; fontSize: "small"; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: "grey"; visible: titleLabel.visible && titleLabel.text; text: cardData && cardData["subtitle"] || ""; font.weight: Font.Light; horizontalAlignment: root.headerAlignment; }}}implicitHeight: row.y + row.height + units.gu(1);}
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property real fontScale: 1.0;
7+ property int headerAlignment: Text.AlignLeft;
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;
14+readonly property size artShapeSize: Qt.size(-1, -1);
15+readonly property int headerHeight: row.height + row.margins * 2;
16+Row {
17+ id: row;
18+ objectName: "outerRow";
19+ property real margins: units.gu(1);
20+ spacing: margins;
21+ anchors.top: parent.top;
22+ anchors.topMargin: units.gu(1);
23+
24+ anchors.left: parent.left;
25+
26+ anchors.right: parent.right;
27+ anchors.margins: margins;
28+Loader {
29+ id: mascotShapeLoader;
30+ objectName: "mascotShapeLoader";
31+ asynchronous: root.asynchronous;
32+ active: mascotImage.status === Image.Ready;
33+ visible: showHeader && active && status == Loader.Ready;
34+ width: units.gu(6);
35+ height: units.gu(5.625);
36+ sourceComponent: UbuntuShape { image: mascotImage }
37+ anchors.verticalCenter: parent.verticalCenter;
38+ }
39+Image {
40+ id: mascotImage;
41+ objectName: "mascotImage";
42+ anchors.verticalCenter: parent.verticalCenter;
43+ readonly property int maxSize: Math.max(width, height) * 4;
44+ source: cardData && cardData["mascot"];
45+ width: units.gu(6);
46+ height: units.gu(5.625);
47+ sourceSize { width: maxSize; height: maxSize }
48+ fillMode: Image.PreserveAspectCrop;
49+ horizontalAlignment: Image.AlignHCenter;
50+ verticalAlignment: Image.AlignVCenter;
51+ visible: showHeader && false;
52+ }
53+Column {
54+ anchors.verticalCenter: parent.verticalCenter;
55+ spacing: units.dp(2);
56+ width: parent.width - x;
57+Label {
58+ id: titleLabel;
59+ objectName: "titleLabel";
60+ anchors { left: parent.left; right: parent.right }
61+
62+ elide: Text.ElideRight;
63+ fontSize: "small";
64+ wrapMode: Text.Wrap;
65+ maximumLineCount: 2;
66+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
67+ color: "grey";
68+ visible: showHeader ;
69+ text: root.title;
70+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
71+ horizontalAlignment: root.headerAlignment;
72+ }
73+Label {
74+ id: subtitleLabel;
75+ objectName: "subtitleLabel";
76+ anchors { left: parent.left; right: parent.right }
77+
78+ elide: Text.ElideRight;
79+ fontSize: "small";
80+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
81+ color: "grey";
82+ visible: titleLabel.visible && titleLabel.text;
83+ text: cardData && cardData["subtitle"] || "";
84+ font.weight: Font.Light;
85+ horizontalAlignment: root.headerAlignment;
86+ }
87+}
88+}
89+implicitHeight: row.y + row.height + units.gu(1);
90+}
tests/plugins/Dash/cardcreator/5.res+140−1
@@ -1 +1,140 @@
1−AbstractButton { id: root; property var template; property var components; property var cardData; property real fontScale: 1.0; property int headerAlignment: Text.AlignLeft; property int fixedHeaderHeight: -1; property size fixedArtShapeSize: Qt.size(-1, -1); readonly property string title: cardData && cardData["title"] || ""; property bool asynchronous: true; property bool showHeader: true; implicitWidth: childrenRect.width; readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);Item { id: artShapeHolder; height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height; width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width; anchors.horizontalCenter: parent.horizontalCenter; Loader { id: artShapeLoader; objectName: "artShapeLoader"; active: cardData && cardData["art"] || false; asynchronous: root.asynchronous; visible: status == Loader.Ready; sourceComponent: UbuntuShape { id: artShape; objectName: "artShape"; radius: "medium"; readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1; readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; Component.onCompleted: updateWidthHeightBindings(); onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); visible: image.status == Image.Ready; function updateWidthHeightBindings() { if (aspectSmallerThanImageAspect) { width = Qt.binding(function() { return !visible ? 0 : image.width }); height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); } else { width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); height = Qt.binding(function() { return !visible ? 0 : image.height }); } } image: Image { objectName: "artImage"; source: cardData && cardData["art"] || ""; cache: true; asynchronous: root.asynchronous; fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; readonly property real aspect: implicitWidth / implicitHeight; width: root.width; height: width / artShape.aspect; } } } }Loader { id: overlayLoader; anchors { left: artShapeHolder.left; right: artShapeHolder.right; bottom: artShapeHolder.bottom; } active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; asynchronous: root.asynchronous; visible: showHeader && status == Loader.Ready; sourceComponent: ShaderEffect { id: overlay; height: fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight; opacity: 0.6; property var source: ShaderEffectSource { id: shaderSource; sourceItem: artShapeLoader.item; onVisibleChanged: if (visible) scheduleUpdate(); live: false; sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height); } vertexShader: " uniform highp mat4 qt_Matrix; attribute highp vec4 qt_Vertex; attribute highp vec2 qt_MultiTexCoord0; varying highp vec2 coord; void main() { coord = qt_MultiTexCoord0; gl_Position = qt_Matrix * qt_Vertex; }"; fragmentShader: " varying highp vec2 coord; uniform sampler2D source; uniform lowp float qt_Opacity; void main() { lowp vec4 tex = texture2D(source, coord); gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; }"; } }readonly property int headerHeight: subtitleLabel.y + subtitleLabel.height - titleLabel.y + titleLabel.anchors.topMargin * 2 + subtitleLabel.anchors.topMargin;Label { id: titleLabel; objectName: "titleLabel"; anchors.left: parent.left; anchors.leftMargin: units.gu(1); anchors.right: parent.right; anchors.top: overlayLoader.top; anchors.topMargin: units.gu(1); elide: Text.ElideRight; fontSize: "small"; wrapMode: Text.Wrap; maximumLineCount: 2; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: "white"; visible: showHeader && overlayLoader.active; text: root.title; font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; horizontalAlignment: root.headerAlignment; }Label { id: subtitleLabel; objectName: "subtitleLabel"; anchors.left: titleLabel.left; anchors.leftMargin: titleLabel.leftMargin; anchors.right: titleLabel.right; anchors.top: titleLabel.bottom; anchors.topMargin: units.dp(2); elide: Text.ElideRight; fontSize: "small"; font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); color: "white"; visible: titleLabel.visible && titleLabel.text; text: cardData && cardData["subtitle"] || ""; font.weight: Font.Light; horizontalAlignment: root.headerAlignment; }implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);}
1+AbstractButton {
2+ id: root;
3+ property var template;
4+ property var components;
5+ property var cardData;
6+ property real fontScale: 1.0;
7+ property int headerAlignment: Text.AlignLeft;
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;
14+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
15+Item {
16+ id: artShapeHolder;
17+ height: root.fixedArtShapeSize.height != -1 ? root.fixedArtShapeSize.height : artShapeLoader.height;
18+ width: root.fixedArtShapeSize.width != -1 ? root.fixedArtShapeSize.width : artShapeLoader.width;
19+ anchors.horizontalCenter: parent.horizontalCenter;
20+
21+ Loader {
22+ id: artShapeLoader;
23+ objectName: "artShapeLoader";
24+ active: cardData && cardData["art"] || false;
25+ asynchronous: root.asynchronous;
26+ visible: status == Loader.Ready;
27+ sourceComponent: UbuntuShape {
28+ id: artShape;
29+ objectName: "artShape";
30+ radius: "medium";
31+ readonly property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1;
32+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
33+ Component.onCompleted: updateWidthHeightBindings();
34+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
35+ visible: image.status == Image.Ready;
36+ function updateWidthHeightBindings() {
37+ if (aspectSmallerThanImageAspect) {
38+ width = Qt.binding(function() { return !visible ? 0 : image.width });
39+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
40+ } else {
41+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
42+ height = Qt.binding(function() { return !visible ? 0 : image.height });
43+ }
44+ }
45+ image: Image {
46+ objectName: "artImage";
47+ source: cardData && cardData["art"] || "";
48+ cache: true;
49+ asynchronous: root.asynchronous;
50+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
51+ readonly property real aspect: implicitWidth / implicitHeight;
52+ width: root.width;
53+ height: width / artShape.aspect;
54+
55+ }
56+ }
57+ }
58+ }
59+Loader {
60+ id: overlayLoader;
61+ anchors {
62+ left: artShapeHolder.left;
63+ right: artShapeHolder.right;
64+ bottom: artShapeHolder.bottom;
65+ }
66+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
67+ asynchronous: root.asynchronous;
68+ visible: showHeader && status == Loader.Ready;
69+ sourceComponent: ShaderEffect {
70+ id: overlay;
71+ height: fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight;
72+
73+ opacity: 0.6;
74+ property var source: ShaderEffectSource {
75+ id: shaderSource;
76+ sourceItem: artShapeLoader.item;
77+ onVisibleChanged: if (visible) scheduleUpdate();
78+ live: false;
79+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
80+ }
81+ vertexShader: "
82+ uniform highp mat4 qt_Matrix;
83+ attribute highp vec4 qt_Vertex;
84+ attribute highp vec2 qt_MultiTexCoord0;
85+ varying highp vec2 coord;
86+ void main() {
87+ coord = qt_MultiTexCoord0;
88+ gl_Position = qt_Matrix * qt_Vertex;
89+ }";
90+ fragmentShader: "
91+ varying highp vec2 coord;
92+ uniform sampler2D source;
93+ uniform lowp float qt_Opacity;
94+ void main() {
95+ lowp vec4 tex = texture2D(source, coord);
96+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
97+ }";
98+ }
99+ }
100+readonly property int headerHeight: subtitleLabel.y + subtitleLabel.height - titleLabel.y + titleLabel.anchors.topMargin * 2 + subtitleLabel.anchors.topMargin;
101+Label {
102+ id: titleLabel;
103+ objectName: "titleLabel";
104+ anchors.left: parent.left;
105+ anchors.leftMargin: units.gu(1);
106+ anchors.right: parent.right;
107+ anchors.top: overlayLoader.top;
108+ anchors.topMargin: units.gu(1);
109+
110+ elide: Text.ElideRight;
111+ fontSize: "small";
112+ wrapMode: Text.Wrap;
113+ maximumLineCount: 2;
114+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
115+ color: "white";
116+ visible: showHeader && overlayLoader.active;
117+ text: root.title;
118+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
119+ horizontalAlignment: root.headerAlignment;
120+ }
121+Label {
122+ id: subtitleLabel;
123+ objectName: "subtitleLabel";
124+ anchors.left: titleLabel.left;
125+ anchors.leftMargin: titleLabel.leftMargin;
126+ anchors.right: titleLabel.right;
127+ anchors.top: titleLabel.bottom;
128+ anchors.topMargin: units.dp(2);
129+
130+ elide: Text.ElideRight;
131+ fontSize: "small";
132+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
133+ color: "white";
134+ visible: titleLabel.visible && titleLabel.text;
135+ text: cardData && cardData["subtitle"] || "";
136+ font.weight: Font.Light;
137+ horizontalAlignment: root.headerAlignment;
138+ }
139+implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
140+}
tests/plugins/Dash/cardcreatortest.cpp+2−1
@@ -44,7 +44,7 @@ private Q_SLOTS:
44 delete view;
44 delete view;
45 }
45 }
46
46
47− void testKnownCases()
47+ void testKnownCases()
48 {
48 {
49 const QString templateString("template: ");
49 const QString templateString("template: ");
50 const QString componentsString("components: ");
50 const QString componentsString("components: ");
@@ -54,6 +54,7 @@ private Q_SLOTS:
54 QDir d(testDirPath);
54 QDir d(testDirPath);
55 const QStringList testFiles = d.entryList(QStringList() << "*.tst");
55 const QStringList testFiles = d.entryList(QStringList() << "*.tst");
56 foreach(const QString &testFileName, testFiles) {
56 foreach(const QString &testFileName, testFiles) {
57+ qDebug() << testFileName;
57 QFile testFile(testDirPath + testFileName);
58 QFile testFile(testDirPath + testFileName);
58 QVERIFY(testFile.open(QIODevice::ReadOnly));
59 QVERIFY(testFile.open(QIODevice::ReadOnly));
59 QTextStream ts(&testFile);
60 QTextStream ts(&testFile);