OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of view; | 5 part of view; |
6 | 6 |
7 class PageState { | 7 class PageState { |
8 final ObservableValue<int> current; | 8 final ObservableValue<int> current; |
9 final ObservableValue<int> target; | 9 final ObservableValue<int> target; |
10 final ObservableValue<int> length; | 10 final ObservableValue<int> length; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 return node; | 128 return node; |
129 } | 129 } |
130 | 130 |
131 int _getViewLength(Element element) { | 131 int _getViewLength(Element element) { |
132 return _computePageSize(element) * pages.length.value; | 132 return _computePageSize(element) * pages.length.value; |
133 } | 133 } |
134 | 134 |
135 // TODO(jmesserly): would be better to not have this code in enterDocument. | 135 // TODO(jmesserly): would be better to not have this code in enterDocument. |
136 // But we need computedStyle to read our CSS properties. | 136 // But we need computedStyle to read our CSS properties. |
137 void enterDocument() { | 137 void enterDocument() { |
138 window.setImmediate(() { | 138 scheduleMicrotask(() { |
139 var style = contentView.node.getComputedStyle(); | 139 var style = contentView.node.getComputedStyle(); |
140 _computeColumnGap(style); | 140 _computeColumnGap(style); |
141 | 141 |
142 // Trigger a fake resize event so we measure our height. | 142 // Trigger a fake resize event so we measure our height. |
143 windowResized(); | 143 windowResized(); |
144 | 144 |
145 // Hook img onload events, so we find out about changes in content size | 145 // Hook img onload events, so we find out about changes in content size |
146 for (ImageElement img in contentView.node.queryAll("img")) { | 146 for (ImageElement img in contentView.node.queryAll("img")) { |
147 if (!img.complete) { | 147 if (!img.complete) { |
148 img.onLoad.listen((e) { | 148 img.onLoad.listen((e) { |
(...skipping 27 matching lines...) Expand all Loading... |
176 return double.parse(value).round(); | 176 return double.parse(value).round(); |
177 } | 177 } |
178 | 178 |
179 /** Watch for resize and update page count. */ | 179 /** Watch for resize and update page count. */ |
180 void windowResized() { | 180 void windowResized() { |
181 // TODO(jmesserly): verify we aren't triggering unnecessary layouts. | 181 // TODO(jmesserly): verify we aren't triggering unnecessary layouts. |
182 | 182 |
183 // The content needs to have its height explicitly set, or columns don't | 183 // The content needs to have its height explicitly set, or columns don't |
184 // flow to the right correctly. So we copy our own height and set the height | 184 // flow to the right correctly. So we copy our own height and set the height |
185 // of the content. | 185 // of the content. |
186 window.setImmediate(() { | 186 scheduleMicrotask(() { |
187 contentView.node.style.height = '${node.offset.height}px'; | 187 contentView.node.style.height = '${node.offset.height}px'; |
188 }); | 188 }); |
189 _updatePageCount(null); | 189 _updatePageCount(null); |
190 } | 190 } |
191 | 191 |
192 bool _updatePageCount(Callback callback) { | 192 bool _updatePageCount(Callback callback) { |
193 int pageLength = 1; | 193 int pageLength = 1; |
194 window.setImmediate(() { | 194 scheduleMicrotask(() { |
195 if (_container.scrollWidth > _container.offset.width) { | 195 if (_container.scrollWidth > _container.offset.width) { |
196 pageLength = (_container.scrollWidth / _computePageSize(_container)) | 196 pageLength = (_container.scrollWidth / _computePageSize(_container)) |
197 .ceil(); | 197 .ceil(); |
198 } | 198 } |
199 pageLength = Math.max(pageLength, 1); | 199 pageLength = Math.max(pageLength, 1); |
200 | 200 |
201 int oldPage = pages.target.value; | 201 int oldPage = pages.target.value; |
202 int newPage = Math.min(oldPage, pageLength - 1); | 202 int newPage = Math.min(oldPage, pageLength - 1); |
203 | 203 |
204 // Hacky: make sure a change event always fires. | 204 // Hacky: make sure a change event always fires. |
205 // This is so we adjust the 3d transform after resize. | 205 // This is so we adjust the 3d transform after resize. |
206 if (oldPage == newPage) { | 206 if (oldPage == newPage) { |
207 pages.target.value = 0; | 207 pages.target.value = 0; |
208 } | 208 } |
209 assert(newPage < pageLength); | 209 assert(newPage < pageLength); |
210 pages.target.value = newPage; | 210 pages.target.value = newPage; |
211 pages.length.value = pageLength; | 211 pages.length.value = pageLength; |
212 if (callback != null) { | 212 if (callback != null) { |
213 callback(); | 213 callback(); |
214 } | 214 } |
215 }); | 215 }); |
216 } | 216 } |
217 | 217 |
218 void _onContentMoved(Event e) { | 218 void _onContentMoved(Event e) { |
219 window.setImmediate(() { | 219 scheduleMicrotask(() { |
220 num current = scroller.contentOffset.x; | 220 num current = scroller.contentOffset.x; |
221 int pageSize = _computePageSize(_container); | 221 int pageSize = _computePageSize(_container); |
222 pages.current.value = -(current / pageSize).round(); | 222 pages.current.value = -(current / pageSize).round(); |
223 }); | 223 }); |
224 } | 224 } |
225 | 225 |
226 void _snapToPage(Event e) { | 226 void _snapToPage(Event e) { |
227 num current = scroller.contentOffset.x; | 227 num current = scroller.contentOffset.x; |
228 num currentTarget = scroller.currentTarget.x; | 228 num currentTarget = scroller.currentTarget.x; |
229 window.setImmediate(() { | 229 scheduleMicrotask(() { |
230 int pageSize = _computePageSize(_container); | 230 int pageSize = _computePageSize(_container); |
231 int destination; | 231 int destination; |
232 num currentPageNumber = -(current / pageSize).round(); | 232 num currentPageNumber = -(current / pageSize).round(); |
233 num pageNumber = -currentTarget / pageSize; | 233 num pageNumber = -currentTarget / pageSize; |
234 if (current == currentTarget) { | 234 if (current == currentTarget) { |
235 // User was just static dragging so round to the nearest page. | 235 // User was just static dragging so round to the nearest page. |
236 pageNumber = pageNumber.round(); | 236 pageNumber = pageNumber.round(); |
237 } else { | 237 } else { |
238 if (currentPageNumber == pageNumber.round() && | 238 if (currentPageNumber == pageNumber.round() && |
239 (pageNumber - currentPageNumber).abs() > MIN_THROW_PAGE_FRACTION && | 239 (pageNumber - currentPageNumber).abs() > MIN_THROW_PAGE_FRACTION && |
(...skipping 30 matching lines...) Expand all Loading... |
270 (_viewportSize + _columnGap) ~/ (_columnWidth + _columnGap)); | 270 (_viewportSize + _columnGap) ~/ (_columnWidth + _columnGap)); |
271 | 271 |
272 // Divide up the viewport between the columns. | 272 // Divide up the viewport between the columns. |
273 int columnSize = (_viewportSize - (perPage - 1) * _columnGap) ~/ perPage; | 273 int columnSize = (_viewportSize - (perPage - 1) * _columnGap) ~/ perPage; |
274 | 274 |
275 // Finally, compute how big each page is, and how far to translate. | 275 // Finally, compute how big each page is, and how far to translate. |
276 return perPage * (columnSize + _columnGap); | 276 return perPage * (columnSize + _columnGap); |
277 } | 277 } |
278 | 278 |
279 void _onPageSelected() { | 279 void _onPageSelected() { |
280 window.setImmediate(() { | 280 scheduleMicrotask(() { |
281 int translate = -pages.target.value * _computePageSize(_container); | 281 int translate = -pages.target.value * _computePageSize(_container); |
282 scroller.throwTo(translate, 0); | 282 scroller.throwTo(translate, 0); |
283 }); | 283 }); |
284 } | 284 } |
285 } | 285 } |
OLD | NEW |