| 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 /** | 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 * |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 Scroller(Element scrollableElem, [this.verticalEnabled = false, | 137 Scroller(Element scrollableElem, [this.verticalEnabled = false, |
| 138 this.horizontalEnabled = false, | 138 this.horizontalEnabled = false, |
| 139 momentumEnabled = true, | 139 momentumEnabled = true, |
| 140 lookupContentSizeDelegate = null, | 140 lookupContentSizeDelegate = null, |
| 141 num defaultDecelerationFactor = 1, | 141 num defaultDecelerationFactor = 1, |
| 142 int scrollTechnique = null, bool capture = false]) | 142 int scrollTechnique = null, bool capture = false]) |
| 143 : _momentumEnabled = momentumEnabled, | 143 : _momentumEnabled = momentumEnabled, |
| 144 _lookupContentSizeDelegate = lookupContentSizeDelegate, | 144 _lookupContentSizeDelegate = lookupContentSizeDelegate, |
| 145 _element = scrollableElem, | 145 _element = scrollableElem, |
| 146 _frame = scrollableElem.parent, | 146 _frame = scrollableElem.parent, |
| 147 _scrollTechnique = scrollTechnique !== null | 147 _scrollTechnique = scrollTechnique != null |
| 148 ? scrollTechnique : ScrollerScrollTechnique.TRANSFORM_3D, | 148 ? scrollTechnique : ScrollerScrollTechnique.TRANSFORM_3D, |
| 149 _minPoint = new Coordinate(0, 0), | 149 _minPoint = new Coordinate(0, 0), |
| 150 _maxPoint = new Coordinate(0, 0), | 150 _maxPoint = new Coordinate(0, 0), |
| 151 _maxOffset = new Coordinate(0, 0), | 151 _maxOffset = new Coordinate(0, 0), |
| 152 _minOffset = new Coordinate(0, 0), | 152 _minOffset = new Coordinate(0, 0), |
| 153 _contentOffset = new Coordinate(0, 0) { | 153 _contentOffset = new Coordinate(0, 0) { |
| 154 _touchHandler = new TouchHandler(this, scrollableElem.parent); | 154 _touchHandler = new TouchHandler(this, scrollableElem.parent); |
| 155 _momentum = new Momentum(this, defaultDecelerationFactor); | 155 _momentum = new Momentum(this, defaultDecelerationFactor); |
| 156 | 156 |
| 157 Element parentElem = scrollableElem.parent; | 157 Element parentElem = scrollableElem.parent; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 if (_scrollTechnique == ScrollerScrollTechnique.RELATIVE_POSITIONING) { | 233 if (_scrollTechnique == ScrollerScrollTechnique.RELATIVE_POSITIONING) { |
| 234 _element.computedStyle.then((CSSStyleDeclaration style) { | 234 _element.computedStyle.then((CSSStyleDeclaration style) { |
| 235 assert(style.position != "static"); | 235 assert(style.position != "static"); |
| 236 }); | 236 }); |
| 237 } | 237 } |
| 238 | 238 |
| 239 _initLayer(); | 239 _initLayer(); |
| 240 } | 240 } |
| 241 | 241 |
| 242 EventListenerList get onScrollerStart { | 242 EventListenerList get onScrollerStart { |
| 243 if (_onScrollerStart === null) { | 243 if (_onScrollerStart == null) { |
| 244 _onScrollerStart = new SimpleEventListenerList(); | 244 _onScrollerStart = new SimpleEventListenerList(); |
| 245 } | 245 } |
| 246 return _onScrollerStart; | 246 return _onScrollerStart; |
| 247 } | 247 } |
| 248 | 248 |
| 249 EventListenerList get onScrollerEnd { | 249 EventListenerList get onScrollerEnd { |
| 250 if (_onScrollerEnd === null) { | 250 if (_onScrollerEnd == null) { |
| 251 _onScrollerEnd = new SimpleEventListenerList(); | 251 _onScrollerEnd = new SimpleEventListenerList(); |
| 252 } | 252 } |
| 253 return _onScrollerEnd; | 253 return _onScrollerEnd; |
| 254 } | 254 } |
| 255 | 255 |
| 256 EventListenerList get onScrollerDragEnd { | 256 EventListenerList get onScrollerDragEnd { |
| 257 if (_onScrollerDragEnd === null) { | 257 if (_onScrollerDragEnd == null) { |
| 258 _onScrollerDragEnd = new SimpleEventListenerList(); | 258 _onScrollerDragEnd = new SimpleEventListenerList(); |
| 259 } | 259 } |
| 260 return _onScrollerDragEnd; | 260 return _onScrollerDragEnd; |
| 261 } | 261 } |
| 262 | 262 |
| 263 EventListenerList get onContentMoved { | 263 EventListenerList get onContentMoved { |
| 264 if (_onContentMoved === null) { | 264 if (_onContentMoved == null) { |
| 265 _onContentMoved = new SimpleEventListenerList(); | 265 _onContentMoved = new SimpleEventListenerList(); |
| 266 } | 266 } |
| 267 return _onContentMoved; | 267 return _onContentMoved; |
| 268 } | 268 } |
| 269 | 269 |
| 270 EventListenerList get onDecelStart { | 270 EventListenerList get onDecelStart { |
| 271 if (_onDecelStart === null) { | 271 if (_onDecelStart == null) { |
| 272 _onDecelStart = new SimpleEventListenerList(); | 272 _onDecelStart = new SimpleEventListenerList(); |
| 273 } | 273 } |
| 274 return _onDecelStart; | 274 return _onDecelStart; |
| 275 } | 275 } |
| 276 | 276 |
| 277 | 277 |
| 278 /** | 278 /** |
| 279 * Add a scroll listener. This allows other classes to subscribe to scroll | 279 * Add a scroll listener. This allows other classes to subscribe to scroll |
| 280 * notifications from this scroller. | 280 * notifications from this scroller. |
| 281 */ | 281 */ |
| 282 void addScrollListener(ScrollListener listener) { | 282 void addScrollListener(ScrollListener listener) { |
| 283 if (_scrollWatcher === null) { | 283 if (_scrollWatcher == null) { |
| 284 _scrollWatcher = new ScrollWatcher(this); | 284 _scrollWatcher = new ScrollWatcher(this); |
| 285 _scrollWatcher.initialize(); | 285 _scrollWatcher.initialize(); |
| 286 } | 286 } |
| 287 _scrollWatcher.addListener(listener); | 287 _scrollWatcher.addListener(listener); |
| 288 } | 288 } |
| 289 | 289 |
| 290 /** | 290 /** |
| 291 * Adjust the new calculated scroll position based on the minimum allowed | 291 * Adjust the new calculated scroll position based on the minimum allowed |
| 292 * position and returns the adjusted scroll value. | 292 * position and returns the adjusted scroll value. |
| 293 */ | 293 */ |
| 294 num _adjustValue(num newPosition, num minPosition, | 294 num _adjustValue(num newPosition, num minPosition, |
| 295 num maxPosition) { | 295 num maxPosition) { |
| 296 assert(minPosition <= maxPosition); | 296 assert(minPosition <= maxPosition); |
| 297 | 297 |
| 298 if (newPosition < minPosition) { | 298 if (newPosition < minPosition) { |
| 299 newPosition -= (newPosition - minPosition) / 2; | 299 newPosition -= (newPosition - minPosition) / 2; |
| 300 } else { | 300 } else { |
| 301 if (newPosition > maxPosition) { | 301 if (newPosition > maxPosition) { |
| 302 newPosition -= (newPosition - maxPosition) / 2; | 302 newPosition -= (newPosition - maxPosition) / 2; |
| 303 } | 303 } |
| 304 } | 304 } |
| 305 return newPosition; | 305 return newPosition; |
| 306 } | 306 } |
| 307 | 307 |
| 308 /** | 308 /** |
| 309 * Coordinate we would end up at if we did nothing. | 309 * Coordinate we would end up at if we did nothing. |
| 310 */ | 310 */ |
| 311 Coordinate get currentTarget { | 311 Coordinate get currentTarget { |
| 312 Coordinate end = _momentum.destination; | 312 Coordinate end = _momentum.destination; |
| 313 if (end === null) { | 313 if (end == null) { |
| 314 end = _contentOffset; | 314 end = _contentOffset; |
| 315 } | 315 } |
| 316 return end; | 316 return end; |
| 317 } | 317 } |
| 318 | 318 |
| 319 Coordinate get contentOffset => _contentOffset; | 319 Coordinate get contentOffset => _contentOffset; |
| 320 | 320 |
| 321 /** | 321 /** |
| 322 * Animate the position of the scroller to the specified [x], [y] coordinates | 322 * Animate the position of the scroller to the specified [x], [y] coordinates |
| 323 * by applying the throw gesture with the correct velocity to end at that | 323 * by applying the throw gesture with the correct velocity to end at that |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 Element getElement() => _element; | 385 Element getElement() => _element; |
| 386 Element getFrame() => _frame; | 386 Element getFrame() => _frame; |
| 387 num getHorizontalOffset() => _contentOffset.x; | 387 num getHorizontalOffset() => _contentOffset.x; |
| 388 | 388 |
| 389 /** | 389 /** |
| 390 * [x] Value to use as reference for percent measurement. If | 390 * [x] Value to use as reference for percent measurement. If |
| 391 * none is provided then the content's current x offset will be used. | 391 * none is provided then the content's current x offset will be used. |
| 392 * Returns the percent of the page scrolled horizontally. | 392 * Returns the percent of the page scrolled horizontally. |
| 393 */ | 393 */ |
| 394 num getHorizontalScrollPercent([num x = null]) { | 394 num getHorizontalScrollPercent([num x = null]) { |
| 395 x = x !== null ? x : _contentOffset.x; | 395 x = x != null ? x : _contentOffset.x; |
| 396 return (x - _minPoint.x) / (_maxPoint.x - _minPoint.x); | 396 return (x - _minPoint.x) / (_maxPoint.x - _minPoint.x); |
| 397 } | 397 } |
| 398 | 398 |
| 399 num getMaxPointY()=> _maxPoint.y; | 399 num getMaxPointY()=> _maxPoint.y; |
| 400 num getMinPointY() => _minPoint.y; | 400 num getMinPointY() => _minPoint.y; |
| 401 Momentum get momentum => _momentum; | 401 Momentum get momentum => _momentum; |
| 402 | 402 |
| 403 /** | 403 /** |
| 404 * Provide access to the touch handler that the scroller created to manage | 404 * Provide access to the touch handler that the scroller created to manage |
| 405 * touch events. | 405 * touch events. |
| 406 */ | 406 */ |
| 407 TouchHandler getTouchHandler() => _touchHandler; | 407 TouchHandler getTouchHandler() => _touchHandler; |
| 408 num getVerticalOffset() => _contentOffset.y; | 408 num getVerticalOffset() => _contentOffset.y; |
| 409 | 409 |
| 410 /** | 410 /** |
| 411 * [y] value is used as reference for percent measurement. If | 411 * [y] value is used as reference for percent measurement. If |
| 412 * none is provided then the content's current y offset will be used. | 412 * none is provided then the content's current y offset will be used. |
| 413 */ | 413 */ |
| 414 num getVerticalScrollPercent([num y = null]) { | 414 num getVerticalScrollPercent([num y = null]) { |
| 415 y = y !== null ? y : _contentOffset.y; | 415 y = y != null ? y : _contentOffset.y; |
| 416 return (y - _minPoint.y) / Math.max(1, _maxPoint.y - _minPoint.y); | 416 return (y - _minPoint.y) / Math.max(1, _maxPoint.y - _minPoint.y); |
| 417 } | 417 } |
| 418 | 418 |
| 419 /** | 419 /** |
| 420 * Initialize the dom elements necessary for the scrolling to work. | 420 * Initialize the dom elements necessary for the scrolling to work. |
| 421 */ | 421 */ |
| 422 void _initLayer() { | 422 void _initLayer() { |
| 423 // The scrollable node provided to Scroller must be a direct child | 423 // The scrollable node provided to Scroller must be a direct child |
| 424 // of the scrollable frame. | 424 // of the scrollable frame. |
| 425 // TODO(jacobr): Figure out why this is failing on dartium. | 425 // TODO(jacobr): Figure out why this is failing on dartium. |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 _minOffset.y = 0; | 535 _minOffset.y = 0; |
| 536 reconfigure(() => _setContentOffset(_maxPoint.x, _maxPoint.y)); | 536 reconfigure(() => _setContentOffset(_maxPoint.x, _maxPoint.y)); |
| 537 } | 537 } |
| 538 | 538 |
| 539 /** | 539 /** |
| 540 * Recalculate dimensions of the frame and the content. Adjust the minPoint | 540 * Recalculate dimensions of the frame and the content. Adjust the minPoint |
| 541 * and maxPoint allowed for scrolling. | 541 * and maxPoint allowed for scrolling. |
| 542 */ | 542 */ |
| 543 void _resize(Callback callback) { | 543 void _resize(Callback callback) { |
| 544 window.requestLayoutFrame(() { | 544 window.requestLayoutFrame(() { |
| 545 if (_lookupContentSizeDelegate !== null) { | 545 if (_lookupContentSizeDelegate != null) { |
| 546 _contentSize = _lookupContentSizeDelegate(); | 546 _contentSize = _lookupContentSizeDelegate(); |
| 547 } else { | 547 } else { |
| 548 _contentSize = new Size(_element.scrollWidth, _element.scrollHeight); | 548 _contentSize = new Size(_element.scrollWidth, _element.scrollHeight); |
| 549 } | 549 } |
| 550 | 550 |
| 551 _scrollSize = new Size(_frame.offsetWidth, | 551 _scrollSize = new Size(_frame.offsetWidth, |
| 552 _frame.offsetHeight); | 552 _frame.offsetHeight); |
| 553 Size adjusted = _getAdjustedContentSize(); | 553 Size adjusted = _getAdjustedContentSize(); |
| 554 _maxPoint = new Coordinate(-_maxOffset.x, -_maxOffset.y); | 554 _maxPoint = new Coordinate(-_maxOffset.x, -_maxOffset.y); |
| 555 _minPoint = new Coordinate( | 555 _minPoint = new Coordinate( |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 for (EventListener listener in _listeners) { | 713 for (EventListener listener in _listeners) { |
| 714 listener(evt); | 714 listener(evt); |
| 715 } | 715 } |
| 716 } | 716 } |
| 717 } | 717 } |
| 718 | 718 |
| 719 class ScrollerScrollTechnique { | 719 class ScrollerScrollTechnique { |
| 720 static const TRANSFORM_3D = 1; | 720 static const TRANSFORM_3D = 1; |
| 721 static const RELATIVE_POSITIONING = 2; | 721 static const RELATIVE_POSITIONING = 2; |
| 722 } | 722 } |
| OLD | NEW |