Winson Chung | 82f5553 | 2011-08-09 14:14:23 -0700 | [diff] [blame^] | 1 | /* |
| 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 | |
| 17 | package com.android.launcher2; |
| 18 | |
| 19 | import android.content.Context; |
| 20 | import android.content.res.Resources; |
| 21 | import android.content.res.TypedArray; |
| 22 | import android.graphics.Canvas; |
| 23 | import android.graphics.Paint; |
| 24 | import android.graphics.Point; |
| 25 | import android.graphics.drawable.Drawable; |
| 26 | import android.util.AttributeSet; |
| 27 | import android.util.DisplayMetrics; |
| 28 | import android.view.View; |
| 29 | import android.widget.FrameLayout; |
| 30 | |
| 31 | import com.android.launcher.R; |
| 32 | |
| 33 | public class Cling extends FrameLayout { |
| 34 | |
| 35 | private static String WORKSPACE_PORTRAIT = "workspace_portrait"; |
| 36 | private static String WORKSPACE_LANDSCAPE = "workspace_landscape"; |
| 37 | private static String ALLAPPS_PORTRAIT = "all_apps_portrait"; |
| 38 | private static String ALLAPPS_LANDSCAPE = "all_apps_landscape"; |
| 39 | |
| 40 | private Launcher mLauncher; |
| 41 | private boolean mIsInitialized; |
| 42 | private String mDrawIdentifier; |
| 43 | private Drawable mPunchThroughGraphic; |
| 44 | private int mPunchThroughGraphicCenterRadius; |
| 45 | private int mAppIconSize; |
| 46 | private int mTabBarHeight; |
| 47 | private int mTabBarHorizontalPadding; |
| 48 | |
| 49 | View mWorkspaceDesc1; |
| 50 | View mWorkspaceDesc2; |
| 51 | View mAllAppsDesc; |
| 52 | |
| 53 | public Cling(Context context) { |
| 54 | this(context, null, 0); |
| 55 | } |
| 56 | |
| 57 | public Cling(Context context, AttributeSet attrs) { |
| 58 | this(context, attrs, 0); |
| 59 | } |
| 60 | |
| 61 | public Cling(Context context, AttributeSet attrs, int defStyle) { |
| 62 | super(context, attrs, defStyle); |
| 63 | |
| 64 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Cling, defStyle, 0); |
| 65 | mDrawIdentifier = a.getString(R.styleable.Cling_drawIdentifier); |
| 66 | a.recycle(); |
| 67 | } |
| 68 | |
| 69 | void init(Launcher l) { |
| 70 | if (!mIsInitialized) { |
| 71 | mLauncher = l; |
| 72 | |
| 73 | Resources r = getContext().getResources(); |
| 74 | mPunchThroughGraphic = r.getDrawable(R.drawable.cling); |
| 75 | mPunchThroughGraphicCenterRadius = |
| 76 | r.getDimensionPixelSize(R.dimen.clingPunchThroughGraphicCenterRadius); |
| 77 | mAppIconSize = r.getDimensionPixelSize(R.dimen.app_icon_size); |
| 78 | mTabBarHeight = r.getDimensionPixelSize(R.dimen.apps_customize_tab_bar_height); |
| 79 | mTabBarHorizontalPadding = |
| 80 | r.getDimensionPixelSize(R.dimen.toolbar_button_horizontal_padding); |
| 81 | |
| 82 | mWorkspaceDesc1 = findViewById(R.id.workspace_cling_move_item); |
| 83 | mWorkspaceDesc2 = findViewById(R.id.workspace_cling_open_all_apps); |
| 84 | mAllAppsDesc = findViewById(R.id.all_apps_cling_add_item); |
| 85 | mIsInitialized = true; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | void cleanup() { |
| 90 | mPunchThroughGraphic = null; |
| 91 | } |
| 92 | |
| 93 | @Override |
| 94 | public boolean onTouchEvent(android.view.MotionEvent event) { |
| 95 | // Do nothing |
| 96 | return true; |
| 97 | }; |
| 98 | |
| 99 | @Override |
| 100 | protected void dispatchDraw(Canvas canvas) { |
| 101 | // Draw the rest of the cling |
| 102 | super.dispatchDraw(canvas); |
| 103 | |
| 104 | if (mIsInitialized) { |
| 105 | DisplayMetrics metrics = new DisplayMetrics(); |
| 106 | mLauncher.getWindowManager().getDefaultDisplay().getMetrics(metrics); |
| 107 | int dotRadius = (int) (6f * metrics.density); |
| 108 | |
| 109 | Paint p = new Paint(); |
| 110 | p.setAntiAlias(true); |
| 111 | p.setColor(0xFF49C0EC); |
| 112 | |
| 113 | if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT)) { |
| 114 | /* Draw the all apps line */ { |
| 115 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) |
| 116 | mWorkspaceDesc2.getLayoutParams(); |
| 117 | int[] loc = new int[2]; |
| 118 | mWorkspaceDesc2.getLocationInWindow(loc); |
| 119 | int x = loc[0]; |
| 120 | int xOffset = (int) (10f * metrics.density); |
| 121 | int y = loc[1]; |
| 122 | int yOffset = (int) (30f * metrics.density); |
| 123 | int w = mWorkspaceDesc2.getWidth(); |
| 124 | int h = mWorkspaceDesc2.getHeight(); |
| 125 | |
| 126 | Point p1 = new Point(x + w + xOffset, y - (2 * dotRadius)); |
| 127 | Point p2 = new Point(getMeasuredWidth() / 2, getMeasuredHeight() - |
| 128 | mAppIconSize / 2 - yOffset); |
| 129 | canvas.drawCircle(p1.x, p1.y, dotRadius, p); |
| 130 | canvas.drawCircle(p2.x, p2.y, dotRadius, p); |
| 131 | |
| 132 | Point p3 = new Point(p1.x, (int) (p1.y + (p2.y - p1.y) * 0.30f)); |
| 133 | Point p4 = new Point(p2.x, (int) (p1.y + (p2.y - p1.y) * 0.55f)); |
| 134 | canvas.drawLine(p1.x, p1.y, p3.x, p3.y, p); |
| 135 | canvas.drawLine(p3.x, p3.y, p4.x, p4.y, p); |
| 136 | canvas.drawLine(p4.x, p4.y, p2.x, p2.y, p); |
| 137 | } |
| 138 | |
| 139 | /* Draw the move line */ { |
| 140 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) |
| 141 | mWorkspaceDesc1.getLayoutParams(); |
| 142 | int[] loc = new int[2]; |
| 143 | mWorkspaceDesc1.getLocationInWindow(loc); |
| 144 | int x = loc[0]; |
| 145 | int y = loc[1]; |
| 146 | int w = mWorkspaceDesc1.getWidth(); |
| 147 | int h = mWorkspaceDesc1.getHeight(); |
| 148 | |
| 149 | Point p1 = new Point(x + w, y - (2 * dotRadius)); |
| 150 | Point p2 = new Point(x + w, getMeasuredHeight() - (4 * mAppIconSize)); |
| 151 | canvas.drawCircle(p1.x, p1.y, dotRadius, p); |
| 152 | canvas.drawCircle(p2.x, p2.y, dotRadius, p); |
| 153 | canvas.drawLine(p1.x, p1.y, p2.x, p2.y, p); |
| 154 | } |
| 155 | } else if (mDrawIdentifier.equals(WORKSPACE_LANDSCAPE)) { |
| 156 | int xOffset = (int) (1.5f * mAppIconSize); |
| 157 | /* Draw the all apps line */ { |
| 158 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) |
| 159 | mWorkspaceDesc2.getLayoutParams(); |
| 160 | int[] loc = new int[2]; |
| 161 | mWorkspaceDesc2.getLocationInWindow(loc); |
| 162 | int x = loc[0]; |
| 163 | int y = loc[1]; |
| 164 | int w = mWorkspaceDesc2.getWidth(); |
| 165 | int h = mWorkspaceDesc2.getHeight(); |
| 166 | |
| 167 | Point p1 = new Point(x + w, y - (2 * dotRadius)); |
| 168 | Point p2 = new Point(getMeasuredWidth() - xOffset, |
| 169 | getMeasuredHeight() / 2); |
| 170 | canvas.drawCircle(p1.x, p1.y, dotRadius, p); |
| 171 | canvas.drawCircle(p2.x, p2.y, dotRadius, p); |
| 172 | |
| 173 | Point p3 = new Point((int) (p1.x + (p2.x - p1.x) * 0.6f), p1.y); |
| 174 | Point p4 = new Point((int) (p1.x + (p2.x - p1.x) * 0.75f), p2.y); |
| 175 | canvas.drawLine(p1.x, p1.y, p3.x, p3.y, p); |
| 176 | canvas.drawLine(p3.x, p3.y, p4.x, p4.y, p); |
| 177 | canvas.drawLine(p4.x, p4.y, p2.x, p2.y, p); |
| 178 | } |
| 179 | |
| 180 | /* Draw the move line */ { |
| 181 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) |
| 182 | mWorkspaceDesc1.getLayoutParams(); |
| 183 | int[] loc = new int[2]; |
| 184 | mWorkspaceDesc1.getLocationInWindow(loc); |
| 185 | int x = loc[0]; |
| 186 | int y = loc[1]; |
| 187 | int w = mWorkspaceDesc1.getWidth(); |
| 188 | int h = mWorkspaceDesc1.getHeight(); |
| 189 | |
| 190 | Point p1 = new Point(x + w, y - (2 * dotRadius)); |
| 191 | Point p2 = new Point(getMeasuredWidth() - xOffset, y - (2 * dotRadius)); |
| 192 | canvas.drawCircle(p1.x, p1.y, dotRadius, p); |
| 193 | canvas.drawCircle(p2.x, p2.y, dotRadius, p); |
| 194 | canvas.drawLine(p1.x, p1.y, p2.x, p2.y, p); |
| 195 | } |
| 196 | } else if (mDrawIdentifier.equals(ALLAPPS_PORTRAIT)) { |
| 197 | float r = mAppIconSize * 1.1f; |
| 198 | float scale = r / mPunchThroughGraphicCenterRadius; |
| 199 | int dw = (int) (scale * mPunchThroughGraphic.getIntrinsicWidth()); |
| 200 | int dh = (int) (scale * mPunchThroughGraphic.getIntrinsicHeight()); |
| 201 | int cx = getMeasuredWidth() / 2; |
| 202 | int cy = mTabBarHeight + ((getMeasuredHeight() - mTabBarHeight) / 2); |
| 203 | mPunchThroughGraphic.setBounds(cx - dw/2, cy - dh/2, cx + dw/2, cy + dh/2); |
| 204 | mPunchThroughGraphic.draw(canvas); |
| 205 | |
| 206 | /* Draw the line */ { |
| 207 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) |
| 208 | mAllAppsDesc.getLayoutParams(); |
| 209 | int[] loc = new int[2]; |
| 210 | mAllAppsDesc.getLocationInWindow(loc); |
| 211 | int x = loc[0]; |
| 212 | int y = loc[1]; |
| 213 | int yOffset = (int) (2.5f * metrics.density); |
| 214 | int w = mAllAppsDesc.getWidth(); |
| 215 | int h = mAllAppsDesc.getHeight(); |
| 216 | |
| 217 | Point p1 = new Point(getMeasuredWidth() / 2, y + h + yOffset); |
| 218 | Point p2 = new Point(cx, cy); |
| 219 | canvas.drawCircle(p1.x, p1.y, dotRadius, p); |
| 220 | canvas.drawCircle(p2.x, p2.y, dotRadius, p); |
| 221 | canvas.drawLine(p1.x, p1.y, p2.x, p2.y, p); |
| 222 | } |
| 223 | } else if (mDrawIdentifier.equals(ALLAPPS_LANDSCAPE)) { |
| 224 | float r = mAppIconSize * 1.1f; |
| 225 | float scale = r / mPunchThroughGraphicCenterRadius; |
| 226 | int dw = (int) (scale * mPunchThroughGraphic.getIntrinsicWidth()); |
| 227 | int dh = (int) (scale * mPunchThroughGraphic.getIntrinsicHeight()); |
| 228 | int cx = getMeasuredWidth() / 2 + getMeasuredWidth() / 4; |
| 229 | int cy = mTabBarHeight + ((getMeasuredHeight() - mTabBarHeight) / 2); |
| 230 | mPunchThroughGraphic.setBounds(cx - dw/2, cy - dh/2, cx + dw/2, cy + dh/2); |
| 231 | mPunchThroughGraphic.draw(canvas); |
| 232 | |
| 233 | /* Draw the line */ { |
| 234 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) |
| 235 | mAllAppsDesc.getLayoutParams(); |
| 236 | int[] loc = new int[2]; |
| 237 | mAllAppsDesc.getLocationInWindow(loc); |
| 238 | int x = loc[0]; |
| 239 | int y = loc[1]; |
| 240 | int w = mAllAppsDesc.getWidth(); |
| 241 | int h = mAllAppsDesc.getHeight(); |
| 242 | |
| 243 | Point p1 = new Point(x + w, y); |
| 244 | Point p2 = new Point(cx, cy); |
| 245 | canvas.drawCircle(p1.x, p1.y, dotRadius, p); |
| 246 | canvas.drawCircle(p2.x, p2.y, dotRadius, p); |
| 247 | canvas.drawLine(p1.x, p1.y, p2.x, p2.y, p); |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | /* |
| 252 | // Draw the background |
| 253 | Bitmap b = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), |
| 254 | Bitmap.Config.ARGB_8888); |
| 255 | Canvas c = new Canvas(b); |
| 256 | c.drawColor(0xD4000000); |
| 257 | Paint p = new Paint(); |
| 258 | p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); |
| 259 | p.setColor(0xFFFFFF); |
| 260 | p.setAlpha(0); |
| 261 | |
| 262 | int cx = -1; |
| 263 | int cy = -1; |
| 264 | float r = mAppIconSize * 1.4f; |
| 265 | float scale = r / mPunchThroughGraphicCenterRadius; |
| 266 | int dw = (int) (scale * mPunchThroughGraphic.getIntrinsicWidth()); |
| 267 | int dh = (int) (scale * mPunchThroughGraphic.getIntrinsicHeight()); |
| 268 | |
| 269 | if (mDrawIdentifier.equals("workspace_portrait")) { |
| 270 | cx = getMeasuredWidth() / 2; |
| 271 | cy = getMeasuredHeight() - mAppIconSize / 2; |
| 272 | } else if (mDrawIdentifier.equals("workspace_landscape")) { |
| 273 | cx = getMeasuredWidth() - mAppIconSize / 2; |
| 274 | cy = getMeasuredHeight() / 2; |
| 275 | } else if (mDrawIdentifier.equals("large_workspace_landscape") || |
| 276 | mDrawIdentifier.equals("large_workspace_portrait")) { |
| 277 | cx = getMeasuredWidth() - mTabBarHorizontalPadding; |
| 278 | cy = 0; |
| 279 | } else if (mDrawIdentifier.equals("all_apps_portrait")) { |
| 280 | cx = getMeasuredWidth() / 2; |
| 281 | cy = mTabBarHeight + ((getMeasuredHeight() - mTabBarHeight) / 2); |
| 282 | } else if (mDrawIdentifier.equals("all_apps_landscape")) { |
| 283 | cx = getMeasuredWidth() / 2 + getMeasuredWidth() / 4; |
| 284 | cy = mTabBarHeight + ((getMeasuredHeight() - mTabBarHeight) / 2); |
| 285 | } else if (mDrawIdentifier.equals("large_all_apps_portrait")) { |
| 286 | cx = getMeasuredWidth() / 2; |
| 287 | cy = mTabBarHeight + (int) ((getMeasuredHeight() - mTabBarHeight) * 2f / 5f); |
| 288 | } else if (mDrawIdentifier.equals("large_all_apps_landscape")) { |
| 289 | cx = getMeasuredWidth() / 2 + getMeasuredWidth() / 6; |
| 290 | cy = mTabBarHeight + (int) ((getMeasuredHeight() - mTabBarHeight) * 2f / 5f); |
| 291 | } |
| 292 | if (cx > -1 && cy > -1) { |
| 293 | c.drawCircle(cx, cy, r, p); |
| 294 | mPunchThroughGraphic.setBounds(cx - dw/2, cy - dh/2, cx + dw/2, cy + dh/2); |
| 295 | mPunchThroughGraphic.draw(c); |
| 296 | } |
| 297 | canvas.drawBitmap(b, 0, 0, null); |
| 298 | c.setBitmap(null); |
| 299 | b = null; |
| 300 | */ |
| 301 | } |
| 302 | }; |
| 303 | } |