1637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell/*
2637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * Copyright (C) 2010 The Android Open Source Project
3637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell *
4637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * you may not use this file except in compliance with the License.
6637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * You may obtain a copy of the License at
7637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell *
8637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell *
10637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * Unless required by applicable law or agreed to in writing, software
11637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * See the License for the specific language governing permissions and
14637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * limitations under the License.
15637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell */
16637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powellpackage android.webkit;
17637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
18637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powellimport com.android.internal.R;
19637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
204e30d89ceda832300f80bf73f4f58cd2b51bf112Mindy Pereiraimport android.content.Context;
21637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powellimport android.content.res.Resources;
22637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powellimport android.graphics.Canvas;
23637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powellimport android.graphics.drawable.Drawable;
24637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powellimport android.view.View;
2589935e41c593a599e8955388b27fb926e60e5e94Adam Powellimport android.widget.EdgeEffect;
26637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
27637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell/**
28637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * This class manages the edge glow effect when a WebView is flung or pulled beyond the edges.
29637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell * @hide
30637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell */
31637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powellpublic class OverScrollGlow {
323c90952036a5ff7ddb2946c643f1a0bf1c31d53aJonathan Dixon    private WebViewClassic mHostView;
33637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
3489935e41c593a599e8955388b27fb926e60e5e94Adam Powell    private EdgeEffect mEdgeGlowTop;
3589935e41c593a599e8955388b27fb926e60e5e94Adam Powell    private EdgeEffect mEdgeGlowBottom;
3689935e41c593a599e8955388b27fb926e60e5e94Adam Powell    private EdgeEffect mEdgeGlowLeft;
3789935e41c593a599e8955388b27fb926e60e5e94Adam Powell    private EdgeEffect mEdgeGlowRight;
38637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
39637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    private int mOverScrollDeltaX;
40637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    private int mOverScrollDeltaY;
41637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
423c90952036a5ff7ddb2946c643f1a0bf1c31d53aJonathan Dixon    public OverScrollGlow(WebViewClassic host) {
43637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        mHostView = host;
444e30d89ceda832300f80bf73f4f58cd2b51bf112Mindy Pereira        Context context = host.getContext();
4589935e41c593a599e8955388b27fb926e60e5e94Adam Powell        mEdgeGlowTop = new EdgeEffect(context);
4689935e41c593a599e8955388b27fb926e60e5e94Adam Powell        mEdgeGlowBottom = new EdgeEffect(context);
4789935e41c593a599e8955388b27fb926e60e5e94Adam Powell        mEdgeGlowLeft = new EdgeEffect(context);
4889935e41c593a599e8955388b27fb926e60e5e94Adam Powell        mEdgeGlowRight = new EdgeEffect(context);
49637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    }
50637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
51637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    /**
52637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * Pull leftover touch scroll distance into one of the edge glows as appropriate.
53637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     *
54637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param x Current X scroll offset
55637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param y Current Y scroll offset
56637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param oldX Old X scroll offset
57637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param oldY Old Y scroll offset
58637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param maxX Maximum range for horizontal scrolling
59637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param maxY Maximum range for vertical scrolling
60637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     */
61637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    public void pullGlow(int x, int y, int oldX, int oldY, int maxX, int maxY) {
62637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        // Only show overscroll bars if there was no movement in any direction
63637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        // as a result of scrolling.
64637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        if (oldX == mHostView.getScrollX() && oldY == mHostView.getScrollY()) {
65637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            // Don't show left/right glows if we fit the whole content.
66637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            // Also don't show if there was vertical movement.
67637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            if (maxX > 0) {
68637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                final int pulledToX = oldX + mOverScrollDeltaX;
69637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                if (pulledToX < 0) {
70637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    mEdgeGlowLeft.onPull((float) mOverScrollDeltaX / mHostView.getWidth());
71637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    if (!mEdgeGlowRight.isFinished()) {
72637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                        mEdgeGlowRight.onRelease();
73637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    }
74637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                } else if (pulledToX > maxX) {
75637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    mEdgeGlowRight.onPull((float) mOverScrollDeltaX / mHostView.getWidth());
76637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    if (!mEdgeGlowLeft.isFinished()) {
77637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                        mEdgeGlowLeft.onRelease();
78637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    }
79637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                }
80637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                mOverScrollDeltaX = 0;
81637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            }
82637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
833c90952036a5ff7ddb2946c643f1a0bf1c31d53aJonathan Dixon            if (maxY > 0 || mHostView.getWebView().getOverScrollMode() == View.OVER_SCROLL_ALWAYS) {
84637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                final int pulledToY = oldY + mOverScrollDeltaY;
85637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                if (pulledToY < 0) {
86637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    mEdgeGlowTop.onPull((float) mOverScrollDeltaY / mHostView.getHeight());
87637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    if (!mEdgeGlowBottom.isFinished()) {
88637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                        mEdgeGlowBottom.onRelease();
89637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    }
90637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                } else if (pulledToY > maxY) {
91637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    mEdgeGlowBottom.onPull((float) mOverScrollDeltaY / mHostView.getHeight());
92637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    if (!mEdgeGlowTop.isFinished()) {
93637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                        mEdgeGlowTop.onRelease();
94637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    }
95637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                }
96637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                mOverScrollDeltaY = 0;
97637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            }
98637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        }
99637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    }
100637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
101637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    /**
102637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * Set touch delta values indicating the current amount of overscroll.
103637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     *
104637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param deltaX
105637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param deltaY
106637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     */
107637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    public void setOverScrollDeltas(int deltaX, int deltaY) {
108637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        mOverScrollDeltaX = deltaX;
109637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        mOverScrollDeltaY = deltaY;
110637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    }
111637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
112637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    /**
113637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * Absorb leftover fling velocity into one of the edge glows as appropriate.
114637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     *
115637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param x Current X scroll offset
116637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param y Current Y scroll offset
117637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param oldX Old X scroll offset
118637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param oldY Old Y scroll offset
119637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param rangeX Maximum range for horizontal scrolling
120637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param rangeY Maximum range for vertical scrolling
121637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     */
122637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    public void absorbGlow(int x, int y, int oldX, int oldY, int rangeX, int rangeY) {
1233c90952036a5ff7ddb2946c643f1a0bf1c31d53aJonathan Dixon        if (rangeY > 0 || mHostView.getWebView().getOverScrollMode() == View.OVER_SCROLL_ALWAYS) {
124637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            if (y < 0 && oldY >= 0) {
125637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                mEdgeGlowTop.onAbsorb((int) mHostView.mScroller.getCurrVelocity());
126637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                if (!mEdgeGlowBottom.isFinished()) {
127637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    mEdgeGlowBottom.onRelease();
128637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                }
129637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            } else if (y > rangeY && oldY <= rangeY) {
130637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                mEdgeGlowBottom.onAbsorb((int) mHostView.mScroller.getCurrVelocity());
131637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                if (!mEdgeGlowTop.isFinished()) {
132637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    mEdgeGlowTop.onRelease();
133637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                }
134637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            }
135637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        }
136637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
137637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        if (rangeX > 0) {
138637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            if (x < 0 && oldX >= 0) {
139637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                mEdgeGlowLeft.onAbsorb((int) mHostView.mScroller.getCurrVelocity());
140637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                if (!mEdgeGlowRight.isFinished()) {
141637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    mEdgeGlowRight.onRelease();
142637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                }
143637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            } else if (x > rangeX && oldX <= rangeX) {
144637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                mEdgeGlowRight.onAbsorb((int) mHostView.mScroller.getCurrVelocity());
145637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                if (!mEdgeGlowLeft.isFinished()) {
146637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    mEdgeGlowLeft.onRelease();
147637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                }
148637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            }
149637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        }
150637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    }
151637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
152637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    /**
153637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * Draw the glow effect along the sides of the widget. mEdgeGlow* must be non-null.
154637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     *
155637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @param canvas Canvas to draw into, transformed into view coordinates.
156637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @return true if glow effects are still animating and the view should invalidate again.
157637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     */
158637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    public boolean drawEdgeGlows(Canvas canvas) {
159637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        final int scrollX = mHostView.getScrollX();
160637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        final int scrollY = mHostView.getScrollY();
161637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        final int width = mHostView.getWidth();
162637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        int height = mHostView.getHeight();
163637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
164637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        boolean invalidateForGlow = false;
165637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        if (!mEdgeGlowTop.isFinished()) {
166637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            final int restoreCount = canvas.save();
167637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
1683331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira            canvas.translate(scrollX, mHostView.getVisibleTitleHeight() + Math.min(0, scrollY));
1693331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira            mEdgeGlowTop.setSize(width, height);
170637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            invalidateForGlow |= mEdgeGlowTop.draw(canvas);
171637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            canvas.restoreToCount(restoreCount);
172637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        }
173637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        if (!mEdgeGlowBottom.isFinished()) {
174637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            final int restoreCount = canvas.save();
175637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
1763331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira            canvas.translate(-width + scrollX, Math.max(mHostView.computeMaxScrollY(), scrollY)
1773331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira                    + height);
178637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            canvas.rotate(180, width, 0);
1793331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira            mEdgeGlowBottom.setSize(width, height);
180637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            invalidateForGlow |= mEdgeGlowBottom.draw(canvas);
181637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            canvas.restoreToCount(restoreCount);
182637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        }
183637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        if (!mEdgeGlowLeft.isFinished()) {
184637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            final int restoreCount = canvas.save();
185637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
186637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            canvas.rotate(270);
1873331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira            canvas.translate(-height - scrollY, Math.min(0, scrollX));
1883331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira            mEdgeGlowLeft.setSize(height, width);
189637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            invalidateForGlow |= mEdgeGlowLeft.draw(canvas);
190637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            canvas.restoreToCount(restoreCount);
191637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        }
192637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        if (!mEdgeGlowRight.isFinished()) {
193637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            final int restoreCount = canvas.save();
194637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
195637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            canvas.rotate(90);
1963331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira            canvas.translate(scrollY,
197637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                    -(Math.max(mHostView.computeMaxScrollX(), scrollX) + width));
1983331f2be93902694ccda848d88b4008eb3a22baaMindy Pereira            mEdgeGlowRight.setSize(height, width);
199637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            invalidateForGlow |= mEdgeGlowRight.draw(canvas);
200637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell            canvas.restoreToCount(restoreCount);
201637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        }
202637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        return invalidateForGlow;
203637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    }
204637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
205637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    /**
206637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * @return True if any glow is still animating
207637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     */
208637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    public boolean isAnimating() {
209637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        return (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished() ||
210637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell                !mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished());
211637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    }
212637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell
213637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    /**
214637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     * Release all glows from any touch pulls in progress.
215637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell     */
216637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    public void releaseAll() {
217637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        mEdgeGlowTop.onRelease();
218637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        mEdgeGlowBottom.onRelease();
219637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        mEdgeGlowLeft.onRelease();
220637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell        mEdgeGlowRight.onRelease();
221637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell    }
222637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell}
223