Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/appmenu/PulseDrawable.java

Issue 2779543005: Add support for highlighting menu items (Closed)
Patch Set: Removed test code Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.appmenu;
6
7 import android.content.res.Resources;
8 import android.graphics.Canvas;
9 import android.graphics.ColorFilter;
10 import android.graphics.Paint;
11 import android.graphics.PixelFormat;
12 import android.graphics.Rect;
13 import android.graphics.drawable.Drawable;
14 import android.os.SystemClock;
15 import android.support.annotation.ColorInt;
16 import android.support.annotation.ColorRes;
17 import android.view.animation.Interpolator;
18
19 import org.chromium.base.ApiCompatibilityUtils;
20
21 /**
22 * A custom {@link Drawable} that will animate a pulse using the {@link PulseInt erpolator}. Meant
23 * to be created with a {@link PulseDrawable#Painter} that does the actual drawi ng work based on
24 * the pulse interpolation value.
25 */
26 public class PulseDrawable extends Drawable {
David Trainor- moved to gerrit 2017/04/11 18:43:04 These should be in a better, more generic place.
27 private static final long PULSE_DURATION_MS = 2500;
28 private static final long FRAME_RATE = 60;
29
30 /**
31 * An interface that does the actual drawing work for this {@link Drawable}. Not meant to be
32 * stateful, as this could be shared across multiple instances of this drawa ble if it gets
33 * copied or mutated.
34 */
35 public interface Painter {
36 /**
37 * Called when this drawable updates it's pulse interpolation. Should m utate the drawable
38 * as necessary. This is responsible for invalidating this {@link Drawa ble} if something
39 * needs to be redrawn.
40 *
41 * @param drawable The {@link PulseDrawable} that is updated.
42 * @param interpolation The current progress of whatever is being pulsed .
43 */
44 void modifyDrawable(PulseDrawable drawable, float interpolation);
45
46 /**
47 * Called when this {@link PulseDrawable} needs to draw. Should perform any draw operation
48 * for the specific type of pulse.
49 * @param drawable The calling {@link PulseDrawable}.
50 * @param paint A {@link Paint} object to use. This will automa tically have the
51 * color set.
52 * @param canvas The {@link Canvas} to draw to.
53 * @param interpolation The current progress of whatever is being pulsed .
54 */
55 void draw(PulseDrawable drawable, Paint paint, Canvas canvas, float inte rpolation);
56 }
57
58 private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
59 private final Rect mInset = new Rect();
60 private final Rect mOriginalBounds = new Rect();
61 private final Rect mInsetBounds = new Rect();
62
63 protected PulseState mState;
64 private boolean mMutated;
65
66 /**
67 * Creates a new {@link PulseDrawable} instance.
68 * @param res A {@link Resources} object used to load the {@link Dr awable} parameters.
69 * @param color A color resource.
70 * @param interpolator An {@link Interpolator} that defines how the pulse wi ll fade in and out.
71 * @param painter The {@link Painter} that will be responsible for draw ing the pulse.
72 */
73 public PulseDrawable(
74 Resources res, @ColorRes int color, Interpolator interpolator, Paint er painter) {
75 this(new PulseState(res, color, interpolator, painter));
76 }
77
78 private PulseDrawable(PulseState state) {
79 mState = state;
80 }
81
82 /** What color to set the pulse to. */
83 public void setColor(@ColorInt int color) {
84 mState.color = mState.drawColor = color;
85 invalidateSelf();
86 }
87
88 /** How much to inset the bounds of this {@link Drawable} by. */
89 public void setInset(int left, int top, int right, int bottom) {
90 mInset.set(left, top, right, bottom);
91 setBounds(mOriginalBounds);
92 }
93
94 // Drawable implementation.
95 // Overriding only this method because {@link Drawable#setBounds(Rect)} call s into this.
96 @Override
97 public void setBounds(int left, int top, int right, int bottom) {
98 mOriginalBounds.set(left, top, right, bottom);
99 mInsetBounds.set(
100 left + mInset.left, top + mInset.top, right - mInset.right, bott om - mInset.bottom);
101 super.setBounds(
102 mInsetBounds.left, mInsetBounds.top, mInsetBounds.right, mInsetB ounds.bottom);
103 }
104
105 @Override
106 public void draw(Canvas canvas) {
107 mPaint.setColor(mState.drawColor);
108 mState.painter.draw(this, mPaint, canvas, mState.progress);
109 }
110
111 @Override
112 public void setAlpha(int alpha) {
113 // Encode the alpha into the color.
114 alpha += alpha >> 7; // make it 0..256
115 final int baseAlpha = mState.color >>> 24;
116 final int useAlpha = baseAlpha * alpha >> 8;
117 final int useColor = (mState.color << 8 >>> 8) | (useAlpha << 24);
118 if (mState.drawColor != useColor) {
119 mState.drawColor = useColor;
120 invalidateSelf();
121 }
122 }
123
124 @Override
125 public int getAlpha() {
126 return mState.drawColor >>> 24;
127 }
128
129 @Override
130 public void setColorFilter(ColorFilter colorFilter) {
131 mPaint.setColorFilter(colorFilter);
132 }
133
134 @Override
135 public int getOpacity() {
136 return PixelFormat.TRANSLUCENT;
137 }
138
139 @Override
140 public boolean setVisible(boolean visible, boolean restart) {
141 final boolean changed = super.setVisible(visible, restart);
142 if (visible) {
143 if (changed || restart) {
144 startPulsing();
145 }
146 } else {
147 stopPulsing();
148 }
149 return changed;
150 }
151
152 @Override
153 public Drawable mutate() {
154 if (!mMutated && super.mutate() == this) {
155 mState = new PulseState(mState);
156 mMutated = true;
157 }
158 return this;
159 }
160
161 private void startPulsing() {
162 mState.startTime = SystemClock.uptimeMillis();
163 mNextFrame.run();
164 }
165
166 private void stopPulsing() {
167 unscheduleSelf(mNextFrame);
168 }
169
170 /**
171 * The {@link ConstantState} subclass for this {@link PulseDrawable}.
172 */
173 private static final class PulseState extends ConstantState {
174 // Current Paint State.
175 /** The current color, including alpha, to draw. */
176 public int drawColor;
177
178 /** The original color to draw (may not include any alpha updates. */
179 public int color;
180
181 // Current Animation State
182 /** The time from {@link SystemClock#updateMillis()} that this animation started at. */
183 public long startTime;
184
185 /** The current progress from 0 to 1 of the pulse. */
186 public float progress;
187
188 /** The {@link Interpolator} that makes the pulse and generates the prog ress. */
189 public Interpolator interpolator;
190
191 /**
192 * The {@link Painter} object that is responsible for modifying and draw ing this
193 * {@link PulseDrawable}.
194 */
195 public Painter painter;
196
197 PulseState(Resources res, @ColorRes int color, Interpolator interpolator , Painter painter) {
198 this.color = this.drawColor = ApiCompatibilityUtils.getColor(res, co lor);
199
200 this.interpolator = new PulseInterpolator(interpolator);
201 this.painter = painter;
202 }
203
204 PulseState(PulseState other) {
205 drawColor = other.drawColor;
206 color = other.color;
207
208 startTime = other.startTime;
209
210 interpolator = other.interpolator;
211 painter = other.painter;
212 }
213
214 @Override
215 public Drawable newDrawable() {
216 return new PulseDrawable(this);
217 }
218
219 @Override
220 public int getChangingConfigurations() {
221 return 0;
222 }
223 }
224
225 private final Runnable mNextFrame = new Runnable() {
226 @Override
227 public void run() {
228 long curTime = SystemClock.uptimeMillis();
229 long msIntoAnim = (curTime - mState.startTime) % PULSE_DURATION_MS;
230 float progress = ((float) msIntoAnim) / ((float) PULSE_DURATION_MS);
231 mState.progress = mState.interpolator.getInterpolation(progress);
232 mState.painter.modifyDrawable(PulseDrawable.this, mState.progress);
233
234 unscheduleSelf(mNextFrame);
235 scheduleSelf(mNextFrame, SystemClock.uptimeMillis() + 1000 / FRAME_R ATE);
236 }
237 };
238 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698