@@ -4,9 +4,9 @@ AbstractButton {
4 property var components;
4 property var components;
5 property var cardData;
5 property var cardData;
6 property var artShapeBorderSource: undefined;
6 property var artShapeBorderSource: undefined;
7− property real fontScale: 1.0;
7+ property real fontScale: 1.0;
8− property var scopeStyle: null;
8+ property var scopeStyle: null;
9− property int headerAlignment: Text.AlignLeft;
9+ property int headerAlignment: Text.AlignLeft;
10 property int fixedHeaderHeight: -1;
10 property int fixedHeaderHeight: -1;
11 property size fixedArtShapeSize: Qt.size(-1, -1);
11 property size fixedArtShapeSize: Qt.size(-1, -1);
12 readonly property string title: cardData && cardData["title"] || "";
12 readonly property string title: cardData && cardData["title"] || "";
@@ -16,130 +16,132 @@ AbstractButton {
16onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
16onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
17readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
17readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
19− id: artShapeHolder;
19+ id: artShapeHolder;
20− height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
20+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
21− width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
21+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
22− anchors { horizontalCenter: parent.horizontalCenter; }
22+ anchors { horizontalCenter: parent.horizontalCenter; }
23− Loader {
23+ Loader {
24− id: artShapeLoader;
24+ id: artShapeLoader;
25− objectName: "artShapeLoader";
25+ objectName: "artShapeLoader";
26− active: cardData && cardData["art"] || false;
26+ active: cardData && cardData["art"] || false;
27− asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
29− sourceComponent: UbuntuShape {
31− objectName: "artShape";
33− visible: image.status == Image.Ready;
34− readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39− Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40− function updateWidthHeightBindings() {
41− if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42− width = root.fixedArtShapeSize.width;
43− height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
53− objectName: "artImage";
54− source: cardData && cardData["art"] || "";
56 asynchronous: root.asynchronous;
27 asynchronous: root.asynchronous;
28+ visible: status == Loader.Ready;
29+ sourceComponent: UbuntuShape {
31+ objectName: "artShape";
33+ visible: image.status == Image.Ready;
34+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40+ function updateWidthHeightBindings() {
41+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42+ width = root.fixedArtShapeSize.width;
43+ height = root.fixedArtShapeSize.height;
44+ } else if (aspectSmallerThanImageAspect) {
45+ width = Qt.binding(function() { return !visible ? 0 : image.width });
46+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
48+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49+ height = Qt.binding(function() { return !visible ? 0 : image.height });
53+ objectName: "artImage";
54+ source: cardData && cardData["art"] || "";
56+ asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
57+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
58+ readonly property real aspect: implicitWidth / implicitHeight;
59− width: root.width;
59+ width: root.width;
60− height: width / artShape.aspect;
60+ height: width / artShape.aspect;
66− id: overlayLoader;
66+ id: overlayLoader;
67− anchors {
67+ anchors {
68− left: artShapeHolder.left;
68+ left: artShapeHolder.left;
69− right: artShapeHolder.right;
69+ right: artShapeHolder.right;
70− bottom: artShapeHolder.bottom;
70+ bottom: artShapeHolder.bottom;
72− active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
72+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
73− asynchronous: root.asynchronous;
73+ asynchronous: root.asynchronous;
74− visible: showHeader && status == Loader.Ready;
74+ visible: showHeader && status == Loader.Ready;
75− sourceComponent: ShaderEffect {
75+ sourceComponent: ShaderEffect {
76− id: overlay;
76+ id: overlay;
77− height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
77+ height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
78− opacity: 0.6;
78+ opacity: 0.6;
79− property var source: ShaderEffectSource {
79+ property var source: ShaderEffectSource {
80− id: shaderSource;
80+ id: shaderSource;
81− sourceItem: artShapeLoader.item;
81+ sourceItem: artShapeLoader.item;
82− onVisibleChanged: if (visible) scheduleUpdate();
82+ onVisibleChanged: if (visible) scheduleUpdate();
83− live: false;
83+ live: false;
84− sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
84+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
86− vertexShader: "
86+ vertexShader: "
87− uniform highp mat4 qt_Matrix;
87+ uniform highp mat4 qt_Matrix;
88− attribute highp vec4 qt_Vertex;
88+ attribute highp vec4 qt_Vertex;
89− attribute highp vec2 qt_MultiTexCoord0;
89+ attribute highp vec2 qt_MultiTexCoord0;
90− varying highp vec2 coord;
90+ varying highp vec2 coord;
91− void main() {
91+ void main() {
92− coord = qt_MultiTexCoord0;
92+ coord = qt_MultiTexCoord0;
93− gl_Position = qt_Matrix * qt_Vertex;
93+ gl_Position = qt_Matrix * qt_Vertex;
95− fragmentShader: "
95+ fragmentShader: "
96− varying highp vec2 coord;
96+ varying highp vec2 coord;
97− uniform sampler2D source;
97+ uniform sampler2D source;
98− uniform lowp float qt_Opacity;
98+ uniform lowp float qt_Opacity;
99− void main() {
99+ void main() {
100− lowp vec4 tex = texture2D(source, coord);
100+ lowp vec4 tex = texture2D(source, coord);
101− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
101+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
105readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
105readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
107− id: titleLabel;
107+ id: titleLabel;
108− objectName: "titleLabel";
108+ objectName: "titleLabel";
109− anchors { left: parent.left;
109+ anchors { left: parent.left;
110− leftMargin: units.gu(1);
110+ leftMargin: units.gu(1);
111− right: parent.right;
111+ right: parent.right;
112− top: overlayLoader.top;
113− topMargin: units.gu(1);
112+ rightMargin: units.gu(1);
115− elide: Text.ElideRight;
117− wrapMode: Text.Wrap;
118− maximumLineCount: 2;
119− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
121− visible: showHeader && overlayLoader.active;
113+ top: overlayLoader.top;
123− font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
124− horizontalAlignment: root.headerAlignment;
128− objectName: "subtitleLabel";
129− anchors { left: titleLabel.left;
130− leftMargin: titleLabel.leftMargin;
131− right: titleLabel.right;
132− top: titleLabel.bottom;
133− topMargin: units.dp(2);
114+ topMargin: units.gu(1);
135 elide: Text.ElideRight;
116 elide: Text.ElideRight;
136 fontSize: "small";
117 fontSize: "small";
118+ wrapMode: Text.Wrap;
119+ maximumLineCount: 2;
137 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
120 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
138 color: "white";
121 color: "white";
139− visible: titleLabel.visible && titleLabel.text;
122+ visible: showHeader && overlayLoader.active;
140− text: cardData && cardData["subtitle"] || "";
123+ text: root.title;
141− font.weight: Font.Light;
124+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
142 horizontalAlignment: root.headerAlignment;
125 horizontalAlignment: root.headerAlignment;
129+ objectName: "subtitleLabel";
130+ anchors { left: titleLabel.left;
131+ leftMargin: titleLabel.leftMargin;
132+ right: titleLabel.right;
133+ rightMargin: titleLabel.rightMargin;
134+ top: titleLabel.bottom;
135+ topMargin: units.dp(2);
137+ elide: Text.ElideRight;
139+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
141+ visible: titleLabel.visible && titleLabel.text;
142+ text: cardData && cardData["subtitle"] || "";
143+ font.weight: Font.Light;
144+ horizontalAlignment: root.headerAlignment;
144implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
146implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);