mobile/android/base/gfx/OverscrollEdgeEffect.java

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:b4503106ac36
1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 package org.mozilla.gecko.gfx;
7
8 import android.content.Context;
9 import android.graphics.Canvas;
10 import android.os.Build;
11 import android.widget.EdgeEffect;
12 import android.view.View;
13
14
15 public class OverscrollEdgeEffect implements Overscroll {
16 // Used to index particular edges in the edges array
17 private static final int TOP = 0;
18 private static final int BOTTOM = 1;
19 private static final int LEFT = 2;
20 private static final int RIGHT = 3;
21
22 // All four edges of the screen
23 private final EdgeEffect[] mEdges = new EdgeEffect[4];
24
25 // The view we're showing this overscroll on.
26 private final View mView;
27
28 public OverscrollEdgeEffect(final View v) {
29 mView = v;
30 Context context = v.getContext();
31 for (int i = 0; i < 4; i++) {
32 mEdges[i] = new EdgeEffect(context);
33 }
34 }
35
36 public void setSize(final int width, final int height) {
37 mEdges[LEFT].setSize(height, width);
38 mEdges[RIGHT].setSize(height, width);
39 mEdges[TOP].setSize(width, height);
40 mEdges[BOTTOM].setSize(width, height);
41 }
42
43 private EdgeEffect getEdgeForAxisAndSide(final Axis axis, final float side) {
44 if (axis == Axis.Y) {
45 if (side < 0) {
46 return mEdges[TOP];
47 } else {
48 return mEdges[BOTTOM];
49 }
50 } else {
51 if (side < 0) {
52 return mEdges[LEFT];
53 } else {
54 return mEdges[RIGHT];
55 }
56 }
57 }
58
59 private void invalidate() {
60 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
61 mView.postInvalidateOnAnimation();
62 } else {
63 mView.postInvalidateDelayed(10);
64 }
65 }
66
67 public void setVelocity(final float velocity, final Axis axis) {
68 final EdgeEffect edge = getEdgeForAxisAndSide(axis, velocity);
69
70 // If we're showing overscroll already, start fading it out.
71 if (!edge.isFinished()) {
72 edge.onRelease();
73 } else {
74 // Otherwise, show an absorb effect
75 edge.onAbsorb((int)velocity);
76 }
77
78 invalidate();
79 }
80
81 public void setDistance(final float distance, final Axis axis) {
82 // The first overscroll event often has zero distance. Throw it out
83 if (distance == 0.0f) {
84 return;
85 }
86
87 final EdgeEffect edge = getEdgeForAxisAndSide(axis, (int)distance);
88 edge.onPull(distance / (axis == Axis.X ? mView.getWidth() : mView.getHeight()));
89 invalidate();
90 }
91
92 public void draw(final Canvas canvas, final ImmutableViewportMetrics metrics) {
93 if (metrics == null) {
94 return;
95 }
96
97 // If we're pulling an edge, or fading it out, draw!
98 boolean invalidate = false;
99 if (!mEdges[TOP].isFinished()) {
100 invalidate |= draw(mEdges[TOP], canvas, metrics.marginLeft, metrics.marginTop, 0);
101 }
102
103 if (!mEdges[BOTTOM].isFinished()) {
104 invalidate |= draw(mEdges[BOTTOM], canvas, mView.getWidth(), mView.getHeight(), 180);
105 }
106
107 if (!mEdges[LEFT].isFinished()) {
108 invalidate |= draw(mEdges[LEFT], canvas, metrics.marginLeft, mView.getHeight(), 270);
109 }
110
111 if (!mEdges[RIGHT].isFinished()) {
112 invalidate |= draw(mEdges[RIGHT], canvas, mView.getWidth(), metrics.marginTop, 90);
113 }
114
115 // If the edge effect is animating off screen, invalidate.
116 if (invalidate) {
117 invalidate();
118 }
119 }
120
121 public boolean draw(final EdgeEffect edge, final Canvas canvas, final float translateX, final float translateY, final float rotation) {
122 final int state = canvas.save();
123 canvas.translate(translateX, translateY);
124 canvas.rotate(rotation);
125 boolean invalidate = edge.draw(canvas);
126 canvas.restoreToCount(state);
127
128 return invalidate;
129 }
130 }

mercurial