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

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

Issue 9148015: Example showing alternate async measurement solution (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Final version Created 8 years, 11 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
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * Implementation of a custom scrolling behavior. 6 * Implementation of a custom scrolling behavior.
7 * This behavior overrides native scrolling for an area. This area can be a 7 * This behavior overrides native scrolling for an area. This area can be a
8 * single defined part of a page, the entire page, or several different parts 8 * single defined part of a page, the entire page, or several different parts
9 * of a page. 9 * of a page.
10 * 10 *
11 * To use this scrolling behavior you need to define a frame and the content. 11 * To use this scrolling behavior you need to define a frame and the content.
(...skipping 13 matching lines...) Expand all
25 * For this to work properly you need to set -webkit-text-size-adjust to 'none' 25 * For this to work properly you need to set -webkit-text-size-adjust to 'none'
26 * on an ancestor element of the frame, or on the frame itself. If you forget 26 * on an ancestor element of the frame, or on the frame itself. If you forget
27 * this you may see the text content of the scrollable area changing size as it 27 * this you may see the text content of the scrollable area changing size as it
28 * moves. 28 * moves.
29 * 29 *
30 * The behavior is intended to support vertical and horizontal scrolling, and 30 * The behavior is intended to support vertical and horizontal scrolling, and
31 * scrolling with momentum when a touch gesture flicks with enough velocity. 31 * scrolling with momentum when a touch gesture flicks with enough velocity.
32 */ 32 */
33 typedef void Callback(); 33 typedef void Callback();
34 34
35 // Helper method to await the completion of 2 futures.
36 void joinFutures(List<Future> futures, Callback callback) {
37 int count = 0;
38 int len = futures.length;
39 void helper(value) {
40 count++;
41 if (count == len) {
42 callback();
43 }
44 }
45 for (Future p in futures) {
46 p.then(helper);
47 }
48 }
49
50 class Scroller implements Draggable, MomentumDelegate { 35 class Scroller implements Draggable, MomentumDelegate {
51 36
52 /** Pixels to move each time an arrow key is pressed. */ 37 /** Pixels to move each time an arrow key is pressed. */
53 static final ARROW_KEY_DELTA = 30; 38 static final ARROW_KEY_DELTA = 30;
54 static final SCROLL_WHEEL_VELOCITY = 0.01; 39 static final SCROLL_WHEEL_VELOCITY = 0.01;
55 static final FAST_SNAP_DECELERATION_FACTOR = 0.84; 40 static final FAST_SNAP_DECELERATION_FACTOR = 0.84;
56 static final PAGE_KEY_SCROLL_FRACTION = .85; 41 static final PAGE_KEY_SCROLL_FRACTION = .85;
57 42
58 // TODO(jacobr): remove this static variable. 43 // TODO(jacobr): remove this static variable.
59 static bool _dragInProgress = false; 44 static bool _dragInProgress = false;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 break; 209 break;
225 */ 210 */
226 } 211 }
227 if (handled) { 212 if (handled) {
228 e.preventDefault(); 213 e.preventDefault();
229 } 214 }
230 }); 215 });
231 // The scrollable element must be relatively positioned. 216 // The scrollable element must be relatively positioned.
232 // TODO(jacobr): this assert fires asynchronously which could be confusing. 217 // TODO(jacobr): this assert fires asynchronously which could be confusing.
233 if (_scrollTechnique == ScrollerScrollTechnique.RELATIVE_POSITIONING) { 218 if (_scrollTechnique == ScrollerScrollTechnique.RELATIVE_POSITIONING) {
234 _element.computedStyle.then((CSSStyleDeclaration style) { 219 window.requestMeasurementFrame(() {
235 assert(style.position != "static"); 220 assert(_element.computedStyle.position != "static");
236 }); 221 });
237 } 222 }
238 223
239 _initLayer(); 224 _initLayer();
240 } 225 }
241 226
242 EventListenerList get onScrollerStart() { 227 EventListenerList get onScrollerStart() {
243 if (_onScrollerStart === null) { 228 if (_onScrollerStart === null) {
244 _onScrollerStart = new SimpleEventListenerList(); 229 _onScrollerStart = new SimpleEventListenerList();
245 } 230 }
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 void onTouchEnd() { 481 void onTouchEnd() {
497 } 482 }
498 483
499 /** 484 /**
500 * Prepare the scrollable area for possible movement. 485 * Prepare the scrollable area for possible movement.
501 */ 486 */
502 bool onTouchStart(TouchEvent e) { 487 bool onTouchStart(TouchEvent e) {
503 reconfigure(() { 488 reconfigure(() {
504 final touch = e.touches[0]; 489 final touch = e.touches[0];
505 if (_momentum.decelerating) { 490 if (_momentum.decelerating) {
491 // TODO(jacobr): this won't do any good as it is called too late due
492 // to async measurement.
506 e.preventDefault(); 493 e.preventDefault();
507 e.stopPropagation(); 494 e.stopPropagation();
508 stop(); 495 stop();
509 } 496 }
510 _contentStartOffset = _contentOffset.clone(); 497 _contentStartOffset = _contentOffset.clone();
511 _snapContentOffsetToBounds(); 498 _snapContentOffsetToBounds();
512 }); 499 });
513 return true; 500 return true;
514 } 501 }
515 502
(...skipping 18 matching lines...) Expand all
534 _minOffset.x = 0; 521 _minOffset.x = 0;
535 _minOffset.y = 0; 522 _minOffset.y = 0;
536 reconfigure(() => _setContentOffset(_maxPoint.x, _maxPoint.y)); 523 reconfigure(() => _setContentOffset(_maxPoint.x, _maxPoint.y));
537 } 524 }
538 525
539 /** 526 /**
540 * Recalculate dimensions of the frame and the content. Adjust the minPoint 527 * Recalculate dimensions of the frame and the content. Adjust the minPoint
541 * and maxPoint allowed for scrolling. 528 * and maxPoint allowed for scrolling.
542 */ 529 */
543 void _resize(Callback callback) { 530 void _resize(Callback callback) {
544 final frameRect = _frame.rect; 531 window.requestMeasurementFrame(() {
545 Future contentSizeFuture; 532 final offset = _frame.rect.offset;
546 533
547 if (_lookupContentSizeDelegate !== null) { 534 if (_lookupContentSizeDelegate !== null) {
548 contentSizeFuture = _lookupContentSizeDelegate(); 535 // Guaranteed to be called within a measurement frame
549 contentSizeFuture.then((Size size) { 536 _contentSize = _lookupContentSizeDelegate();
550 _contentSize = size; 537 } else {
551 }); 538 final scroll = _element.rect.scroll;
552 } else { 539 _contentSize = new Size(scroll.width, scroll.height);
553 contentSizeFuture = _element.rect; 540 }
554 contentSizeFuture.then((ElementRect rect) {
555 _contentSize = new Size(rect.scroll.width, rect.scroll.height);
556 });
557 }
558 541
559 joinFutures(<Future>[frameRect, contentSizeFuture], () { 542 _scrollSize = new Size(offset.width, offset.height);
560 _scrollSize = new Size(frameRect.value.offset.width,
561 frameRect.value.offset.height);
562 Size adjusted = _getAdjustedContentSize(); 543 Size adjusted = _getAdjustedContentSize();
563 _maxPoint = new Coordinate(-_maxOffset.x, -_maxOffset.y); 544 _maxPoint = new Coordinate(-_maxOffset.x, -_maxOffset.y);
564 _minPoint = new Coordinate( 545 _minPoint = new Coordinate(
565 Math.min( 546 Math.min(
566 _scrollSize.width - adjusted.width + _minOffset.x, _maxPoint.x), 547 _scrollSize.width - adjusted.width + _minOffset.x, _maxPoint.x),
567 Math.min( 548 Math.min(
568 _scrollSize.height - adjusted.height + _minOffset.y, _maxPoint.y)) ; 549 _scrollSize.height - adjusted.height + _minOffset.y, _maxPoint.y)) ;
569 callback(); 550 return callback;
570 }); 551 });
571 } 552 }
572 553
573 Coordinate _snapToBounds(num x, num y) { 554 Coordinate _snapToBounds(num x, num y) {
574 num clampX = GoogleMath.clamp(_minPoint.x, x, _maxPoint.x); 555 num clampX = GoogleMath.clamp(_minPoint.x, x, _maxPoint.x);
575 num clampY = GoogleMath.clamp(_minPoint.y, y, _maxPoint.y); 556 num clampY = GoogleMath.clamp(_minPoint.y, y, _maxPoint.y);
576 return new Coordinate(clampX, clampY); 557 return new Coordinate(clampX, clampY);
577 } 558 }
578 559
579 /** 560 /**
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 for (EventListener listener in _listeners) { 703 for (EventListener listener in _listeners) {
723 listener(evt); 704 listener(evt);
724 } 705 }
725 } 706 }
726 } 707 }
727 708
728 class ScrollerScrollTechnique { 709 class ScrollerScrollTechnique {
729 static final TRANSFORM_3D = 1; 710 static final TRANSFORM_3D = 1;
730 static final RELATIVE_POSITIONING = 2; 711 static final RELATIVE_POSITIONING = 2;
731 } 712 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698