[go: nahoru, domu]

Utilities.java revision 59924fe0d9136cf349759bea1e06b661603f95fe
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.recents.misc;
18
19import android.animation.Animator;
20import android.animation.AnimatorSet;
21import android.annotation.FloatRange;
22import android.content.res.Resources;
23import android.graphics.Color;
24import android.graphics.Rect;
25import android.graphics.RectF;
26import android.graphics.drawable.Drawable;
27import android.util.ArraySet;
28import android.util.IntProperty;
29import android.util.Property;
30import android.util.TypedValue;
31import android.view.View;
32import android.view.ViewParent;
33
34import com.android.systemui.recents.model.Task;
35import com.android.systemui.recents.views.TaskViewTransform;
36
37import java.util.ArrayList;
38import java.util.Collections;
39import java.util.List;
40
41/* Common code */
42public class Utilities {
43
44    public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
45            new IntProperty<Drawable>("drawableAlpha") {
46                @Override
47                public void setValue(Drawable object, int alpha) {
48                    object.setAlpha(alpha);
49                }
50
51                @Override
52                public Integer get(Drawable object) {
53                    return object.getAlpha();
54                }
55            };
56
57    public static final Property<Drawable, Rect> DRAWABLE_RECT =
58            new Property<Drawable, Rect>(Rect.class, "drawableBounds") {
59                @Override
60                public void set(Drawable object, Rect bounds) {
61                    object.setBounds(bounds);
62                }
63
64                @Override
65                public Rect get(Drawable object) {
66                    return object.getBounds();
67                }
68            };
69
70    public static final RectFEvaluator RECTF_EVALUATOR = new RectFEvaluator();
71
72    public static final Rect EMPTY_RECT = new Rect();
73
74    /**
75     * @return the first parent walking up the view hierarchy that has the given class type.
76     *
77     * @param parentClass must be a class derived from {@link View}
78     */
79    public static <T extends View> T findParent(View v, Class<T> parentClass) {
80        ViewParent parent = v.getParent();
81        while (parent != null) {
82            if (parent.getClass().equals(parentClass)) {
83                return (T) parent;
84            }
85            parent = parent.getParent();
86        }
87        return null;
88    }
89
90    /**
91     * Initializes the {@param setOut} with the given object.
92     */
93    public static <T> ArraySet<T> objectToSet(T obj, ArraySet<T> setOut) {
94        setOut.clear();
95        if (obj != null) {
96            setOut.add(obj);
97        }
98        return setOut;
99    }
100
101    /**
102     * Replaces the contents of {@param setOut} with the contents of the {@param array}.
103     */
104    public static <T> ArraySet<T> arrayToSet(T[] array, ArraySet<T> setOut) {
105        setOut.clear();
106        if (array != null) {
107            Collections.addAll(setOut, array);
108        }
109        return setOut;
110    }
111
112    /**
113     * @return the clamped {@param value} between the provided {@param min} and {@param max}.
114     */
115    public static float clamp(float value, float min, float max) {
116        return Math.max(min, Math.min(max, value));
117    }
118
119    /**
120     * @return the clamped {@param value} between the provided {@param min} and {@param max}.
121     */
122    public static int clamp(int value, int min, int max) {
123        return Math.max(min, Math.min(max, value));
124    }
125
126    /**
127     * @return the clamped {@param value} between 0 and 1.
128     */
129    public static float clamp01(float value) {
130        return Math.max(0f, Math.min(1f, value));
131    }
132
133    /**
134     * Scales the {@param value} to be proportionally between the {@param min} and
135     * {@param max} values.
136     *
137     * @param value must be between 0 and 1
138     */
139    public static float mapRange(@FloatRange(from=0.0,to=1.0) float value, float min, float max) {
140        return min + (value * (max - min));
141    }
142
143    /**
144     * Scales the {@param value} proportionally from {@param min} and {@param max} to 0 and 1.
145     *
146     * @param value must be between {@param min} and {@param max}
147     */
148    public static float unmapRange(float value, float min, float max) {
149        return (value - min) / (max - min);
150    }
151
152    /** Scales a rect about its centroid */
153    public static void scaleRectAboutCenter(RectF r, float scale) {
154        if (scale != 1.0f) {
155            float cx = r.centerX();
156            float cy = r.centerY();
157            r.offset(-cx, -cy);
158            r.left *= scale;
159            r.top *= scale;
160            r.right *= scale;
161            r.bottom *= scale;
162            r.offset(cx, cy);
163        }
164    }
165
166    /** Calculates the constrast between two colors, using the algorithm provided by the WCAG v2. */
167    public static float computeContrastBetweenColors(int bg, int fg) {
168        float bgR = Color.red(bg) / 255f;
169        float bgG = Color.green(bg) / 255f;
170        float bgB = Color.blue(bg) / 255f;
171        bgR = (bgR < 0.03928f) ? bgR / 12.92f : (float) Math.pow((bgR + 0.055f) / 1.055f, 2.4f);
172        bgG = (bgG < 0.03928f) ? bgG / 12.92f : (float) Math.pow((bgG + 0.055f) / 1.055f, 2.4f);
173        bgB = (bgB < 0.03928f) ? bgB / 12.92f : (float) Math.pow((bgB + 0.055f) / 1.055f, 2.4f);
174        float bgL = 0.2126f * bgR + 0.7152f * bgG + 0.0722f * bgB;
175
176        float fgR = Color.red(fg) / 255f;
177        float fgG = Color.green(fg) / 255f;
178        float fgB = Color.blue(fg) / 255f;
179        fgR = (fgR < 0.03928f) ? fgR / 12.92f : (float) Math.pow((fgR + 0.055f) / 1.055f, 2.4f);
180        fgG = (fgG < 0.03928f) ? fgG / 12.92f : (float) Math.pow((fgG + 0.055f) / 1.055f, 2.4f);
181        fgB = (fgB < 0.03928f) ? fgB / 12.92f : (float) Math.pow((fgB + 0.055f) / 1.055f, 2.4f);
182        float fgL = 0.2126f * fgR + 0.7152f * fgG + 0.0722f * fgB;
183
184        return Math.abs((fgL + 0.05f) / (bgL + 0.05f));
185    }
186
187    /** Returns the base color overlaid with another overlay color with a specified alpha. */
188    public static int getColorWithOverlay(int baseColor, int overlayColor, float overlayAlpha) {
189        return Color.rgb(
190            (int) (overlayAlpha * Color.red(baseColor) +
191                    (1f - overlayAlpha) * Color.red(overlayColor)),
192            (int) (overlayAlpha * Color.green(baseColor) +
193                    (1f - overlayAlpha) * Color.green(overlayColor)),
194            (int) (overlayAlpha * Color.blue(baseColor) +
195                    (1f - overlayAlpha) * Color.blue(overlayColor)));
196    }
197
198    /**
199     * Cancels an animation ensuring that if it has listeners, onCancel and onEnd
200     * are not called.
201     */
202    public static void cancelAnimationWithoutCallbacks(Animator animator) {
203        if (animator != null && animator.isStarted()) {
204            removeAnimationListenersRecursive(animator);
205            animator.cancel();
206        }
207    }
208
209    /**
210     * Recursively removes all the listeners of all children of this animator
211     */
212    public static void removeAnimationListenersRecursive(Animator animator) {
213        if (animator instanceof AnimatorSet) {
214            ArrayList<Animator> animators = ((AnimatorSet) animator).getChildAnimations();
215            for (int i = animators.size() - 1; i >= 0; i--) {
216                removeAnimationListenersRecursive(animators.get(i));
217            }
218        }
219        animator.removeAllListeners();
220    }
221
222    /**
223     * Updates {@param transforms} to be the same size as {@param tasks}.
224     */
225    public static void matchTaskListSize(List<Task> tasks, List<TaskViewTransform> transforms) {
226        // We can reuse the task transforms where possible to reduce object allocation
227        int taskTransformCount = transforms.size();
228        int taskCount = tasks.size();
229        if (taskTransformCount < taskCount) {
230            // If there are less transforms than tasks, then add as many transforms as necessary
231            for (int i = taskTransformCount; i < taskCount; i++) {
232                transforms.add(new TaskViewTransform());
233            }
234        } else if (taskTransformCount > taskCount) {
235            // If there are more transforms than tasks, then just subset the transform list
236            transforms.subList(taskCount, taskTransformCount).clear();
237        }
238    }
239
240    /**
241     * Used for debugging, converts DP to PX.
242     */
243    public static float dpToPx(Resources res, float dp) {
244        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics());
245    }
246}
247