Merge lp:~paulliu/unity8/attribute into lp:unity8

Proposed by Ying-Chun Liu
Status: Merged
Approved by: Albert Astals Cid
Approved revision: 1080
Merged at revision: 1101
Proposed branch: lp:~paulliu/unity8/attribute
Merge into: lp:unity8
Diff against target: 1413 lines (+725/-357)
15 files modified
plugins/Dash/CardAttributes.qml (+65/-0)
plugins/Dash/CardCreator.js (+76/-7)
plugins/Dash/qmldir (+1/-0)
qml/Dash/CardTool.qml (+27/-2)
tests/plugins/Dash/CMakeLists.txt (+1/-0)
tests/plugins/Dash/cardcreator/1.res (+63/-61)
tests/plugins/Dash/cardcreator/2.res (+94/-91)
tests/plugins/Dash/cardcreator/3.res (+77/-74)
tests/plugins/Dash/cardcreator/5.res (+119/-117)
tests/plugins/Dash/cardcreator/7.res (+128/-0)
tests/plugins/Dash/cardcreator/7.tst (+3/-0)
tests/plugins/Dash/cardcreatortest.cpp (+9/-1)
tests/plugins/Dash/tst_CardAttributes.qml (+54/-0)
tests/qmltests/Dash/CardHelpers.js (+5/-3)
tests/qmltests/Dash/tst_Card.qml (+3/-1)
To merge this branch: bzr merge lp:~paulliu/unity8/attribute
Reviewer Review Type Date Requested Status
Albert Astals Cid (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Michał Sawicz Needs Fixing
Michal Hruby (community) Needs Fixing
Review via email: mp+223242@code.launchpad.net

Commit message

Implement Attribute UI.

Description of the change

* Are there any related MPs required for this MP to build/function as expected?
No

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

 * If you changed the UI, has there been a design review?
Not yet.

To post a comment you must log in.
lp:~paulliu/unity8/attribute updated
970. By Paweł Stołowski on 2014-06-16

Extend the hack for click scope categories with the upcoming 'store' category: single-tap on results from the 'store' category should activate them, instead of requesting a preview. Fixes: 1326292

971. By Albert Astals Cid on 2014-06-16

Drop the " Preview" suffix from Preview title

As requested in https://bugs.launchpad.net/unity8/+bug/1316671 Fixes: 1316671

972. By PS Jenkins bot on 2014-06-16

Releasing 7.89+14.10.20140616.1-0ubuntu1

lp:~paulliu/unity8/attribute updated
973. By Launchpad Translations on behalf of unity-team on 2014-06-17

Launchpad automatic translations update.

974. By Albert Astals Cid on 2014-06-19

Departments support Fixes: 1320847

975. By PS Jenkins bot on 2014-06-19

Releasing 7.89+14.10.20140619.2-0ubuntu1

976. By PS Jenkins bot on 2014-06-19

No change rebuild against Qt 5.3

977. By PS Jenkins bot on 2014-06-19

Releasing 7.89+14.10.20140619.3-0ubuntu1

978. By Mirco Müller on 2014-06-23

Added the frontend-part of sound-hint support for notifications with updated QML-tests.

979. By Albert Astals Cid on 2014-06-23

Add VerticalJournal integration to Dash/scopes/QML Fixes: 1326467

980. By Michał Sawicz on 2014-06-23

Make so that fixedArtShapeSize actually fixes artShapeSize.

981. By PS Jenkins bot on 2014-06-23

Releasing 7.89+14.10.20140623.1-0ubuntu1

982. By Launchpad Translations on behalf of unity-team on 2014-06-24

Launchpad automatic translations update.

983. By Ying-Chun Liu on 2014-06-24

Add logout support.

Reviewed by: Daniel d'Andrada Fixes: 1302213

984. By PS Jenkins bot on 2014-06-24

Releasing 7.89+14.10.20140624-0ubuntu1

Michał Sawicz (saviq) wrote :

You need to merge trunk.

review: Needs Fixing
lp:~paulliu/unity8/attribute updated
985. By Alberto Aguirre on 2014-06-24

Update Powerd plugin and Shell.qml to accommodate changes in the display power state notification.

986. By PS Jenkins bot on 2014-06-24

Releasing 7.89+14.10.20140624.1-0ubuntu1

987. By PS Jenkins bot on 2014-06-26

Resync trunk

988. By Launchpad Translations on behalf of unity-team on 2014-06-27

Launchpad automatic translations update.

989. By Michał Sawicz on 2014-06-27

Adapt scope mock to new api and quiet unused variable warnings.

990. By Michael Terry on 2014-06-27

Fix path in launcher mock after moving our mock icons, to avoid a lot of "icon not found" warnings during qmluitests.

991. By Ying-Chun Liu on 2014-06-27

Fix LP:1330957
Fix some failed test cases. Fixes: 1330957

992. By Albert Astals Cid on 2014-06-27

Don't seem to need this waitForRendering

And makes test fail in 5.3

993. By Michael Terry on 2014-06-27

Fix the testMultiGreeter qmluitest. Incoming method variables are apparently read-only in Qt5.3. Fixes: 1332488

994. By Michał Sawicz on 2014-06-27

Fix dynamic overlay height. Fixes: 1334879

995. By Michał Sawicz on 2014-06-27

Don't center items in CardVerticalJournal, kind of beats the purpose... Also don't bind unnecessarily.

996. By PS Jenkins bot on 2014-06-27

Releasing 7.89+14.10.20140627-0ubuntu1

Michal Hruby (mhr3) wrote :

66 + text: modelData["text"]; \n\

Can you please use "value" instead of "text", that's what the shell plugin expects and server scopes provide already. Unless someone feels strongly about using "text", then we can change it.

review: Needs Fixing
lp:~paulliu/unity8/attribute updated
997. By Didier Roche on 2014-07-01

switch the default theme to suru Fixes: 1246688

998. By PS Jenkins bot on 2014-07-01

Releasing 7.90+14.10.20140701.2-0ubuntu1

999. By Sebastien Bacher on 2014-07-03

Resync distro.

1000. By Michal Hruby on 2014-07-03

Cache network requests to reduce data usage and increase dash icon loading speed.

1001. By Leo Arias on 2014-07-03

Fixed style and static python errors.

1002. By Nick Dedekind on 2014-07-03

Moved [Message]MenuItemFacotory from Unity.Indicators plugin to qml folder.

1003. By Michael Zanetti on 2014-07-03

drop launcher item spacing Fixes: 1332022

1004. By Michał Sawicz on 2014-07-03

Initial code for a payment button widget, to handle purchasing apps from the click scope.

1005. By Michael Zanetti on 2014-07-03

change wording in launcher quicklist Fixes: 1332035

1006. By Albert Astals Cid on 2014-07-03

EasingCurve: Initialize members

1007. By Albert Astals Cid on 2014-07-03

Fix valgrind warning by not emitting reset on model destructor

That won't be supported until Qt 5.4

More info at https://bugreports.qt-project.org/browse/QTBUG-39780

Warning was

==16693== Invalid read of size 8
==16693== at 0x72B19A0: QQmlContext::isValid() const (qqmlcontext.cpp:231)
==16693== by 0x736C82B: QQmlDelegateModelPrivate::emitChanges() (qqmldelegatemodel.cpp:1412)
==16693== by 0x7372AE6: QQmlDelegateModel::_q_modelReset() (qqmldelegatemodel.cpp:1463)
==16693== by 0x7397224: QQmlDelegateModel::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (moc_qqmldelegatemodel_p.cpp:196)
==16693== by 0x739769E: QQmlDelegateModel::qt_metacall(QMetaObject::Call, int, void**) (moc_qqmldelegatemodel_p.cpp:292)
==16693== by 0x66379CC: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==16693== by 0x65AEEFD: QAbstractItemModel::endResetModel() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==16693== by 0x23461EFD: FakeIndicatorsModel::unload() (fakeindicatorsmodel.cpp:53)
==16693== by 0x23461E13: FakeIndicatorsModel::~FakeIndicatorsModel() (fakeindicatorsmodel.cpp:34)
==16693== by 0x2345C073: QQmlPrivate::QQmlElement<FakeIndicatorsModel>::~QQmlElement() (in /home/tsdgeos_work/phablet/unity8/investigate_test_shell_crash/builddir/tests/mocks/Unity/Indicators/libIndicatorsFakeQml.so)
==16693== by 0x2345C0A3: QQmlPrivate::QQmlElement<FakeIndicatorsModel>::~QQmlElement() (qqmlprivate.h:106)
==16693== by 0x663636B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==16693== Address 0x1862d448 is 8 bytes inside a block of size 16 free'd
==16693== at 0x4C2C2BC: operator delete(void*) (vg_replace_malloc.c:503)
==16693== by 0x72B21B8: QQmlContextData::destroy() (qqmlcontext.cpp:647)
==16693== by 0x7293458: QQmlPrivate::qdeclarativeelement_destructor(QObject*) (qqmlengine.cpp:612)
==16693== by 0x6C0CADD: QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement() (qqmlprivate.h:105)
==16693== by 0x663636B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==16693== by 0x663F0EB: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==16693== by 0x6BF64B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064)
==16693== by 0x6C0CAE5: QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement() (qqmlprivate.h:106)
==16693== by 0x663636B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==16693== by 0x663F0EB: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==16693== by 0x6BF64B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064)
==16693== by 0x6C0CAE5: QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement() (qqmlprivate.h:106)
 Fixes: 1332598

1008. By Renato Araujo Oliveira Filho on 2014-07-03

Create IndicatorsLight.qml component used to control indicator led.

A blue led will pulse if the message indicator is blue and screen is off.

1009. By PS Jenkins bot on 2014-07-03

Releasing 7.90+14.10.20140703.1-0ubuntu1

1010. By Launchpad Translations on behalf of unity-team on 2014-07-04

Launchpad automatic translations update.

1011. By Launchpad Translations on behalf of unity-team on 2014-07-05

Launchpad automatic translations update.

lp:~paulliu/unity8/attribute updated
1012. By Launchpad Translations on behalf of unity-team on 2014-07-07

Launchpad automatic translations update.

1013. By Nick Dedekind on 2014-07-07

Added support for TransferMenu
Approved by: Charles Kerr, Michał Sawicz

1014. By PS Jenkins bot on 2014-07-07

Releasing 7.90+14.10.20140707-0ubuntu1

1015. By Launchpad Translations on behalf of unity-team on 2014-07-09

Launchpad automatic translations update.

Michał Sawicz (saviq) wrote :

See inline.

BTW, when you merge / rebase, don't copy the whole commit log, it's available in the commit hierarchy anyway and just make it hard to read.

review: Needs Fixing
lp:~paulliu/unity8/attribute updated
1016. By Michael Zanetti on 2014-07-09

make the launcher's drag'n'drop indicator more prominent Fixes: 1332042
Approved by: PS Jenkins bot, Andrea Cimitan

1017. By Michael Zanetti on 2014-07-09

make launcher items live

having them non-live is not really required and reveals an issue in combination with UbuntuShape Fixes: 1302761
Approved by: PS Jenkins bot, Andrea Cimitan

1018. By Michael Zanetti on 2014-07-09

Fade out launcher in place instead of moving it to the left on long left edge swipes. Fixes: 1332096
Approved by: Vesa Rautiainen, Michał Sawicz, PS Jenkins bot

1019. By Michael Zanetti on 2014-07-09

update launcher icon glow as requested by design Fixes: 1336725
Approved by: Vesa Rautiainen, Michał Sawicz

1020. By Michael Zanetti on 2014-07-09

update header in dash to use the new header from the SDK Fixes: 1335491
Approved by: Michał Sawicz

1021. By Michał Sawicz on 2014-07-09

Refactor carousel item activation.
Approved by: Andrea Cimitan, Michael Zanetti

1022. By Albert Astals Cid on 2014-07-09

We need to boostrap height also when we have 1 item ^_^
 Fixes: 1337408
Approved by: Michał Sawicz

1023. By Michał Sawicz on 2014-07-09

Refactor ScopeItem into GenericScopeView.
Approved by: Michael Zanetti, Michael Zanetti

1024. By Michal Hruby on 2014-07-09

Fix FTBFS when using latest unity-api.
Approved by: Michał Sawicz

1025. By Michał Sawicz on 2014-07-09

Add initial support for scope customizations.
Approved by: Michael Zanetti, Michael Zanetti

1026. By Nick Dedekind on 2014-07-09

Added active call hint

A hint is displayed in the indicator panel when an call is active on the Telephony Serivce
Approved by: Olga Kemmet, Daniel d'Andrada, PS Jenkins bot, Michał Sawicz

1027. By Michał Sawicz on 2014-07-09

Make rating stars in PreviewReviewDisplay.qml non-interactive. Fixes: 1337508
Approved by: PS Jenkins bot, Andrea Cimitan, PS Jenkins bot

1028. By Michael Zanetti on 2014-07-09

fix testPreview with larger GRID_UNIT_PX values
Approved by: PS Jenkins bot, Michał Sawicz

1029. By Albert Astals Cid on 2014-07-09

CardCreator: Give a correct implicitHeight if we only have art

The hasSubtitle change is really unrelated and not needed here, just sneaking it in to not create yet another review. Fixes: 1330899
Approved by: Michał Sawicz

1030. By Albert Astals Cid on 2014-07-09

Fake Scopes Plugin: Register PreviewModelInterface

Approved by: Michał Sawicz

1031. By PS Jenkins bot on 2014-07-09

make launcher items live

having them non-live is not really required and reveals an issue in combination with UbuntuShape Fixes: 1302761
Approved by: PS Jenkins bot, Andrea Cimitan

1032. By Michael Zanetti on 2014-07-09

clip the corner of pinned icons in the launcher as per new design
Approved by: PS Jenkins bot, Vesa Rautiainen, PS Jenkins bot, Michał Sawicz

1033. By Michael Zanetti on 2014-07-09

update launcher background according to latest design Fixes: 1336314
Approved by: PS Jenkins bot, PS Jenkins bot, Michał Sawicz, PS Jenkins bot

1034. By Michael Zanetti on 2014-07-09

Update Launcher's home button design according to new spec. Fixes: 1329331
Approved by: Michał Sawicz

1035. By PS Jenkins bot on 2014-07-09

Releasing 7.90+14.10.20140709.2-0ubuntu1

1036. By Launchpad Translations on behalf of unity-team on 2014-07-10

Launchpad automatic translations update.

Albert Astals Cid (aacid) wrote :

Conflict adding file tests/plugins/Dash/cardcreator/6.res. Moved existing file to tests/plugins/Dash/cardcreator/6.res.moved.
Conflict adding file tests/plugins/Dash/cardcreator/6.tst. Moved existing file to tests/plugins/Dash/cardcreator/6.tst.moved.
2 conflicts encountered.

review: Needs Fixing
lp:~paulliu/unity8/attribute updated
1037. By Launchpad Translations on behalf of unity-team on 2014-07-11

Launchpad automatic translations update.

1038. By Launchpad Translations on behalf of unity-team on 2014-07-12

Launchpad automatic translations update.

1039. By Launchpad Translations on behalf of unity-team on 2014-07-13

Launchpad automatic translations update.

1040. By Launchpad Translations on behalf of unity-team on 2014-07-14

Launchpad automatic translations update.

1041. By Michał Sawicz on 2014-07-14

Activate all results in click scope by default. Fixes: 1341262
Approved by: Alejandro J. Cura, PS Jenkins bot, Albert Astals Cid

1042. By Mirco Müller on 2014-07-14

Added support for utilization of the ComboButton SDK-element for snap-decision notifications with many actions.
Approved by: Michał Sawicz, PS Jenkins bot

1043. By PS Jenkins bot on 2014-07-14

Releasing 7.90+14.10.20140714-0ubuntu1

1044. By Launchpad Translations on behalf of unity-team on 2014-07-15

Launchpad automatic translations update.

1045. By Launchpad Translations on behalf of unity-team on 2014-07-16

Launchpad automatic translations update.

1046. By Launchpad Translations on behalf of unity-team on 2014-07-17

Launchpad automatic translations update.

1047. By Michael Terry on 2014-07-17

Expose a new greeter DBus property, IsActive, which tells apps and indicators when the integrated-greeter screen is active. Useful for switching UI modes when the screen is locked.
Approved by: Michael Zanetti, PS Jenkins bot

1048. By Michał Sawicz on 2014-07-17

Only generate .qmltypes files manually, no need to do it build-time.

It didn't work when cross-compiling either, and required builders to have otherwise unnecessary environment.
Approved by: Michael Zanetti

1049. By Michael Terry on 2014-07-17

Allow the session to bring up the greeter/lockscreen over DBus. The emergency dialer will need this support in order to cancel bringing it up.
Approved by: Michael Zanetti, PS Jenkins bot

1050. By Ying-Chun Liu on 2014-07-17

Add reboot/shutdown Fixes: 1234062
Approved by: Michael Zanetti

1051. By Michał Sawicz on 2014-07-17

Fix CardCreator test. It got broken with a merge that got landed along side of it.
Approved by: Albert Astals Cid

1052. By Mirco Müller on 2014-07-17

Fixes gap at top of sim-unlock/fullscreen notification (point 1.), fixes blocking overlay if underlying UnityMenuModel vanishes from DBus (point 2.). The third bullet-point of the bug-report, lockup of shell-UI, could not be reproduced. Fixes: 1308011
Approved by: Michał Sawicz

1053. By Albert Astals Cid on 2014-07-17

Make the departments test more stable

Approved by: Michael Zanetti, PS Jenkins bot

1054. By PS Jenkins bot on 2014-07-17

Releasing 7.90+14.10.20140717.1-0ubuntu1

1055. By Nick Dedekind on 2014-07-17

Added environment variable to upstart conf for mir trusted socket
Approved by: Michał Sawicz

1056. By Nick Dedekind on 2014-07-17

Removed indicator menu dismissal on menu activation Fixes: 1337771
Approved by: Michał Sawicz

1057. By PS Jenkins bot on 2014-07-17

Releasing 7.90+14.10.20140717.3-0ubuntu1

1058. By Launchpad Translations on behalf of unity-team on 2014-07-18

Launchpad automatic translations update.

1059. By Launchpad Translations on behalf of unity-team on 2014-07-19

Launchpad automatic translations update.

1060. By Launchpad Translations on behalf of unity-team on 2014-07-20

Launchpad automatic translations update.

1061. By Launchpad Translations on behalf of unity-team on 2014-07-21

Launchpad automatic translations update.

1062. By Ying-Chun Liu on 2014-07-21

Add attribute UI.

1063. By Ying-Chun Liu on 2014-07-21

Fix 7.tst

1064. By Ying-Chun Liu on 2014-07-21

Add test icons.

Michał Sawicz (saviq) wrote :

plugins/Dash/CardAttributesGrid.qml UNKNOWN *No copyright*

lp:~paulliu/unity8/attribute updated
1065. By Ying-Chun Liu on 2014-07-22

Rename CardAttributesGrid to CardAttributes.
Add copyright header to CardAttributes.qml.

Albert Astals Cid (aacid) wrote :

Merge issues have been fixed

review: Abstain
Albert Astals Cid (aacid) wrote :

* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes, only using the tests since there seems there's no scope that returns this at the moment

 * Did CI run pass? If not, please explain why.
No, known unstable/broken tests

Will wait to have a test-scope that uses this to top approve

review: Approve
lp:~paulliu/unity8/attribute updated
1066. By Ying-Chun Liu on 2014-07-23

Add code for subtitle is not appeared

Albert Astals Cid (aacid) wrote :

Without mascot -> It breaks
Text of attributes -> needs to be "Small"
if remove subtitle -> needs to go a bit up under the title

review: Needs Fixing
lp:~paulliu/unity8/attribute updated
1067. By Ying-Chun Liu on 2014-07-23

Fix anchors/non-subtitles.

1068. By Ying-Chun Liu on 2014-07-23

Fix summary Top anchor for attributes.

lp:~paulliu/unity8/attribute updated
1069. By Ying-Chun Liu on 2014-07-23

Add color.
Fix rightMargin.

lp:~paulliu/unity8/attribute updated
1070. By Ying-Chun Liu on 2014-07-24

Fix implicitHeight.
Update *.res

1071. By Ying-Chun Liu on 2014-07-24

Fix height again.

Albert Astals Cid (aacid) wrote :

Paul knows, but just so that we don't forget, there's still height issues when the title is two lines height

review: Needs Fixing
lp:~paulliu/unity8/attribute updated
1072. By Ying-Chun Liu on 2014-07-24

Fix GridLayout height sometimes 0.

lp:~paulliu/unity8/attribute updated
1073. By Ying-Chun Liu on 2014-07-24

Revert workarounds.
Add maxData for attributes to CardTool.

lp:~paulliu/unity8/attribute updated
1074. By Ying-Chun Liu on 2014-07-25

test 5 attributes.

1075. By Ying-Chun Liu on 2014-07-25

Fix CardTool to generate attributes dynamically.

Albert Astals Cid (aacid) wrote :

Need to use the max-count from attributes in the CardTool.

review: Needs Fixing
lp:~paulliu/unity8/attribute updated
1076. By Ying-Chun Liu on 2014-07-25

Add max-count for attributes

1077. By Ying-Chun Liu on 2014-07-25

test cardData.

1078. By Ying-Chun Liu on 2014-07-25

Merge trunk.

Albert Astals Cid (aacid) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Yes, it's been extensively tested this week in the London design sprint

 * Did CI run pass? If not, please explain why.
It's passing locally here but I'll wait for r1078 CI run to finish before top approving.

review: Approve
Albert Astals Cid (aacid) wrote :

Running make testCard gets me

QWARN : qmltestrunner::Card::test_summary_layout(Without header) file:///home/tsdgeos_work/phablet/unity8/attribute/builddir/plugins/Dash/createCardComponent:103: ReferenceError: attributesRow is not defined
QWARN : qmltestrunner::Card::test_summary_layout(Without header) file:///home/tsdgeos_work/phablet/unity8/attribute/builddir/plugins/Dash/createCardComponent:108: ReferenceError: attributesRow is not defined
QWARN : qmltestrunner::Card::test_summary_layout(Without header) file:///home/tsdgeos_work/phablet/unity8/attribute/builddir/plugins/Dash/createCardComponent:103: ReferenceError: attributesRow is not defined
QWARN : qmltestrunner::Card::test_summary_layout(Without header) file:///home/tsdgeos_work/phablet/unity8/attribute/builddir/plugins/Dash/createCardComponent:108: ReferenceError: attributesRow is not defined
QWARN : qmltestrunner::Card::test_summary_layout(Without header) file:///home/tsdgeos_work/phablet/unity8/attribute/builddir/plugins/Dash/createCardComponent:23: ReferenceError: attributesRow is not defined
QWARN : qmltestrunner::Card::test_summary_layout(Without header) file:///home/tsdgeos_work/phablet/unity8/attribute/builddir/plugins/Dash/createCardComponent:22: ReferenceError: attributesRow is not defined
QWARN : qmltestrunner::Card::test_summary_layout(Without header) file:///home/tsdgeos_work/phablet/unity8/attribute/builddir/plugins/Dash/createCardComponent:23: ReferenceError: attributesRow is not defined
QWARN : qmltestrunner::Card::test_summary_layout(Without header) file:///home/tsdgeos_work/phablet/unity8/attribute/builddir/plugins/Dash/createCardComponent:22: ReferenceError: attributesRow is not defined

a lot, can you have a look?

review: Needs Fixing
Albert Astals Cid (aacid) wrote :

make tryCard, choose the "Art, summary" option, see how it displays broken.

review: Needs Fixing
lp:~paulliu/unity8/attribute updated
1079. By Ying-Chun Liu on 2014-07-28

Fix Reference error on summary.

lp:~paulliu/unity8/attribute updated
1080. By Ying-Chun Liu on 2014-07-28

Remove the TODO line.

Albert Astals Cid (aacid) wrote :

* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes

* Did CI run pass? If not, please explain why.
It did

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'plugins/Dash/CardAttributes.qml'
2--- plugins/Dash/CardAttributes.qml 1970-01-01 00:00:00 +0000
3+++ plugins/Dash/CardAttributes.qml 2014-07-28 12:00:26 +0000
4@@ -0,0 +1,65 @@
5+/*
6+ * Copyright 2014 Canonical Ltd.
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+import QtQuick 2.2
22+import QtQuick.Layouts 1.1
23+import Ubuntu.Components 1.1
24+import Ubuntu.Settings.Components 0.1
25+
26+GridLayout {
27+ id: grid
28+ anchors {
29+ left: parent.left;
30+ right: parent.right;
31+ }
32+ columns: 2 + repeater.count % 2
33+ property alias model: repeater.model
34+ property var color
35+
36+ Repeater {
37+ id: repeater
38+ delegate: Row {
39+ spacing: units.gu(0.5)
40+ readonly property int column: index % grid.columns;
41+ Layout.alignment: {
42+ if (column == 0) return Qt.AlignLeft;
43+ if (column == grid.columns - 1 || index == repeater.count - 1) return Qt.AlignRight;
44+ if (column == 1) return Qt.AlignHCenter;
45+ }
46+ Layout.columnSpan: index == repeater.count - 1 && grid.columns == 3 && column == 1 ? 2 : 1
47+ Layout.maximumWidth: Math.max(icon.width, label.x + label.implicitWidth)
48+ Layout.fillWidth: true
49+ StatusIcon {
50+ id: icon
51+ height: units.gu(2)
52+ sets: ["actions", "status", "apps"]
53+ source: "icon" in modelData ? modelData["icon"] : ""
54+ }
55+ Label {
56+ id: label
57+ width: parent.width - x
58+ anchors.verticalCenter: parent.verticalCenter
59+ text: "value" in modelData ? modelData["value"] : "";
60+ elide: Text.ElideRight
61+ maximumLineCount: 1
62+ font.weight: "style" in modelData && modelData["style"] == "highlighted" ? Font.DemiBold : Font.Light
63+ fontSize: "small"
64+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
65+ color: grid.color
66+ }
67+ }
68+ }
69+}
70
71=== modified file 'plugins/Dash/CardCreator.js'
72--- plugins/Dash/CardCreator.js 2014-07-09 19:44:44 +0000
73+++ plugins/Dash/CardCreator.js 2014-07-28 12:00:26 +0000
74@@ -193,6 +193,21 @@
75 ] \n\
76 }\n';
77
78+// multiple column version of kHeaderColumnCode.
79+function kHeaderColumnCodeGenerator() {
80+ var headerColumnCodeTemplate = 'Column { \n\
81+ anchors.verticalCenter: parent.verticalCenter; \n\
82+ spacing: units.dp(2); \n\
83+ width: parent.width - x;\n\
84+ data: [ \n\
85+ %1 \n\
86+ ]\n\
87+ }\n';
88+ var args = Array.prototype.slice.call(arguments);
89+ var code = headerColumnCodeTemplate.arg(args.join(',\n'));
90+ return code;
91+}
92+
93 // %1 is used as anchors of mascotShapeLoader
94 var kMascotShapeLoaderCode = 'Loader { \n\
95 id: mascotShapeLoader; \n\
96@@ -224,7 +239,7 @@
97 }\n';
98
99 // %1 is used as anchors of titleLabel
100-// %1 is used as color of titleLabel
101+// %2 is used as color of titleLabel
102 // %3 is used as extra condition for visible of titleLabel
103 var kTitleLabelCode = 'Label { \n\
104 id: titleLabel; \n\
105@@ -258,6 +273,15 @@
106 horizontalAlignment: root.headerAlignment; \n\
107 }\n';
108
109+// %1 is used as anchors of attributesRow
110+var kAttributesRowCode = 'CardAttributes { \n\
111+ id: attributesRow; \n\
112+ objectName: "attributesRow"; \n\
113+ anchors { %1 } \n\
114+ color: %2; \n\
115+ model: cardData && cardData["attributes"] || undefined; \n\
116+ }\n';
117+
118 // %1 is used as top anchor of summary
119 // %2 is used as topMargin anchor of summary
120 // %3 is used as color of summary
121@@ -308,6 +332,7 @@
122 var headerAsOverlay = hasArt && template && template["overlay"] === true && (hasTitle || hasMascot);
123 var hasSubtitle = hasTitle && components["subtitle"] || false;
124 var hasHeaderRow = hasMascot && hasTitle;
125+ var hasAttributes = hasTitle && components["attributes"] || false;
126
127 if (hasBackground) {
128 code += kBackgroundLoaderCode;
129@@ -377,6 +402,14 @@
130 code += 'readonly property int headerHeight: row.height;\n'
131 } else if (hasMascot) {
132 code += 'readonly property int headerHeight: mascotImage.height;\n'
133+ } else if (hasAttributes) {
134+ if (hasTitle && hasSubtitle) {
135+ code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + attributesRow.height + attributesRow.anchors.topMargin;\n'
136+ } else if (hasTitle) {
137+ code += 'readonly property int headerHeight: titleLabel.height + attributesRow.height + attributesRow.anchors.topMargin;\n'
138+ } else {
139+ code += 'readonly property int headerHeight: attributesRow.height;\n'
140+ }
141 } else if (hasSubtitle) {
142 code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
143 } else if (hasTitle) {
144@@ -425,10 +458,12 @@
145
146 var titleAnchors;
147 var subtitleAnchors;
148- if (hasMascot && hasSubtitle) {
149+ var attributesAnchors;
150+ if (hasMascot && (hasSubtitle || hasAttributes)) {
151 // Using row + column
152 titleAnchors = 'left: parent.left; right: parent.right';
153 subtitleAnchors = titleAnchors;
154+ attributesAnchors = subtitleAnchors;
155 } else if (hasMascot) {
156 // Using row + label
157 titleAnchors = 'verticalCenter: parent.verticalCenter;\n'
158@@ -438,11 +473,13 @@
159 titleAnchors = 'left: parent.left; \n\
160 leftMargin: units.gu(1); \n\
161 right: parent.right; \n\
162+ rightMargin: units.gu(1); \n\
163 top: overlayLoader.top; \n\
164 topMargin: units.gu(1);\n';
165 } else {
166 // Using anchors to the mascot/parent
167- titleAnchors = "right: parent.right;";
168+ titleAnchors = "right: parent.right;\n";
169+ titleAnchors += "rightMargin: units.gu(1);\n";
170 titleAnchors += headerLeftAnchor;
171 titleAnchors += headerVerticalAnchors;
172 if (!headerLeftAnchorHasMargin) {
173@@ -452,8 +489,19 @@
174 subtitleAnchors = 'left: titleLabel.left; \n\
175 leftMargin: titleLabel.leftMargin; \n\
176 right: titleLabel.right; \n\
177+ rightMargin: titleLabel.rightMargin; \n\
178 top: titleLabel.bottom; \n\
179 topMargin: units.dp(2);\n';
180+ if (hasSubtitle) {
181+ attributesAnchors = 'left: subtitleLabel.left; \n\
182+ leftMargin: subtitleLabel.leftMargin; \n\
183+ right: subtitleLabel.right; \n\
184+ rightMargin: subtitleLabel.rightMargin; \n\
185+ top: subtitleLabel.bottom; \n\
186+ topMargin: units.dp(2);\n';
187+ } else {
188+ attributesAnchors = subtitleAnchors;
189+ }
190 }
191
192 var titleLabelVisibleExtra = (headerAsOverlay ? '&& overlayLoader.active': '');
193@@ -463,11 +511,27 @@
194 subtitleCode += kSubtitleLabelCode.arg(subtitleAnchors).arg(color);
195 }
196
197- if (hasMascot && hasSubtitle) {
198+ if (hasMascot && (hasSubtitle || hasAttributes)) {
199 // If using row + column wrap the code in the column
200 titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(subtitleCode);
201+ if (hasSubtitle && hasAttributes) {
202+ var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color);
203+ titleSubtitleCode = kHeaderColumnCodeGenerator(titleCode, subtitleCode, attributesCode);
204+ } else if (hasSubtitle) {
205+ titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(subtitleCode);
206+ } else if (hasAttributes) {
207+ var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color);
208+ titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(attributesCode);
209+ }
210 } else {
211- titleSubtitleCode = titleCode + subtitleCode;
212+ titleSubtitleCode = titleCode;
213+ if (hasSubtitle) {
214+ titleSubtitleCode = titleSubtitleCode + subtitleCode;
215+ }
216+ if (hasAttributes) {
217+ var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color);
218+ titleSubtitleCode = titleSubtitleCode + attributesCode;
219+ }
220 }
221 }
222
223@@ -487,6 +551,7 @@
224 else if (headerAsOverlay && hasArt) summaryTopAnchor = "artShapeHolder.bottom";
225 else if (hasHeaderRow) summaryTopAnchor = "row.bottom";
226 else if (hasMascot) summaryTopAnchor = "mascotImage.bottom";
227+ else if (hasAttributes) summaryTopAnchor = "attributesRow.bottom";
228 else if (hasSubtitle) summaryTopAnchor = "subtitleLabel.bottom";
229 else if (hasTitle) summaryTopAnchor = "titleLabel.bottom";
230 else if (hasArt) summaryTopAnchor = "artShapeHolder.bottom";
231@@ -499,7 +564,7 @@
232 color = 'root.scopeStyle ? root.scopeStyle.foreground : "grey"';
233 }
234
235- var summaryTopMargin = (hasMascot || hasSubtitle ? 'anchors.margins' : '0');
236+ var summaryTopMargin = (hasMascot || hasSubtitle || hasAttributes ? 'anchors.margins' : '0');
237
238 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
239 }
240@@ -510,6 +575,8 @@
241 code += 'implicitHeight: row.y + row.height + units.gu(1);\n';
242 } else if (hasMascot) {
243 code += 'implicitHeight: mascotImage.y + mascotImage.height;\n';
244+ } else if (hasAttributes) {
245+ code += 'implicitHeight: attributesRow.y + attributesRow.height + units.gu(1);\n';
246 } else if (hasSubtitle) {
247 code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
248 } else if (hasTitle) {
249@@ -526,8 +593,10 @@
250 function createCardComponent(parent, template, components) {
251 var imports = 'import QtQuick 2.2; \n\
252 import Ubuntu.Components 0.1; \n\
253- import Ubuntu.Thumbnailer 0.1;\n';
254+ import Ubuntu.Thumbnailer 0.1;\n\
255+ import Dash 0.1;\n';
256 var card = cardString(template, components);
257 var code = imports + 'Component {\n' + card + '}\n';
258+
259 return Qt.createQmlObject(code, parent, "createCardComponent");
260 }
261
262=== modified file 'plugins/Dash/qmldir'
263--- plugins/Dash/qmldir 2014-07-08 08:30:46 +0000
264+++ plugins/Dash/qmldir 2014-07-28 12:00:26 +0000
265@@ -3,3 +3,4 @@
266 typeinfo Dash.qmltypes
267 singleton CardCreatorCache 0.1 CardCreatorCache.qml
268 ScopeStyle 0.1 ScopeStyle.qml
269+CardAttributes 0.1 CardAttributes.qml
270\ No newline at end of file
271
272=== modified file 'qml/Dash/CardTool.qml'
273--- qml/Dash/CardTool.qml 2014-05-02 14:51:22 +0000
274+++ qml/Dash/CardTool.qml 2014-07-28 12:00:26 +0000
275@@ -165,15 +165,40 @@
276 }
277 }
278
279+ Item {
280+ id: attributesModel
281+ property int numOfAttributes: 0
282+ property var model: []
283+ property bool hasAttributes: {
284+ var attributes = components["attributes"];
285+ var hasAttributesFlag = (attributes != undefined) && attributes["field"];
286+
287+ if (hasAttributesFlag) {
288+ if (attributes["max-count"]) {
289+ numOfAttributes = attributes["max-count"];
290+ }
291+ }
292+ return hasAttributesFlag
293+ }
294+
295+ onNumOfAttributesChanged: {
296+ model = []
297+ for (var i = 0; i < numOfAttributes; i++) {
298+ model.push( {"value":"text"+(i+1), "icon":"image://theme/ok" } );
299+ }
300+ }
301+ }
302+
303 Loader {
304 id: cardLoader
305- property var fields: ["art", "mascot", "title", "subtitle", "summary"]
306+ property var fields: ["art", "mascot", "title", "subtitle", "summary", "attributes"]
307 property var maxData: {
308 "art": Qt.resolvedUrl("graphics/checkers.png"),
309 "mascot": Qt.resolvedUrl("graphics/checkers.png"),
310 "title": "—\n—",
311 "subtitle": "—",
312- "summary": "—\n—\n—\n—\n—"
313+ "summary": "—\n—\n—\n—\n—",
314+ "attributes": attributesModel.model
315 }
316 sourceComponent: cardTool.cardComponent
317 onLoaded: {
318
319=== modified file 'tests/plugins/Dash/CMakeLists.txt'
320--- tests/plugins/Dash/CMakeLists.txt 2014-07-08 08:35:20 +0000
321+++ tests/plugins/Dash/CMakeLists.txt 2014-07-28 12:00:26 +0000
322@@ -79,3 +79,4 @@
323 set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
324 add_qml_test(. ScopeStyle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
325 add_qml_test(. ListViewWithPageHeaderQML IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
326+add_qml_test(. CardAttributes IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
327
328=== modified file 'tests/plugins/Dash/cardcreator/1.res'
329--- tests/plugins/Dash/cardcreator/1.res 2014-07-08 12:37:34 +0000
330+++ tests/plugins/Dash/cardcreator/1.res 2014-07-28 12:00:26 +0000
331@@ -5,8 +5,8 @@
332 property var cardData;
333 property var artShapeBorderSource: undefined;
334 property real fontScale: 1.0;
335- property var scopeStyle: null;
336- property int headerAlignment: Text.AlignLeft;
337+ property var scopeStyle: null;
338+ property int headerAlignment: Text.AlignLeft;
339 property int fixedHeaderHeight: -1;
340 property size fixedArtShapeSize: Qt.size(-1, -1);
341 readonly property string title: cardData && cardData["title"] || "";
342@@ -16,71 +16,73 @@
343 onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
344 readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
345 Item {
346- id: artShapeHolder;
347- height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
348- width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
349- anchors { horizontalCenter: parent.horizontalCenter; }
350- Loader {
351- id: artShapeLoader;
352- objectName: "artShapeLoader";
353- active: cardData && cardData["art"] || false;
354- asynchronous: root.asynchronous;
355- visible: status == Loader.Ready;
356- sourceComponent: UbuntuShape {
357- id: artShape;
358- objectName: "artShape";
359- radius: "medium";
360- visible: image.status == Image.Ready;
361- readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
362- readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
363- readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
364- Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
365- onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
366- Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
367- function updateWidthHeightBindings() {
368- if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
369- width = root.fixedArtShapeSize.width;
370- height = root.fixedArtShapeSize.height;
371- } else if (aspectSmallerThanImageAspect) {
372- width = Qt.binding(function() { return !visible ? 0 : image.width });
373- height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
374- } else {
375- width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
376- height = Qt.binding(function() { return !visible ? 0 : image.height });
377+ id: artShapeHolder;
378+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
379+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
380+ anchors { horizontalCenter: parent.horizontalCenter; }
381+ Loader {
382+ id: artShapeLoader;
383+ objectName: "artShapeLoader";
384+ active: cardData && cardData["art"] || false;
385+ asynchronous: root.asynchronous;
386+ visible: status == Loader.Ready;
387+ sourceComponent: UbuntuShape {
388+ id: artShape;
389+ objectName: "artShape";
390+ radius: "medium";
391+ visible: image.status == Image.Ready;
392+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
393+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
394+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
395+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
396+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
397+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
398+ function updateWidthHeightBindings() {
399+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
400+ width = root.fixedArtShapeSize.width;
401+ height = root.fixedArtShapeSize.height;
402+ } else if (aspectSmallerThanImageAspect) {
403+ width = Qt.binding(function() { return !visible ? 0 : image.width });
404+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
405+ } else {
406+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
407+ height = Qt.binding(function() { return !visible ? 0 : image.height });
408+ }
409+ }
410+ image: Image {
411+ objectName: "artImage";
412+ source: cardData && cardData["art"] || "";
413+ cache: true;
414+ asynchronous: root.asynchronous;
415+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
416+ readonly property real aspect: implicitWidth / implicitHeight;
417+ width: root.width;
418+ height: width / artShape.aspect;
419+ }
420 }
421 }
422- image: Image {
423- objectName: "artImage";
424- source: cardData && cardData["art"] || "";
425- cache: true;
426- asynchronous: root.asynchronous;
427- fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
428- readonly property real aspect: implicitWidth / implicitHeight;
429- width: root.width;
430- height: width / artShape.aspect;
431- }
432- }
433- }
434- }
435+ }
436 readonly property int headerHeight: titleLabel.height;
437 Label {
438- id: titleLabel;
439- objectName: "titleLabel";
440- anchors { right: parent.right;left: parent.left;
441+ id: titleLabel;
442+ objectName: "titleLabel";
443+ anchors { right: parent.right;
444+rightMargin: units.gu(1);
445+left: parent.left;
446 top: artShapeHolder.bottom;
447 topMargin: units.gu(1);
448 leftMargin: units.gu(1);
449- }
450- elide: Text.ElideRight;
451- fontSize: "small";
452- wrapMode: Text.Wrap;
453- maximumLineCount: 2;
454- font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
455- color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
456- visible: showHeader ;
457- text: root.title;
458- font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
459- horizontalAlignment: root.headerAlignment;
460- }
461+ }
462+ elide: Text.ElideRight;
463+ fontSize: "small";
464+ wrapMode: Text.Wrap;
465+ maximumLineCount: 2;
466+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
467+ color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
468+ visible: showHeader ;
469+ text: root.title;
470+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
471+ horizontalAlignment: root.headerAlignment;
472+ }
473 implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
474 }
475
476=== modified file 'tests/plugins/Dash/cardcreator/2.res'
477--- tests/plugins/Dash/cardcreator/2.res 2014-07-08 12:53:51 +0000
478+++ tests/plugins/Dash/cardcreator/2.res 2014-07-28 12:00:26 +0000
479@@ -5,8 +5,8 @@
480 property var cardData;
481 property var artShapeBorderSource: undefined;
482 property real fontScale: 1.0;
483- property var scopeStyle: null;
484- property int headerAlignment: Text.AlignLeft;
485+ property var scopeStyle: null;
486+ property int headerAlignment: Text.AlignLeft;
487 property int fixedHeaderHeight: -1;
488 property size fixedArtShapeSize: Qt.size(-1, -1);
489 readonly property string title: cardData && cardData["title"] || "";
490@@ -14,104 +14,107 @@
491 property bool showHeader: true;
492 implicitWidth: childrenRect.width;
493 Loader {
494- id: backgroundLoader;
495- objectName: "backgroundLoader";
496- anchors.fill: parent;
497- asynchronous: root.asynchronous;
498- visible: status == Loader.Ready;
499- sourceComponent: UbuntuShape {
500- objectName: "background";
501- radius: "medium";
502- color: getColor(0) || "white";
503- gradientColor: getColor(1) || color;
504- anchors.fill: parent;
505- image: backgroundImage.source ? backgroundImage : null;
506- property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
507- property Image backgroundImage: Image {
508- objectName: "backgroundImage";
509- source: {
510- if (cardData && typeof cardData["background"] === "string") return cardData["background"];
511- else if (template && typeof template["card-background"] === "string") return template["card-background"];
512- else return "";
513- }
514- }
515- function getColor(index) {
516- if (cardData && typeof cardData["background"] === "object"
517- && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
518- return cardData["background"]["elements"][index];
519- } else if (template && typeof template["card-background"] === "object"
520- && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
521- return template["card-background"]["elements"][index];
522- } else return undefined;
523- }
524- }
525- }
526+ id: backgroundLoader;
527+ objectName: "backgroundLoader";
528+ anchors.fill: parent;
529+ asynchronous: root.asynchronous;
530+ visible: status == Loader.Ready;
531+ sourceComponent: UbuntuShape {
532+ objectName: "background";
533+ radius: "medium";
534+ color: getColor(0) || "white";
535+ gradientColor: getColor(1) || color;
536+ anchors.fill: parent;
537+ image: backgroundImage.source ? backgroundImage : null;
538+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
539+ property Image backgroundImage: Image {
540+ objectName: "backgroundImage";
541+ source: {
542+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
543+ else if (template && typeof template["card-background"] === "string") return template["card-background"];
544+ else return "";
545+ }
546+ }
547+ function getColor(index) {
548+ if (cardData && typeof cardData["background"] === "object"
549+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
550+ return cardData["background"]["elements"][index];
551+ } else if (template && typeof template["card-background"] === "object"
552+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
553+ return template["card-background"]["elements"][index];
554+ } else return undefined;
555+ }
556+ }
557+ }
558 readonly property size artShapeSize: Qt.size(-1, -1);
559 readonly property int headerHeight: row.height;
560 Row {
561- id: row;
562- objectName: "outerRow";
563- property real margins: units.gu(1);
564- spacing: margins;
565- height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
566- anchors { top: parent.top;
567+ id: row;
568+ objectName: "outerRow";
569+ property real margins: units.gu(1);
570+ spacing: margins;
571+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
572+ anchors { top: parent.top;
573 topMargin: units.gu(1);
574- left: parent.left;
575-}
576- anchors.right: parent.right;
577- anchors.margins: margins;
578-data: [ Image {
579- id: mascotImage;
580- objectName: "mascotImage";
581- anchors { verticalCenter: parent.verticalCenter; }
582- readonly property int maxSize: Math.max(width, height) * 4;
583- source: cardData && cardData["mascot"];
584- width: units.gu(6);
585- height: units.gu(5.625);
586- sourceSize { width: maxSize; height: maxSize }
587- fillMode: Image.PreserveAspectCrop;
588- horizontalAlignment: Image.AlignHCenter;
589- verticalAlignment: Image.AlignVCenter;
590- visible: showHeader;
591- }
592-,
593-Column {
594- anchors.verticalCenter: parent.verticalCenter;
595- spacing: units.dp(2);
596- width: parent.width - x;
597- data: [ Label {
598- id: titleLabel;
599- objectName: "titleLabel";
600- anchors { left: parent.left; right: parent.right }
601- elide: Text.ElideRight;
602- fontSize: "small";
603- wrapMode: Text.Wrap;
604- maximumLineCount: 2;
605- font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
606- color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
607- visible: showHeader ;
608- text: root.title;
609- font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
610- horizontalAlignment: root.headerAlignment;
611- }
612-,
613-Label {
614- id: subtitleLabel;
615- objectName: "subtitleLabel";
616- anchors { left: parent.left; right: parent.right }
617+left: parent.left;
618+ }
619+ anchors.right: parent.right;
620+ anchors.margins: margins;
621+ data: [ Image {
622+ id: mascotImage;
623+ objectName: "mascotImage";
624+ anchors { verticalCenter: parent.verticalCenter; }
625+ readonly property int maxSize: Math.max(width, height) * 4;
626+ source: cardData && cardData["mascot"];
627+ width: units.gu(6);
628+ height: units.gu(5.625);
629+ sourceSize { width: maxSize; height: maxSize }
630+ fillMode: Image.PreserveAspectCrop;
631+ horizontalAlignment: Image.AlignHCenter;
632+ verticalAlignment: Image.AlignVCenter;
633+ visible: showHeader;
634+ }
635
636+ ,
637+ Column {
638+ anchors.verticalCenter: parent.verticalCenter;
639+ spacing: units.dp(2);
640+ width: parent.width - x;
641+ data: [ Label {
642+ id: titleLabel;
643+ objectName: "titleLabel";
644+ anchors { left: parent.left; right: parent.right }
645 elide: Text.ElideRight;
646 fontSize: "small";
647+ wrapMode: Text.Wrap;
648+ maximumLineCount: 2;
649 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
650- color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
651- visible: titleLabel.visible && titleLabel.text;
652- text: cardData && cardData["subtitle"] || "";
653- font.weight: Font.Light;
654+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
655+ visible: showHeader ;
656+ text: root.title;
657+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
658 horizontalAlignment: root.headerAlignment;
659 }
660-]
661-}
662-]
663-}
664+
665+ ,
666+ Label {
667+ id: subtitleLabel;
668+ objectName: "subtitleLabel";
669+ anchors { left: parent.left; right: parent.right }
670+ elide: Text.ElideRight;
671+ fontSize: "small";
672+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
673+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
674+ visible: titleLabel.visible && titleLabel.text;
675+ text: cardData && cardData["subtitle"] || "";
676+ font.weight: Font.Light;
677+ horizontalAlignment: root.headerAlignment;
678+ }
679+
680+ ]
681+ }
682+
683+ ]
684+ }
685 implicitHeight: row.y + row.height + units.gu(1);
686 }
687
688=== modified file 'tests/plugins/Dash/cardcreator/3.res'
689--- tests/plugins/Dash/cardcreator/3.res 2014-07-08 12:37:34 +0000
690+++ tests/plugins/Dash/cardcreator/3.res 2014-07-28 12:00:26 +0000
691@@ -5,8 +5,8 @@
692 property var cardData;
693 property var artShapeBorderSource: undefined;
694 property real fontScale: 1.0;
695- property var scopeStyle: null;
696- property int headerAlignment: Text.AlignLeft;
697+ property var scopeStyle: null;
698+ property int headerAlignment: Text.AlignLeft;
699 property int fixedHeaderHeight: -1;
700 property size fixedArtShapeSize: Qt.size(-1, -1);
701 readonly property string title: cardData && cardData["title"] || "";
702@@ -16,89 +16,92 @@
703 onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
704 readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
705 Item {
706- id: artShapeHolder;
707- height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
708- width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
709- anchors { horizontalCenter: parent.horizontalCenter; }
710- Loader {
711- id: artShapeLoader;
712- objectName: "artShapeLoader";
713- active: cardData && cardData["art"] || false;
714- asynchronous: root.asynchronous;
715- visible: status == Loader.Ready;
716- sourceComponent: UbuntuShape {
717- id: artShape;
718- objectName: "artShape";
719- radius: "medium";
720- visible: image.status == Image.Ready;
721- readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
722- readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
723- readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
724- Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
725- onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
726- Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
727- function updateWidthHeightBindings() {
728- if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
729- width = root.fixedArtShapeSize.width;
730- height = root.fixedArtShapeSize.height;
731- } else if (aspectSmallerThanImageAspect) {
732- width = Qt.binding(function() { return !visible ? 0 : image.width });
733- height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
734- } else {
735- width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
736- height = Qt.binding(function() { return !visible ? 0 : image.height });
737- }
738- }
739- image: Image {
740- objectName: "artImage";
741- source: cardData && cardData["art"] || "";
742- cache: true;
743+ id: artShapeHolder;
744+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
745+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
746+ anchors { horizontalCenter: parent.horizontalCenter; }
747+ Loader {
748+ id: artShapeLoader;
749+ objectName: "artShapeLoader";
750+ active: cardData && cardData["art"] || false;
751 asynchronous: root.asynchronous;
752- fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
753- readonly property real aspect: implicitWidth / implicitHeight;
754- width: root.width;
755- height: width / artShape.aspect;
756+ visible: status == Loader.Ready;
757+ sourceComponent: UbuntuShape {
758+ id: artShape;
759+ objectName: "artShape";
760+ radius: "medium";
761+ visible: image.status == Image.Ready;
762+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
763+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
764+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
765+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
766+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
767+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
768+ function updateWidthHeightBindings() {
769+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
770+ width = root.fixedArtShapeSize.width;
771+ height = root.fixedArtShapeSize.height;
772+ } else if (aspectSmallerThanImageAspect) {
773+ width = Qt.binding(function() { return !visible ? 0 : image.width });
774+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
775+ } else {
776+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
777+ height = Qt.binding(function() { return !visible ? 0 : image.height });
778+ }
779+ }
780+ image: Image {
781+ objectName: "artImage";
782+ source: cardData && cardData["art"] || "";
783+ cache: true;
784+ asynchronous: root.asynchronous;
785+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
786+ readonly property real aspect: implicitWidth / implicitHeight;
787+ width: root.width;
788+ height: width / artShape.aspect;
789+ }
790+ }
791 }
792- }
793- }
794- }
795+ }
796 readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
797 Label {
798- id: titleLabel;
799- objectName: "titleLabel";
800- anchors { right: parent.right;left: parent.left;
801+ id: titleLabel;
802+ objectName: "titleLabel";
803+ anchors { right: parent.right;
804+rightMargin: units.gu(1);
805+left: parent.left;
806 top: artShapeHolder.bottom;
807 topMargin: units.gu(1);
808 leftMargin: units.gu(1);
809-}
810- elide: Text.ElideRight;
811- fontSize: "small";
812- wrapMode: Text.Wrap;
813- maximumLineCount: 2;
814- font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
815- color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
816- visible: showHeader ;
817- text: root.title;
818- font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
819- horizontalAlignment: root.headerAlignment;
820- }
821-Label {
822- id: subtitleLabel;
823- objectName: "subtitleLabel";
824- anchors { left: titleLabel.left;
825- leftMargin: titleLabel.leftMargin;
826- right: titleLabel.right;
827- top: titleLabel.bottom;
828- topMargin: units.dp(2);
829- }
830+ }
831 elide: Text.ElideRight;
832 fontSize: "small";
833+ wrapMode: Text.Wrap;
834+ maximumLineCount: 2;
835 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
836- color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
837- visible: titleLabel.visible && titleLabel.text;
838- text: cardData && cardData["subtitle"] || "";
839- font.weight: Font.Light;
840+ color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
841+ visible: showHeader ;
842+ text: root.title;
843+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
844 horizontalAlignment: root.headerAlignment;
845 }
846+Label {
847+ id: subtitleLabel;
848+ objectName: "subtitleLabel";
849+ anchors { left: titleLabel.left;
850+ leftMargin: titleLabel.leftMargin;
851+ right: titleLabel.right;
852+ rightMargin: titleLabel.rightMargin;
853+ top: titleLabel.bottom;
854+ topMargin: units.dp(2);
855+ }
856+ elide: Text.ElideRight;
857+ fontSize: "small";
858+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
859+ color: root.scopeStyle ? root.scopeStyle.foreground : "grey";
860+ visible: titleLabel.visible && titleLabel.text;
861+ text: cardData && cardData["subtitle"] || "";
862+ font.weight: Font.Light;
863+ horizontalAlignment: root.headerAlignment;
864+ }
865 implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
866 }
867
868=== modified file 'tests/plugins/Dash/cardcreator/5.res'
869--- tests/plugins/Dash/cardcreator/5.res 2014-07-08 12:37:34 +0000
870+++ tests/plugins/Dash/cardcreator/5.res 2014-07-28 12:00:26 +0000
871@@ -4,9 +4,9 @@
872 property var components;
873 property var cardData;
874 property var artShapeBorderSource: undefined;
875- property real fontScale: 1.0;
876- property var scopeStyle: null;
877- property int headerAlignment: Text.AlignLeft;
878+ property real fontScale: 1.0;
879+ property var scopeStyle: null;
880+ property int headerAlignment: Text.AlignLeft;
881 property int fixedHeaderHeight: -1;
882 property size fixedArtShapeSize: Qt.size(-1, -1);
883 readonly property string title: cardData && cardData["title"] || "";
884@@ -16,130 +16,132 @@
885 onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
886 readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
887 Item {
888- id: artShapeHolder;
889- height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
890- width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
891- anchors { horizontalCenter: parent.horizontalCenter; }
892- Loader {
893- id: artShapeLoader;
894- objectName: "artShapeLoader";
895- active: cardData && cardData["art"] || false;
896- asynchronous: root.asynchronous;
897- visible: status == Loader.Ready;
898- sourceComponent: UbuntuShape {
899- id: artShape;
900- objectName: "artShape";
901- radius: "medium";
902- visible: image.status == Image.Ready;
903- readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
904- readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
905- readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
906- Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
907- onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
908- Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
909- function updateWidthHeightBindings() {
910- if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
911- width = root.fixedArtShapeSize.width;
912- height = root.fixedArtShapeSize.height;
913- } else if (aspectSmallerThanImageAspect) {
914- width = Qt.binding(function() { return !visible ? 0 : image.width });
915- height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
916- } else {
917- width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
918- height = Qt.binding(function() { return !visible ? 0 : image.height });
919- }
920- }
921- image: Image {
922- objectName: "artImage";
923- source: cardData && cardData["art"] || "";
924- cache: true;
925+ id: artShapeHolder;
926+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
927+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
928+ anchors { horizontalCenter: parent.horizontalCenter; }
929+ Loader {
930+ id: artShapeLoader;
931+ objectName: "artShapeLoader";
932+ active: cardData && cardData["art"] || false;
933 asynchronous: root.asynchronous;
934- fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
935- readonly property real aspect: implicitWidth / implicitHeight;
936- width: root.width;
937- height: width / artShape.aspect;
938+ visible: status == Loader.Ready;
939+ sourceComponent: UbuntuShape {
940+ id: artShape;
941+ objectName: "artShape";
942+ radius: "medium";
943+ visible: image.status == Image.Ready;
944+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
945+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
946+ readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
947+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
948+ onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
949+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
950+ function updateWidthHeightBindings() {
951+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
952+ width = root.fixedArtShapeSize.width;
953+ height = root.fixedArtShapeSize.height;
954+ } else if (aspectSmallerThanImageAspect) {
955+ width = Qt.binding(function() { return !visible ? 0 : image.width });
956+ height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
957+ } else {
958+ width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
959+ height = Qt.binding(function() { return !visible ? 0 : image.height });
960+ }
961+ }
962+ image: Image {
963+ objectName: "artImage";
964+ source: cardData && cardData["art"] || "";
965+ cache: true;
966+ asynchronous: root.asynchronous;
967+ fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
968+ readonly property real aspect: implicitWidth / implicitHeight;
969+ width: root.width;
970+ height: width / artShape.aspect;
971+ }
972+ }
973 }
974- }
975- }
976- }
977+ }
978 Loader {
979- id: overlayLoader;
980- anchors {
981- left: artShapeHolder.left;
982- right: artShapeHolder.right;
983- bottom: artShapeHolder.bottom;
984- }
985- active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
986- asynchronous: root.asynchronous;
987- visible: showHeader && status == Loader.Ready;
988- sourceComponent: ShaderEffect {
989- id: overlay;
990- height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
991- opacity: 0.6;
992- property var source: ShaderEffectSource {
993- id: shaderSource;
994- sourceItem: artShapeLoader.item;
995- onVisibleChanged: if (visible) scheduleUpdate();
996- live: false;
997- sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
998- }
999- vertexShader: "
1000- uniform highp mat4 qt_Matrix;
1001- attribute highp vec4 qt_Vertex;
1002- attribute highp vec2 qt_MultiTexCoord0;
1003- varying highp vec2 coord;
1004- void main() {
1005- coord = qt_MultiTexCoord0;
1006- gl_Position = qt_Matrix * qt_Vertex;
1007- }";
1008- fragmentShader: "
1009- varying highp vec2 coord;
1010- uniform sampler2D source;
1011- uniform lowp float qt_Opacity;
1012- void main() {
1013- lowp vec4 tex = texture2D(source, coord);
1014- gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
1015- }";
1016- }
1017- }
1018+ id: overlayLoader;
1019+ anchors {
1020+ left: artShapeHolder.left;
1021+ right: artShapeHolder.right;
1022+ bottom: artShapeHolder.bottom;
1023+ }
1024+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
1025+ asynchronous: root.asynchronous;
1026+ visible: showHeader && status == Loader.Ready;
1027+ sourceComponent: ShaderEffect {
1028+ id: overlay;
1029+ height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
1030+ opacity: 0.6;
1031+ property var source: ShaderEffectSource {
1032+ id: shaderSource;
1033+ sourceItem: artShapeLoader.item;
1034+ onVisibleChanged: if (visible) scheduleUpdate();
1035+ live: false;
1036+ sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
1037+ }
1038+ vertexShader: "
1039+ uniform highp mat4 qt_Matrix;
1040+ attribute highp vec4 qt_Vertex;
1041+ attribute highp vec2 qt_MultiTexCoord0;
1042+ varying highp vec2 coord;
1043+ void main() {
1044+ coord = qt_MultiTexCoord0;
1045+ gl_Position = qt_Matrix * qt_Vertex;
1046+ }";
1047+ fragmentShader: "
1048+ varying highp vec2 coord;
1049+ uniform sampler2D source;
1050+ uniform lowp float qt_Opacity;
1051+ void main() {
1052+ lowp vec4 tex = texture2D(source, coord);
1053+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
1054+ }";
1055+ }
1056+ }
1057 readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
1058 Label {
1059- id: titleLabel;
1060- objectName: "titleLabel";
1061- anchors { left: parent.left;
1062- leftMargin: units.gu(1);
1063- right: parent.right;
1064- top: overlayLoader.top;
1065- topMargin: units.gu(1);
1066-}
1067- elide: Text.ElideRight;
1068- fontSize: "small";
1069- wrapMode: Text.Wrap;
1070- maximumLineCount: 2;
1071- font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
1072- color: "white";
1073- visible: showHeader && overlayLoader.active;
1074- text: root.title;
1075- font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
1076- horizontalAlignment: root.headerAlignment;
1077- }
1078-Label {
1079- id: subtitleLabel;
1080- objectName: "subtitleLabel";
1081- anchors { left: titleLabel.left;
1082- leftMargin: titleLabel.leftMargin;
1083- right: titleLabel.right;
1084- top: titleLabel.bottom;
1085- topMargin: units.dp(2);
1086- }
1087+ id: titleLabel;
1088+ objectName: "titleLabel";
1089+ anchors { left: parent.left;
1090+ leftMargin: units.gu(1);
1091+ right: parent.right;
1092+ rightMargin: units.gu(1);
1093+ top: overlayLoader.top;
1094+ topMargin: units.gu(1);
1095+ }
1096 elide: Text.ElideRight;
1097 fontSize: "small";
1098+ wrapMode: Text.Wrap;
1099+ maximumLineCount: 2;
1100 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
1101 color: "white";
1102- visible: titleLabel.visible && titleLabel.text;
1103- text: cardData && cardData["subtitle"] || "";
1104- font.weight: Font.Light;
1105+ visible: showHeader && overlayLoader.active;
1106+ text: root.title;
1107+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
1108 horizontalAlignment: root.headerAlignment;
1109 }
1110+Label {
1111+ id: subtitleLabel;
1112+ objectName: "subtitleLabel";
1113+ anchors { left: titleLabel.left;
1114+ leftMargin: titleLabel.leftMargin;
1115+ right: titleLabel.right;
1116+ rightMargin: titleLabel.rightMargin;
1117+ top: titleLabel.bottom;
1118+ topMargin: units.dp(2);
1119+ }
1120+ elide: Text.ElideRight;
1121+ fontSize: "small";
1122+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
1123+ color: "white";
1124+ visible: titleLabel.visible && titleLabel.text;
1125+ text: cardData && cardData["subtitle"] || "";
1126+ font.weight: Font.Light;
1127+ horizontalAlignment: root.headerAlignment;
1128+ }
1129 implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
1130 }
1131
1132=== added file 'tests/plugins/Dash/cardcreator/7.res'
1133--- tests/plugins/Dash/cardcreator/7.res 1970-01-01 00:00:00 +0000
1134+++ tests/plugins/Dash/cardcreator/7.res 2014-07-28 12:00:26 +0000
1135@@ -0,0 +1,128 @@
1136+AbstractButton {
1137+ id: root;
1138+ property var template;
1139+ property var components;
1140+ property var cardData;
1141+ property var artShapeBorderSource: undefined;
1142+ property real fontScale: 1.0;
1143+ property var scopeStyle: null;
1144+ property int headerAlignment: Text.AlignLeft;
1145+ property int fixedHeaderHeight: -1;
1146+ property size fixedArtShapeSize: Qt.size(-1, -1);
1147+ readonly property string title: cardData && cardData["title"] || "";
1148+ property bool asynchronous: true;
1149+ property bool showHeader: true;
1150+ implicitWidth: childrenRect.width;
1151+Loader {
1152+ id: backgroundLoader;
1153+ objectName: "backgroundLoader";
1154+ anchors.fill: parent;
1155+ asynchronous: root.asynchronous;
1156+ visible: status == Loader.Ready;
1157+ sourceComponent: UbuntuShape {
1158+ objectName: "background";
1159+ radius: "medium";
1160+ color: getColor(0) || "white";
1161+ gradientColor: getColor(1) || color;
1162+ anchors.fill: parent;
1163+ image: backgroundImage.source ? backgroundImage : null;
1164+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
1165+ property Image backgroundImage: Image {
1166+ objectName: "backgroundImage";
1167+ source: {
1168+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
1169+ else if (template && typeof template["card-background"] === "string") return template["card-background"];
1170+ else return "";
1171+ }
1172+ }
1173+ function getColor(index) {
1174+ if (cardData && typeof cardData["background"] === "object"
1175+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
1176+ return cardData["background"]["elements"][index];
1177+ } else if (template && typeof template["card-background"] === "object"
1178+ && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
1179+ return template["card-background"]["elements"][index];
1180+ } else return undefined;
1181+ }
1182+ }
1183+ }
1184+readonly property size artShapeSize: Qt.size(-1, -1);
1185+readonly property int headerHeight: row.height;
1186+Row {
1187+ id: row;
1188+ objectName: "outerRow";
1189+ property real margins: units.gu(1);
1190+ spacing: margins;
1191+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
1192+ anchors { top: parent.top;
1193+ topMargin: units.gu(1);
1194+left: parent.left;
1195+ }
1196+ anchors.right: parent.right;
1197+ anchors.margins: margins;
1198+ data: [ Image {
1199+ id: mascotImage;
1200+ objectName: "mascotImage";
1201+ anchors { verticalCenter: parent.verticalCenter; }
1202+ readonly property int maxSize: Math.max(width, height) * 4;
1203+ source: cardData && cardData["mascot"];
1204+ width: units.gu(6);
1205+ height: units.gu(5.625);
1206+ sourceSize { width: maxSize; height: maxSize }
1207+ fillMode: Image.PreserveAspectCrop;
1208+ horizontalAlignment: Image.AlignHCenter;
1209+ verticalAlignment: Image.AlignVCenter;
1210+ visible: showHeader;
1211+ }
1212+
1213+ ,
1214+ Column {
1215+ anchors.verticalCenter: parent.verticalCenter;
1216+ spacing: units.dp(2);
1217+ width: parent.width - x;
1218+ data: [
1219+ Label {
1220+ id: titleLabel;
1221+ objectName: "titleLabel";
1222+ anchors { left: parent.left; right: parent.right }
1223+ elide: Text.ElideRight;
1224+ fontSize: "small";
1225+ wrapMode: Text.Wrap;
1226+ maximumLineCount: 2;
1227+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
1228+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
1229+ visible: showHeader ;
1230+ text: root.title;
1231+ font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
1232+ horizontalAlignment: root.headerAlignment;
1233+ }
1234+,
1235+Label {
1236+ id: subtitleLabel;
1237+ objectName: "subtitleLabel";
1238+ anchors { left: parent.left; right: parent.right }
1239+ elide: Text.ElideRight;
1240+ fontSize: "small";
1241+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
1242+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
1243+ visible: titleLabel.visible && titleLabel.text;
1244+ text: cardData && cardData["subtitle"] || "";
1245+ font.weight: Font.Light;
1246+ horizontalAlignment: root.headerAlignment;
1247+ }
1248+,
1249+CardAttributes {
1250+ id: attributesRow;
1251+ objectName: "attributesRow";
1252+ anchors { left: parent.left; right: parent.right }
1253+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
1254+ model: cardData["attributes"]
1255+ }
1256+
1257+ ]
1258+ }
1259+
1260+ ]
1261+ }
1262+implicitHeight: row.y + row.height + units.gu(1);
1263+}
1264
1265=== added file 'tests/plugins/Dash/cardcreator/7.tst'
1266--- tests/plugins/Dash/cardcreator/7.tst 1970-01-01 00:00:00 +0000
1267+++ tests/plugins/Dash/cardcreator/7.tst 2014-07-28 12:00:26 +0000
1268@@ -0,0 +1,3 @@
1269+template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
1270+components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{"field":"attributes","max-count":2}}
1271+result: 7.res
1272
1273=== modified file 'tests/plugins/Dash/cardcreatortest.cpp'
1274--- tests/plugins/Dash/cardcreatortest.cpp 2014-05-06 13:09:08 +0000
1275+++ tests/plugins/Dash/cardcreatortest.cpp 2014-07-28 12:00:26 +0000
1276@@ -19,6 +19,7 @@
1277 #include <QQuickItem>
1278 #include <QQuickView>
1279 #include <QtTestGui>
1280+#include <QTemporaryFile>
1281
1282 class CardCreatorTest : public QObject
1283 {
1284@@ -74,7 +75,14 @@
1285 QVERIFY(testResultFile.open(QIODevice::ReadOnly));
1286 QTextStream ts2(&testResultFile);
1287 const QString expectedResult = ts2.readAll();
1288- QCOMPARE(cardStringResult.toString().simplified(), expectedResult.simplified());
1289+ const QString executedResult = cardStringResult.toString();
1290+ // Record failed results to /tmp
1291+ QTemporaryFile tmpFile(QDir::tempPath() + QDir::separator() + "testCardCreatorFailedResultXXXXXX");
1292+ tmpFile.open();
1293+ tmpFile.setAutoRemove(false);
1294+ tmpFile.write(executedResult.toUtf8().constData());
1295+ QCOMPARE(executedResult.simplified(), expectedResult.simplified());
1296+ tmpFile.setAutoRemove(true); // Remove the result if it passed
1297
1298 QVariant createCardComponentResult;
1299 QMetaObject::invokeMethod(view->rootObject(), "createCardComponent", Q_RETURN_ARG(QVariant, createCardComponentResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
1300
1301=== added file 'tests/plugins/Dash/tst_CardAttributes.qml'
1302--- tests/plugins/Dash/tst_CardAttributes.qml 1970-01-01 00:00:00 +0000
1303+++ tests/plugins/Dash/tst_CardAttributes.qml 2014-07-28 12:00:26 +0000
1304@@ -0,0 +1,54 @@
1305+/*
1306+ * Copyright 2013 Canonical Ltd.
1307+ *
1308+ * This program is free software; you can redistribute it and/or modify
1309+ * it under the terms of the GNU General Public License as published by
1310+ * the Free Software Foundation; version 3.
1311+ *
1312+ * This program is distributed in the hope that it will be useful,
1313+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1314+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1315+ * GNU General Public License for more details.
1316+ *
1317+ * You should have received a copy of the GNU General Public License
1318+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1319+ */
1320+
1321+import QtQuick 2.0
1322+import QtTest 1.0
1323+import Dash 0.1
1324+
1325+Item {
1326+ width: units.gu(40)
1327+ height: units.gu(4.5)
1328+
1329+ property var testData: [
1330+ [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}],
1331+ [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"},{"value":"text3"}],
1332+ [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"},{"value":"text3"},{"value":"text4"}],
1333+ [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"},{"value":"text3","style":"highlighted"},{"value":"text4","icon":"image://theme/close","style":"highlighted"},{"value":"text5"}]
1334+ ]
1335+
1336+ CardAttributes {
1337+ id: cardAttributes
1338+ model: testData[3]
1339+ clip: true
1340+ }
1341+
1342+ TestCase {
1343+ name: "CardAttributesTest"
1344+ when: windowShown
1345+
1346+ function init() {
1347+ }
1348+
1349+ function test_columns_data() {
1350+ return testData;
1351+ }
1352+
1353+ function test_columns(data) {
1354+ cardAttributes.model = data;
1355+ compare(cardAttributes.columns, 2 + data.length % 2);
1356+ }
1357+ }
1358+}
1359
1360=== modified file 'tests/qmltests/Dash/CardHelpers.js'
1361--- tests/qmltests/Dash/CardHelpers.js 2014-02-04 18:14:07 +0000
1362+++ tests/qmltests/Dash/CardHelpers.js 2014-07-28 12:00:26 +0000
1363@@ -16,7 +16,7 @@
1364
1365 .pragma library
1366
1367-var components = ["title", "art", "subtitle", "mascot", "emblem", "old-price", "price", "alt-price", "rating", "alt-rating", "summary"]
1368+var components = ["title", "art", "subtitle", "mascot", "emblem", "old-price", "price", "alt-price", "rating", "alt-rating", "summary", "attributes"]
1369
1370 var defaultLayout = ' \
1371 { \
1372@@ -48,7 +48,8 @@
1373 "empty": "image://theme/rating-star-empty" \
1374 }, \
1375 "alt-rating": null, \
1376- "summary": null \
1377+ "summary": null, \
1378+ "attributes": { "max-count": 2 } \
1379 }, \
1380 "resources": {} \
1381 }'
1382@@ -59,7 +60,8 @@
1383 "art": "art", \
1384 "subtitle": "subtitle", \
1385 "mascot": "mascot", \
1386- "summary": "summary" \
1387+ "summary": "summary", \
1388+ "attributes": "attributes" \
1389 }'
1390
1391
1392
1393=== modified file 'tests/qmltests/Dash/tst_Card.qml'
1394--- tests/qmltests/Dash/tst_Card.qml 2014-06-27 08:47:04 +0000
1395+++ tests/qmltests/Dash/tst_Card.qml 2014-07-28 12:00:26 +0000
1396@@ -33,7 +33,8 @@
1397 "mascot": "../../../tests/qmltests/Dash/artwork/avatar.png",
1398 "title": "foo",
1399 "subtitle": "bar",
1400- "summary": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
1401+ "summary": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
1402+ "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
1403 }'
1404
1405 property var cardsModel: [
1406@@ -110,6 +111,7 @@
1407 anchors { top: parent.top; left: parent.left; margins: units.gu(1) }
1408
1409 sourceComponent: cardTool.cardComponent
1410+ clip: true
1411 onLoaded: {
1412 item.template = Qt.binding(function() { return cardTool.template; });
1413 item.components = Qt.binding(function() { return cardTool.components; });

Subscribers

People subscribed via source and target branches