blob: 185b49b088a5e473bbbaabbd2bb8273001390f3c [file] [log] [blame]
Winson Chung82f55532011-08-09 14:14:23 -07001/*
2 * Copyright (C) 2011 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
Daniel Sandler325dc232013-06-05 22:57:57 -040017package com.android.launcher3;
Winson Chung82f55532011-08-09 14:14:23 -070018
Winson Chungaf40f202013-09-18 18:26:31 -070019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
Winson Chung3a6e7f32013-10-09 15:50:52 -070021import android.content.ComponentName;
Michael Jurka34c2e6c2013-12-13 16:07:45 +010022import android.content.Context;
Winson Chung3a6e7f32013-10-09 15:50:52 -070023import android.content.Intent;
Winson Chung82f55532011-08-09 14:14:23 -070024import android.content.res.Resources;
25import android.content.res.TypedArray;
Winson Chung3a6e7f32013-10-09 15:50:52 -070026import android.graphics.*;
Winson Chung82f55532011-08-09 14:14:23 -070027import android.graphics.drawable.Drawable;
28import android.util.AttributeSet;
29import android.util.DisplayMetrics;
Svetoslav Ganov55d225d2012-05-22 15:19:14 -070030import android.view.FocusFinder;
31import android.view.MotionEvent;
32import android.view.View;
Winson Chungaf40f202013-09-18 18:26:31 -070033import android.view.animation.AccelerateInterpolator;
Winson Chung82f55532011-08-09 14:14:23 -070034import android.widget.FrameLayout;
Winson Chung3a6e7f32013-10-09 15:50:52 -070035import android.widget.TextView;
Winson Chung82f55532011-08-09 14:14:23 -070036
Winson Chung3a6e7f32013-10-09 15:50:52 -070037public class Cling extends FrameLayout implements Insettable, View.OnClickListener,
38 View.OnLongClickListener, View.OnTouchListener {
Winson Chung82f55532011-08-09 14:14:23 -070039
Winson Chungaf40f202013-09-18 18:26:31 -070040 private static String FIRST_RUN_PORTRAIT = "first_run_portrait";
41 private static String FIRST_RUN_LANDSCAPE = "first_run_landscape";
Winson Chung7d7541e2011-09-16 20:14:36 -070042
Winson Chung82f55532011-08-09 14:14:23 -070043 private static String WORKSPACE_PORTRAIT = "workspace_portrait";
44 private static String WORKSPACE_LANDSCAPE = "workspace_landscape";
Andrew Flynn2f5f9452012-05-12 17:00:35 -070045 private static String WORKSPACE_LARGE = "workspace_large";
46 private static String WORKSPACE_CUSTOM = "workspace_custom";
47
Winson Chunga6945242014-01-08 14:04:34 -080048 private static String MIGRATION_PORTRAIT = "migration_portrait";
49 private static String MIGRATION_LANDSCAPE = "migration_landscape";
50
51 private static String MIGRATION_WORKSPACE_PORTRAIT = "migration_workspace_portrait";
52 private static String MIGRATION_WORKSPACE_LANDSCAPE = "migration_workspace_landscape";
53
Winson Chung7d7541e2011-09-16 20:14:36 -070054 private static String FOLDER_PORTRAIT = "folder_portrait";
55 private static String FOLDER_LANDSCAPE = "folder_landscape";
Winson Chungd0160152011-11-15 15:04:42 -080056 private static String FOLDER_LARGE = "folder_large";
Winson Chung82f55532011-08-09 14:14:23 -070057
Winson Chunge6eabff2013-09-24 11:01:23 -070058 private static float FIRST_RUN_CIRCLE_BUFFER_DPS = 60;
Winson Chungaf40f202013-09-18 18:26:31 -070059 private static float WORKSPACE_INNER_CIRCLE_RADIUS_DPS = 50;
60 private static float WORKSPACE_OUTER_CIRCLE_RADIUS_DPS = 60;
61 private static float WORKSPACE_CIRCLE_Y_OFFSET_DPS = 30;
Winson Chunga6945242014-01-08 14:04:34 -080062 private static float MIGRATION_WORKSPACE_INNER_CIRCLE_RADIUS_DPS = 42;
63 private static float MIGRATION_WORKSPACE_OUTER_CIRCLE_RADIUS_DPS = 46;
Winson Chungaf40f202013-09-18 18:26:31 -070064
Winson Chung82f55532011-08-09 14:14:23 -070065 private Launcher mLauncher;
66 private boolean mIsInitialized;
67 private String mDrawIdentifier;
Winson Chung7d7541e2011-09-16 20:14:36 -070068 private Drawable mBackground;
Winson Chung82f55532011-08-09 14:14:23 -070069
Winson Chung3a6e7f32013-10-09 15:50:52 -070070 private int[] mTouchDownPt = new int[2];
71
72 private Drawable mFocusedHotseatApp;
73 private ComponentName mFocusedHotseatAppComponent;
74 private Rect mFocusedHotseatAppBounds;
75
Winson Chung7d7541e2011-09-16 20:14:36 -070076 private Paint mErasePaint;
Winson Chunga6945242014-01-08 14:04:34 -080077 private Paint mBorderPaint;
Winson Chungaf40f202013-09-18 18:26:31 -070078 private Paint mBubblePaint;
79 private Paint mDotPaint;
80
Winson Chungfa545132013-09-26 17:45:32 -070081 private View mScrimView;
82 private int mBackgroundColor;
83
Winson Chungaf40f202013-09-18 18:26:31 -070084 private final Rect mInsets = new Rect();
Winson Chung7d7541e2011-09-16 20:14:36 -070085
Winson Chung82f55532011-08-09 14:14:23 -070086 public Cling(Context context) {
87 this(context, null, 0);
88 }
89
90 public Cling(Context context, AttributeSet attrs) {
91 this(context, attrs, 0);
92 }
93
94 public Cling(Context context, AttributeSet attrs, int defStyle) {
95 super(context, attrs, defStyle);
96
97 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Cling, defStyle, 0);
98 mDrawIdentifier = a.getString(R.styleable.Cling_drawIdentifier);
99 a.recycle();
Michael Jurka9bc8eba2012-05-21 20:36:44 -0700100
101 setClickable(true);
Winson Chungaf40f202013-09-18 18:26:31 -0700102
Winson Chung82f55532011-08-09 14:14:23 -0700103 }
104
Winson Chungfa545132013-09-26 17:45:32 -0700105 void init(Launcher l, View scrim) {
Winson Chung82f55532011-08-09 14:14:23 -0700106 if (!mIsInitialized) {
107 mLauncher = l;
Winson Chungfa545132013-09-26 17:45:32 -0700108 mScrimView = scrim;
109 mBackgroundColor = 0xdd000000;
Winson Chungaf40f202013-09-18 18:26:31 -0700110 setOnLongClickListener(this);
Winson Chung3a6e7f32013-10-09 15:50:52 -0700111 setOnClickListener(this);
112 setOnTouchListener(this);
Winson Chung82f55532011-08-09 14:14:23 -0700113
Winson Chung7d7541e2011-09-16 20:14:36 -0700114 mErasePaint = new Paint();
115 mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
116 mErasePaint.setColor(0xFFFFFF);
117 mErasePaint.setAlpha(0);
Winson Chungaf40f202013-09-18 18:26:31 -0700118 mErasePaint.setAntiAlias(true);
119
Winson Chunga6945242014-01-08 14:04:34 -0800120 mBorderPaint = new Paint();
121 mBorderPaint.setColor(0xFFFFFFFF);
122 mBorderPaint.setAntiAlias(true);
123
Winson Chunge6eabff2013-09-24 11:01:23 -0700124 int circleColor = getResources().getColor(
125 R.color.first_run_cling_circle_background_color);
Winson Chungaf40f202013-09-18 18:26:31 -0700126 mBubblePaint = new Paint();
Winson Chunge6eabff2013-09-24 11:01:23 -0700127 mBubblePaint.setColor(circleColor);
Winson Chungaf40f202013-09-18 18:26:31 -0700128 mBubblePaint.setAntiAlias(true);
129
130 mDotPaint = new Paint();
131 mDotPaint.setColor(0x72BBED);
132 mDotPaint.setAntiAlias(true);
Winson Chung7d7541e2011-09-16 20:14:36 -0700133
Winson Chung82f55532011-08-09 14:14:23 -0700134 mIsInitialized = true;
135 }
136 }
137
Winson Chung3a6e7f32013-10-09 15:50:52 -0700138 void setFocusedHotseatApp(int drawableId, int appRank, ComponentName cn, String title,
139 String description) {
140 // Get the app to draw
141 Resources r = getResources();
142 int appIconId = drawableId;
143 Hotseat hotseat = mLauncher.getHotseat();
144 if (hotseat != null && appIconId > -1 && appRank > -1 && !title.isEmpty() &&
145 !description.isEmpty()) {
146 // Set the app bounds
147 int x = hotseat.getCellXFromOrder(appRank);
148 int y = hotseat.getCellYFromOrder(appRank);
149 Rect pos = hotseat.getCellCoordinates(x, y);
150 LauncherAppState app = LauncherAppState.getInstance();
151 DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
152 mFocusedHotseatApp = getResources().getDrawable(appIconId);
153 mFocusedHotseatAppComponent = cn;
154 mFocusedHotseatAppBounds = new Rect(pos.left, pos.top,
155 pos.left + Utilities.sIconTextureWidth,
156 pos.top + Utilities.sIconTextureHeight);
157 Utilities.scaleRectAboutCenter(mFocusedHotseatAppBounds,
Winson Chung6e1c0d32013-10-25 15:24:24 -0700158 ((float) grid.hotseatIconSizePx / grid.iconSizePx));
Winson Chung3a6e7f32013-10-09 15:50:52 -0700159
160 // Set the title
161 TextView v = (TextView) findViewById(R.id.focused_hotseat_app_title);
162 if (v != null) {
163 v.setText(title);
164 }
165
166 // Set the description
167 v = (TextView) findViewById(R.id.focused_hotseat_app_description);
168 if (v != null) {
169 v.setText(description);
170 }
171
172 // Show the bubble
173 View bubble = findViewById(R.id.focused_hotseat_app_bubble);
174 bubble.setVisibility(View.VISIBLE);
175 }
176 }
177
Winson Chunga6945242014-01-08 14:04:34 -0800178 void updateMigrationWorkspaceBubblePosition() {
179 DisplayMetrics metrics = new DisplayMetrics();
180 mLauncher.getWindowManager().getDefaultDisplay().getMetrics(metrics);
181
182 // Get the page indicator bounds
183 LauncherAppState app = LauncherAppState.getInstance();
184 DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
185 Rect pageIndicatorBounds = grid.getWorkspacePageIndicatorBounds(mInsets);
186
187 View bubble = findViewById(R.id.migration_workspace_cling_bubble);
188 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) bubble.getLayoutParams();
189 lp.bottomMargin = grid.heightPx - pageIndicatorBounds.top;
190 bubble.requestLayout();
191 }
192
Winson Chungaf40f202013-09-18 18:26:31 -0700193 void show(boolean animate, int duration) {
194 setVisibility(View.VISIBLE);
195 setLayerType(View.LAYER_TYPE_HARDWARE, null);
196 if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
197 mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
198 mDrawIdentifier.equals(WORKSPACE_LARGE) ||
Winson Chunga6945242014-01-08 14:04:34 -0800199 mDrawIdentifier.equals(WORKSPACE_CUSTOM) ||
200 mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) ||
201 mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
Winson Chungaf40f202013-09-18 18:26:31 -0700202 View content = getContent();
203 content.setAlpha(0f);
204 content.animate()
205 .alpha(1f)
206 .setDuration(duration)
Winson Chungfa545132013-09-26 17:45:32 -0700207 .setListener(null)
Winson Chungaf40f202013-09-18 18:26:31 -0700208 .start();
209 setAlpha(1f);
210 } else {
211 if (animate) {
212 buildLayer();
213 setAlpha(0f);
214 animate()
215 .alpha(1f)
216 .setInterpolator(new AccelerateInterpolator())
217 .setDuration(duration)
Winson Chungfa545132013-09-26 17:45:32 -0700218 .setListener(null)
Winson Chungaf40f202013-09-18 18:26:31 -0700219 .start();
220 } else {
221 setAlpha(1f);
222 }
223 }
Winson Chungfa545132013-09-26 17:45:32 -0700224
225 // Show the scrim if necessary
226 if (mScrimView != null) {
227 mScrimView.setVisibility(View.VISIBLE);
228 mScrimView.setAlpha(0f);
229 mScrimView.animate()
230 .alpha(1f)
231 .setDuration(duration)
232 .setListener(null)
233 .start();
234 }
235
Winson Chungaf40f202013-09-18 18:26:31 -0700236 setFocusableInTouchMode(true);
237 post(new Runnable() {
238 public void run() {
239 setFocusable(true);
240 requestFocus();
241 }
242 });
243 }
244
245 void hide(final int duration, final Runnable postCb) {
246 if (mDrawIdentifier.equals(FIRST_RUN_PORTRAIT) ||
Winson Chunga6945242014-01-08 14:04:34 -0800247 mDrawIdentifier.equals(FIRST_RUN_LANDSCAPE) ||
248 mDrawIdentifier.equals(MIGRATION_PORTRAIT) ||
249 mDrawIdentifier.equals(MIGRATION_LANDSCAPE)) {
Winson Chungaf40f202013-09-18 18:26:31 -0700250 View content = getContent();
Winson Chungfa545132013-09-26 17:45:32 -0700251 content.animate()
252 .alpha(0f)
253 .setDuration(duration)
254 .setListener(new AnimatorListenerAdapter() {
255 public void onAnimationEnd(Animator animation) {
256 // We are about to trigger the workspace cling, so don't do anything else
257 setVisibility(View.GONE);
258 postCb.run();
259 };
260 })
261 .start();
Winson Chungaf40f202013-09-18 18:26:31 -0700262 } else {
Winson Chungfa545132013-09-26 17:45:32 -0700263 animate()
264 .alpha(0f)
265 .setDuration(duration)
266 .setListener(new AnimatorListenerAdapter() {
267 public void onAnimationEnd(Animator animation) {
268 // We are about to trigger the workspace cling, so don't do anything else
269 setVisibility(View.GONE);
270 postCb.run();
271 };
272 })
273 .start();
274 }
275
276 // Show the scrim if necessary
277 if (mScrimView != null) {
278 mScrimView.animate()
279 .alpha(0f)
280 .setDuration(duration)
281 .setListener(new AnimatorListenerAdapter() {
282 public void onAnimationEnd(Animator animation) {
283 mScrimView.setVisibility(View.GONE);
284 };
285 })
286 .start();
Winson Chungaf40f202013-09-18 18:26:31 -0700287 }
288 }
289
Winson Chung82f55532011-08-09 14:14:23 -0700290 void cleanup() {
Winson Chung7d7541e2011-09-16 20:14:36 -0700291 mBackground = null;
Winson Chung7d7541e2011-09-16 20:14:36 -0700292 mIsInitialized = false;
293 }
294
Winson Chungfa545132013-09-26 17:45:32 -0700295 void bringScrimToFront() {
296 if (mScrimView != null) {
297 mScrimView.bringToFront();
298 }
299 }
300
Winson Chungaf40f202013-09-18 18:26:31 -0700301 @Override
302 public void setInsets(Rect insets) {
303 mInsets.set(insets);
304 setPadding(insets.left, insets.top, insets.right, insets.bottom);
Michael Jurka974c3862012-05-22 22:00:31 -0700305 }
306
Winson Chungaf40f202013-09-18 18:26:31 -0700307 View getContent() {
308 return findViewById(R.id.content);
309 }
310
311 String getDrawIdentifier() {
312 return mDrawIdentifier;
Winson Chung82f55532011-08-09 14:14:23 -0700313 }
314
315 @Override
Svetoslav Ganov55d225d2012-05-22 15:19:14 -0700316 public View focusSearch(int direction) {
Michael Jurka9bc8eba2012-05-21 20:36:44 -0700317 return this.focusSearch(this, direction);
Svetoslav Ganov55d225d2012-05-22 15:19:14 -0700318 }
319
320 @Override
321 public View focusSearch(View focused, int direction) {
322 return FocusFinder.getInstance().findNextFocus(this, focused, direction);
323 }
324
325 @Override
326 public boolean onHoverEvent(MotionEvent event) {
327 return (mDrawIdentifier.equals(WORKSPACE_PORTRAIT)
328 || mDrawIdentifier.equals(WORKSPACE_LANDSCAPE)
329 || mDrawIdentifier.equals(WORKSPACE_LARGE)
Svetoslav Ganov55d225d2012-05-22 15:19:14 -0700330 || mDrawIdentifier.equals(WORKSPACE_CUSTOM));
331 }
332
333 @Override
Winson Chung82f55532011-08-09 14:14:23 -0700334 public boolean onTouchEvent(android.view.MotionEvent event) {
Winson Chungaf40f202013-09-18 18:26:31 -0700335 if (mDrawIdentifier.equals(FOLDER_PORTRAIT) ||
Winson Chungd0160152011-11-15 15:04:42 -0800336 mDrawIdentifier.equals(FOLDER_LANDSCAPE) ||
337 mDrawIdentifier.equals(FOLDER_LARGE)) {
Winson Chung7d7541e2011-09-16 20:14:36 -0700338 Folder f = mLauncher.getWorkspace().getOpenFolder();
339 if (f != null) {
340 Rect r = new Rect();
341 f.getHitRect(r);
342 if (r.contains((int) event.getX(), (int) event.getY())) {
343 return false;
344 }
345 }
346 }
Winson Chungaf40f202013-09-18 18:26:31 -0700347 return super.onTouchEvent(event);
Winson Chung82f55532011-08-09 14:14:23 -0700348 };
349
350 @Override
Winson Chung3a6e7f32013-10-09 15:50:52 -0700351 public boolean onTouch(View v, MotionEvent ev) {
352 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
353 mTouchDownPt[0] = (int) ev.getX();
354 mTouchDownPt[1] = (int) ev.getY();
355 }
356 return false;
357 }
358
359 @Override
360 public void onClick(View v) {
361 if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
362 mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
363 mDrawIdentifier.equals(WORKSPACE_LARGE)) {
364 if (mFocusedHotseatAppBounds != null &&
365 mFocusedHotseatAppBounds.contains(mTouchDownPt[0], mTouchDownPt[1])) {
366 // Launch the activity that is being highlighted
367 Intent intent = new Intent(Intent.ACTION_MAIN);
368 intent.setComponent(mFocusedHotseatAppComponent);
369 intent.addCategory(Intent.CATEGORY_LAUNCHER);
370 mLauncher.startActivity(intent, null);
Winson Chunga6945242014-01-08 14:04:34 -0800371 mLauncher.getLauncherClings().dismissWorkspaceCling(this);
Winson Chung3a6e7f32013-10-09 15:50:52 -0700372 }
373 }
374 }
375
376 @Override
Winson Chungaf40f202013-09-18 18:26:31 -0700377 public boolean onLongClick(View v) {
378 if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
379 mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
380 mDrawIdentifier.equals(WORKSPACE_LARGE)) {
Winson Chunga6945242014-01-08 14:04:34 -0800381 mLauncher.getLauncherClings().dismissWorkspaceCling(null);
382 return true;
383 } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) ||
384 mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
385 mLauncher.getLauncherClings().dismissMigrationWorkspaceCling(null);
Winson Chungaf40f202013-09-18 18:26:31 -0700386 return true;
387 }
388 return false;
389 }
390
391 @Override
Winson Chung82f55532011-08-09 14:14:23 -0700392 protected void dispatchDraw(Canvas canvas) {
Winson Chung82f55532011-08-09 14:14:23 -0700393 if (mIsInitialized) {
Winson Chungaf40f202013-09-18 18:26:31 -0700394 canvas.save();
Winson Chung82f55532011-08-09 14:14:23 -0700395
Winson Chunga6945242014-01-08 14:04:34 -0800396 // Get the page indicator bounds
397 LauncherAppState app = LauncherAppState.getInstance();
398 DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
399 Rect pageIndicatorBounds = grid.getWorkspacePageIndicatorBounds(mInsets);
400
Winson Chungaf40f202013-09-18 18:26:31 -0700401 // Get the background override if there is one
Winson Chung7d7541e2011-09-16 20:14:36 -0700402 if (mBackground == null) {
Winson Chungaf40f202013-09-18 18:26:31 -0700403 if (mDrawIdentifier.equals(WORKSPACE_CUSTOM)) {
Andrew Flynna743d352012-05-18 13:38:52 -0700404 mBackground = getResources().getDrawable(R.drawable.bg_cling5);
Winson Chung7d7541e2011-09-16 20:14:36 -0700405 }
406 }
Winson Chungaf40f202013-09-18 18:26:31 -0700407 // Draw the background
408 Bitmap eraseBg = null;
409 Canvas eraseCanvas = null;
Winson Chungfa545132013-09-26 17:45:32 -0700410 if (mScrimView != null) {
411 // Skip drawing the background
412 mScrimView.setBackgroundColor(mBackgroundColor);
413 } else if (mBackground != null) {
Winson Chung7d7541e2011-09-16 20:14:36 -0700414 mBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
Winson Chungaf40f202013-09-18 18:26:31 -0700415 mBackground.draw(canvas);
Winson Chungaf40f202013-09-18 18:26:31 -0700416 } else if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
417 mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
Winson Chunga6945242014-01-08 14:04:34 -0800418 mDrawIdentifier.equals(WORKSPACE_LARGE) ||
419 mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) ||
420 mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
Winson Chungaf40f202013-09-18 18:26:31 -0700421 // Initialize the draw buffer (to allow punching through)
422 eraseBg = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
423 Bitmap.Config.ARGB_8888);
424 eraseCanvas = new Canvas(eraseBg);
Winson Chungfa545132013-09-26 17:45:32 -0700425 eraseCanvas.drawColor(mBackgroundColor);
Winson Chung7d7541e2011-09-16 20:14:36 -0700426 } else {
Winson Chungfa545132013-09-26 17:45:32 -0700427 canvas.drawColor(mBackgroundColor);
Winson Chung7d7541e2011-09-16 20:14:36 -0700428 }
Winson Chung82f55532011-08-09 14:14:23 -0700429
Winson Chungaf40f202013-09-18 18:26:31 -0700430 // Draw everything else
431 DisplayMetrics metrics = new DisplayMetrics();
432 mLauncher.getWindowManager().getDefaultDisplay().getMetrics(metrics);
433 float alpha = getAlpha();
434 View content = getContent();
435 if (content != null) {
436 alpha *= content.getAlpha();
437 }
438 if (mDrawIdentifier.equals(FIRST_RUN_PORTRAIT) ||
439 mDrawIdentifier.equals(FIRST_RUN_LANDSCAPE)) {
Winson Chung45cab392013-10-02 17:45:32 -0700440 // Draw the circle
Winson Chungaf40f202013-09-18 18:26:31 -0700441 View bubbleContent = findViewById(R.id.bubble_content);
442 Rect bubbleRect = new Rect();
443 bubbleContent.getGlobalVisibleRect(bubbleRect);
444 mBubblePaint.setAlpha((int) (255 * alpha));
445 float buffer = DynamicGrid.pxFromDp(FIRST_RUN_CIRCLE_BUFFER_DPS, metrics);
446 canvas.drawCircle(metrics.widthPixels / 2,
447 bubbleRect.centerY(),
448 (bubbleContent.getMeasuredWidth() + buffer) / 2,
449 mBubblePaint);
450 } else if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
451 mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
452 mDrawIdentifier.equals(WORKSPACE_LARGE)) {
453 int offset = DynamicGrid.pxFromDp(WORKSPACE_CIRCLE_Y_OFFSET_DPS, metrics);
Winson Chunga6945242014-01-08 14:04:34 -0800454 // Draw the outer circle
455 mErasePaint.setAlpha(128);
Winson Chungaf40f202013-09-18 18:26:31 -0700456 eraseCanvas.drawCircle(metrics.widthPixels / 2,
457 metrics.heightPixels / 2 - offset,
458 DynamicGrid.pxFromDp(WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, metrics),
459 mErasePaint);
Winson Chunga6945242014-01-08 14:04:34 -0800460 // Draw the inner circle
Winson Chungaf40f202013-09-18 18:26:31 -0700461 mErasePaint.setAlpha(0);
462 eraseCanvas.drawCircle(metrics.widthPixels / 2,
463 metrics.heightPixels / 2 - offset,
464 DynamicGrid.pxFromDp(WORKSPACE_INNER_CIRCLE_RADIUS_DPS, metrics),
465 mErasePaint);
466 canvas.drawBitmap(eraseBg, 0, 0, null);
467 eraseCanvas.setBitmap(null);
468 eraseBg = null;
Winson Chung7d7541e2011-09-16 20:14:36 -0700469
Winson Chung3a6e7f32013-10-09 15:50:52 -0700470 // Draw the focused hotseat app icon
471 if (mFocusedHotseatAppBounds != null && mFocusedHotseatApp != null) {
472 mFocusedHotseatApp.setBounds(mFocusedHotseatAppBounds.left,
473 mFocusedHotseatAppBounds.top, mFocusedHotseatAppBounds.right,
474 mFocusedHotseatAppBounds.bottom);
475 mFocusedHotseatApp.setAlpha((int) (255 * alpha));
476 mFocusedHotseatApp.draw(canvas);
477 }
Winson Chunga6945242014-01-08 14:04:34 -0800478 } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) ||
479 mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
480 int offset = DynamicGrid.pxFromDp(WORKSPACE_CIRCLE_Y_OFFSET_DPS, metrics);
481 // Draw the outer circle
482 eraseCanvas.drawCircle(pageIndicatorBounds.centerX(),
483 pageIndicatorBounds.centerY(),
484 DynamicGrid.pxFromDp(MIGRATION_WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, metrics),
485 mBorderPaint);
486 // Draw the inner circle
487 mErasePaint.setAlpha(0);
488 eraseCanvas.drawCircle(pageIndicatorBounds.centerX(),
489 pageIndicatorBounds.centerY(),
490 DynamicGrid.pxFromDp(MIGRATION_WORKSPACE_INNER_CIRCLE_RADIUS_DPS, metrics),
491 mErasePaint);
492 canvas.drawBitmap(eraseBg, 0, 0, null);
493 eraseCanvas.setBitmap(null);
494 eraseBg = null;
Winson Chung3a6e7f32013-10-09 15:50:52 -0700495 }
Winson Chungaf40f202013-09-18 18:26:31 -0700496 canvas.restore();
Winson Chung82f55532011-08-09 14:14:23 -0700497 }
Winson Chung7d7541e2011-09-16 20:14:36 -0700498
499 // Draw the rest of the cling
500 super.dispatchDraw(canvas);
Winson Chung82f55532011-08-09 14:14:23 -0700501 };
502}