OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.android_webview; | 5 package org.chromium.android_webview; |
6 | 6 |
7 import android.graphics.Rect; | 7 import android.graphics.Rect; |
8 import android.widget.OverScroller; | 8 import android.widget.OverScroller; |
9 | 9 |
10 import org.chromium.base.VisibleForTesting; | 10 import org.chromium.base.VisibleForTesting; |
11 | 11 |
12 /** | 12 /** |
13 * Takes care of syncing the scroll offset between the Android View system and t he | 13 * Takes care of syncing the scroll offset between the Android View system and t he |
14 * InProcessViewRenderer. | 14 * InProcessViewRenderer. |
15 * | 15 * |
16 * Unless otherwise values (sizes, scroll offsets) are in physical pixels. | 16 * Unless otherwise values (sizes, scroll offsets) are in physical pixels. |
17 */ | 17 */ |
18 @VisibleForTesting | 18 @VisibleForTesting |
19 public class AwScrollOffsetManager { | 19 public class AwScrollOffsetManager { |
20 // Values taken from WebViewClassic. | 20 // Values taken from WebViewClassic. |
21 | 21 |
22 // The amount of content to overlap between two screens when using pageUp/pa geDown methiods. | 22 // The amount of content to overlap between two screens when using pageUp/pa geDown methiods. |
23 private static final int PAGE_SCROLL_OVERLAP = 24; | 23 private static final int PAGE_SCROLL_OVERLAP = 24; |
24 // Standard animated scroll speed. | 24 // Standard animated scroll speed. |
25 private static final int STD_SCROLL_ANIMATION_SPEED_PIX_PER_SEC = 480; | 25 private static final int STD_SCROLL_ANIMATION_SPEED_PIX_PER_SEC = 480; |
26 // Time for the longest scroll animation. | 26 // Time for the longest scroll animation. |
27 private static final int MAX_SCROLL_ANIMATION_DURATION_MILLISEC = 750; | 27 private static final int MAX_SCROLL_ANIMATION_DURATION_MILLISEC = 750; |
28 | 28 |
29 private boolean mIsAnimatingScroll = false; | |
boliu
2015/05/29 19:42:47
what's the difference between mIsAnimatingScroll a
hush (inactive)
2015/06/05 21:47:22
I was silly there.
mIsAnimatingScroll is equal to
| |
30 | |
29 /** | 31 /** |
30 * The interface that all users of AwScrollOffsetManager should implement. | 32 * The interface that all users of AwScrollOffsetManager should implement. |
31 * | 33 * |
32 * The unit of all the values in this delegate are physical pixels. | 34 * The unit of all the values in this delegate are physical pixels. |
33 */ | 35 */ |
34 public interface Delegate { | 36 public interface Delegate { |
35 // Call View#overScrollBy on the containerView. | 37 // Call View#overScrollBy on the containerView. |
36 void overScrollContainerViewBy(int deltaX, int deltaY, int scrollX, int scrollY, | 38 void overScrollContainerViewBy(int deltaX, int deltaY, int scrollX, int scrollY, |
37 int scrollRangeX, int scrollRangeY, boolean isTouchEvent); | 39 int scrollRangeX, int scrollRangeY, boolean isTouchEvent); |
38 // Call View#scrollTo on the containerView. | 40 // Call View#scrollTo on the containerView. |
(...skipping 20 matching lines...) Expand all Loading... | |
59 private int mMaxVerticalScrollOffset; | 61 private int mMaxVerticalScrollOffset; |
60 | 62 |
61 // Size of the container view. | 63 // Size of the container view. |
62 private int mContainerViewWidth; | 64 private int mContainerViewWidth; |
63 private int mContainerViewHeight; | 65 private int mContainerViewHeight; |
64 | 66 |
65 // Whether we're in the middle of processing a touch event. | 67 // Whether we're in the middle of processing a touch event. |
66 private boolean mProcessingTouchEvent; | 68 private boolean mProcessingTouchEvent; |
67 | 69 |
68 // Don't skip computeScrollAndAbsorbGlow just because isFling is called in b etween. | 70 // Don't skip computeScrollAndAbsorbGlow just because isFling is called in b etween. |
69 private boolean mWasFlinging; | 71 private boolean mWasSmoothScrolling; |
hush (inactive)
2015/06/05 21:47:22
This field is not needed any more. It is used to g
| |
70 | 72 |
71 // Whether (and to what value) to update the native side scroll offset after we've finished | 73 // Whether (and to what value) to update the native side scroll offset after we've finished |
72 // processing a touch event. | 74 // processing a touch event. |
73 private boolean mApplyDeferredNativeScroll; | 75 private boolean mApplyDeferredNativeScroll; |
74 private int mDeferredNativeScrollX; | 76 private int mDeferredNativeScrollX; |
75 private int mDeferredNativeScrollY; | 77 private int mDeferredNativeScrollY; |
76 | 78 |
77 private OverScroller mScroller; | 79 private OverScroller mScroller; |
78 | 80 |
79 public AwScrollOffsetManager(Delegate delegate, OverScroller overScroller) { | 81 public AwScrollOffsetManager(Delegate delegate, OverScroller overScroller) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 final int deltaY = y - scrollY; | 158 final int deltaY = y - scrollY; |
157 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); | 159 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); |
158 final int scrollRangeY = computeMaximumVerticalScrollOffset(); | 160 final int scrollRangeY = computeMaximumVerticalScrollOffset(); |
159 | 161 |
160 // We use overScrollContainerViewBy to be compatible with WebViewClassic which used this | 162 // We use overScrollContainerViewBy to be compatible with WebViewClassic which used this |
161 // method for handling both over-scroll as well as in-bounds scroll. | 163 // method for handling both over-scroll as well as in-bounds scroll. |
162 mDelegate.overScrollContainerViewBy(deltaX, deltaY, scrollX, scrollY, | 164 mDelegate.overScrollContainerViewBy(deltaX, deltaY, scrollX, scrollY, |
163 scrollRangeX, scrollRangeY, mProcessingTouchEvent); | 165 scrollRangeX, scrollRangeY, mProcessingTouchEvent); |
164 } | 166 } |
165 | 167 |
166 public boolean isFlingActive() { | 168 // This is used temporarily until animateScrollTo path of Android WebView (p ageUp, pageDown) |
167 boolean flinging = mScroller.computeScrollOffset(); | 169 // is unified with Chrome smooth scrolling. |
168 mWasFlinging |= flinging; | 170 public boolean isSmoothScrollingActive() { |
169 return flinging; | 171 boolean smoothScrolling = mScroller.computeScrollOffset(); |
172 mWasSmoothScrolling |= smoothScrolling; | |
173 return smoothScrolling; | |
170 } | 174 } |
171 | 175 |
172 // Called by the native side to over-scroll the container view. | 176 // Called by the native side to over-scroll the container view. |
173 public void overScrollBy(int deltaX, int deltaY) { | 177 public void overScrollBy(int deltaX, int deltaY) { |
174 // TODO(mkosiba): Once http://crbug.com/260663 and http://crbug.com/2612 39 are fixed it | 178 // TODO(mkosiba): Once http://crbug.com/260663 and http://crbug.com/2612 39 are fixed it |
175 // should be possible to uncomment the following asserts: | 179 // should be possible to uncomment the following asserts: |
176 // if (deltaX < 0) assert mDelegate.getContainerViewScrollX() == 0; | 180 // if (deltaX < 0) assert mDelegate.getContainerViewScrollX() == 0; |
177 // if (deltaX > 0) assert mDelegate.getContainerViewScrollX() == | 181 // if (deltaX > 0) assert mDelegate.getContainerViewScrollX() == |
178 // computeMaximumHorizontalScrollOffset(); | 182 // computeMaximumHorizontalScrollOffset(); |
179 scrollBy(deltaX, deltaY); | 183 scrollBy(deltaX, deltaY); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
251 mDelegate.scrollNativeTo(x, y); | 255 mDelegate.scrollNativeTo(x, y); |
252 } | 256 } |
253 | 257 |
254 // Called whenever some other touch interaction requires the fling gesture t o be canceled. | 258 // Called whenever some other touch interaction requires the fling gesture t o be canceled. |
255 public void onFlingCancelGesture() { | 259 public void onFlingCancelGesture() { |
256 // TODO(mkosiba): Support speeding up a fling by flinging again. | 260 // TODO(mkosiba): Support speeding up a fling by flinging again. |
257 // http://crbug.com/265841 | 261 // http://crbug.com/265841 |
258 mScroller.forceFinished(true); | 262 mScroller.forceFinished(true); |
259 } | 263 } |
260 | 264 |
261 // Called when a fling gesture is not handled by the renderer. | 265 // This is used temporarily until animateScrollTo path of Android WebView (p ageUp, pageDown) |
262 // We explicitly ask the renderer not to handle fling gestures targeted at t he root | 266 // is unified with Chrome smooth scrolling. |
263 // scroll layer. | 267 public boolean willComputeScroll() { |
264 public void onUnhandledFlingStartEvent(int velocityX, int velocityY) { | 268 if (mScroller.isFinished()) mIsAnimatingScroll = false; |
boliu
2015/05/29 19:42:47
not quite the same as mIsAnimatingScroll = mScroll
hush (inactive)
2015/06/05 21:47:21
Sorry. Same as I said above. This function should
| |
265 flingScroll(-velocityX, -velocityY); | 269 return mIsAnimatingScroll && !mScroller.isFinished(); |
266 } | |
267 | |
268 // Starts the fling animation. Called both as a response to a fling gesture and as via the | |
269 // public WebView#flingScroll(int, int) API. | |
270 public void flingScroll(int velocityX, int velocityY) { | |
271 final int scrollX = mDelegate.getContainerViewScrollX(); | |
272 final int scrollY = mDelegate.getContainerViewScrollY(); | |
273 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); | |
274 final int scrollRangeY = computeMaximumVerticalScrollOffset(); | |
275 | |
276 mScroller.fling(scrollX, scrollY, velocityX, velocityY, | |
277 0, scrollRangeX, 0, scrollRangeY); | |
278 mDelegate.invalidate(); | |
279 } | 270 } |
280 | 271 |
281 // Called immediately before the draw to update the scroll offset. | 272 // Called immediately before the draw to update the scroll offset. |
282 public void computeScrollAndAbsorbGlow(OverScrollGlow overScrollGlow) { | 273 public void computeScrollAndAbsorbGlow(OverScrollGlow overScrollGlow) { |
283 if (!mScroller.computeScrollOffset() && !mWasFlinging) { | 274 if (!mScroller.computeScrollOffset() && !mWasSmoothScrolling) { |
284 return; | 275 return; |
285 } | 276 } |
286 mWasFlinging = false; | 277 mWasSmoothScrolling = false; |
287 | 278 |
288 final int oldX = mDelegate.getContainerViewScrollX(); | 279 final int oldX = mDelegate.getContainerViewScrollX(); |
289 final int oldY = mDelegate.getContainerViewScrollY(); | 280 final int oldY = mDelegate.getContainerViewScrollY(); |
290 int x = mScroller.getCurrX(); | 281 int x = mScroller.getCurrX(); |
291 int y = mScroller.getCurrY(); | 282 int y = mScroller.getCurrY(); |
292 | 283 |
293 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); | 284 final int scrollRangeX = computeMaximumHorizontalScrollOffset(); |
294 final int scrollRangeY = computeMaximumVerticalScrollOffset(); | 285 final int scrollRangeY = computeMaximumVerticalScrollOffset(); |
295 | 286 |
296 if (overScrollGlow != null) { | 287 if (overScrollGlow != null) { |
(...skipping 19 matching lines...) Expand all Loading... | |
316 final int scrollY = mDelegate.getContainerViewScrollY(); | 307 final int scrollY = mDelegate.getContainerViewScrollY(); |
317 | 308 |
318 x = clampHorizontalScroll(x); | 309 x = clampHorizontalScroll(x); |
319 y = clampVerticalScroll(y); | 310 y = clampVerticalScroll(y); |
320 | 311 |
321 int dx = x - scrollX; | 312 int dx = x - scrollX; |
322 int dy = y - scrollY; | 313 int dy = y - scrollY; |
323 | 314 |
324 if (dx == 0 && dy == 0) return false; | 315 if (dx == 0 && dy == 0) return false; |
325 | 316 |
317 mIsAnimatingScroll = true; | |
318 | |
326 mScroller.startScroll(scrollX, scrollY, dx, dy, computeDurationInMilliSe c(dx, dy)); | 319 mScroller.startScroll(scrollX, scrollY, dx, dy, computeDurationInMilliSe c(dx, dy)); |
327 mDelegate.invalidate(); | 320 mDelegate.invalidate(); |
328 | 321 |
329 return true; | 322 return true; |
330 } | 323 } |
331 | 324 |
332 /** | 325 /** |
333 * See {@link android.webkit.WebView#pageUp(boolean)} | 326 * See {@link android.webkit.WebView#pageUp(boolean)} |
334 */ | 327 */ |
335 public boolean pageUp(boolean top) { | 328 public boolean pageUp(boolean top) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 } | 416 } |
424 | 417 |
425 if (immediate) { | 418 if (immediate) { |
426 scrollBy(scrollXDelta, scrollYDelta); | 419 scrollBy(scrollXDelta, scrollYDelta); |
427 return true; | 420 return true; |
428 } else { | 421 } else { |
429 return animateScrollTo(scrollX + scrollXDelta, scrollY + scrollYDelt a); | 422 return animateScrollTo(scrollX + scrollXDelta, scrollY + scrollYDelt a); |
430 } | 423 } |
431 } | 424 } |
432 } | 425 } |
OLD | NEW |