on xenial help sign in
Fix last item X position
f2bd4e1Albert Astals
qml/Components/Carousel.qml+13−19
@@ -75,6 +75,7 @@ Item {
75 The scaling of the items is controlled by the variable continuousIndex, described below. */
75 The scaling of the items is controlled by the variable continuousIndex, described below. */
76 ListView {
76 ListView {
77 id: listView
77 id: listView
78+ objectName: "listView"
78
79
79 property int highlightIndex: -1
80 property int highlightIndex: -1
80 property real minimumTileWidth: 0
81 property real minimumTileWidth: 0
@@ -148,15 +149,19 @@ Item {
148 maximumFlickVelocity: Math.max(2500 * Math.pow(realWidth / referenceWidth, 1.5), 2500) // 2500 is platform default
149 maximumFlickVelocity: Math.max(2500 * Math.pow(realWidth / referenceWidth, 1.5), 2500) // 2500 is platform default
149 orientation: ListView.Horizontal
150 orientation: ListView.Horizontal
150
151
151− function itemClicked(index, delegateItem) {
152+ function getXFromContinuousIndex(index) {
152− listView.currentIndex = index
153− var x = CarouselJS.getXFromContinuousIndex(index,
153+ return CarouselJS.getXFromContinuousIndex(index,
154 realWidth,
154 realWidth,
155− realContentWidth,
155+ footerItem.x,
156 tileWidth,
156 tileWidth,
157 gapToMiddlePhase,
157 gapToMiddlePhase,
158 gapToEndPhase,
158 gapToEndPhase,
159 carousel.drawBuffer)
159 carousel.drawBuffer)
160+ }
161+
162+ function itemClicked(index, delegateItem) {
163+ listView.currentIndex = index
164+ var x = getXFromContinuousIndex(index);
160
165
161 if (Math.abs(x - contentX) < 1 && delegateItem !== undefined) {
166 if (Math.abs(x - contentX) < 1 && delegateItem !== undefined) {
162 /* We're clicking the selected item and
167 /* We're clicking the selected item and
@@ -174,13 +179,7 @@ Item {
174 }
179 }
175
180
176 function itemPressAndHold(index, delegateItem) {
181 function itemPressAndHold(index, delegateItem) {
177− var x = CarouselJS.getXFromContinuousIndex(index,
182+ var x = getXFromContinuousIndex(index);
178− realWidth,
179− realContentWidth,
180− tileWidth,
181− gapToMiddlePhase,
182− gapToEndPhase,
183− carousel.drawBuffer);
184
183
185 if (Math.abs(x - contentX) < 1 && delegateItem !== undefined) {
184 if (Math.abs(x - contentX) < 1 && delegateItem !== undefined) {
186 /* We're pressAndHold the selected item and
185 /* We're pressAndHold the selected item and
@@ -209,22 +208,17 @@ Item {
209 newContentX = disabledNewContentX
208 newContentX = disabledNewContentX
210 }
209 }
211 onMovementEnded: {
210 onMovementEnded: {
212− if (realContentX > 0 && realContentX < realContentWidth - realWidth)
211+ if (realContentX > 0)
213 stepAnimation.start()
212 stepAnimation.start()
214 }
213 }
215
214
216 SmoothedAnimation {
215 SmoothedAnimation {
217 id: stepAnimation
216 id: stepAnimation
217+ objectName: "stepAnimation"
218
218
219 target: listView
219 target: listView
220 property: "contentX"
220 property: "contentX"
221− to: CarouselJS.getXFromContinuousIndex(listView.selectedIndex,
221+ to: listView.getXFromContinuousIndex(listView.selectedIndex)
222− listView.realWidth,
223− listView.realContentWidth,
224− listView.tileWidth,
225− listView.gapToMiddlePhase,
226− listView.gapToEndPhase,
227− carousel.drawBuffer)
228 duration: 450
222 duration: 450
229 velocity: 200
223 velocity: 200
230 easing.type: Easing.InOutQuad
224 easing.type: Easing.InOutQuad
tests/qmltests/Components/tst_Carousel.qml+27−3
@@ -18,6 +18,7 @@ import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19import "../../../qml/Components/"
19import "../../../qml/Components/"
20import "../../../qml/Components/carousel.js" as Carousel
20import "../../../qml/Components/carousel.js" as Carousel
21+import Unity.Test 0.1 as UT
21
22
22Item {
23Item {
23 width: 700
24 width: 700
@@ -32,12 +33,13 @@ Item {
32 property int destroyedDelegates: 0
33 property int destroyedDelegates: 0
33
34
34 itemComponent: Rectangle {
35 itemComponent: Rectangle {
36+ border.color: "black"
35 color: "red"
37 color: "red"
36 Component.onCompleted: carousel.createdDelegates++
38 Component.onCompleted: carousel.createdDelegates++
37 Component.onDestruction: carousel.destroyedDelegates++
39 Component.onDestruction: carousel.destroyedDelegates++
38 }
40 }
39 }
41 }
40− TestCase {
42+ UT.UnityTestCase {
41 id: root
43 id: root
42 name: "Carousel"
44 name: "Carousel"
43 when: windowShown
45 when: windowShown
@@ -55,8 +57,11 @@ Item {
55 property real kGapEnd: kMiddleIndex * (1 - gapToEndPhase / gapToMiddlePhase)
57 property real kGapEnd: kMiddleIndex * (1 - gapToEndPhase / gapToMiddlePhase)
56 property real kXBeginningEnd: 1 / tileWidth + kMiddleIndex / gapToMiddlePhase
58 property real kXBeginningEnd: 1 / tileWidth + kMiddleIndex / gapToMiddlePhase
57
59
58− function test_onlyNeededItemsCreated() {
60+ // This test needs to run first since it tests a corner case condition
61+ // to where the carousel is just being created
62+ // That is why it has a 1 in the name
63+ function test_1onlyNeededItemsCreated() {
59− compare(carousel.createdDelegates, 10);
64+ tryCompare(carousel, "createdDelegates", 10);
60 compare(carousel.destroyedDelegates, 0);
65 compare(carousel.destroyedDelegates, 0);
61 }
66 }
62
67
@@ -216,5 +221,24 @@ Item {
216 data.maxTranslation)
221 data.maxTranslation)
217 compare(scale, data.result)
222 compare(scale, data.result)
218 }
223 }
224+
225+ function test_lastItemXPosition() {
226+ var carouselList = findChild(carousel, "listView");
227+ var stepAnimation = findInvisibleChild(carouselList, "stepAnimation");
228+ var stepDiff = 0;
229+ stepAnimation.onRunningChanged.connect(function() { if (stepAnimation.running) stepDiff = Math.abs(carouselList.contentX - stepAnimation.to); })
230+ var overshootOnce = false;
231+ while (!overshootOnce) {
232+ overshootOnce = carouselList.realContentX > carouselList.realContentWidth - carouselList.realWidth;
233+ mouseFlick(carousel, carousel.width - units.gu(1),
234+ carousel.height / 2,
235+ units.gu(2),
236+ carousel.height / 2);
237+ tryCompare(carouselList, "moving", false);
238+ }
239+ verify(stepDiff < 1);
240+ var x = carouselList.getXFromContinuousIndex(carousel.model - 1);
241+ verify(Math.abs(x - carouselList.contentX) < 1);
242+ }
219 }
243 }
220}
244}