Merge lp:~unity-team/unity/8.carousel-listview into lp:unity/8.0

Proposed by Michał Sawicz
Status: Merged
Approved by: Albert Astals Cid
Approved revision: no longer in the source branch.
Merged at revision: 9
Proposed branch: lp:~unity-team/unity/8.carousel-listview
Merge into: lp:unity/8.0
Diff against target: 603 lines (+244/-173)
3 files modified
Components/Carousel.qml (+159/-128)
Components/carousel.js (+47/-11)
tests/qmltests/Components/tst_Carousel.qml (+38/-34)
To merge this branch: bzr merge lp:~unity-team/unity/8.carousel-listview
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Albert Astals Cid (community) Approve
Andrea Cimitan Pending
Review via email: mp+167713@code.launchpad.net

This proposal supersedes a proposal from 2013-05-22.

Commit message

Bring back ListView'ed Carousel now that Qt is fixed.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Andrea Cimitan (cimi) wrote : Posted in a previous version of this proposal

Since we are here, shall we add some extra tests? (in case, push as unity-team so I can contribute)

Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

> Since we are here, shall we add some extra tests? (in case, push as unity-team so I can contribute)

Done. Test away :)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Exactly the same code i have in the branch i had for testing the listview-carousel crashes

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Components/Carousel.qml'
2--- Components/Carousel.qml 2013-06-05 22:03:08 +0000
3+++ Components/Carousel.qml 2013-06-06 08:03:28 +0000
4@@ -18,26 +18,50 @@
5 import Ubuntu.Components 0.1
6 import "carousel.js" as CarouselJS
7
8+/*! The Carousel component presents the items of a model in a carousel view. It's similar to a
9+ cover flow. But it stops at it's boundaries (therefore no PathView is used).
10+ */
11 Item {
12 id: carousel
13
14+ /// The component to be used as delegate. This component has to be derived from BaseCarouselDelegate
15 property Component itemComponent
16- property var model
17- property alias minimumTileWidth: flickable.minimumTileWidth
18- property alias pathItemCount: flickable.pathItemCount
19- property alias tileAspectRatio: flickable.tileAspectRatio
20- property int cacheBuffer: 0
21+ /// Model for the Carousel, which has to be a model usable by a ListView
22+ property alias model: listView.model
23+ /// A minimal width of a tile can be set here. Per default a best fit will be calculated
24+ property alias minimumTileWidth: listView.minimumTileWidth
25+ /// Sets the number of tiles that are visible
26+ property alias pathItemCount: listView.pathItemCount
27+ /// Aspect ratio of the tiles width/height
28+ property alias tileAspectRatio: listView.tileAspectRatio
29+ /// Used to cache some delegates for performance reasons. See the ListView documentation for details
30+ property alias cacheBuffer: listView.cacheBuffer
31+ /// Width of the "draw buffer" in pixel. The drawBuffer is an additional area at start/end where
32+ /// items drawn, even if it is not in the visible area.
33+ /// cacheBuffer controls only the to retain delegates outside the visible area (and is used on top of the drawBuffer)
34+ /// see https://bugreports.qt-project.org/browse/QTBUG-29173
35+ property int drawBuffer: width / pathItemCount // an "ok" value - but values used from the listView cause loops
36+ /// The selected item can be shown in a different size controlled by selectedItemScaleFactor
37 property real selectedItemScaleFactor: 1.1
38
39+ /// Emitted when the user clicked on an item
40+ /// @param index is the index of the clicked item
41+ /// @param delegateItem is the clicked component/delegate itself
42+ /// @param itemY is y of the clicked delegate
43 signal clicked(int index, var delegateItem, real itemY)
44
45- implicitHeight: flickable.tileHeight * selectedItemScaleFactor
46-
47- /* TODO: evaluate if the component could be more efficient with a ListView,
48- using this technique https://bugreports.qt-project.org/browse/QTBUG-29173 */
49-
50- Flickable {
51- id: flickable
52+ implicitHeight: listView.tileHeight * selectedItemScaleFactor
53+
54+ /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
55+ One drawback is, that more delegates have to be drawn than usually. As some items are moved from the
56+ invisible to the visible area. Setting the cacheBuffer does not fix this.
57+ See https://bugreports.qt-project.org/browse/QTBUG-29173
58+ Therefore the ListView has negative left and right anchors margins, and in addition a header
59+ and footer item to compensate that.
60+
61+ The scaling of the items is controlled by the variable continuousIndex, described below. */
62+ ListView {
63+ id: listView
64
65 property real minimumTileWidth: 0
66 property real newContentX: -1
67@@ -57,20 +81,27 @@
68 - 'gapToEndPhase' gap in pixels between middle and end phase
69 - 'kGapEnd' constant used to calculate 'continuousIndex' in end phase
70 - 'kMiddleIndex' constant used to calculate 'continuousIndex' in middle phase
71- - 'kXBeginningEnd' constant used to calculate 'continuousIndex' in beginning and end phase. */
72+ - 'kXBeginningEnd' constant used to calculate 'continuousIndex' in beginning and end phase
73+ - 'realContentWidth' the width of all the delegates only (without header/footer)
74+ - 'realContentX' the 'contentX' of the listview ignoring the 'drawBuffer'
75+ - 'realWidth' the 'width' of the listview, as it is used as component. */
76
77- readonly property real gapToMiddlePhase: Math.min(width / 2 - tileWidth / 2, (contentWidth - width) / 2)
78- readonly property real gapToEndPhase: contentWidth - width - gapToMiddlePhase
79+ readonly property real gapToMiddlePhase: Math.min(realWidth / 2 - tileWidth / 2, (realContentWidth - realWidth) / 2)
80+ readonly property real gapToEndPhase: realContentWidth - realWidth - gapToMiddlePhase
81 readonly property real kGapEnd: kMiddleIndex * (1 - gapToEndPhase / gapToMiddlePhase)
82- readonly property real kMiddleIndex: (width / 2) / tileWidth - 0.5
83+ readonly property real kMiddleIndex: (realWidth / 2) / tileWidth - 0.5
84 readonly property real kXBeginningEnd: 1 / tileWidth + kMiddleIndex / gapToMiddlePhase
85- readonly property real realPathItemCount: Math.min(width / tileWidth, pathItemCount)
86- readonly property real referenceGapToMiddlePhase: width / 2 - tileWidth / 2
87+ readonly property real maximumItemTranslation: (listView.tileWidth * 3) / listView.scaleFactor
88+ readonly property real realContentWidth: contentWidth - 2 * carousel.drawBuffer
89+ readonly property real realContentX: contentX + carousel.drawBuffer
90+ readonly property real realPathItemCount: Math.min(realWidth / tileWidth, pathItemCount)
91+ readonly property real realWidth: carousel.width
92+ readonly property real referenceGapToMiddlePhase: realWidth / 2 - tileWidth / 2
93 readonly property real referencePathItemCount: referenceWidth / referenceTileWidth
94 readonly property real referenceWidth: 848
95 readonly property real referenceTileWidth: 175
96 readonly property real scaleFactor: tileWidth / referenceTileWidth
97- readonly property real tileWidth: Math.max(width / pathItemCount, minimumTileWidth)
98+ readonly property real tileWidth: Math.max(realWidth / pathItemCount, minimumTileWidth)
99 readonly property real tileHeight: tileWidth / tileAspectRatio
100 readonly property real translationXViewFactor: 0.2 * (referenceGapToMiddlePhase / gapToMiddlePhase)
101 readonly property real verticalMargin: (parent.height - tileHeight) / 2
102@@ -80,20 +111,36 @@
103 fill: parent
104 topMargin: verticalMargin
105 bottomMargin: verticalMargin
106- }
107- contentWidth: view.width
108- contentHeight: height
109+ // extending the "drawing area"
110+ leftMargin: -carousel.drawBuffer
111+ rightMargin: -carousel.drawBuffer
112+ }
113+
114+ /* The header and footer help to "extend" the area, the listview draws items.
115+ This together with anchors.leftMargin and anchors.rightMargin. */
116+ header: Item {
117+ width: carousel.drawBuffer
118+ height: listView.tileHeight
119+ }
120+ footer: Item {
121+ width: carousel.drawBuffer
122+ height: listView.tileHeight
123+ }
124+
125 boundsBehavior: Flickable.StopAtBounds
126- flickDeceleration: Math.max(1500 * Math.pow(width / referenceWidth, 1.5), 1500) // 1500 is platform default
127- maximumFlickVelocity: Math.max(2500 * Math.pow(width / referenceWidth, 1.5), 2500) // 2500 is platform default
128+ cacheBuffer: carousel.cacheBuffer
129+ flickDeceleration: Math.max(1500 * Math.pow(realWidth / referenceWidth, 1.5), 1500) // 1500 is platform default
130+ maximumFlickVelocity: Math.max(2500 * Math.pow(realWidth / referenceWidth, 1.5), 2500) // 2500 is platform default
131+ orientation: ListView.Horizontal
132
133 function itemClicked(index, delegateItem) {
134 var x = CarouselJS.getXFromContinuousIndex(index,
135- width,
136- contentWidth,
137+ realWidth,
138+ realContentWidth,
139 tileWidth,
140 gapToMiddlePhase,
141- gapToEndPhase)
142+ gapToEndPhase,
143+ carousel.drawBuffer)
144
145 if (Math.abs(x - contentX) < 1) {
146 /* We're clicking the selected item and
147@@ -116,22 +163,22 @@
148 newContentX = -1
149 }
150 onMovementEnded: {
151- if (contentX > 0 && contentX < contentWidth - width)
152+ if (realContentX > 0 && realContentX < realContentWidth - realWidth)
153 stepAnimation.start()
154 }
155
156 SmoothedAnimation {
157 id: stepAnimation
158
159- target: flickable
160+ target: listView
161 property: "contentX"
162- from: flickable.contentX
163- to: CarouselJS.getXFromContinuousIndex(view.selectedIndex,
164- flickable.width,
165- flickable.contentWidth,
166- flickable.tileWidth,
167- flickable.gapToMiddlePhase,
168- flickable.gapToEndPhase)
169+ to: CarouselJS.getXFromContinuousIndex(listView.selectedIndex,
170+ listView.realWidth,
171+ listView.realContentWidth,
172+ listView.tileWidth,
173+ listView.gapToMiddlePhase,
174+ listView.gapToEndPhase,
175+ carousel.drawBuffer)
176 duration: 450
177 velocity: 200
178 easing.type: Easing.InOutQuad
179@@ -141,113 +188,97 @@
180 id: newContentXAnimation
181
182 NumberAnimation {
183- target: flickable
184+ target: listView
185 property: "contentX"
186- from: flickable.contentX
187- to: flickable.newContentX
188+ from: listView.contentX
189+ to: listView.newContentX
190 duration: 300
191 easing.type: Easing.InOutQuad
192 }
193 ScriptAction {
194- script: flickable.newContentX = -1
195+ script: listView.newContentX = -1
196 }
197 }
198
199- Row {
200- id: view
201-
202- readonly property int selectedIndex: Math.round(continuousIndex)
203- readonly property real continuousIndex: CarouselJS.getContinuousIndex(flickable.contentX,
204- flickable.tileWidth,
205- flickable.gapToMiddlePhase,
206- flickable.gapToEndPhase,
207- flickable.kGapEnd,
208- flickable.kMiddleIndex,
209- flickable.kXBeginningEnd)
210-
211- height: parent.height
212- anchors.verticalCenter: parent.verticalCenter
213+ readonly property int selectedIndex: Math.round(continuousIndex)
214+ readonly property real continuousIndex: CarouselJS.getContinuousIndex(listView.realContentX,
215+ listView.tileWidth,
216+ listView.gapToMiddlePhase,
217+ listView.gapToEndPhase,
218+ listView.kGapEnd,
219+ listView.kMiddleIndex,
220+ listView.kXBeginningEnd)
221+
222+ property real viewTranslation: CarouselJS.getViewTranslation(listView.realContentX,
223+ listView.tileWidth,
224+ listView.gapToMiddlePhase,
225+ listView.gapToEndPhase,
226+ listView.translationXViewFactor)
227+
228+ delegate: Loader {
229+ property bool explicitlyScaled: explicitScaleFactor == carousel.selectedItemScaleFactor
230+ property real explicitScaleFactor: explicitScale ? carousel.selectedItemScaleFactor : 1.0
231+ readonly property bool explicitScale: (!listView.moving ||
232+ listView.realContentX <= 0 ||
233+ listView.realContentX >= listView.realContentWidth - listView.realWidth) &&
234+ listView.newContentX < 0 &&
235+ index === listView.selectedIndex
236+ readonly property real cachedTiles: listView.realPathItemCount + carousel.drawBuffer / listView.tileWidth
237+ readonly property real distance: listView.continuousIndex - index
238+ readonly property real itemTranslationScale: CarouselJS.getItemScale(0.5,
239+ (index + 0.5), // good approximation of scale while changing selected item
240+ listView.count,
241+ listView.visibleTilesScaleFactor)
242+ readonly property real itemScale: CarouselJS.getItemScale(distance,
243+ listView.continuousIndex,
244+ listView.count,
245+ listView.visibleTilesScaleFactor)
246+ readonly property real translationX: CarouselJS.getItemTranslation(index,
247+ listView.selectedIndex,
248+ distance,
249+ itemScale,
250+ itemTranslationScale,
251+ listView.maximumItemTranslation)
252+
253+ width: listView.tileWidth
254+ height: listView.tileHeight
255+ scale: itemScale * explicitScaleFactor
256+ sourceComponent: itemComponent
257+ z: cachedTiles - Math.abs(index - listView.selectedIndex)
258
259 transform: Translate {
260- x: CarouselJS.getViewTranslation(flickable.contentX,
261- flickable.tileWidth,
262- flickable.gapToMiddlePhase,
263- flickable.gapToEndPhase,
264- flickable.translationXViewFactor)
265+ x: listView.viewTranslation + translationX * listView.scaleFactor
266 }
267
268- Repeater {
269- id: repeater
270-
271- model: carousel.model
272-
273- Loader {
274- property bool explicitlyScaled: explicitScaleFactor == carousel.selectedItemScaleFactor
275- property real explicitScaleFactor: explicitScale ? carousel.selectedItemScaleFactor : 1.0
276- readonly property bool explicitScale: (!flickable.moving ||
277- flickable.contentX <= 0 ||
278- flickable.contentX >= flickable.contentWidth - flickable.width) &&
279- flickable.newContentX < 0 &&
280- index === view.selectedIndex
281- readonly property real cachedTiles: flickable.realPathItemCount + carousel.cacheBuffer / flickable.tileWidth
282- readonly property real distance: view.continuousIndex - index
283- readonly property real itemTranslationScale: CarouselJS.getItemScale(0.5,
284- (index + 0.5), // good approximation of scale while changing selected item
285- repeater.count,
286- flickable.visibleTilesScaleFactor)
287- readonly property real itemScale: CarouselJS.getItemScale(distance,
288- view.continuousIndex,
289- repeater.count,
290- flickable.visibleTilesScaleFactor)
291- readonly property real translationFactor: (flickable.tileWidth * 3) / flickable.scaleFactor
292- readonly property real translationX: index === view.selectedIndex ? 0 :
293- CarouselJS.getItemTranslation(distance,
294- itemScale,
295- itemTranslationScale,
296- translationFactor)
297-
298- width: flickable.tileWidth
299- height: flickable.tileHeight
300- scale: itemScale * explicitScaleFactor
301- opacity: scale > 0.02 ? 1 : 0
302- sourceComponent: z > 0 ? itemComponent : undefined
303- z: cachedTiles - Math.abs(index - view.selectedIndex)
304-
305- transform: Translate {
306- x: translationX * flickable.scaleFactor
307- }
308-
309- Behavior on explicitScaleFactor {
310- SequentialAnimation {
311- ScriptAction {
312- script: if (!explicitScale)
313- explicitlyScaled = false
314- }
315- NumberAnimation {
316- duration: explicitScaleFactor === 1.0 ? 250 : 150
317- easing.type: Easing.InOutQuad
318- }
319- ScriptAction {
320- script: if (explicitScale)
321- explicitlyScaled = true
322- }
323- }
324- }
325-
326- onLoaded: {
327- item.explicitlyScaled = Qt.binding(function() { return explicitlyScaled; })
328- item.model = Qt.binding(function() { return model; })
329- }
330-
331- MouseArea {
332- id: mouseArea
333-
334- anchors.fill: parent
335-
336- onClicked: flickable.itemClicked(index, item)
337+ Behavior on explicitScaleFactor {
338+ SequentialAnimation {
339+ ScriptAction {
340+ script: if (!explicitScale)
341+ explicitlyScaled = false
342+ }
343+ NumberAnimation {
344+ duration: explicitScaleFactor === 1.0 ? 250 : 150
345+ easing.type: Easing.InOutQuad
346+ }
347+ ScriptAction {
348+ script: if (explicitScale)
349+ explicitlyScaled = true
350 }
351 }
352 }
353+
354+ onLoaded: {
355+ item.explicitlyScaled = Qt.binding(function() { return explicitlyScaled; })
356+ item.model = Qt.binding(function() { return model; })
357+ }
358+
359+ MouseArea {
360+ id: mouseArea
361+
362+ anchors.fill: parent
363+
364+ onClicked: listView.itemClicked(index, item)
365+ }
366 }
367 }
368 }
369
370=== modified file 'Components/carousel.js'
371--- Components/carousel.js 2013-06-05 22:03:08 +0000
372+++ Components/carousel.js 2013-06-06 08:03:28 +0000
373@@ -16,7 +16,15 @@
374
375 .pragma library
376
377-// get the element which is selected accordingly to x, the hero of the view
378+/*! get the element which is selected accordingly to x, the hero of the view
379+ @param x contentX of the ListView
380+ @param tileWidth width of a single tile
381+ @param gapToMiddlePhase gap in pixels between beginning and middle phase
382+ @param gapToEndPhase gap in pixels between middle and end phase
383+ @param kGapEnd
384+ @param kMiddleIndex
385+ @param kXBeginningEnd
386+*/
387 function getContinuousIndex(x, tileWidth, gapToMiddlePhase, gapToEndPhase, kGapEnd, kMiddleIndex, kXBeginningEnd) {
388 if (x < gapToMiddlePhase) {
389 // beginning
390@@ -30,8 +38,16 @@
391 return x / tileWidth + kMiddleIndex
392 }
393
394-// obtain x position relative to an index, essentially an inverse of getContinuousIndex()
395-function getXFromContinuousIndex(index, viewWidth, contentWidth, tileWidth, gapToMiddlePhase, gapToEndPhase) {
396+/*! obtain x position relative to an index, essentially an inverse of getContinuousIndex()
397+ @param index index of the item to calcualte the proper X value for
398+ @param viewWidth visible width of the view
399+ @param contentWidth width off all items in the view
400+ @param tileWidth width of one item
401+ @param gapToMiddlePhase
402+ @param gapToEndPhase
403+ @param drawBuffer width of the drawBuffer
404+*/
405+function getXFromContinuousIndex(index, viewWidth, contentWidth, tileWidth, gapToMiddlePhase, gapToEndPhase, drawBuffer) {
406 var middleX = (index + 0.5) * tileWidth - viewWidth / 2
407
408 if (middleX < gapToMiddlePhase) {
409@@ -40,6 +56,7 @@
410 ((1 / tileWidth) +
411 (viewWidth / (2 * tileWidth * gapToMiddlePhase)) -
412 1 / (2 * gapToMiddlePhase))
413+ - drawBuffer
414 } else if (middleX > gapToEndPhase) {
415 // inverse of 'middleIndex + kGap' of getContinuousIndex()
416 return (index +
417@@ -50,13 +67,19 @@
418 (1 / tileWidth +
419 viewWidth / (2 * tileWidth * gapToMiddlePhase) -
420 1 / (2 * gapToMiddlePhase))
421+ - drawBuffer
422 }
423
424 // inverse of 'middleIndex' of getContinuousIndex()
425- return middleX
426+ return middleX - drawBuffer
427 }
428
429-// get translation of the whole view, adds gaps on sides
430+/*! get translation of the whole view, adds gaps on sides
431+ @param x contentX of the ListView
432+ @param gapToMiddlePhase
433+ @param gapToEndPhase
434+ @param translationXViewFactor
435+*/
436 function getViewTranslation(x, tileWidth, gapToMiddlePhase, gapToEndPhase, translationXViewFactor) {
437 if (x < gapToMiddlePhase) {
438 // beginning
439@@ -70,16 +93,29 @@
440 return 0
441 }
442
443-// item scale
444-function getItemScale(distance, continuousIndex, end, scaleFactor) {
445+/*! item scale
446+ @param distance is the difference of the item's index to the continuousIndex
447+ @param continuousIndex the current index in real number
448+ @param numberOfItems the total number of items in the model
449+ @param scaleFactor if bigger than 1, the scaling is done slower (more distance needed)
450+*/
451+function getItemScale(distance, continuousIndex, numberOfItems, scaleFactor) {
452 var distanceAbs = Math.abs(distance)
453- var distanceToBounds = Math.min(continuousIndex, end - continuousIndex)
454+ var distanceToBounds = Math.min(continuousIndex, numberOfItems - continuousIndex)
455 var k = Math.max(200 + 100 * (-distanceToBounds / (3 * scaleFactor)), 50)
456 return Math.max(0.01, 1 - Math.pow(distanceAbs, 2.5) / (k * scaleFactor))
457 }
458
459-// item translation
460-function getItemTranslation(distance, scale, maxScale, translationFactor) {
461+/*! item translation
462+ @param index index of the current item
463+ @param selectedIndex index of the selected item
464+ @param distance controls the direction wich is left/negative and right/positive
465+ @param scale is the current scale factor of the item
466+ @param maxScale the maximum scale factor (the one used when the index is on that item
467+ @param maxTranslation the maximum translation length in pixel
468+*/
469+function getItemTranslation(index, selectedIndex, distance, scale, maxScale, maxTranslation) {
470+ if (index === selectedIndex) return 0
471 var sign = distance > 0 ? 1 : -1
472- return sign * (maxScale - scale) * translationFactor
473+ return sign * (maxScale - scale) * maxTranslation
474 }
475
476=== modified file 'tests/qmltests/Components/tst_Carousel.qml'
477--- tests/qmltests/Components/tst_Carousel.qml 2013-06-05 22:03:08 +0000
478+++ tests/qmltests/Components/tst_Carousel.qml 2013-06-06 08:03:28 +0000
479@@ -19,6 +19,7 @@
480 import "../../../Components/carousel.js" as Carousel
481
482 TestCase {
483+ id: root
484 name: "Carousel"
485
486 property real carouselWidth
487@@ -49,9 +50,9 @@
488 }
489
490 function test_getContinuousIndex(data) {
491- carouselWidth = data.carouselWidth
492- tileWidth = data.tileWidth
493- itemCount = data.itemCount
494+ root.carouselWidth = data.carouselWidth
495+ root.tileWidth = data.tileWidth
496+ root.itemCount = data.itemCount
497
498 var index = Carousel.getContinuousIndex(data.x,
499 data.tileWidth,
500@@ -69,23 +70,23 @@
501 index: 0, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:0, result: 0},
502 {tag:"in startup",
503 index: 2, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:0, result: 100},
504-// {tag:"in startup with drawBuffer",
505-// index: 2, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 0},
506+ {tag:"in startup with drawBuffer",
507+ index: 2, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 0},
508 {tag:"in the middle",
509 index: 5, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:0, result: 350},
510-// {tag:"in the middle with drawBuffer",
511-// index: 5, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 250},
512+ {tag:"in the middle with drawBuffer",
513+ index: 5, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 250},
514 {tag:"at end",
515 index: 9, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:0, result: 600},
516-// {tag:"at end with drawBuffer",
517-// index: 9, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 500},
518+ {tag:"at end with drawBuffer",
519+ index: 9, carouselWidth:400, tileWidth:100, itemCount:10, drawBuffer:100, result: 500},
520 ]
521 }
522
523 function test_getXFromContinuousIndex(data) {
524- carouselWidth = data.carouselWidth
525- tileWidth = data.tileWidth
526- itemCount = data.itemCount
527+ root.carouselWidth = data.carouselWidth
528+ root.tileWidth = data.tileWidth
529+ root.itemCount = data.itemCount
530
531 var x = Carousel.getXFromContinuousIndex(data.index,
532 data.carouselWidth,
533@@ -113,14 +114,14 @@
534 }
535
536 function test_getViewTranslation(data) {
537- carouselWidth = data.carouselWidth
538- tileWidth = data.tileWidth
539- itemCount = data.itemCount
540+ root.carouselWidth = data.carouselWidth
541+ root.tileWidth = data.tileWidth
542+ root.itemCount = data.itemCount
543
544 var x = Carousel.getViewTranslation(data.x,
545 data.tileWidth,
546- gapToMiddlePhase,
547- gapToEndPhase,
548+ root.gapToMiddlePhase,
549+ root.gapToEndPhase,
550 data.translationXViewFactor)
551 compare(x, data.result)
552 }
553@@ -158,30 +159,33 @@
554
555 // test for the getItemTranslation() function
556 function test_getItemTranslation_data() {
557- return [ // tests if distance only affects the sign
558- {distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
559-// {distance: 99, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
560- {distance: 0, scale: 0, maxScale: 1, maxTranslation: 10, result: -10},
561- {distance: -1, scale: 0, maxScale: 1, maxTranslation: 10, result: -10},
562+ return [ // tests for index and selectedIndex
563+ {index: 1, selectedIndex: 1, distance: 1, scale: 1, maxScale: 1, maxTranslation: 10, result: 0},
564+ // tests if distance only affects the sign
565+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
566+ {index: 1, selectedIndex: 2, distance: 99, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
567+ {index: 1, selectedIndex: 2, distance: -1, scale: 0, maxScale: 1, maxTranslation: 10, result: -10},
568+ {index: 1, selectedIndex: 2, distance: -99, scale: 0, maxScale: 1, maxTranslation: 10, result: -10},
569 // tests for the scale
570- {distance: 1, scale: 1, maxScale: 1, maxTranslation: 10, result: 0},
571- {distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
572- {distance: 1, scale: 0.5, maxScale: 1, maxTranslation: 10, result: 5},
573+ {index: 1, selectedIndex: 2, distance: 1, scale: 1, maxScale: 1, maxTranslation: 10, result: 0},
574+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
575+ {index: 1, selectedIndex: 2, distance: 1, scale: 0.5, maxScale: 1, maxTranslation: 10, result: 5},
576 // tests for maxScale
577- {distance: 1, scale: 1, maxScale: 1, maxTranslation: 10, result: 0},
578- {distance: 1, scale: 1, maxScale: 2, maxTranslation: 10, result: 10},
579-// {distance: 1, scale: 1, maxScale: 0, maxTranslation: 10, result: 0},
580-// {distance: 1, scale: 1, maxScale: 99, maxTranslation: 10, result: 10},
581+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 0.98, maxTranslation: 10, result: 9.8},
582+ {index: 1, selectedIndex: 2, distance: 1, scale: 0.5, maxScale: 0.95, maxTranslation: 10, result: 4.5},
583+ {index: 1, selectedIndex: 2, distance: 1, scale: 0.8, maxScale: 0.93, maxTranslation: 10, result: 1.3},
584 // test for maxTranslation
585- {distance: 1, scale: 1, maxScale: 1, maxTranslation: 1, result: 0},
586- {distance: 1, scale: 0, maxScale: 1, maxTranslation: 1, result: 1},
587- {distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
588- {distance: 1, scale: 0, maxScale: 1, maxTranslation: 0, result: 0},
589+ {index: 1, selectedIndex: 2, distance: 1, scale: 1, maxScale: 1, maxTranslation: 1, result: 0},
590+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 1, result: 1},
591+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 10, result: 10},
592+ {index: 1, selectedIndex: 2, distance: 1, scale: 0, maxScale: 1, maxTranslation: 0, result: 0},
593 ]
594 }
595
596 function test_getItemTranslation(data) {
597- var scale = Carousel.getItemTranslation(data.distance,
598+ var scale = Carousel.getItemTranslation(data.index,
599+ data.selectedIndex,
600+ data.distance,
601 data.scale,
602 data.maxScale,
603 data.maxTranslation)

Subscribers

People subscribed via source and target branches

to all changes: