on xenial help sign in
Bring back ListView'ed Carousel now that Qt is fixed.

Approved by PS Jenkins bot, Albert Astals Cid.

commit289eb1db0b2237a73462ef8ea977938f39c9029b authorGünter Schwann <guenter.schwann@canonical.com> dateMon 10 Jun 2013, 17:24 (13 years ago) parent84aae6a6f40eab
3 files changed+237−166
Components/Carousel.qml+152−121 Components/carousel.js+47−11 tests/qmltests/Components/tst_Carousel.qml+38−34
Components/Carousel.qml+152−121
@@ -18,26 +18,50 @@ import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import "carousel.js" as CarouselJS
2020
21+/*! The Carousel component presents the items of a model in a carousel view. It's similar to a
22+ cover flow. But it stops at it's boundaries (therefore no PathView is used).
23+ */
2124Item {
2225 id: carousel
2326
27+ /// The component to be used as delegate. This component has to be derived from BaseCarouselDelegate
2428 property Component itemComponent
25− property var model
26− property alias minimumTileWidth: flickable.minimumTileWidth
27− property alias pathItemCount: flickable.pathItemCount
28− property alias tileAspectRatio: flickable.tileAspectRatio
29− property int cacheBuffer: 0
29+ /// Model for the Carousel, which has to be a model usable by a ListView
30+ property alias model: listView.model
31+ /// A minimal width of a tile can be set here. Per default a best fit will be calculated
32+ property alias minimumTileWidth: listView.minimumTileWidth
33+ /// Sets the number of tiles that are visible
34+ property alias pathItemCount: listView.pathItemCount
35+ /// Aspect ratio of the tiles width/height
36+ property alias tileAspectRatio: listView.tileAspectRatio
37+ /// Used to cache some delegates for performance reasons. See the ListView documentation for details
38+ property alias cacheBuffer: listView.cacheBuffer
39+ /// Width of the "draw buffer" in pixel. The drawBuffer is an additional area at start/end where
40+ /// items drawn, even if it is not in the visible area.
41+ /// cacheBuffer controls only the to retain delegates outside the visible area (and is used on top of the drawBuffer)
42+ /// see https://bugreports.qt-project.org/browse/QTBUG-29173
43+ property int drawBuffer: width / pathItemCount // an "ok" value - but values used from the listView cause loops
44+ /// The selected item can be shown in a different size controlled by selectedItemScaleFactor
3045 property real selectedItemScaleFactor: 1.1
3146
47+ /// Emitted when the user clicked on an item
48+ /// @param index is the index of the clicked item
49+ /// @param delegateItem is the clicked component/delegate itself
50+ /// @param itemY is y of the clicked delegate
3251 signal clicked(int index, var delegateItem, real itemY)
3352
34− implicitHeight: flickable.tileHeight * selectedItemScaleFactor
53+ implicitHeight: listView.tileHeight * selectedItemScaleFactor
3554
36− /* TODO: evaluate if the component could be more efficient with a ListView,
37− using this technique https://bugreports.qt-project.org/browse/QTBUG-29173 */
55+ /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
56+ One drawback is, that more delegates have to be drawn than usually. As some items are moved from the
57+ invisible to the visible area. Setting the cacheBuffer does not fix this.
58+ See https://bugreports.qt-project.org/browse/QTBUG-29173
59+ Therefore the ListView has negative left and right anchors margins, and in addition a header
60+ and footer item to compensate that.
3861
39− Flickable {
40− id: flickable
62+ The scaling of the items is controlled by the variable continuousIndex, described below. */
63+ ListView {
64+ id: listView
4165
4266 property real minimumTileWidth: 0
4367 property real newContentX: -1
@@ -57,20 +81,27 @@ Item {
5781 - 'gapToEndPhase' gap in pixels between middle and end phase
5882 - 'kGapEnd' constant used to calculate 'continuousIndex' in end phase
5983 - 'kMiddleIndex' constant used to calculate 'continuousIndex' in middle phase
60− - 'kXBeginningEnd' constant used to calculate 'continuousIndex' in beginning and end phase. */
84+ - 'kXBeginningEnd' constant used to calculate 'continuousIndex' in beginning and end phase
85+ - 'realContentWidth' the width of all the delegates only (without header/footer)
86+ - 'realContentX' the 'contentX' of the listview ignoring the 'drawBuffer'
87+ - 'realWidth' the 'width' of the listview, as it is used as component. */
6188
62− readonly property real gapToMiddlePhase: Math.min(width / 2 - tileWidth / 2, (contentWidth - width) / 2)
63− readonly property real gapToEndPhase: contentWidth - width - gapToMiddlePhase
89+ readonly property real gapToMiddlePhase: Math.min(realWidth / 2 - tileWidth / 2, (realContentWidth - realWidth) / 2)
90+ readonly property real gapToEndPhase: realContentWidth - realWidth - gapToMiddlePhase
6491 readonly property real kGapEnd: kMiddleIndex * (1 - gapToEndPhase / gapToMiddlePhase)
65− readonly property real kMiddleIndex: (width / 2) / tileWidth - 0.5
92+ readonly property real kMiddleIndex: (realWidth / 2) / tileWidth - 0.5
6693 readonly property real kXBeginningEnd: 1 / tileWidth + kMiddleIndex / gapToMiddlePhase
67− readonly property real realPathItemCount: Math.min(width / tileWidth, pathItemCount)
68− readonly property real referenceGapToMiddlePhase: width / 2 - tileWidth / 2
94+ readonly property real maximumItemTranslation: (listView.tileWidth * 3) / listView.scaleFactor
95+ readonly property real realContentWidth: contentWidth - 2 * carousel.drawBuffer
96+ readonly property real realContentX: contentX + carousel.drawBuffer
97+ readonly property real realPathItemCount: Math.min(realWidth / tileWidth, pathItemCount)
98+ readonly property real realWidth: carousel.width
99+ readonly property real referenceGapToMiddlePhase: realWidth / 2 - tileWidth / 2
69100 readonly property real referencePathItemCount: referenceWidth / referenceTileWidth
70101 readonly property real referenceWidth: 848
71102 readonly property real referenceTileWidth: 175
72103 readonly property real scaleFactor: tileWidth / referenceTileWidth
73− readonly property real tileWidth: Math.max(width / pathItemCount, minimumTileWidth)
104+ readonly property real tileWidth: Math.max(realWidth / pathItemCount, minimumTileWidth)
74105 readonly property real tileHeight: tileWidth / tileAspectRatio
75106 readonly property real translationXViewFactor: 0.2 * (referenceGapToMiddlePhase / gapToMiddlePhase)
76107 readonly property real verticalMargin: (parent.height - tileHeight) / 2
@@ -80,20 +111,36 @@ Item {
80111 fill: parent
81112 topMargin: verticalMargin
82113 bottomMargin: verticalMargin
114+ // extending the "drawing area"
115+ leftMargin: -carousel.drawBuffer
116+ rightMargin: -carousel.drawBuffer
83117 }
84− contentWidth: view.width
85− contentHeight: height
118+
119+ /* The header and footer help to "extend" the area, the listview draws items.
120+ This together with anchors.leftMargin and anchors.rightMargin. */
121+ header: Item {
122+ width: carousel.drawBuffer
123+ height: listView.tileHeight
124+ }
125+ footer: Item {
126+ width: carousel.drawBuffer
127+ height: listView.tileHeight
128+ }
129+
86130 boundsBehavior: Flickable.StopAtBounds
87− flickDeceleration: Math.max(1500 * Math.pow(width / referenceWidth, 1.5), 1500) // 1500 is platform default
88− maximumFlickVelocity: Math.max(2500 * Math.pow(width / referenceWidth, 1.5), 2500) // 2500 is platform default
131+ cacheBuffer: carousel.cacheBuffer
132+ flickDeceleration: Math.max(1500 * Math.pow(realWidth / referenceWidth, 1.5), 1500) // 1500 is platform default
133+ maximumFlickVelocity: Math.max(2500 * Math.pow(realWidth / referenceWidth, 1.5), 2500) // 2500 is platform default
134+ orientation: ListView.Horizontal
89135
90136 function itemClicked(index, delegateItem) {
91137 var x = CarouselJS.getXFromContinuousIndex(index,
92− width,
93− contentWidth,
138+ realWidth,
139+ realContentWidth,
94140 tileWidth,
95141 gapToMiddlePhase,
96− gapToEndPhase)
142+ gapToEndPhase,
143+ carousel.drawBuffer)
97144
98145 if (Math.abs(x - contentX) < 1) {
99146 /* We're clicking the selected item and
@@ -116,22 +163,22 @@ Item {
116163 newContentX = -1
117164 }
118165 onMovementEnded: {
119− if (contentX > 0 && contentX < contentWidth - width)
166+ if (realContentX > 0 && realContentX < realContentWidth - realWidth)
120167 stepAnimation.start()
121168 }
122169
123170 SmoothedAnimation {
124171 id: stepAnimation
125172
126− target: flickable
173+ target: listView
127174 property: "contentX"
128− from: flickable.contentX
129− to: CarouselJS.getXFromContinuousIndex(view.selectedIndex,
130− flickable.width,
131− flickable.contentWidth,
132− flickable.tileWidth,
133− flickable.gapToMiddlePhase,
134− flickable.gapToEndPhase)
175+ to: CarouselJS.getXFromContinuousIndex(listView.selectedIndex,
176+ listView.realWidth,
177+ listView.realContentWidth,
178+ listView.tileWidth,
179+ listView.gapToMiddlePhase,
180+ listView.gapToEndPhase,
181+ carousel.drawBuffer)
135182 duration: 450
136183 velocity: 200
137184 easing.type: Easing.InOutQuad
@@ -141,112 +188,96 @@ Item {
141188 id: newContentXAnimation
142189
143190 NumberAnimation {
144− target: flickable
191+ target: listView
145192 property: "contentX"
146− from: flickable.contentX
147− to: flickable.newContentX
193+ from: listView.contentX
194+ to: listView.newContentX
148195 duration: 300
149196 easing.type: Easing.InOutQuad
150197 }
151198 ScriptAction {
152− script: flickable.newContentX = -1
199+ script: listView.newContentX = -1
153200 }
154201 }
155202
156− Row {
157− id: view
158−
159− readonly property int selectedIndex: Math.round(continuousIndex)
160− readonly property real continuousIndex: CarouselJS.getContinuousIndex(flickable.contentX,
161− flickable.tileWidth,
162− flickable.gapToMiddlePhase,
163− flickable.gapToEndPhase,
164− flickable.kGapEnd,
165− flickable.kMiddleIndex,
166− flickable.kXBeginningEnd)
167−
168− height: parent.height
169− anchors.verticalCenter: parent.verticalCenter
203+ readonly property int selectedIndex: Math.round(continuousIndex)
204+ readonly property real continuousIndex: CarouselJS.getContinuousIndex(listView.realContentX,
205+ listView.tileWidth,
206+ listView.gapToMiddlePhase,
207+ listView.gapToEndPhase,
208+ listView.kGapEnd,
209+ listView.kMiddleIndex,
210+ listView.kXBeginningEnd)
211+
212+ property real viewTranslation: CarouselJS.getViewTranslation(listView.realContentX,
213+ listView.tileWidth,
214+ listView.gapToMiddlePhase,
215+ listView.gapToEndPhase,
216+ listView.translationXViewFactor)
217+
218+ delegate: Loader {
219+ property bool explicitlyScaled: explicitScaleFactor == carousel.selectedItemScaleFactor
220+ property real explicitScaleFactor: explicitScale ? carousel.selectedItemScaleFactor : 1.0
221+ readonly property bool explicitScale: (!listView.moving ||
222+ listView.realContentX <= 0 ||
223+ listView.realContentX >= listView.realContentWidth - listView.realWidth) &&
224+ listView.newContentX < 0 &&
225+ index === listView.selectedIndex
226+ readonly property real cachedTiles: listView.realPathItemCount + carousel.drawBuffer / listView.tileWidth
227+ readonly property real distance: listView.continuousIndex - index
228+ readonly property real itemTranslationScale: CarouselJS.getItemScale(0.5,
229+ (index + 0.5), // good approximation of scale while changing selected item
230+ listView.count,
231+ listView.visibleTilesScaleFactor)
232+ readonly property real itemScale: CarouselJS.getItemScale(distance,
233+ listView.continuousIndex,
234+ listView.count,
235+ listView.visibleTilesScaleFactor)
236+ readonly property real translationX: CarouselJS.getItemTranslation(index,
237+ listView.selectedIndex,
238+ distance,
239+ itemScale,
240+ itemTranslationScale,
241+ listView.maximumItemTranslation)
242+
243+ width: listView.tileWidth
244+ height: listView.tileHeight
245+ scale: itemScale * explicitScaleFactor
246+ sourceComponent: itemComponent
247+ z: cachedTiles - Math.abs(index - listView.selectedIndex)
170248
171249 transform: Translate {
172− x: CarouselJS.getViewTranslation(flickable.contentX,
173− flickable.tileWidth,
174− flickable.gapToMiddlePhase,
175− flickable.gapToEndPhase,
176− flickable.translationXViewFactor)
250+ x: listView.viewTranslation + translationX * listView.scaleFactor
177251 }
178252
179− Repeater {
180− id: repeater
181−
182− model: carousel.model
183−
184− Loader {
185− property bool explicitlyScaled: explicitScaleFactor == carousel.selectedItemScaleFactor
186− property real explicitScaleFactor: explicitScale ? carousel.selectedItemScaleFactor : 1.0
187− readonly property bool explicitScale: (!flickable.moving ||
188− flickable.contentX <= 0 ||
189− flickable.contentX >= flickable.contentWidth - flickable.width) &&
190− flickable.newContentX < 0 &&
191− index === view.selectedIndex
192− readonly property real cachedTiles: flickable.realPathItemCount + carousel.cacheBuffer / flickable.tileWidth
193− readonly property real distance: view.continuousIndex - index
194− readonly property real itemTranslationScale: CarouselJS.getItemScale(0.5,
195− (index + 0.5), // good approximation of scale while changing selected item
196− repeater.count,
197− flickable.visibleTilesScaleFactor)
198− readonly property real itemScale: CarouselJS.getItemScale(distance,
199− view.continuousIndex,
200− repeater.count,
201− flickable.visibleTilesScaleFactor)
202− readonly property real translationFactor: (flickable.tileWidth * 3) / flickable.scaleFactor
203− readonly property real translationX: index === view.selectedIndex ? 0 :
204− CarouselJS.getItemTranslation(distance,
205− itemScale,
206− itemTranslationScale,
207− translationFactor)
208−
209− width: flickable.tileWidth
210− height: flickable.tileHeight
211− scale: itemScale * explicitScaleFactor
212− opacity: scale > 0.02 ? 1 : 0
213− sourceComponent: z > 0 ? itemComponent : undefined
214− z: cachedTiles - Math.abs(index - view.selectedIndex)
215−
216− transform: Translate {
217− x: translationX * flickable.scaleFactor
253+ Behavior on explicitScaleFactor {
254+ SequentialAnimation {
255+ ScriptAction {
256+ script: if (!explicitScale)
257+ explicitlyScaled = false
218258 }
219−
220− Behavior on explicitScaleFactor {
221− SequentialAnimation {
222− ScriptAction {
223− script: if (!explicitScale)
224− explicitlyScaled = false
225− }
226− NumberAnimation {
227− duration: explicitScaleFactor === 1.0 ? 250 : 150
228− easing.type: Easing.InOutQuad
229− }
230− ScriptAction {
231− script: if (explicitScale)
232− explicitlyScaled = true
233− }
234− }
259+ NumberAnimation {
260+ duration: explicitScaleFactor === 1.0 ? 250 : 150
261+ easing.type: Easing.InOutQuad
235262 }
236−
237− onLoaded: {
238− item.explicitlyScaled = Qt.binding(function() { return explicitlyScaled; })
239− item.model = Qt.binding(function() { return model; })
263+ ScriptAction {
264+ script: if (explicitScale)
265+ explicitlyScaled = true
240266 }
267+ }
268+ }
241269
242− MouseArea {
243− id: mouseArea
270+ onLoaded: {
271+ item.explicitlyScaled = Qt.binding(function() { return explicitlyScaled; })
272+ item.model = Qt.binding(function() { return model; })
273+ }
244274
245− anchors.fill: parent
275+ MouseArea {
276+ id: mouseArea
246277
247− onClicked: flickable.itemClicked(index, item)
248− }
249− }
278+ anchors.fill: parent
279+
280+ onClicked: listView.itemClicked(index, item)
250281 }
251282 }
252283 }
Components/carousel.js+47−11
@@ -16,7 +16,15 @@
1616
1717.pragma library
1818
19−// get the element which is selected accordingly to x, the hero of the view
19+/*! get the element which is selected accordingly to x, the hero of the view
20+ @param x contentX of the ListView
21+ @param tileWidth width of a single tile
22+ @param gapToMiddlePhase gap in pixels between beginning and middle phase
23+ @param gapToEndPhase gap in pixels between middle and end phase
24+ @param kGapEnd
25+ @param kMiddleIndex
26+ @param kXBeginningEnd
27+*/
2028function getContinuousIndex(x, tileWidth, gapToMiddlePhase, gapToEndPhase, kGapEnd, kMiddleIndex, kXBeginningEnd) {
2129 if (x < gapToMiddlePhase) {
2230 // beginning
@@ -30,8 +38,16 @@ function getContinuousIndex(x, tileWidth, gapToMiddlePhase, gapToEndPhase, kGapE
3038 return x / tileWidth + kMiddleIndex
3139}
3240
33−// obtain x position relative to an index, essentially an inverse of getContinuousIndex()
34−function getXFromContinuousIndex(index, viewWidth, contentWidth, tileWidth, gapToMiddlePhase, gapToEndPhase) {
41+/*! obtain x position relative to an index, essentially an inverse of getContinuousIndex()
42+ @param index index of the item to calcualte the proper X value for
43+ @param viewWidth visible width of the view
44+ @param contentWidth width off all items in the view
45+ @param tileWidth width of one item
46+ @param gapToMiddlePhase
47+ @param gapToEndPhase
48+ @param drawBuffer width of the drawBuffer
49+*/
50+function getXFromContinuousIndex(index, viewWidth, contentWidth, tileWidth, gapToMiddlePhase, gapToEndPhase, drawBuffer) {
3551 var middleX = (index + 0.5) * tileWidth - viewWidth / 2
3652
3753 if (middleX < gapToMiddlePhase) {
@@ -40,6 +56,7 @@ function getXFromContinuousIndex(index, viewWidth, contentWidth, tileWidth, gapT
4056 ((1 / tileWidth) +
4157 (viewWidth / (2 * tileWidth * gapToMiddlePhase)) -
4258 1 / (2 * gapToMiddlePhase))
59+ - drawBuffer
4360 } else if (middleX > gapToEndPhase) {
4461 // inverse of 'middleIndex + kGap' of getContinuousIndex()
4562 return (index +
@@ -50,13 +67,19 @@ function getXFromContinuousIndex(index, viewWidth, contentWidth, tileWidth, gapT
5067 (1 / tileWidth +
5168 viewWidth / (2 * tileWidth * gapToMiddlePhase) -
5269 1 / (2 * gapToMiddlePhase))
70+ - drawBuffer
5371 }
5472
5573 // inverse of 'middleIndex' of getContinuousIndex()
56− return middleX
74+ return middleX - drawBuffer
5775}
5876
59−// get translation of the whole view, adds gaps on sides
77+/*! get translation of the whole view, adds gaps on sides
78+ @param x contentX of the ListView
79+ @param gapToMiddlePhase
80+ @param gapToEndPhase
81+ @param translationXViewFactor
82+*/
6083function getViewTranslation(x, tileWidth, gapToMiddlePhase, gapToEndPhase, translationXViewFactor) {
6184 if (x < gapToMiddlePhase) {
6285 // beginning
@@ -70,16 +93,29 @@ function getViewTranslation(x, tileWidth, gapToMiddlePhase, gapToEndPhase, trans
7093 return 0
7194}
7295
73−// item scale
74−function getItemScale(distance, continuousIndex, end, scaleFactor) {
96+/*! item scale
97+ @param distance is the difference of the item's index to the continuousIndex
98+ @param continuousIndex the current index in real number
99+ @param numberOfItems the total number of items in the model
100+ @param scaleFactor if bigger than 1, the scaling is done slower (more distance needed)
101+*/
102+function getItemScale(distance, continuousIndex, numberOfItems, scaleFactor) {
75103 var distanceAbs = Math.abs(distance)
76− var distanceToBounds = Math.min(continuousIndex, end - continuousIndex)
104+ var distanceToBounds = Math.min(continuousIndex, numberOfItems - continuousIndex)
77105 var k = Math.max(200 + 100 * (-distanceToBounds / (3 * scaleFactor)), 50)
78106 return Math.max(0.01, 1 - Math.pow(distanceAbs, 2.5) / (k * scaleFactor))
79107}
80108
81−// item translation
82−function getItemTranslation(distance, scale, maxScale, translationFactor) {
109+/*! item translation
110+ @param index index of the current item
111+ @param selectedIndex index of the selected item
112+ @param distance controls the direction wich is left/negative and right/positive
113+ @param scale is the current scale factor of the item
114+ @param maxScale the maximum scale factor (the one used when the index is on that item
115+ @param maxTranslation the maximum translation length in pixel
116+*/
117+function getItemTranslation(index, selectedIndex, distance, scale, maxScale, maxTranslation) {
118+ if (index === selectedIndex) return 0
83119 var sign = distance > 0 ? 1 : -1
84− return sign * (maxScale - scale) * translationFactor
120+ return sign * (maxScale - scale) * maxTranslation
85121}
tests/qmltests/Components/tst_Carousel.qml+38−34
@@ -19,6 +19,7 @@ import QtTest 1.0
1919import "../../../Components/carousel.js" as Carousel
2020
2121TestCase {
22+ id: root
2223 name: "Carousel"
2324
2425 property real carouselWidth
@@ -49,9 +50,9 @@ TestCase {
4950 }
5051
5152 function test_getContinuousIndex(data) {
52− carouselWidth = data.carouselWidth
53− tileWidth = data.tileWidth
54− itemCount = data.itemCount
53+ root.carouselWidth = data.carouselWidth
54+ root.tileWidth = data.tileWidth
55+ root.itemCount = data.itemCount
5556
5657 var index = Carousel.getContinuousIndex(data.x,
5758 data.tileWidth,
@@ -69,23 +70,23 @@ TestCase {
6970 index: 0, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:0, result: 0},
7071 {tag:"in startup",
7172 index: 2, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:0, result: 100},
72−// {tag:"in startup with drawBuffer",
73−// index: 2, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 0},
73+ {tag:"in startup with drawBuffer",
74+ index: 2, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 0},
7475 {tag:"in the middle",
7576 index: 5, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:0, result: 350},
76−// {tag:"in the middle with drawBuffer",
77−// index: 5, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 250},
77+ {tag:"in the middle with drawBuffer",
78+ index: 5, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 250},
7879 {tag:"at end",
7980 index: 9, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:0, result: 600},
80−// {tag:"at end with drawBuffer",
81−// index: 9, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 500},
81+ {tag:"at end with drawBuffer",
82+ index: 9, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 500},
8283 ]
8384 }
8485
8586 function test_getXFromContinuousIndex(data) {
86− carouselWidth = data.carouselWidth
87− tileWidth = data.tileWidth
88− itemCount = data.itemCount
87+ root.carouselWidth = data.carouselWidth
88+ root.tileWidth = data.tileWidth
89+ root.itemCount = data.itemCount
8990
9091 var x = Carousel.getXFromContinuousIndex(data.index,
9192 data.carouselWidth,
@@ -113,14 +114,14 @@ TestCase {
113114 }
114115
115116 function test_getViewTranslation(data) {
116− carouselWidth = data.carouselWidth
117− tileWidth = data.tileWidth
118− itemCount = data.itemCount
117+ root.carouselWidth = data.carouselWidth
118+ root.tileWidth = data.tileWidth
119+ root.itemCount = data.itemCount
119120
120121 var x = Carousel.getViewTranslation(data.x,
121122 data.tileWidth,
122− gapToMiddlePhase,
123− gapToEndPhase,
123+ root.gapToMiddlePhase,
124+ root.gapToEndPhase,
124125 data.translationXViewFactor)
125126 compare(x, data.result)
126127 }
@@ -158,30 +159,33 @@ TestCase {
158159
159160 // test for the getItemTranslation() function
160161 function test_getItemTranslation_data() {
161− return [ // tests if distance only affects the sign
162− {distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
163−// {distance: 99, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
164− {distance: 0, scale: 0, maxScale: 1, maxTranslation: 10, result: -10},
165− {distance: -1, scale: 0, maxScale: 1, maxTranslation: 10, result: -10},
162+ return [ // tests for index and selectedIndex
163+ {index: 1, selectedIndex: 1, distance: 1, scale: 1, maxScale: 1, maxTranslation: 10, result: 0},
164+ // tests if distance only affects the sign
165+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
166+ {index: 1, selectedIndex: 2, distance: 99, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
167+ {index: 1, selectedIndex: 2, distance: -1, scale: 0, maxScale: 1, maxTranslation: 10, result: -10},
168+ {index: 1, selectedIndex: 2, distance: -99, scale: 0, maxScale: 1, maxTranslation: 10, result: -10},
166169 // tests for the scale
167− {distance: 1, scale: 1, maxScale: 1, maxTranslation: 10, result: 0},
168− {distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
169− {distance: 1, scale: 0.5, maxScale: 1, maxTranslation: 10, result: 5},
170+ {index: 1, selectedIndex: 2, distance: 1, scale: 1, maxScale: 1, maxTranslation: 10, result: 0},
171+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
172+ {index: 1, selectedIndex: 2, distance: 1, scale: 0.5, maxScale: 1, maxTranslation: 10, result: 5},
170173 // tests for maxScale
171− {distance: 1, scale: 1, maxScale: 1, maxTranslation: 10, result: 0},
172− {distance: 1, scale: 1, maxScale: 2, maxTranslation: 10, result: 10},
173−// {distance: 1, scale: 1, maxScale: 0, maxTranslation: 10, result: 0},
174−// {distance: 1, scale: 1, maxScale: 99, maxTranslation: 10, result: 10},
174+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 0.98, maxTranslation: 10, result: 9.8},
175+ {index: 1, selectedIndex: 2, distance: 1, scale: 0.5, maxScale: 0.95, maxTranslation: 10, result: 4.5},
176+ {index: 1, selectedIndex: 2, distance: 1, scale: 0.8, maxScale: 0.93, maxTranslation: 10, result: 1.3},
175177 // test for maxTranslation
176− {distance: 1, scale: 1, maxScale: 1, maxTranslation: 1, result: 0},
177− {distance: 1, scale: 0, maxScale: 1, maxTranslation: 1, result: 1},
178− {distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
179− {distance: 1, scale: 0, maxScale: 1, maxTranslation: 0, result: 0},
178+ {index: 1, selectedIndex: 2, distance: 1, scale: 1, maxScale: 1, maxTranslation: 1, result: 0},
179+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 1, result: 1},
180+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
181+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 0, result: 0},
180182 ]
181183 }
182184
183185 function test_getItemTranslation(data) {
184− var scale = Carousel.getItemTranslation(data.distance,
186+ var scale = Carousel.getItemTranslation(data.index,
187+ data.selectedIndex,
188+ data.distance,
185189 data.scale,
186190 data.maxScale,
187191 data.maxTranslation)