@@ -4,9 +4,9 @@ AbstractButton {
44 property var components;
55 property var cardData;
66 property var artShapeBorderSource: undefined;
7− property real fontScale: 1.0;
8− property var scopeStyle: null;
9− property int headerAlignment: Text.AlignLeft;
7+ property real fontScale: 1.0;
8+ property var scopeStyle: null;
9+ property int headerAlignment: Text.AlignLeft;
1010 property int fixedHeaderHeight: -1;
1111 property size fixedArtShapeSize: Qt.size(-1, -1);
1212 readonly property string title: cardData && cardData["title"] || "";
@@ -16,124 +16,126 @@ AbstractButton {
1616onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
1717readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
1818Item {
19− id: artShapeHolder;
20− height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
21− width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
22− anchors { horizontalCenter: parent.horizontalCenter; }
23− Loader {
24− id: artShapeLoader;
25− objectName: "artShapeLoader";
26− active: cardData && cardData["art"] || false;
27− asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
29− sourceComponent: UbuntuShape {
30− id: artShape;
31− objectName: "artShape";
32− radius: "medium";
33− visible: image.status == Image.Ready;
34− readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
37− Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
38− function updateWidthHeightBindings() {
39− if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
40− width = root.fixedArtShapeSize.width;
41− height = root.fixedArtShapeSize.height;
42− } else {
43− width = Qt.binding(function() { return !visible ? 0 : image.width });
44− height = Qt.binding(function() { return !visible ? 0 : image.height });
45− }
46− }
47− image: Image {
48− objectName: "artImage";
49− source: cardData && cardData["art"] || "";
50− cache: true;
19+ id: artShapeHolder;
20+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
21+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
22+ anchors { horizontalCenter: parent.horizontalCenter; }
23+ Loader {
24+ id: artShapeLoader;
25+ objectName: "artShapeLoader";
26+ active: cardData && cardData["art"] || false;
5127 asynchronous: root.asynchronous;
52− fillMode: Image.PreserveAspectCrop;
53− width: root.width;
54− height: width / artShape.aspect;
55− }
56− }
57− }
58− }
28+ visible: status == Loader.Ready;
29+ sourceComponent: UbuntuShape {
30+ id: artShape;
31+ objectName: "artShape";
32+ radius: "medium";
33+ visible: image.status == Image.Ready;
34+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
37+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
38+ function updateWidthHeightBindings() {
39+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
40+ width = root.fixedArtShapeSize.width;
41+ height = root.fixedArtShapeSize.height;
42+ } else {
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
45+ }
46+ }
47+ image: Image {
48+ objectName: "artImage";
49+ source: cardData && cardData["art"] || "";
50+ cache: true;
51+ asynchronous: root.asynchronous;
52+ fillMode: Image.PreserveAspectCrop;
53+ width: root.width;
54+ height: width / artShape.aspect;
55+ }
56+ }
57+ }
58+ }
5959Loader {
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 > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
72− opacity: 0.6;
73− property var source: ShaderEffectSource {
74− id: shaderSource;
75− sourceItem: artShapeLoader.item;
76− onVisibleChanged: if (visible) scheduleUpdate();
77− live: false;
78− sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
79− }
80− vertexShader: "
81− uniform highp mat4 qt_Matrix;
82− attribute highp vec4 qt_Vertex;
83− attribute highp vec2 qt_MultiTexCoord0;
84− varying highp vec2 coord;
85− void main() {
86− coord = qt_MultiTexCoord0;
87− gl_Position = qt_Matrix * qt_Vertex;
88− }";
89− fragmentShader: "
90− varying highp vec2 coord;
91− uniform sampler2D source;
92− uniform lowp float qt_Opacity;
93− void main() {
94− lowp vec4 tex = texture2D(source, coord);
95− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
96− }";
97− }
98− }
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 > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
72+ opacity: 0.6;
73+ property var source: ShaderEffectSource {
74+ id: shaderSource;
75+ sourceItem: artShapeLoader.item;
76+ onVisibleChanged: if (visible) scheduleUpdate();
77+ live: false;
78+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
79+ }
80+ vertexShader: "
81+ uniform highp mat4 qt_Matrix;
82+ attribute highp vec4 qt_Vertex;
83+ attribute highp vec2 qt_MultiTexCoord0;
84+ varying highp vec2 coord;
85+ void main() {
86+ coord = qt_MultiTexCoord0;
87+ gl_Position = qt_Matrix * qt_Vertex;
88+ }";
89+ fragmentShader: "
90+ varying highp vec2 coord;
91+ uniform sampler2D source;
92+ uniform lowp float qt_Opacity;
93+ void main() {
94+ lowp vec4 tex = texture2D(source, coord);
95+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
96+ }";
97+ }
98+ }
9999readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
100100Label {
101− id: titleLabel;
102− objectName: "titleLabel";
103− anchors { left: parent.left;
104− leftMargin: units.gu(1);
105− right: parent.right;
106− top: overlayLoader.top;
107− topMargin: units.gu(1);
108−}
109− elide: Text.ElideRight;
110− fontSize: "small";
111− wrapMode: Text.Wrap;
112− maximumLineCount: 2;
113− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
114− color: "white";
115− visible: showHeader && overlayLoader.active;
116− text: root.title;
117− font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
118− horizontalAlignment: root.headerAlignment;
119− }
120−Label {
121− id: subtitleLabel;
122− objectName: "subtitleLabel";
123− anchors { left: titleLabel.left;
124− leftMargin: titleLabel.leftMargin;
125− right: titleLabel.right;
126− top: titleLabel.bottom;
127− topMargin: units.dp(2);
128− }
101+ id: titleLabel;
102+ objectName: "titleLabel";
103+ anchors { left: parent.left;
104+ leftMargin: units.gu(1);
105+ right: parent.right;
106+ rightMargin: units.gu(1);
107+ top: overlayLoader.top;
108+ topMargin: units.gu(1);
109+ }
129110 elide: Text.ElideRight;
130111 fontSize: "small";
112+ wrapMode: Text.Wrap;
113+ maximumLineCount: 2;
131114 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
132115 color: "white";
133− visible: titleLabel.visible && titleLabel.text;
134− text: cardData && cardData["subtitle"] || "";
135− font.weight: Font.Light;
116+ visible: showHeader && overlayLoader.active;
117+ text: root.title;
118+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
136119 horizontalAlignment: root.headerAlignment;
137120 }
121+Label {
122+ id: subtitleLabel;
123+ objectName: "subtitleLabel";
124+ anchors { left: titleLabel.left;
125+ leftMargin: titleLabel.leftMargin;
126+ right: titleLabel.right;
127+ rightMargin: titleLabel.rightMargin;
128+ top: titleLabel.bottom;
129+ topMargin: units.dp(2);
130+ }
131+ elide: Text.ElideRight;
132+ fontSize: "small";
133+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
134+ color: "white";
135+ visible: titleLabel.visible && titleLabel.text;
136+ text: cardData && cardData["subtitle"] || "";
137+ font.weight: Font.Light;
138+ horizontalAlignment: root.headerAlignment;
139+ }
138140implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
139141}