Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2013 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.systemui; |
| 18 | |
| 19 | import android.animation.Animator; |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 20 | import android.animation.AnimatorListenerAdapter; |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 21 | import android.animation.AnimatorSet; |
| 22 | import android.animation.ObjectAnimator; |
| 23 | import android.content.Context; |
| 24 | import android.content.res.Resources; |
Winson | c0d7058 | 2016-01-29 10:24:39 -0800 | [diff] [blame] | 25 | import android.graphics.Bitmap; |
| 26 | import android.graphics.BitmapFactory; |
| 27 | import android.graphics.Canvas; |
| 28 | import android.graphics.Color; |
| 29 | import android.graphics.ColorMatrixColorFilter; |
| 30 | import android.graphics.Paint; |
| 31 | import android.graphics.Point; |
| 32 | import android.graphics.Rect; |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 33 | import android.graphics.drawable.BitmapDrawable; |
| 34 | import android.graphics.drawable.Drawable; |
| 35 | import android.os.Handler; |
| 36 | import android.util.AttributeSet; |
| 37 | import android.util.Log; |
| 38 | import android.util.SparseArray; |
| 39 | import android.view.View; |
| 40 | import android.view.animation.AccelerateInterpolator; |
| 41 | import android.view.animation.AnticipateOvershootInterpolator; |
| 42 | import android.view.animation.DecelerateInterpolator; |
| 43 | import android.widget.FrameLayout; |
| 44 | import android.widget.ImageView; |
| 45 | |
| 46 | import java.util.HashSet; |
| 47 | import java.util.Set; |
| 48 | |
| 49 | public class DessertCaseView extends FrameLayout { |
| 50 | private static final String TAG = DessertCaseView.class.getSimpleName(); |
| 51 | |
| 52 | private static final boolean DEBUG = false; |
| 53 | |
| 54 | static final int START_DELAY = 5000; |
| 55 | static final int DELAY = 2000; |
| 56 | static final int DURATION = 500; |
| 57 | |
| 58 | private static final int TAG_POS = 0x2000001; |
| 59 | private static final int TAG_SPAN = 0x2000002; |
| 60 | |
| 61 | private static final int[] PASTRIES = { |
| 62 | R.drawable.dessert_kitkat, // used with permission |
| 63 | R.drawable.dessert_android, // thx irina |
| 64 | }; |
| 65 | |
| 66 | private static final int[] RARE_PASTRIES = { |
| 67 | R.drawable.dessert_cupcake, // 2009 |
| 68 | R.drawable.dessert_donut, // 2009 |
| 69 | R.drawable.dessert_eclair, // 2009 |
| 70 | R.drawable.dessert_froyo, // 2010 |
| 71 | R.drawable.dessert_gingerbread, // 2010 |
| 72 | R.drawable.dessert_honeycomb, // 2011 |
| 73 | R.drawable.dessert_ics, // 2011 |
| 74 | R.drawable.dessert_jellybean, // 2012 |
| 75 | }; |
| 76 | |
| 77 | private static final int[] XRARE_PASTRIES = { |
| 78 | R.drawable.dessert_petitfour, // the original and still delicious |
| 79 | |
| 80 | R.drawable.dessert_donutburger, // remember kids, this was long before cronuts |
| 81 | |
| 82 | R.drawable.dessert_flan, // sholes final approach |
| 83 | // landing gear punted to flan |
| 84 | // runway foam glistens |
| 85 | // -- mcleron |
| 86 | |
| 87 | R.drawable.dessert_keylimepie, // from an alternative timeline |
| 88 | }; |
| 89 | private static final int[] XXRARE_PASTRIES = { |
| 90 | R.drawable.dessert_zombiegingerbread, // thx hackbod |
| 91 | R.drawable.dessert_dandroid, // thx morrildl |
| 92 | R.drawable.dessert_jandycane, // thx nes |
| 93 | }; |
| 94 | |
| 95 | private static final int NUM_PASTRIES = PASTRIES.length + RARE_PASTRIES.length |
| 96 | + XRARE_PASTRIES.length + XXRARE_PASTRIES.length; |
| 97 | |
| 98 | private SparseArray<Drawable> mDrawables = new SparseArray<Drawable>(NUM_PASTRIES); |
| 99 | |
| 100 | private static final float[] MASK = { |
| 101 | 0f, 0f, 0f, 0f, 255f, |
| 102 | 0f, 0f, 0f, 0f, 255f, |
| 103 | 0f, 0f, 0f, 0f, 255f, |
| 104 | 1f, 0f, 0f, 0f, 0f |
| 105 | }; |
| 106 | |
Daniel Sandler | f9f6335 | 2013-10-15 00:17:25 -0400 | [diff] [blame] | 107 | private static final float[] ALPHA_MASK = { |
| 108 | 0f, 0f, 0f, 0f, 255f, |
| 109 | 0f, 0f, 0f, 0f, 255f, |
| 110 | 0f, 0f, 0f, 0f, 255f, |
| 111 | 0f, 0f, 0f, 1f, 0f |
| 112 | }; |
| 113 | |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 114 | private static final float[] WHITE_MASK = { |
| 115 | 0f, 0f, 0f, 0f, 255f, |
| 116 | 0f, 0f, 0f, 0f, 255f, |
| 117 | 0f, 0f, 0f, 0f, 255f, |
| 118 | -1f, 0f, 0f, 0f, 255f |
| 119 | }; |
| 120 | |
| 121 | public static final float SCALE = 0.25f; // natural display size will be SCALE*mCellSize |
| 122 | |
| 123 | private static final float PROB_2X = 0.33f; |
| 124 | private static final float PROB_3X = 0.1f; |
| 125 | private static final float PROB_4X = 0.01f; |
| 126 | |
| 127 | private boolean mStarted; |
| 128 | |
| 129 | private int mCellSize; |
| 130 | private int mWidth, mHeight; |
| 131 | private int mRows, mColumns; |
| 132 | private View[] mCells; |
| 133 | |
| 134 | private final Set<Point> mFreeList = new HashSet<Point>(); |
| 135 | |
| 136 | private final Handler mHandler = new Handler(); |
| 137 | |
| 138 | private final Runnable mJuggle = new Runnable() { |
| 139 | @Override |
| 140 | public void run() { |
| 141 | final int N = getChildCount(); |
| 142 | |
| 143 | final int K = 1; //irand(1,3); |
| 144 | for (int i=0; i<K; i++) { |
| 145 | final View child = getChildAt((int) (Math.random() * N)); |
| 146 | place(child, true); |
| 147 | } |
| 148 | |
| 149 | fillFreeList(); |
| 150 | |
| 151 | if (mStarted) { |
| 152 | mHandler.postDelayed(mJuggle, DELAY); |
| 153 | } |
| 154 | } |
| 155 | }; |
| 156 | |
| 157 | public DessertCaseView(Context context) { |
| 158 | this(context, null); |
| 159 | } |
| 160 | |
| 161 | public DessertCaseView(Context context, AttributeSet attrs) { |
| 162 | this(context, attrs, 0); |
| 163 | } |
| 164 | |
| 165 | public DessertCaseView(Context context, AttributeSet attrs, int defStyle) { |
| 166 | super(context, attrs, defStyle); |
| 167 | |
| 168 | final Resources res = getResources(); |
| 169 | |
| 170 | mStarted = false; |
| 171 | |
| 172 | mCellSize = res.getDimensionPixelSize(R.dimen.dessert_case_cell_size); |
| 173 | final BitmapFactory.Options opts = new BitmapFactory.Options(); |
| 174 | if (mCellSize < 512) { // assuming 512x512 images |
| 175 | opts.inSampleSize = 2; |
| 176 | } |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 177 | opts.inMutable = true; |
| 178 | Bitmap loaded = null; |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 179 | for (int[] list : new int[][] { PASTRIES, RARE_PASTRIES, XRARE_PASTRIES, XXRARE_PASTRIES }) { |
| 180 | for (int resid : list) { |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 181 | opts.inBitmap = loaded; |
| 182 | loaded = BitmapFactory.decodeResource(res, resid, opts); |
| 183 | final BitmapDrawable d = new BitmapDrawable(res, convertToAlphaMask(loaded)); |
Daniel Sandler | f9f6335 | 2013-10-15 00:17:25 -0400 | [diff] [blame] | 184 | d.setColorFilter(new ColorMatrixColorFilter(ALPHA_MASK)); |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 185 | d.setBounds(0, 0, mCellSize, mCellSize); |
| 186 | mDrawables.append(resid, d); |
| 187 | } |
| 188 | } |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 189 | loaded = null; |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 190 | if (DEBUG) setWillNotDraw(false); |
| 191 | } |
| 192 | |
Daniel Sandler | f9f6335 | 2013-10-15 00:17:25 -0400 | [diff] [blame] | 193 | private static Bitmap convertToAlphaMask(Bitmap b) { |
| 194 | Bitmap a = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ALPHA_8); |
| 195 | Canvas c = new Canvas(a); |
| 196 | Paint pt = new Paint(); |
| 197 | pt.setColorFilter(new ColorMatrixColorFilter(MASK)); |
| 198 | c.drawBitmap(b, 0.0f, 0.0f, pt); |
| 199 | return a; |
| 200 | } |
| 201 | |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 202 | public void start() { |
| 203 | if (!mStarted) { |
| 204 | mStarted = true; |
| 205 | fillFreeList(DURATION * 4); |
| 206 | } |
| 207 | mHandler.postDelayed(mJuggle, START_DELAY); |
| 208 | } |
| 209 | |
| 210 | public void stop() { |
| 211 | mStarted = false; |
| 212 | mHandler.removeCallbacks(mJuggle); |
| 213 | } |
| 214 | |
| 215 | int pick(int[] a) { |
| 216 | return a[(int)(Math.random()*a.length)]; |
| 217 | } |
| 218 | |
| 219 | <T> T pick(T[] a) { |
| 220 | return a[(int)(Math.random()*a.length)]; |
| 221 | } |
| 222 | |
| 223 | <T> T pick(SparseArray<T> sa) { |
| 224 | return sa.valueAt((int)(Math.random()*sa.size())); |
| 225 | } |
| 226 | |
| 227 | float[] hsv = new float[] { 0, 1f, .85f }; |
| 228 | int random_color() { |
| 229 | // return 0xFF000000 | (int) (Math.random() * (float) 0xFFFFFF); // totally random |
| 230 | final int COLORS = 12; |
| 231 | hsv[0] = irand(0,COLORS) * (360f/COLORS); |
| 232 | return Color.HSVToColor(hsv); |
| 233 | } |
| 234 | |
| 235 | @Override |
| 236 | protected synchronized void onSizeChanged (int w, int h, int oldw, int oldh) { |
| 237 | super.onSizeChanged(w, h, oldw, oldh); |
| 238 | if (mWidth == w && mHeight == h) return; |
| 239 | |
| 240 | final boolean wasStarted = mStarted; |
| 241 | if (wasStarted) { |
| 242 | stop(); |
| 243 | } |
| 244 | |
| 245 | mWidth = w; |
| 246 | mHeight = h; |
| 247 | |
| 248 | mCells = null; |
| 249 | removeAllViewsInLayout(); |
| 250 | mFreeList.clear(); |
| 251 | |
| 252 | mRows = mHeight / mCellSize; |
| 253 | mColumns = mWidth / mCellSize; |
| 254 | |
| 255 | mCells = new View[mRows * mColumns]; |
| 256 | |
| 257 | if (DEBUG) Log.v(TAG, String.format("New dimensions: %dx%d", mColumns, mRows)); |
| 258 | |
| 259 | setScaleX(SCALE); |
| 260 | setScaleY(SCALE); |
| 261 | setTranslationX(0.5f * (mWidth - mCellSize * mColumns) * SCALE); |
| 262 | setTranslationY(0.5f * (mHeight - mCellSize * mRows) * SCALE); |
| 263 | |
| 264 | for (int j=0; j<mRows; j++) { |
| 265 | for (int i=0; i<mColumns; i++) { |
| 266 | mFreeList.add(new Point(i,j)); |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | if (wasStarted) { |
| 271 | start(); |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | public void fillFreeList() { |
| 276 | fillFreeList(DURATION); |
| 277 | } |
| 278 | |
| 279 | public synchronized void fillFreeList(int animationLen) { |
| 280 | final Context ctx = getContext(); |
| 281 | final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(mCellSize, mCellSize); |
| 282 | |
| 283 | while (! mFreeList.isEmpty()) { |
| 284 | Point pt = mFreeList.iterator().next(); |
| 285 | mFreeList.remove(pt); |
| 286 | final int i=pt.x; |
| 287 | final int j=pt.y; |
| 288 | |
| 289 | if (mCells[j*mColumns+i] != null) continue; |
| 290 | final ImageView v = new ImageView(ctx); |
| 291 | v.setOnClickListener(new OnClickListener() { |
| 292 | @Override |
| 293 | public void onClick(View view) { |
| 294 | place(v, true); |
| 295 | postDelayed(new Runnable() { public void run() { fillFreeList(); } }, DURATION/2); |
| 296 | } |
| 297 | }); |
| 298 | |
| 299 | final int c = random_color(); |
| 300 | v.setBackgroundColor(c); |
| 301 | |
| 302 | final float which = frand(); |
| 303 | final Drawable d; |
Daniel Sandler | f9f6335 | 2013-10-15 00:17:25 -0400 | [diff] [blame] | 304 | if (which < 0.0005f) { |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 305 | d = mDrawables.get(pick(XXRARE_PASTRIES)); |
Daniel Sandler | f9f6335 | 2013-10-15 00:17:25 -0400 | [diff] [blame] | 306 | } else if (which < 0.005f) { |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 307 | d = mDrawables.get(pick(XRARE_PASTRIES)); |
| 308 | } else if (which < 0.5f) { |
| 309 | d = mDrawables.get(pick(RARE_PASTRIES)); |
| 310 | } else if (which < 0.7f) { |
| 311 | d = mDrawables.get(pick(PASTRIES)); |
| 312 | } else { |
| 313 | d = null; |
| 314 | } |
| 315 | if (d != null) { |
| 316 | v.getOverlay().add(d); |
| 317 | } |
| 318 | |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 319 | lp.width = lp.height = mCellSize; |
| 320 | addView(v, lp); |
| 321 | place(v, pt, false); |
| 322 | if (animationLen > 0) { |
| 323 | final float s = (Integer) v.getTag(TAG_SPAN); |
| 324 | v.setScaleX(0.5f * s); |
| 325 | v.setScaleY(0.5f * s); |
| 326 | v.setAlpha(0f); |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 327 | v.animate().withLayer().scaleX(s).scaleY(s).alpha(1f).setDuration(animationLen); |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 328 | } |
| 329 | } |
| 330 | } |
| 331 | |
| 332 | public void place(View v, boolean animate) { |
| 333 | place(v, new Point(irand(0, mColumns), irand(0, mRows)), animate); |
| 334 | } |
| 335 | |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 336 | // we don't have .withLayer() on general Animators |
| 337 | private final Animator.AnimatorListener makeHardwareLayerListener(final View v) { |
| 338 | return new AnimatorListenerAdapter() { |
| 339 | @Override |
| 340 | public void onAnimationStart(Animator animator) { |
| 341 | v.setLayerType(View.LAYER_TYPE_HARDWARE, null); |
| 342 | v.buildLayer(); |
| 343 | } |
| 344 | @Override |
| 345 | public void onAnimationEnd(Animator animator) { |
| 346 | v.setLayerType(View.LAYER_TYPE_NONE, null); |
| 347 | } |
| 348 | }; |
| 349 | } |
| 350 | |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 351 | private final HashSet<View> tmpSet = new HashSet<View>(); |
| 352 | public synchronized void place(View v, Point pt, boolean animate) { |
| 353 | final int i = pt.x; |
| 354 | final int j = pt.y; |
| 355 | final float rnd = frand(); |
| 356 | if (v.getTag(TAG_POS) != null) { |
| 357 | for (final Point oc : getOccupied(v)) { |
| 358 | mFreeList.add(oc); |
| 359 | mCells[oc.y*mColumns + oc.x] = null; |
| 360 | } |
| 361 | } |
| 362 | int scale = 1; |
| 363 | if (rnd < PROB_4X) { |
| 364 | if (!(i >= mColumns-3 || j >= mRows-3)) { |
| 365 | scale = 4; |
| 366 | } |
| 367 | } else if (rnd < PROB_3X) { |
| 368 | if (!(i >= mColumns-2 || j >= mRows-2)) { |
| 369 | scale = 3; |
| 370 | } |
| 371 | } else if (rnd < PROB_2X) { |
| 372 | if (!(i == mColumns-1 || j == mRows-1)) { |
| 373 | scale = 2; |
| 374 | } |
| 375 | } |
| 376 | |
| 377 | v.setTag(TAG_POS, pt); |
| 378 | v.setTag(TAG_SPAN, scale); |
| 379 | |
| 380 | tmpSet.clear(); |
| 381 | |
| 382 | final Point[] occupied = getOccupied(v); |
| 383 | for (final Point oc : occupied) { |
| 384 | final View squatter = mCells[oc.y*mColumns + oc.x]; |
| 385 | if (squatter != null) { |
| 386 | tmpSet.add(squatter); |
| 387 | } |
| 388 | } |
| 389 | |
| 390 | for (final View squatter : tmpSet) { |
| 391 | for (final Point sq : getOccupied(squatter)) { |
| 392 | mFreeList.add(sq); |
| 393 | mCells[sq.y*mColumns + sq.x] = null; |
| 394 | } |
| 395 | if (squatter != v) { |
| 396 | squatter.setTag(TAG_POS, null); |
| 397 | if (animate) { |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 398 | squatter.animate().withLayer() |
| 399 | .scaleX(0.5f).scaleY(0.5f).alpha(0) |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 400 | .setDuration(DURATION) |
| 401 | .setInterpolator(new AccelerateInterpolator()) |
| 402 | .setListener(new Animator.AnimatorListener() { |
| 403 | public void onAnimationStart(Animator animator) { } |
| 404 | public void onAnimationEnd(Animator animator) { |
| 405 | removeView(squatter); |
| 406 | } |
| 407 | public void onAnimationCancel(Animator animator) { } |
| 408 | public void onAnimationRepeat(Animator animator) { } |
| 409 | }) |
| 410 | .start(); |
| 411 | } else { |
| 412 | removeView(squatter); |
| 413 | } |
| 414 | } |
| 415 | } |
| 416 | |
| 417 | for (final Point oc : occupied) { |
| 418 | mCells[oc.y*mColumns + oc.x] = v; |
| 419 | mFreeList.remove(oc); |
| 420 | } |
| 421 | |
| 422 | final float rot = (float)irand(0, 4) * 90f; |
| 423 | |
| 424 | if (animate) { |
| 425 | v.bringToFront(); |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 426 | |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 427 | AnimatorSet set1 = new AnimatorSet(); |
| 428 | set1.playTogether( |
| 429 | ObjectAnimator.ofFloat(v, View.SCALE_X, (float) scale), |
| 430 | ObjectAnimator.ofFloat(v, View.SCALE_Y, (float) scale) |
| 431 | ); |
| 432 | set1.setInterpolator(new AnticipateOvershootInterpolator()); |
| 433 | set1.setDuration(DURATION); |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 434 | |
| 435 | AnimatorSet set2 = new AnimatorSet(); |
| 436 | set2.playTogether( |
| 437 | ObjectAnimator.ofFloat(v, View.ROTATION, rot), |
| 438 | ObjectAnimator.ofFloat(v, View.X, i* mCellSize + (scale-1) * mCellSize /2), |
| 439 | ObjectAnimator.ofFloat(v, View.Y, j* mCellSize + (scale-1) * mCellSize /2) |
| 440 | ); |
| 441 | set2.setInterpolator(new DecelerateInterpolator()); |
| 442 | set2.setDuration(DURATION); |
Daniel Sandler | 9279d45 | 2013-10-17 13:05:53 -0400 | [diff] [blame] | 443 | |
| 444 | set1.addListener(makeHardwareLayerListener(v)); |
| 445 | |
| 446 | set1.start(); |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 447 | set2.start(); |
| 448 | } else { |
| 449 | v.setX(i * mCellSize + (scale-1) * mCellSize /2); |
| 450 | v.setY(j * mCellSize + (scale-1) * mCellSize /2); |
| 451 | v.setScaleX((float) scale); |
| 452 | v.setScaleY((float) scale); |
| 453 | v.setRotation(rot); |
| 454 | } |
| 455 | } |
| 456 | |
| 457 | private Point[] getOccupied(View v) { |
| 458 | final int scale = (Integer) v.getTag(TAG_SPAN); |
| 459 | final Point pt = (Point)v.getTag(TAG_POS); |
| 460 | if (pt == null || scale == 0) return new Point[0]; |
| 461 | |
| 462 | final Point[] result = new Point[scale * scale]; |
| 463 | int p=0; |
| 464 | for (int i=0; i<scale; i++) { |
| 465 | for (int j=0; j<scale; j++) { |
| 466 | result[p++] = new Point(pt.x + i, pt.y + j); |
| 467 | } |
| 468 | } |
| 469 | return result; |
| 470 | } |
| 471 | |
| 472 | static float frand() { |
| 473 | return (float)(Math.random()); |
| 474 | } |
| 475 | |
| 476 | static float frand(float a, float b) { |
| 477 | return (frand() * (b-a) + a); |
| 478 | } |
| 479 | |
| 480 | static int irand(int a, int b) { |
| 481 | return (int)(frand(a, b)); |
| 482 | } |
| 483 | |
| 484 | @Override |
| 485 | public void onDraw(Canvas c) { |
| 486 | super.onDraw(c); |
| 487 | if (!DEBUG) return; |
| 488 | |
| 489 | Paint pt = new Paint(); |
| 490 | pt.setStyle(Paint.Style.STROKE); |
| 491 | pt.setColor(0xFFCCCCCC); |
| 492 | pt.setStrokeWidth(2.0f); |
| 493 | |
| 494 | final Rect check = new Rect(); |
| 495 | final int N = getChildCount(); |
| 496 | for (int i = 0; i < N; i++) { |
| 497 | View stone = getChildAt(i); |
| 498 | |
| 499 | stone.getHitRect(check); |
| 500 | |
| 501 | c.drawRect(check, pt); |
| 502 | } |
| 503 | } |
| 504 | |
| 505 | public static class RescalingContainer extends FrameLayout { |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 506 | private DessertCaseView mView; |
| 507 | private float mDarkness; |
| 508 | |
| 509 | public RescalingContainer(Context context) { |
| 510 | super(context); |
| 511 | |
| 512 | setSystemUiVisibility(0 |
| 513 | | View.SYSTEM_UI_FLAG_FULLSCREEN |
| 514 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
| 515 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
| 516 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
Daniel Sandler | 5c6a781 | 2013-11-12 21:50:18 -0500 | [diff] [blame] | 517 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
Daniel Sandler | 8475a74 | 2013-09-26 00:24:57 -0400 | [diff] [blame] | 518 | ); |
| 519 | } |
| 520 | |
| 521 | public void setView(DessertCaseView v) { |
| 522 | addView(v); |
| 523 | mView = v; |
| 524 | } |
| 525 | |
| 526 | @Override |
| 527 | protected void onLayout (boolean changed, int left, int top, int right, int bottom) { |
| 528 | final float w = right-left; |
| 529 | final float h = bottom-top; |
| 530 | final int w2 = (int) (w / mView.SCALE / 2); |
| 531 | final int h2 = (int) (h / mView.SCALE / 2); |
| 532 | final int cx = (int) (left + w * 0.5f); |
| 533 | final int cy = (int) (top + h * 0.5f); |
| 534 | mView.layout(cx - w2, cy - h2, cx + w2, cy + h2); |
| 535 | } |
| 536 | |
| 537 | public void setDarkness(float p) { |
| 538 | mDarkness = p; |
| 539 | getDarkness(); |
| 540 | final int x = (int) (p * 0xff); |
| 541 | setBackgroundColor(x << 24 & 0xFF000000); |
| 542 | } |
| 543 | |
| 544 | public float getDarkness() { |
| 545 | return mDarkness; |
| 546 | } |
| 547 | } |
| 548 | } |