Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(464)

Side by Side Diff: client/touch/InfiniteScroller.dart

Issue 9382027: Move client/{base, observable, layout, touch, util, view} to samples/ui_lib . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « client/touch/Geometry.dart ('k') | client/touch/Math.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 * Adds a listener to the scroller with triggers events
7 * when a trigger point at the top, or bottom, of the screen is reached.
8 *
9 * To use this you will need to have an element with a scroller attached
10 * to it. You need to have defined (in pixels) how far from the top or
11 * bottom the scroll position must be in order to trigger (the "trigger
12 * point") The element using this must have functions for hitting the top
13 * trigger, and the bottom trigger. In general, these methods will
14 * ascertain whether we have more data to scroll to (i.e. when we hit
15 * the bottom trigger point but have reached the end of the data
16 * displayed in the element we should ignore it), make the call for
17 * more data and reposition the scroller - repositioning is key to
18 * good user experience.
19 *
20 * Triggers are generated by listening for the SCROLL_END event from the
21 * scroller, so data calls are not initiated whilst scrolling is happening,
22 * but after.
23 *
24 * Controls changing divs between the usual (non-loading) div and the
25 * loading div. To take advantage of this, callback function should return
26 * a boolean indicating whether the usual div should be replaced by the
27 * loading div.
28 */
29 class InfiniteScroller {
30 Scroller _scroller;
31
32 /**
33 * Function to invoke when trigger point is reached at the top of the view.
34 */
35 Function _onTopScroll;
36
37 /**
38 * Function to invoke when trigger point is reached at the bottom of the view.
39 */
40 Function _onBottomScroll;
41
42 /** Offset for trigger point at the top of the view. */
43 double _offsetTop;
44
45 /** Offset for trigger point at the bottom of the view. */
46 double _offsetBottom;
47
48 /** Saves the last Y position. */
49 double _lastScrollY;
50 Element _topDiv;
51 Element _topLoadingDiv;
52 Element _bottomDiv;
53 Element _bottomLoadingDiv;
54
55 InfiniteScroller(Scroller scroller,
56 Function onTopScroll, Function onBottomScroll,
57 double offsetTop, [double offsetBottom = null])
58 : _scroller = scroller,
59 _onTopScroll = onTopScroll,
60 _onBottomScroll = onBottomScroll,
61 _offsetTop = offsetTop,
62 _offsetBottom = offsetBottom == null ? offsetTop : offsetBottom,
63 _lastScrollY = 0.0 {
64 }
65
66 /**
67 * Adds the loading divs.
68 * [topDiv] The div usually shown at the top.
69 * [topLoadingDiv] is the div to show at the top when waiting for more
70 * content to load at the top of the page.
71 * [bottomDiv] is the div usually shown at the bottom.
72 * [bottomLoadingDiv] is the div to show at the bottom when waiting for more
73 * content to load at the end of the page.
74 */
75 void addLoadingDivs([Element topDiv = null,
76 Element topLoadingDiv = null,
77 Element bottomDiv = null,
78 Element bottomLoadingDiv = null]) {
79 _topDiv = topDiv;
80 _topLoadingDiv = topLoadingDiv;
81 _bottomDiv = bottomDiv;
82 _bottomLoadingDiv = bottomLoadingDiv;
83 _updateVisibility(false, _topDiv, _topLoadingDiv);
84 _updateVisibility(false, _bottomDiv, _bottomLoadingDiv);
85 }
86
87 void initialize() {
88 _registerEventListeners();
89 }
90
91 /**
92 * Switch back the divs after loading complete. Delegate should call
93 * this function after loading is complete.
94 */
95 void loadEnd() {
96 _updateVisibility(false, _topDiv, _topLoadingDiv);
97 _updateVisibility(false, _bottomDiv, _bottomLoadingDiv);
98 }
99
100 /**
101 * Called at the end of a scroll event.
102 */
103 void _onScrollEnd() {
104 double ypos = _scroller.getVerticalOffset();
105
106 // Scroll is below last point.
107 if (ypos < _lastScrollY) {
108 double bottomTrigger = _scroller.getMinPointY() + _offsetBottom;
109 // And below trigger point.
110 if (ypos <= bottomTrigger) {
111 _updateVisibility(_onBottomScroll(), _bottomDiv, _bottomLoadingDiv);
112 }
113 } else {
114 if (ypos > _lastScrollY) {
115 // Scroll is above last point.
116 double topTrigger = _scroller.getMaxPointY() - _offsetTop;
117 // And above trigger point.
118 if (ypos >= topTrigger) {
119 _updateVisibility(_onTopScroll(), _topDiv, _topLoadingDiv);
120 }
121 }
122 }
123 _lastScrollY = ypos;
124 }
125
126 /**
127 * Register the event listeners.
128 */
129 void _registerEventListeners() {
130 _scroller.onScrollerEnd.add((Event event) { _onScrollEnd(); });
131 }
132
133 /**
134 * Hides one div and shows another.
135 */
136 void _updateVisibility(bool isLoading, Element element,
137 Element loadingElement) {
138 if (element != null) {
139 element.style.display = isLoading ? "none" : "";
140 }
141 if (loadingElement != null) {
142 loadingElement.style.display = isLoading ? "" : "none";
143 }
144 }
145 }
OLDNEW
« no previous file with comments | « client/touch/Geometry.dart ('k') | client/touch/Math.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698