64
64
anchors.fill: parent; \n\
65
65
source: artImage; \n\
66
66
sourceFillMode: UbuntuShape.PreserveAspectCrop; \n\
71
71
var kArtProportionalShapeCode = 'ProportionalShape { \n\
72
anchors.fill: parent; \n\
72
anchors.left: parent.left; \n\
73
anchors.right: parent.right; \n\
73
74
source: artImage; \n\
74
75
aspect: UbuntuShape.DropShadow; \n\
77
// %1 is used as anchors of artShapeHolder
78
// %2 is used as image width
79
// %3 is used as image height
80
// %4 is whether the image should be visible
81
// %5 is used as aspect ratio fallback
82
// %6 is whether the loader should be asynchronous or not
83
// %7 is the shape code we want to use
84
// %8 is injected as code to artImage
85
// %9 is used as image fallback
86
var kArtShapeHolderCode = 'Item { \n\
87
id: artShapeHolder; \n\
88
height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
89
width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width; \n\
92
id: artShapeLoader; \n\
93
objectName: "artShapeLoader"; \n\
94
readonly property string cardArt: cardData && cardData["art"] || %9; \n\
95
onCardArtChanged: { if (item) { item.image.source = cardArt; } } \n\
96
active: cardArt != ""; \n\
98
visible: status == Loader.Ready; \n\
99
sourceComponent: Item { \n\
101
objectName: "artShape"; \n\
102
visible: image.status == Image.Ready; \n\
103
readonly property alias image: artImage; \n\
105
readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
106
readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : %5; \n\
107
Component.onCompleted: { updateWidthHeightBindings(); } \n\
108
Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
109
function updateWidthHeightBindings() { \n\
110
if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
111
width = root.fixedArtShapeSize.width; \n\
112
height = root.fixedArtShapeSize.height; \n\
114
width = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.width }); \n\
115
height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height }); \n\
118
CroppedImageMinimumSourceSize { \n\
120
objectName: "artImage"; \n\
121
source: artShapeLoader.cardArt; \n\
122
asynchronous: %6; \n\
78
// %1 is used as anchors of artShapeLoader
79
// %2 is used as image width
80
// %3 is used as image height
81
// %4 is whether the image should be visible
82
// %5 is whether the loader should be asynchronous or not
83
// %6 is the shape code we want to use
84
// %7 is injected as code to artImage
85
// %8 is used as image fallback
86
var kArtShapeHolderCode = 'Loader { \n\
87
id: artShapeLoader; \n\
88
height: root.fixedArtShapeSize.height; \n\
89
width: root.fixedArtShapeSize.width; \n\
91
objectName: "artShapeLoader"; \n\
92
readonly property string cardArt: cardData && cardData["art"] || %8; \n\
93
onCardArtChanged: { if (item) { item.image.source = cardArt; } } \n\
94
active: cardArt != ""; \n\
96
visible: status === Loader.Ready; \n\
97
sourceComponent: Item { \n\
99
objectName: "artShape"; \n\
100
visible: image.status === Image.Ready; \n\
101
readonly property alias image: artImage; \n\
103
width: root.fixedArtShapeSize.width; \n\
104
height: root.fixedArtShapeSize.height; \n\
105
CroppedImageMinimumSourceSize { \n\
107
objectName: "artImage"; \n\
108
source: artShapeLoader.cardArt; \n\
109
asynchronous: %5; \n\
118
// %1 is used as anchors of artShapeLoader
119
// %2 is used as image width
120
// %3 is used as image height
121
// %4 is whether the image should be visible
122
// %5 is whether the loader should be asynchronous or not
123
// %6 is the shape code we want to use
124
// %7 is injected as code to artImage
125
// %8 is used as image fallback
126
var kArtShapeHolderCodeCardToolCard = 'Loader { \n\
127
id: artShapeLoader; \n\
129
objectName: "artShapeLoader"; \n\
130
readonly property string cardArt: cardData && cardData["art"] || %8; \n\
131
onCardArtChanged: { if (item) { item.image.source = cardArt; } } \n\
132
active: cardArt != ""; \n\
133
asynchronous: %5; \n\
134
visible: status === Loader.Ready; \n\
135
sourceComponent: Item { \n\
137
objectName: "artShape"; \n\
138
visible: image.status === Image.Ready; \n\
139
readonly property alias image: artImage; \n\
141
width: image.status !== Image.Ready ? 0 : image.width; \n\
142
height: image.status !== Image.Ready ? 0 : image.height; \n\
143
CroppedImageMinimumSourceSize { \n\
145
objectName: "artImage"; \n\
146
source: artShapeLoader.cardArt; \n\
147
asynchronous: %5; \n\
413
440
code = 'AbstractButton { \n\
415
442
property var cardData; \n\
416
property string backgroundShapeStyle: "inset"; \n\
443
property string backgroundShapeStyle: "flat"; \n\
417
444
property real fontScale: 1.0; \n\
418
445
property var scopeStyle: null; \n\
420
property size fixedArtShapeSize: Qt.size(-1, -1); \n\
421
446
readonly property string title: cardData && cardData["title"] || ""; \n\
422
447
property bool showHeader: true; \n\
423
448
implicitWidth: childrenRect.width; \n\
425
450
\n'.arg(templateInteractive);
427
code = code.arg(isCardTool ? "" : "property int fixedHeaderHeight: -1; \n");
453
code += "property int fixedHeaderHeight: -1; \n\
454
property size fixedArtShapeSize: Qt.size(-1, -1); \n";
429
457
var hasArt = components["art"] && components["art"]["field"] || false;
430
458
var hasSummary = components["summary"] || false;
484
code += 'readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);\n';
514
code += 'readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);\n';
516
var artShapeAspect = components["art"] && components["art"]["aspect-ratio"] || 1;
517
if (isNaN(artShapeAspect)) {
521
artShapeAspect = "(root.fixedArtShapeSize.width / root.fixedArtShapeSize.height)";
486
524
var widthCode, heightCode;
488
526
if (isHorizontal) {
489
527
artAnchors = 'left: parent.left';
490
528
if (hasMascot || hasTitle) {
491
widthCode = 'height * artShape.aspect'
529
widthCode = 'height * ' + artShapeAspect;
492
530
heightCode = 'headerHeight + 2 * units.gu(1)';
494
532
// This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
495
533
// So we define a "random" height of the image height + 2 gu for the margins
496
widthCode = 'height * artShape.aspect'
534
widthCode = 'height * ' + artShapeAspect
497
535
heightCode = 'units.gu(7.625)';
500
538
artAnchors = 'horizontalCenter: parent.horizontalCenter;';
501
539
widthCode = 'root.width'
502
heightCode = 'width / artShape.aspect';
540
heightCode = 'width / ' + artShapeAspect;
505
var aspectRatio = components["art"] && components["art"]["aspect-ratio"] || 1;
506
if (isNaN(aspectRatio)) {
509
543
var fallback = !isCardTool && components["art"] && components["art"]["fallback"] || "";
510
544
fallback = encodeURI(fallback);
511
545
var fallbackStatusCode = "";
512
546
var fallbackURICode = '""';
513
547
if (fallback !== "") {
514
// fallbackStatusCode has %9 in it because we want to substitute it for fallbackURICode
515
// which in kArtShapeHolderCode is %9
516
fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %9;';
548
// fallbackStatusCode has %8 in it because we want to substitute it for fallbackURICode
549
// which in kArtShapeHolderCode is %8
550
fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %8;';
517
551
fallbackURICode = 'decodeURI("%1")'.arg(fallback);
519
553
var artShapeHolderShapeCode;
864
898
code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(summaryColor);
868
// if (artShapeStyle != "shadow" && artShapeStyle != "icon") {
869
// var touchdownAnchors;
871
901
if (hasSocialActions) {
872
902
var socialAnchors;
873
903
var socialTopAnchor;
875
905
if (hasSummary) socialTopAnchor = 'summary.bottom;';
876
else if (isHorizontal && hasArt) socialTopAnchor = 'artShapeHolder.bottom;';
877
else if (headerAsOverlay && hasArt) socialTopAnchor = 'artShapeHolder.bottom;';
906
else if (isHorizontal && hasArt) socialTopAnchor = 'artShapeLoader.bottom;';
907
else if (headerAsOverlay && hasArt) socialTopAnchor = 'artShapeLoader.bottom;';
878
908
else if (hasHeaderRow) socialTopAnchor = 'row.bottom;';
879
909
else if (hasTitleContainer) socialTopAnchor = 'headerTitleContainer.bottom;';
880
910
else if (hasMascot) socialTopAnchor = 'mascotImage.bottom;';
881
911
else if (hasAttributes) socialTopAnchor = 'attributesRow.bottom;';
882
912
else if (hasSubtitle) socialTopAnchor = 'subtitleLabel.bottom;';
883
913
else if (hasTitle) socialTopAnchor = 'titleLabel.bottom;';
884
else if (hasArt) socialTopAnchor = 'artShapeHolder.bottom;';
914
else if (hasArt) socialTopAnchor = 'artShapeLoader.bottom;';
885
915
else socialTopAnchor = 'parent.top';
887
917
socialAnchors = 'top: ' + socialTopAnchor + ' left: parent.left; right: parent.right; topMargin: units.gu(1);'
896
926
code += kSocialActionsRowCode.arg(socialAnchors).arg(socialColor);
899
if (artShapeStyle != "shadow" && artShapeStyle != "icon") {
929
if (artShapeStyle != "shadow" && artShapeStyle != "icon" && !isCardTool) {
900
930
var touchdownAnchors;
901
931
if (hasBackground) {
902
932
touchdownAnchors = 'fill: backgroundLoader';
903
933
} else if (touchdownOnArtShape) {
904
touchdownAnchors = 'fill: artShapeHolder';
934
touchdownAnchors = 'fill: artShapeLoader';
906
936
touchdownAnchors = 'fill: root'
908
938
code += kTouchdownCode.arg(touchdownAnchors);
911
var implicitHeight = 'implicitHeight: ';
912
if (hasSocialActions) {
913
implicitHeight += 'socialActionsRow.y + socialActionsRow.height + units.gu(1);\n';
914
} else if (hasSummary) {
915
implicitHeight += 'summary.y + summary.height + units.gu(1);\n';
916
} else if (isAudio) {
917
implicitHeight += 'audioButton.height;\n';
918
} else if (headerAsOverlay) {
919
implicitHeight += 'artShapeHolder.height;\n';
920
} else if (hasHeaderRow) {
921
implicitHeight += 'row.y + row.height + units.gu(1);\n';
922
} else if (hasMascot) {
923
implicitHeight += 'mascotImage.y + mascotImage.height;\n';
924
} else if (hasTitleContainer) {
925
implicitHeight += 'headerTitleContainer.y + headerTitleContainer.height + units.gu(1);\n';
926
} else if (hasAttributes) {
927
implicitHeight += 'attributesRow.y + attributesRow.height + units.gu(1);\n';
928
} else if (hasSubtitle) {
929
implicitHeight += 'subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
930
} else if (hasTitle) {
931
implicitHeight += 'titleLabel.y + titleLabel.height + units.gu(1);\n';
933
implicitHeight += 'artShapeHolder.height;\n';
941
if (isCardTool || categoryLayout !== "grid") {
942
var implicitHeight = 'implicitHeight: ';
943
if (hasSocialActions) {
944
implicitHeight += 'socialActionsRow.y + socialActionsRow.height + units.gu(1);\n';
945
} else if (hasSummary) {
946
implicitHeight += 'summary.y + summary.height + units.gu(1);\n';
947
} else if (isAudio) {
948
implicitHeight += 'audioButton.height;\n';
949
} else if (headerAsOverlay) {
950
implicitHeight += 'artShapeLoader.height;\n';
951
} else if (hasHeaderRow) {
952
implicitHeight += 'row.y + row.height + units.gu(1);\n';
953
} else if (hasMascot) {
954
implicitHeight += 'mascotImage.y + mascotImage.height;\n';
955
} else if (hasTitleContainer) {
956
implicitHeight += 'headerTitleContainer.y + headerTitleContainer.height + units.gu(1);\n';
957
} else if (hasAttributes) {
958
implicitHeight += 'attributesRow.y + attributesRow.height + units.gu(1);\n';
959
} else if (hasSubtitle) {
960
implicitHeight += 'subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
961
} else if (hasTitle) {
962
implicitHeight += 'titleLabel.y + titleLabel.height + units.gu(1);\n';
964
implicitHeight += 'artShapeLoader.height;\n';
935
969
implicitHeight = '';
944
function createCardComponent(parent, template, components, isCardTool, artShapeStyle, identifier) {
978
function createCardComponent(parent, template, components, isCardTool, artShapeStyle, categoryLayout, identifier) {
945
979
var imports = 'import QtQuick 2.4; \n\
946
980
import Ubuntu.Components 1.3; \n\
947
981
import Ubuntu.Settings.Components 0.1; \n\
948
982
import Dash 0.1;\n\
949
983
import Utils 0.1;\n';
950
var card = cardString(template, components, isCardTool, artShapeStyle);
984
var card = cardString(template, components, isCardTool, artShapeStyle, categoryLayout);
951
985
var code = imports + 'Component {\n' + card + '}\n';