Merge "DO NOT MERGE Integrate edge effects into WebView." into gingerbread
This commit is contained in:
@@ -16,13 +16,16 @@
|
||||
|
||||
package android.webkit;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import android.annotation.Widget;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.DialogInterface.OnCancelListener;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.database.DataSetObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
@@ -30,7 +33,6 @@ import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Interpolator;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Picture;
|
||||
import android.graphics.Point;
|
||||
@@ -39,8 +41,8 @@ import android.graphics.RectF;
|
||||
import android.graphics.Region;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.http.SslCertificate;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslCertificate;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@@ -74,8 +76,10 @@ import android.webkit.WebViewCore.TouchEventData;
|
||||
import android.widget.AbsoluteLayout;
|
||||
import android.widget.Adapter;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckedTextView;
|
||||
import android.widget.EdgeGlow;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
@@ -83,17 +87,15 @@ import android.widget.OverScroller;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ZoomButtonsController;
|
||||
import android.widget.ZoomControls;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -757,6 +759,27 @@ public class WebView extends AbsoluteLayout
|
||||
private int mHorizontalScrollBarMode = SCROLLBAR_AUTO;
|
||||
private int mVerticalScrollBarMode = SCROLLBAR_AUTO;
|
||||
|
||||
/**
|
||||
* Max distance to overscroll by in pixels.
|
||||
* This how far content can be pulled beyond its normal bounds by the user.
|
||||
*/
|
||||
private int mOverscrollDistance;
|
||||
|
||||
/**
|
||||
* Max distance to overfling by in pixels.
|
||||
* This is how far flinged content can move beyond the end of its normal bounds.
|
||||
*/
|
||||
private int mOverflingDistance;
|
||||
|
||||
/*
|
||||
* These manage the edge glow effect when flung or pulled beyond the edges.
|
||||
* If one is not null, all are not null. Checking one for null is as good as checking each.
|
||||
*/
|
||||
private EdgeGlow mEdgeGlowTop;
|
||||
private EdgeGlow mEdgeGlowBottom;
|
||||
private EdgeGlow mEdgeGlowLeft;
|
||||
private EdgeGlow mEdgeGlowRight;
|
||||
|
||||
// Used to match key downs and key ups
|
||||
private boolean mGotKeyDown;
|
||||
|
||||
@@ -986,7 +1009,6 @@ public class WebView extends AbsoluteLayout
|
||||
setFocusableInTouchMode(true);
|
||||
setClickable(true);
|
||||
setLongClickable(true);
|
||||
setOverscrollMode(OVERSCROLL_NEVER);
|
||||
|
||||
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
|
||||
int slop = configuration.getScaledTouchSlop();
|
||||
@@ -1009,6 +1031,29 @@ public class WebView extends AbsoluteLayout
|
||||
mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE;
|
||||
mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE;
|
||||
mMaximumFling = configuration.getScaledMaximumFlingVelocity();
|
||||
mOverscrollDistance = configuration.getScaledOverscrollDistance();
|
||||
mOverflingDistance = configuration.getScaledOverflingDistance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOverscrollMode(int mode) {
|
||||
super.setOverscrollMode(mode);
|
||||
if (mode != OVERSCROLL_NEVER) {
|
||||
if (mEdgeGlowTop == null) {
|
||||
final Resources res = getContext().getResources();
|
||||
final Drawable edge = res.getDrawable(R.drawable.edge_light);
|
||||
final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
|
||||
mEdgeGlowTop = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowBottom = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowLeft = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowRight = new EdgeGlow(edge, glow);
|
||||
}
|
||||
} else {
|
||||
mEdgeGlowTop = null;
|
||||
mEdgeGlowBottom = null;
|
||||
mEdgeGlowLeft = null;
|
||||
mEdgeGlowRight = null;
|
||||
}
|
||||
}
|
||||
|
||||
/* package */void updateDefaultZoomDensity(int zoomDensity) {
|
||||
@@ -2500,6 +2545,9 @@ public class WebView extends AbsoluteLayout
|
||||
protected void onDrawVerticalScrollBar(Canvas canvas,
|
||||
Drawable scrollBar,
|
||||
int l, int t, int r, int b) {
|
||||
if (mScrollY < 0) {
|
||||
t -= mScrollY;
|
||||
}
|
||||
scrollBar.setBounds(l, t + getVisibleTitleHeight(), r, b);
|
||||
scrollBar.draw(canvas);
|
||||
}
|
||||
@@ -2518,6 +2566,12 @@ public class WebView extends AbsoluteLayout
|
||||
if (scrollY < 0 || scrollY > computeMaxScrollY()) {
|
||||
mInOverScrollMode = true;
|
||||
}
|
||||
|
||||
if ((clampedX && maxX > 0) || clampedY) {
|
||||
// Hitting a scroll barrier breaks velocity; don't fling further.
|
||||
mVelocityTracker.clear();
|
||||
mLastVelocity = 0;
|
||||
}
|
||||
super.scrollTo(scrollX, scrollY);
|
||||
}
|
||||
|
||||
@@ -2876,12 +2930,35 @@ public class WebView extends AbsoluteLayout
|
||||
int oldY = mScrollY;
|
||||
int x = mScroller.getCurrX();
|
||||
int y = mScroller.getCurrY();
|
||||
postInvalidate(); // So we draw again
|
||||
invalidate(); // So we draw again
|
||||
|
||||
if (oldX != x || oldY != y) {
|
||||
final int rangeX = computeMaxScrollX();
|
||||
final int rangeY = computeMaxScrollY();
|
||||
overscrollBy(x - oldX, y - oldY, oldX, oldY,
|
||||
computeMaxScrollX(), computeMaxScrollY(),
|
||||
getViewWidth() / 3, getViewHeight() / 3, false);
|
||||
rangeX, rangeY,
|
||||
mOverflingDistance, mOverflingDistance, false);
|
||||
|
||||
if (mEdgeGlowTop != null) {
|
||||
if (rangeY > 0 || getOverscrollMode() == OVERSCROLL_ALWAYS) {
|
||||
if (y < 0 && oldY >= 0) {
|
||||
mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity());
|
||||
} else if (y > rangeY && oldY <= rangeY) {
|
||||
mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity());
|
||||
}
|
||||
}
|
||||
|
||||
if (rangeX > 0) {
|
||||
if (x < 0 && oldX >= 0) {
|
||||
mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
|
||||
} else if (x > rangeX && oldX <= rangeX) {
|
||||
mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mScroller.isFinished()) {
|
||||
mPrivateHandler.sendEmptyMessage(RESUME_WEBCORE_PRIORITY);
|
||||
}
|
||||
} else {
|
||||
super.computeScroll();
|
||||
@@ -3292,13 +3369,8 @@ public class WebView extends AbsoluteLayout
|
||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
if (child == mTitleBar) {
|
||||
// When drawing the title bar, move it horizontally to always show
|
||||
// at the top of the WebView. While overscroll, stick the title bar
|
||||
// on the top otherwise we may have two during loading, one is drawn
|
||||
// here, another is drawn by the Browser.
|
||||
// at the top of the WebView.
|
||||
mTitleBar.offsetLeftAndRight(mScrollX - mTitleBar.getLeft());
|
||||
if (mScrollY <= 0) {
|
||||
mTitleBar.offsetTopAndBottom(mScrollY - mTitleBar.getTop());
|
||||
}
|
||||
}
|
||||
return super.drawChild(canvas, child, drawingTime);
|
||||
}
|
||||
@@ -3349,7 +3421,7 @@ public class WebView extends AbsoluteLayout
|
||||
mOverScrollBorder.setColor(0xffbbbbbb);
|
||||
}
|
||||
|
||||
int top = getTitleHeight();
|
||||
int top = 0;
|
||||
int right = computeRealHorizontalScrollRange();
|
||||
int bottom = top + computeRealVerticalScrollRange();
|
||||
// first draw the background and anchor to the top of the view
|
||||
@@ -3389,12 +3461,72 @@ public class WebView extends AbsoluteLayout
|
||||
mScrollY + height);
|
||||
mTitleShadow.draw(canvas);
|
||||
}
|
||||
|
||||
if (AUTO_REDRAW_HACK && mAutoRedraw) {
|
||||
invalidate();
|
||||
}
|
||||
mWebViewCore.signalRepaintDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
if (mEdgeGlowTop != null && drawEdgeGlows(canvas)) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the glow effect along the sides of the widget. mEdgeGlow* must be non-null.
|
||||
*
|
||||
* @param canvas Canvas to draw into, transformed into view coordinates.
|
||||
* @return true if glow effects are still animating and the view should invalidate again.
|
||||
*/
|
||||
private boolean drawEdgeGlows(Canvas canvas) {
|
||||
final int scrollX = mScrollX;
|
||||
final int scrollY = mScrollY;
|
||||
final int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
boolean invalidateForGlow = false;
|
||||
if (!mEdgeGlowTop.isFinished()) {
|
||||
final int restoreCount = canvas.save();
|
||||
|
||||
canvas.translate(-width / 2 + scrollX, scrollY);
|
||||
mEdgeGlowTop.setSize(width * 2, height);
|
||||
invalidateForGlow |= mEdgeGlowTop.draw(canvas);
|
||||
canvas.restoreToCount(restoreCount);
|
||||
}
|
||||
if (!mEdgeGlowBottom.isFinished()) {
|
||||
final int restoreCount = canvas.save();
|
||||
|
||||
canvas.translate(-width / 2 - scrollX, scrollY + height);
|
||||
canvas.rotate(180, width, 0);
|
||||
mEdgeGlowBottom.setSize(width * 2, height);
|
||||
invalidateForGlow |= mEdgeGlowBottom.draw(canvas);
|
||||
canvas.restoreToCount(restoreCount);
|
||||
}
|
||||
if (!mEdgeGlowLeft.isFinished()) {
|
||||
final int restoreCount = canvas.save();
|
||||
|
||||
canvas.rotate(270);
|
||||
canvas.translate(-height * 1.5f - scrollY, scrollX);
|
||||
mEdgeGlowLeft.setSize(height * 2, width);
|
||||
invalidateForGlow |= mEdgeGlowLeft.draw(canvas);
|
||||
canvas.restoreToCount(restoreCount);
|
||||
}
|
||||
if (!mEdgeGlowRight.isFinished()) {
|
||||
final int restoreCount = canvas.save();
|
||||
|
||||
canvas.rotate(90);
|
||||
canvas.translate(-height / 2 + scrollY, -scrollX - width);
|
||||
mEdgeGlowRight.setSize(height * 2, width);
|
||||
invalidateForGlow |= mEdgeGlowRight.draw(canvas);
|
||||
canvas.restoreToCount(restoreCount);
|
||||
}
|
||||
return invalidateForGlow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutParams(ViewGroup.LayoutParams params) {
|
||||
if (params.height == LayoutParams.WRAP_CONTENT) {
|
||||
@@ -5386,9 +5518,34 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
private void doDrag(int deltaX, int deltaY) {
|
||||
if ((deltaX | deltaY) != 0) {
|
||||
overscrollBy(deltaX, deltaY, mScrollX, mScrollY,
|
||||
computeMaxScrollX(), computeMaxScrollY(),
|
||||
getViewWidth() / 3, getViewHeight() / 3, true);
|
||||
final int oldX = mScrollX;
|
||||
final int oldY = mScrollY;
|
||||
final int rangeX = computeMaxScrollX();
|
||||
final int rangeY = computeMaxScrollY();
|
||||
overscrollBy(deltaX, deltaY, oldX, oldY,
|
||||
rangeX, rangeY,
|
||||
mOverscrollDistance, mOverscrollDistance, true);
|
||||
|
||||
if (mEdgeGlowTop != null) {
|
||||
// Don't show left/right glows if we fit the whole content.
|
||||
if (rangeX > 0) {
|
||||
final int pulledToX = oldX + deltaX;
|
||||
if (pulledToX < 0) {
|
||||
mEdgeGlowLeft.onPull((float) deltaX / getWidth());
|
||||
} else if (pulledToX > rangeX) {
|
||||
mEdgeGlowRight.onPull((float) deltaX / getWidth());
|
||||
}
|
||||
}
|
||||
|
||||
if (rangeY > 0 || getOverscrollMode() == OVERSCROLL_ALWAYS) {
|
||||
final int pulledToY = oldY + deltaY;
|
||||
if (pulledToY < 0) {
|
||||
mEdgeGlowTop.onPull((float) deltaY / getHeight());
|
||||
} else if (pulledToY > rangeY) {
|
||||
mEdgeGlowBottom.onPull((float) deltaY / getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!getSettings().getBuiltInZoomControls()) {
|
||||
boolean showPlusMinus = mMinZoomScale < mMaxZoomScale;
|
||||
@@ -5415,6 +5572,14 @@ public class WebView extends AbsoluteLayout
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
|
||||
// Release any pulled glows
|
||||
if (mEdgeGlowTop != null) {
|
||||
mEdgeGlowTop.onRelease();
|
||||
mEdgeGlowBottom.onRelease();
|
||||
mEdgeGlowLeft.onRelease();
|
||||
mEdgeGlowRight.onRelease();
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelTouch() {
|
||||
@@ -5428,6 +5593,15 @@ public class WebView extends AbsoluteLayout
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
|
||||
// Release any pulled glows
|
||||
if (mEdgeGlowTop != null) {
|
||||
mEdgeGlowTop.onRelease();
|
||||
mEdgeGlowBottom.onRelease();
|
||||
mEdgeGlowLeft.onRelease();
|
||||
mEdgeGlowRight.onRelease();
|
||||
}
|
||||
|
||||
if (mTouchMode == TOUCH_DRAG_MODE) {
|
||||
WebViewCore.resumePriority();
|
||||
WebViewCore.resumeUpdatePicture(mWebViewCore);
|
||||
@@ -5746,7 +5920,7 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
public void flingScroll(int vx, int vy) {
|
||||
mScroller.fling(mScrollX, mScrollY, vx, vy, 0, computeMaxScrollX(), 0,
|
||||
computeMaxScrollY(), getViewWidth() / 3, getViewHeight() / 3);
|
||||
computeMaxScrollY(), mOverflingDistance, mOverflingDistance);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@@ -5809,13 +5983,13 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
// no horizontal overscroll if the content just fits
|
||||
mScroller.fling(mScrollX, mScrollY, -vx, -vy, 0, maxX, 0, maxY,
|
||||
maxX == 0 ? 0 : getViewWidth() / 3, getViewHeight() / 3);
|
||||
// TODO: duration is calculated based on velocity, if the range is
|
||||
// small, the animation will stop before duration is up. We may
|
||||
// want to calculate how long the animation is going to run to precisely
|
||||
// resume the webcore update.
|
||||
maxX == 0 ? 0 : mOverflingDistance, mOverflingDistance);
|
||||
// Duration is calculated based on velocity. With range boundaries and overscroll
|
||||
// we may not know how long the final animation will take. (Hence the deprecation
|
||||
// warning on the call below.) It's not a big deal for scroll bars but if webcore
|
||||
// resumes during this effect we will take a performance hit. See computeScroll;
|
||||
// we resume webcore there when the animation is finished.
|
||||
final int time = mScroller.getDuration();
|
||||
mPrivateHandler.sendEmptyMessageDelayed(RESUME_WEBCORE_PRIORITY, time);
|
||||
awakenScrollBars(time);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ public class EdgeGlow {
|
||||
final int glowHeight = mGlow.getIntrinsicHeight();
|
||||
|
||||
mGlow.setAlpha((int) (Math.max(0, Math.min(mGlowAlpha, 1)) * 255));
|
||||
mGlow.setBounds(0, 0, mWidth, (int) (glowHeight * mGlowScaleY));
|
||||
mGlow.setBounds(0, 0, mWidth, (int) (glowHeight * mGlowScaleY * 0.5f));
|
||||
mGlow.draw(canvas);
|
||||
|
||||
mEdge.setAlpha((int) (Math.max(0, Math.min(mEdgeAlpha, 1)) * 255));
|
||||
|
||||
@@ -523,7 +523,7 @@ public class OverScroller {
|
||||
// If the velocity is smaller than this value, no bounce is triggered
|
||||
// when the edge limits are reached (would result in a zero pixels
|
||||
// displacement anyway).
|
||||
private static final float MINIMUM_VELOCITY_FOR_BOUNCE = 140.0f;
|
||||
private static final float MINIMUM_VELOCITY_FOR_BOUNCE = Float.MAX_VALUE;//140.0f;
|
||||
|
||||
// Proportion of the velocity that is preserved when the edge is reached.
|
||||
private static final float DEFAULT_BOUNCE_COEFFICIENT = 0.16f;
|
||||
|
||||
Reference in New Issue
Block a user