blob: c86b0e1e74f57c3f728d0047f16545f66fd87053 [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
17package com.android.systemui.recents.views;
18
Winson Chung303e1ff2014-03-07 15:06:19 -080019import android.content.Context;
20import android.graphics.Canvas;
Winson Chung303e1ff2014-03-07 15:06:19 -080021import android.graphics.Path;
Winson Chung303e1ff2014-03-07 15:06:19 -080022import android.graphics.Rect;
23import android.graphics.RectF;
Winson Chung37c8d8e2014-03-24 14:53:07 -070024import android.util.AttributeSet;
Winson Chung303e1ff2014-03-07 15:06:19 -080025import android.view.View;
26import android.view.animation.AccelerateDecelerateInterpolator;
Winson Chung303e1ff2014-03-07 15:06:19 -080027import android.view.animation.DecelerateInterpolator;
28import android.widget.FrameLayout;
Winson Chung37c8d8e2014-03-24 14:53:07 -070029import com.android.systemui.R;
Winson Chung303e1ff2014-03-07 15:06:19 -080030import com.android.systemui.recents.Constants;
31import com.android.systemui.recents.RecentsConfiguration;
32import com.android.systemui.recents.model.Task;
Winson Chung303e1ff2014-03-07 15:06:19 -080033
Winson Chung303e1ff2014-03-07 15:06:19 -080034
Winson Chung37c8d8e2014-03-24 14:53:07 -070035/* A task view */
36public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
37 /** The TaskView callbacks */
38 interface TaskViewCallbacks {
39 public void onTaskIconClicked(TaskView tv);
40 // public void onTaskViewReboundToTask(TaskView tv, Task t);
41 }
42
Winson Chung303e1ff2014-03-07 15:06:19 -080043 Task mTask;
Winson Chung37c8d8e2014-03-24 14:53:07 -070044 boolean mTaskDataLoaded;
45
46 TaskThumbnailView mThumbnailView;
47 TaskBarView mBarView;
48 TaskViewCallbacks mCb;
Winson Chung303e1ff2014-03-07 15:06:19 -080049
50 Path mRoundedRectClipPath = new Path();
51
Winson Chung37c8d8e2014-03-24 14:53:07 -070052
53 public TaskView(Context context) {
54 this(context, null);
Winson Chung303e1ff2014-03-07 15:06:19 -080055 }
56
Winson Chung37c8d8e2014-03-24 14:53:07 -070057 public TaskView(Context context, AttributeSet attrs) {
58 this(context, attrs, 0);
59 }
Winson Chung303e1ff2014-03-07 15:06:19 -080060
Winson Chung37c8d8e2014-03-24 14:53:07 -070061 public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
62 this(context, attrs, defStyleAttr, 0);
63 }
64
65 public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
66 super(context, attrs, defStyleAttr, defStyleRes);
67 setWillNotDraw(false);
68 }
69
70 @Override
71 protected void onFinishInflate() {
72 // Bind the views
73 mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);
74 mBarView = (TaskBarView) findViewById(R.id.task_view_bar);
75 if (mTaskDataLoaded) {
76 onTaskDataLoaded(false);
Winson Chung303e1ff2014-03-07 15:06:19 -080077 }
78 }
79
Winson Chung303e1ff2014-03-07 15:06:19 -080080 @Override
81 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
82 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
83
84 // Update the rounded rect clip path
85 RecentsConfiguration config = RecentsConfiguration.getInstance();
86 float radius = config.pxFromDp(Constants.Values.TaskView.RoundedCornerRadiusDps);
87 mRoundedRectClipPath.reset();
88 mRoundedRectClipPath.addRoundRect(new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()),
89 radius, radius, Path.Direction.CW);
90 }
91
92 @Override
93 protected void onDraw(Canvas canvas) {
94 if (Constants.Values.TaskView.UseRoundedCorners) {
95 canvas.clipPath(mRoundedRectClipPath);
96 }
97
98 super.onDraw(canvas);
Winson Chung303e1ff2014-03-07 15:06:19 -080099 }
100
Winson Chung04dfe0d2014-03-14 14:06:29 -0700101 /** Set callback */
102 void setCallbacks(TaskViewCallbacks cb) {
Winson Chung303e1ff2014-03-07 15:06:19 -0800103 mCb = cb;
104 }
105
Winson Chung303e1ff2014-03-07 15:06:19 -0800106 /** Gets the task */
107 Task getTask() {
108 return mTask;
109 }
110
111 /** Synchronizes this view's properties with the task's transform */
112 void updateViewPropertiesFromTask(TaskViewTransform animateFromTransform,
113 TaskViewTransform transform, int duration) {
114 if (duration > 0) {
115 if (animateFromTransform != null) {
116 setTranslationY(animateFromTransform.translationY);
117 setScaleX(animateFromTransform.scale);
118 setScaleY(animateFromTransform.scale);
119 }
120 animate().translationY(transform.translationY)
121 .scaleX(transform.scale)
122 .scaleY(transform.scale)
123 .setDuration(duration)
124 .setInterpolator(new AccelerateDecelerateInterpolator())
125 .start();
126 } else {
127 setTranslationY(transform.translationY);
128 setScaleX(transform.scale);
129 setScaleY(transform.scale);
130 }
131 }
132
133 /** Resets this view's properties */
134 void resetViewProperties() {
135 setTranslationX(0f);
136 setTranslationY(0f);
137 setScaleX(1f);
138 setScaleY(1f);
139 setAlpha(1f);
140 }
141
142 /** Animates this task view as it enters recents */
143 public void animateOnEnterRecents() {
Winson Chung37c8d8e2014-03-24 14:53:07 -0700144 RecentsConfiguration config = RecentsConfiguration.getInstance();
145 int translate = config.pxFromDp(10);
146 mBarView.setScaleX(1.25f);
147 mBarView.setScaleY(1.25f);
148 mBarView.setAlpha(0f);
149 mBarView.setTranslationX(translate / 2);
150 mBarView.setTranslationY(-translate);
151 mBarView.animate()
152 .alpha(1f)
153 .scaleX(1f)
154 .scaleY(1f)
155 .translationX(0)
156 .translationY(0)
157 .setStartDelay(235)
158 .setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
159 .withLayer()
160 .start();
Winson Chung303e1ff2014-03-07 15:06:19 -0800161 }
162
163 /** Animates this task view as it exits recents */
164 public void animateOnLeavingRecents(final Runnable r) {
Winson Chung37c8d8e2014-03-24 14:53:07 -0700165 RecentsConfiguration config = RecentsConfiguration.getInstance();
166 int translate = config.pxFromDp(10);
167 mBarView.animate()
168 .alpha(0f)
169 .scaleX(1.1f)
170 .scaleY(1.1f)
171 .translationX(translate / 2)
172 .translationY(-translate)
173 .setStartDelay(0)
174 .setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
175 .setInterpolator(new DecelerateInterpolator())
176 .withLayer()
177 .withEndAction(r)
178 .start();
Winson Chung303e1ff2014-03-07 15:06:19 -0800179 }
180
181 /** Returns the rect we want to clip (it may not be the full rect) */
182 Rect getClippingRect(Rect outRect, boolean accountForRoundedRects) {
183 getHitRect(outRect);
184 // XXX: We should get the hit rect of the thumbnail view and intersect, but this is faster
185 outRect.right = outRect.left + mThumbnailView.getRight();
186 outRect.bottom = outRect.top + mThumbnailView.getBottom();
187 // We need to shrink the next rect by the rounded corners since those are draw on
188 // top of the current view
189 if (accountForRoundedRects) {
190 RecentsConfiguration config = RecentsConfiguration.getInstance();
191 float radius = config.pxFromDp(Constants.Values.TaskView.RoundedCornerRadiusDps);
192 outRect.inset((int) radius, (int) radius);
193 }
194 return outRect;
195 }
196
197 /** Enable the hw layers on this task view */
198 void enableHwLayers() {
Winson Chung303e1ff2014-03-07 15:06:19 -0800199 mThumbnailView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
200 }
201
202 /** Disable the hw layers on this task view */
203 void disableHwLayers() {
Winson Chung303e1ff2014-03-07 15:06:19 -0800204 mThumbnailView.setLayerType(View.LAYER_TYPE_NONE, null);
205 }
206
Winson Chung4d7b0922014-03-13 17:14:17 -0700207 /**** TaskCallbacks Implementation ****/
208
Winson Chung04dfe0d2014-03-14 14:06:29 -0700209 /** Binds this task view to the task */
210 public void onTaskBound(Task t) {
211 mTask = t;
212 mTask.setCallbacks(this);
Winson Chung303e1ff2014-03-07 15:06:19 -0800213 }
214
215 @Override
Winson Chung4c71aef2014-03-21 15:15:11 -0700216 public void onTaskDataLoaded(boolean reloadingTaskData) {
Winson Chung37c8d8e2014-03-24 14:53:07 -0700217 if (mThumbnailView != null && mBarView != null) {
218 // Bind each of the views to the new task data
219 mThumbnailView.rebindToTask(mTask, reloadingTaskData);
220 mBarView.rebindToTask(mTask, reloadingTaskData);
221 }
222 mTaskDataLoaded = true;
Winson Chung4d7b0922014-03-13 17:14:17 -0700223 }
224
225 @Override
Winson Chung04dfe0d2014-03-14 14:06:29 -0700226 public void onTaskDataUnloaded() {
Winson Chung37c8d8e2014-03-24 14:53:07 -0700227 if (mThumbnailView != null && mBarView != null) {
228 // Unbind each of the views from the task data and remove the task callback
229 mTask.setCallbacks(null);
230 mThumbnailView.unbindFromTask();
231 mBarView.unbindFromTask();
232 }
233 mTaskDataLoaded = false;
Winson Chung4d7b0922014-03-13 17:14:17 -0700234 }
235
236 @Override
Winson Chung303e1ff2014-03-07 15:06:19 -0800237 public void onClick(View v) {
238 mCb.onTaskIconClicked(this);
239 }
240}