blob: e86b92dd39b5a010a899075a39316b2531641651 [file] [log] [blame]
Winson Chung303e1ff2014-03-07 15:06:19 -08001/*
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
Winson Chungffa2ec62014-07-03 15:54:42 -070017package com.android.systemui.recents.misc;
Winson Chung303e1ff2014-03-07 15:06:19 -080018
Winson Chung353c0b92014-10-16 17:43:23 -070019import android.animation.Animator;
Winson1bcf3c42016-02-10 13:29:39 -080020import android.animation.AnimatorSet;
Winson68088812016-02-12 16:06:04 -080021import android.annotation.FloatRange;
Winson Chungf5e22e72014-05-02 18:35:35 -070022import android.graphics.Color;
Winson3e874742016-01-07 10:08:17 -080023import android.graphics.Rect;
Winson3150e572015-10-23 15:07:24 -070024import android.graphics.RectF;
Winson3e874742016-01-07 10:08:17 -080025import android.graphics.drawable.Drawable;
Winsonc5fd3502016-01-18 15:18:37 -080026import android.util.ArraySet;
Winson3e874742016-01-07 10:08:17 -080027import android.util.IntProperty;
28import android.util.Property;
Winson Chungbf5dbf12014-09-16 00:58:25 +020029import android.view.View;
Winsonbe7607a2015-10-01 17:24:51 -070030import android.view.ViewParent;
Winsonc0d70582016-01-29 10:24:39 -080031
Winsonc5fd3502016-01-18 15:18:37 -080032import com.android.systemui.recents.model.Task;
33import com.android.systemui.recents.views.TaskViewTransform;
34
Winson1bcf3c42016-02-10 13:29:39 -080035import java.util.ArrayList;
Winsonc5fd3502016-01-18 15:18:37 -080036import java.util.Collections;
37import java.util.List;
Winson Chung303e1ff2014-03-07 15:06:19 -080038
39/* Common code */
40public class Utilities {
Winson Chungcdbbb7e2014-06-24 12:11:49 -070041
Winson3e874742016-01-07 10:08:17 -080042 public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
43 new IntProperty<Drawable>("drawableAlpha") {
44 @Override
45 public void setValue(Drawable object, int alpha) {
46 object.setAlpha(alpha);
47 }
48
49 @Override
50 public Integer get(Drawable object) {
51 return object.getAlpha();
52 }
53 };
54
55 public static final Property<Drawable, Rect> DRAWABLE_RECT =
56 new Property<Drawable, Rect>(Rect.class, "drawableBounds") {
57 @Override
58 public void set(Drawable object, Rect bounds) {
59 object.setBounds(bounds);
60 }
61
62 @Override
63 public Rect get(Drawable object) {
64 return object.getBounds();
65 }
66 };
67
Winson05e46ca2016-02-05 15:40:29 -080068 public static final RectFEvaluator RECTF_EVALUATOR = new RectFEvaluator();
69
Winsonbe7607a2015-10-01 17:24:51 -070070 /**
71 * @return the first parent walking up the view hierarchy that has the given class type.
72 *
73 * @param parentClass must be a class derived from {@link View}
74 */
75 public static <T extends View> T findParent(View v, Class<T> parentClass) {
76 ViewParent parent = v.getParent();
77 while (parent != null) {
78 if (parent.getClass().equals(parentClass)) {
79 return (T) parent;
80 }
81 parent = parent.getParent();
82 }
83 return null;
84 }
85
Winsonc5fd3502016-01-18 15:18:37 -080086 /**
87 * Initializes the {@param setOut} with the given object.
88 */
89 public static <T> ArraySet<T> objectToSet(T obj, ArraySet<T> setOut) {
90 setOut.clear();
91 if (obj != null) {
92 setOut.add(obj);
93 }
94 return setOut;
95 }
96
97 /**
98 * Replaces the contents of {@param setOut} with the contents of the {@param array}.
99 */
100 public static <T> ArraySet<T> arrayToSet(T[] array, ArraySet<T> setOut) {
101 setOut.clear();
102 if (array != null) {
103 Collections.addAll(setOut, array);
104 }
105 return setOut;
106 }
107
Winson68088812016-02-12 16:06:04 -0800108 /**
109 * @return the clamped {@param value} between the provided {@param min} and {@param max}.
110 */
111 public static float clamp(float value, float min, float max) {
112 return Math.max(min, Math.min(max, value));
113 }
114
115 /**
116 * @return the clamped {@param value} between the provided {@param min} and {@param max}.
117 */
118 public static int clamp(int value, int min, int max) {
119 return Math.max(min, Math.min(max, value));
120 }
121
122 /**
123 * @return the clamped {@param value} between 0 and 1.
124 */
125 public static float clamp01(float value) {
126 return Math.max(0f, Math.min(1f, value));
127 }
128
129 /**
130 * Scales the {@param value} to be proportionally between the {@param min} and
131 * {@param max} values.
132 *
133 * @param value must be between 0 and 1
134 */
135 public static float mapRange(@FloatRange(from=0.0,to=1.0) float value, float min, float max) {
136 return min + (value * (max - min));
137 }
138
139 /**
140 * Scales the {@param value} proportionally from {@param min} and {@param max} to 0 and 1.
141 *
142 * @param value must be between {@param min} and {@param max}
143 */
144 public static float unmapRange(float value, float min, float max) {
145 return (value - min) / (max - min);
146 }
147
Winson Chung303e1ff2014-03-07 15:06:19 -0800148 /** Scales a rect about its centroid */
Winson3150e572015-10-23 15:07:24 -0700149 public static void scaleRectAboutCenter(RectF r, float scale) {
Winson Chung303e1ff2014-03-07 15:06:19 -0800150 if (scale != 1.0f) {
Winson3150e572015-10-23 15:07:24 -0700151 float cx = r.centerX();
152 float cy = r.centerY();
Winson Chung303e1ff2014-03-07 15:06:19 -0800153 r.offset(-cx, -cy);
Winson3150e572015-10-23 15:07:24 -0700154 r.left *= scale;
155 r.top *= scale;
156 r.right *= scale;
157 r.bottom *= scale;
Winson Chung303e1ff2014-03-07 15:06:19 -0800158 r.offset(cx, cy);
159 }
160 }
Winson Chungf5e22e72014-05-02 18:35:35 -0700161
Winson Chung93748a12014-07-13 17:43:31 -0700162 /** Calculates the constrast between two colors, using the algorithm provided by the WCAG v2. */
163 public static float computeContrastBetweenColors(int bg, int fg) {
164 float bgR = Color.red(bg) / 255f;
165 float bgG = Color.green(bg) / 255f;
166 float bgB = Color.blue(bg) / 255f;
167 bgR = (bgR < 0.03928f) ? bgR / 12.92f : (float) Math.pow((bgR + 0.055f) / 1.055f, 2.4f);
168 bgG = (bgG < 0.03928f) ? bgG / 12.92f : (float) Math.pow((bgG + 0.055f) / 1.055f, 2.4f);
169 bgB = (bgB < 0.03928f) ? bgB / 12.92f : (float) Math.pow((bgB + 0.055f) / 1.055f, 2.4f);
170 float bgL = 0.2126f * bgR + 0.7152f * bgG + 0.0722f * bgB;
171
172 float fgR = Color.red(fg) / 255f;
173 float fgG = Color.green(fg) / 255f;
174 float fgB = Color.blue(fg) / 255f;
175 fgR = (fgR < 0.03928f) ? fgR / 12.92f : (float) Math.pow((fgR + 0.055f) / 1.055f, 2.4f);
176 fgG = (fgG < 0.03928f) ? fgG / 12.92f : (float) Math.pow((fgG + 0.055f) / 1.055f, 2.4f);
177 fgB = (fgB < 0.03928f) ? fgB / 12.92f : (float) Math.pow((fgB + 0.055f) / 1.055f, 2.4f);
178 float fgL = 0.2126f * fgR + 0.7152f * fgG + 0.0722f * fgB;
Winson Chungf5e22e72014-05-02 18:35:35 -0700179
Winson Chung93748a12014-07-13 17:43:31 -0700180 return Math.abs((fgL + 0.05f) / (bgL + 0.05f));
Winson Chungf5e22e72014-05-02 18:35:35 -0700181 }
Winson Chungcdbbb7e2014-06-24 12:11:49 -0700182
Winson Chunga0e88b52014-08-11 19:25:42 -0700183 /** Returns the base color overlaid with another overlay color with a specified alpha. */
184 public static int getColorWithOverlay(int baseColor, int overlayColor, float overlayAlpha) {
185 return Color.rgb(
186 (int) (overlayAlpha * Color.red(baseColor) +
187 (1f - overlayAlpha) * Color.red(overlayColor)),
188 (int) (overlayAlpha * Color.green(baseColor) +
189 (1f - overlayAlpha) * Color.green(overlayColor)),
190 (int) (overlayAlpha * Color.blue(baseColor) +
191 (1f - overlayAlpha) * Color.blue(overlayColor)));
192 }
193
Winson Chung353c0b92014-10-16 17:43:23 -0700194 /**
195 * Cancels an animation ensuring that if it has listeners, onCancel and onEnd
196 * are not called.
197 */
198 public static void cancelAnimationWithoutCallbacks(Animator animator) {
199 if (animator != null) {
Winson1bcf3c42016-02-10 13:29:39 -0800200 removeAnimationListenersRecursive(animator);
Winson Chung353c0b92014-10-16 17:43:23 -0700201 animator.cancel();
202 }
203 }
Winsonc5fd3502016-01-18 15:18:37 -0800204
205 /**
Winson1bcf3c42016-02-10 13:29:39 -0800206 * Recursively removes all the listeners of all children of this animator
207 */
208 public static void removeAnimationListenersRecursive(Animator animator) {
209 if (animator instanceof AnimatorSet) {
210 ArrayList<Animator> animators = ((AnimatorSet) animator).getChildAnimations();
211 for (int i = animators.size() - 1; i >= 0; i--) {
212 removeAnimationListenersRecursive(animators.get(i));
213 }
214 }
215 animator.removeAllListeners();
216 }
217
218 /**
Winsonc5fd3502016-01-18 15:18:37 -0800219 * Updates {@param transforms} to be the same size as {@param tasks}.
220 */
221 public static void matchTaskListSize(List<Task> tasks, List<TaskViewTransform> transforms) {
222 // We can reuse the task transforms where possible to reduce object allocation
223 int taskTransformCount = transforms.size();
224 int taskCount = tasks.size();
225 if (taskTransformCount < taskCount) {
226 // If there are less transforms than tasks, then add as many transforms as necessary
227 for (int i = taskTransformCount; i < taskCount; i++) {
228 transforms.add(new TaskViewTransform());
229 }
230 } else if (taskTransformCount > taskCount) {
231 // If there are more transforms than tasks, then just subset the transform list
232 transforms.subList(taskCount, taskTransformCount).clear();
233 }
234 }
Winson Chung303e1ff2014-03-07 15:06:19 -0800235}