OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 /** | |
6 * Holds a number of child views. As you switch between views, the old | |
7 * view is pushed off to the side and the new view slides in from the other | |
8 * side. | |
9 */ | |
10 class ConveyorView extends CompositeView { | |
11 // TODO(jmesserly): some places use this property to know when the slide | |
12 // transition is finished. It would be better to have an event that fires | |
13 // when we're done sliding | |
14 static final ANIMATE_SECONDS = 0.25; | |
15 | |
16 View targetView; | |
17 // TODO(rnystrom): Should not be settable. | |
18 View selectedView; | |
19 // TODO(rnystrom): Hackish. Should use a real multicast event-like class. | |
20 // Or just have it depend on an Observable to select a view and indicate | |
21 // which view is selected? (e.g. the MVVM pattern) | |
22 Function viewSelected; | |
23 | |
24 int animationTimeoutId; | |
25 | |
26 ConveyorView() | |
27 : super('conveyor-view', true), | |
28 animationTimeoutId = null { | |
29 } | |
30 | |
31 Element render() { | |
32 final result = super.render(); | |
33 // TODO(rnystrom): Have to do this in render() because container doesn't | |
34 // exist before then. Hack. Should find a cleaner solution. One of: | |
35 // - Add a ctor param to CompositeView for container class name. | |
36 // - Make ConveyorView contain a CompositeView instead of subclass. | |
37 // - Add method to CompositeView to set class name. | |
38 container.attributes['class'] = 'conveyor-view-container'; | |
39 return result; | |
40 } | |
41 | |
42 void selectView(View targetView_, [bool animate = true]) { | |
43 selectedView = targetView_; | |
44 | |
45 // Only animate if we're actually in the document now. | |
46 if (isRendered) { | |
47 adjustOffset(animate); | |
48 } | |
49 } | |
50 | |
51 void adjustOffset(bool animate) { | |
52 int index = getIndexOfSelectedView(); | |
53 final durationSeconds = animate ? ANIMATE_SECONDS : 0.0; | |
54 | |
55 final style = container.style; | |
56 // TODO(jacobr): modify setTransitionDuration so the input is always | |
57 // specified in miliseconds rather than accepting a string. | |
58 style.transitionDuration = '${durationSeconds}s'; | |
59 final xTranslationPercent = -index * 100; | |
60 style.transform = 'translate3d(${xTranslationPercent}%, 0px, 0px)'; | |
61 | |
62 if (animationTimeoutId != null) { | |
63 window.clearTimeout(animationTimeoutId); | |
64 } | |
65 | |
66 if (animate) { | |
67 animationTimeoutId = window.setTimeout( | |
68 () { _onAnimationEnd(); }, (durationSeconds * 1000).toInt()); | |
69 } | |
70 // TODO(mattsh), we should set the visibility to hide everything but the | |
71 // selected view. | |
72 } | |
73 | |
74 int getIndexOfSelectedView() { | |
75 for (int i = 0; i < childViews.length; i++) { | |
76 if (childViews[i] == selectedView) { | |
77 return i; | |
78 } | |
79 } | |
80 throw "view not found"; | |
81 } | |
82 | |
83 /** | |
84 * Adds a child view to the ConveyorView. The views are stacked horizontally | |
85 * in the order they are added. | |
86 */ | |
87 View addChild(View view) { | |
88 view.addClass('conveyor-item'); | |
89 view.transform = 'translate3d(' + (childViews.length * 100) + '%, 0, 0)'; | |
90 return super.addChild(view); | |
91 } | |
92 | |
93 void _onAnimationEnd() { | |
94 if (viewSelected != null) { | |
95 viewSelected(selectedView); | |
96 } | |
97 } | |
98 } | |
OLD | NEW |