on xenial help sign in
Refactor carousel item activation.
commit420f25e64055791af3cb51aed6c91dc9612655c7 authorMichał Sawicz <michal.sawicz@canonical.com> dateSat 5 Jul 2014, 23:55 (12 years ago) parentafd1e08
5 files changed+87−26
qml/Components/BaseCarouselDelegate.qml+16 qml/Components/Carousel.qml+5−14 qml/Dash/CardCarousel.qml+3−3 tests/qmltests/Components/tst_Carousel.qml+61−9 tests/qmltests/Dash/tst_DashContent.qml+2
qml/Components/BaseCarouselDelegate.qml+16
@@ -17,7 +17,23 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919
20+/*!
21+ \brief Base delegate for use with the Carousel component
22+
23+ Use this as the base of your component in a Carousel, the properties
24+ will get updated and signals emitted accordingly.
25+*/
26+
2027Item {
28+ /// True if this item is currently "focused" in the carousel.
2129 property bool explicitlyScaled
30+
31+ /// Model data for this delegate.
2232 property var model
33+
34+ /// Will be emitted when the item is tapped.
35+ signal clicked
36+
37+ /// Will be emitted when the item is long-pressed.
38+ signal pressAndHold
2339}
qml/Components/Carousel.qml+5−14
@@ -52,16 +52,6 @@ Item {
5252 /// exposes the distance to the next row (only one row in carousel, so it's the topMargins)
5353 readonly property alias verticalSpacing: listView.verticalMargin
5454
55− /// Emitted when the user clicked on an item
56− /// @param index is the index of the clicked item
57− /// @param itemY is y of the clicked delegate
58− signal clicked(int index, real itemY)
59−
60− /// Emitted when the user pressed and held on an item
61− /// @param index is the index of the held item
62− /// @param itemY is y of the held delegate
63− signal pressAndHold(int index, real itemY)
64−
6555 implicitHeight: listView.tileHeight * selectedItemScaleFactor
6656 opacity: listView.highlightIndex === -1 ? 1 : 0.6
6757
@@ -167,7 +157,7 @@ Item {
167157 /* We're clicking the selected item and
168158 we're in the neighbourhood of radius 1 pixel from it.
169159 Let's emit the clicked signal. */
170− carousel.clicked(index, delegateItem.y)
160+ delegateItem.clicked()
171161 return
172162 }
173163
@@ -185,7 +175,7 @@ Item {
185175 /* We're pressAndHold the selected item and
186176 we're in the neighbourhood of radius 1 pixel from it.
187177 Let's emit the pressAndHold signal. */
188− carousel.pressAndHold(index, delegateItem.y);
178+ delegateItem.pressAndHold();
189179 return;
190180 }
191181
@@ -316,8 +306,9 @@ Item {
316306 }
317307
318308 onLoaded: {
319− item.explicitlyScaled = Qt.binding(function() { return explicitlyScaled; })
320− item.model = Qt.binding(function() { return model; })
309+ item.objectName = Qt.binding(function() { return "carouselDelegate" + index; });
310+ item.explicitlyScaled = Qt.binding(function() { return explicitlyScaled; });
311+ item.model = Qt.binding(function() { return model; });
321312 }
322313
323314 MouseArea {
qml/Dash/CardCarousel.qml+3−3
@@ -40,9 +40,6 @@ DashRenderer {
4040 cacheBuffer: 1404 // 18px * 13gu * 6
4141 model: cardCarousel.model
4242
43− onClicked: cardCarousel.clicked(index, null)
44− onPressAndHold: cardCarousel.pressAndHold(index)
45−
4643 property real fontScale: 1 / selectedItemScaleFactor
4744 property real headerHeight: cardTool.headerHeight / selectedItemScaleFactor
4845
@@ -53,6 +50,9 @@ DashRenderer {
5350 property var model
5451 enabled: false
5552
53+ function clicked() { cardCarousel.clicked(index, model.result) }
54+ function pressAndHold() { cardCarousel.pressAndHold(index, model.result) }
55+
5656 sourceComponent: cardTool.cardComponent
5757 onLoaded: {
5858 item.objectName = "carouselDelegate" + index;
tests/qmltests/Components/tst_Carousel.qml+61−9
@@ -27,21 +27,27 @@ Item {
2727 Carousel {
2828 anchors.fill: parent
2929 id: carousel
30− model: 40
3130
3231 property int createdDelegates: 0
3332 property int destroyedDelegates: 0
3433
35− itemComponent: BaseCarouselDelegate {
36− Rectangle {
37− anchors.fill: parent
38− border.color: "black"
39− color: "red"
40− Component.onCompleted: carousel.createdDelegates++
41− Component.onDestruction: carousel.destroyedDelegates++
34+ itemComponent: Component {
35+ BaseCarouselDelegate {
36+ Rectangle {
37+ anchors.fill: parent
38+ border.color: "black"
39+ color: "red"
40+ Component.onCompleted: carousel.createdDelegates++
41+ Component.onDestruction: carousel.destroyedDelegates++
42+ }
4243 }
4344 }
4445 }
46+
47+ SignalSpy {
48+ id: spy
49+ }
50+
4551 UT.UnityTestCase {
4652 id: root
4753 name: "Carousel"
@@ -51,6 +57,8 @@ Item {
5157 property int itemCount
5258 property real tileWidth
5359
60+ property Item listView: findChild(carousel, "listView")
61+
5462 property real contentWidth: itemCount * tileWidth
5563 // following variables are copied from Carousel.qml
5664 // I'm not using the variables directly from there, as then tileWidth and others would be affected as well
@@ -60,11 +68,25 @@ Item {
6068 property real kGapEnd: kMiddleIndex * (1 - gapToEndPhase / gapToMiddlePhase)
6169 property real kXBeginningEnd: 1 / tileWidth + kMiddleIndex / gapToMiddlePhase
6270
71+ function init() {
72+ carousel.model = 40;
73+ waitForRendering(carousel)
74+ listView.positionViewAtBeginning();
75+ }
76+
77+ function cleanup() {
78+ carousel.model = 0;
79+ carousel.createdDelegates = 0;
80+ carousel.destroyedDelegates = 0;
81+ spy.target = null;
82+ spy.signalName = "";
83+ }
84+
6385 // This test needs to run first since it tests a corner case condition
6486 // to where the carousel is just being created
6587 // That is why it has a 1 in the name
6688 function test_1onlyNeededItemsCreated() {
67− tryCompare(carousel, "createdDelegates", 10);
89+ tryCompare(carousel, "createdDelegates", 9);
6890 compare(carousel.destroyedDelegates, 0);
6991 }
7092
@@ -243,5 +265,35 @@ Item {
243265 var x = carouselList.getXFromContinuousIndex(carousel.model - 1);
244266 verify(Math.abs(x - carouselList.contentX) < 1);
245267 }
268+
269+ function test_click() {
270+ var carouselList = findChild(carousel, "listView");
271+ tryCompareFunction(function() { return findChild(carouselList, "carouselDelegate3") ? true : false; }, true);
272+ var carouselItem = findChild(carousel, "carouselDelegate3")
273+ verify(carouselItem, "Could not find delegate");
274+ spy.signalName = "clicked";
275+ spy.target = carouselItem;
276+ mouseClick(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
277+ tryCompare(carouselList, "moving", false);
278+ tryCompare(carouselItem, "explicitlyScaled", true);
279+ mouseClick(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
280+ spy.wait();
281+ }
282+
283+ function test_pressAndHold() {
284+ var carouselList = findChild(carousel, "listView");
285+ tryCompareFunction(function() { return findChild(carouselList, "carouselDelegate3") ? true : false; }, true);
286+ var carouselItem = findChild(carousel, "carouselDelegate3")
287+ verify(carouselItem, "Could not find delegate");
288+ spy.signalName = "pressAndHold";
289+ spy.target = carouselItem;
290+ mouseClick(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
291+ tryCompare(carouselList, "moving", false);
292+ tryCompare(carouselItem, "explicitlyScaled", true);
293+ mousePress(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
294+ spy.wait();
295+ mouseRelease(carouselItem, carouselItem.width / 2, carouselItem.height / 2);
296+ }
297+
246298 }
247299}
tests/qmltests/Dash/tst_DashContent.qml+2
@@ -294,6 +294,8 @@ Item {
294294 var dashCategory1 = findChild(scope, "dashCategory1");
295295 var tile = findChild(dashCategory1, "carouselDelegate1");
296296 mouseClick(tile, tile.width / 2, tile.height / 2);
297+ tryCompare(tile, "explicitlyScaled", true);
298+ mouseClick(tile, tile.width / 2, tile.height / 2);
297299 tryCompare(previewListView, "open", true);
298300 tryCompare(previewListView, "x", 0);
299301