18475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler/* 28475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * Copyright (C) 2013 The Android Open Source Project 38475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * 48475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * Licensed under the Apache License, Version 2.0 (the "License"); 58475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * you may not use this file except in compliance with the License. 68475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * You may obtain a copy of the License at 78475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * 88475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * http://www.apache.org/licenses/LICENSE-2.0 98475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * 108475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * Unless required by applicable law or agreed to in writing, software 118475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * distributed under the License is distributed on an "AS IS" BASIS, 128475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * See the License for the specific language governing permissions and 148475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler * limitations under the License. 158475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler */ 168475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 178475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerpackage com.android.systemui; 188475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 198475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.animation.Animator; 209279d45b8d26c88c69fa917816ea396142627020Daniel Sandlerimport android.animation.AnimatorListenerAdapter; 218475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.animation.AnimatorSet; 228475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.animation.ObjectAnimator; 238475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.content.Context; 248475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.content.res.Resources; 258475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.graphics.*; 268475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.graphics.drawable.BitmapDrawable; 278475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.graphics.drawable.Drawable; 288475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.os.Handler; 298475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.util.AttributeSet; 308475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.util.Log; 318475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.util.SparseArray; 328475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.view.View; 338475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.view.animation.AccelerateInterpolator; 348475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.view.animation.AnticipateOvershootInterpolator; 358475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.view.animation.DecelerateInterpolator; 368475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.widget.FrameLayout; 378475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport android.widget.ImageView; 388475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 398475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport java.util.HashSet; 408475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerimport java.util.Set; 418475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 428475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandlerpublic class DessertCaseView extends FrameLayout { 438475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final String TAG = DessertCaseView.class.getSimpleName(); 448475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 458475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final boolean DEBUG = false; 468475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 478475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler static final int START_DELAY = 5000; 488475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler static final int DELAY = 2000; 498475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler static final int DURATION = 500; 508475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 518475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final int TAG_POS = 0x2000001; 528475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final int TAG_SPAN = 0x2000002; 538475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 548475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final int[] PASTRIES = { 558475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_kitkat, // used with permission 568475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_android, // thx irina 578475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }; 588475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 598475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final int[] RARE_PASTRIES = { 608475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_cupcake, // 2009 618475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_donut, // 2009 628475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_eclair, // 2009 638475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_froyo, // 2010 648475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_gingerbread, // 2010 658475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_honeycomb, // 2011 668475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_ics, // 2011 678475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_jellybean, // 2012 688475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }; 698475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 708475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final int[] XRARE_PASTRIES = { 718475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_petitfour, // the original and still delicious 728475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 738475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_donutburger, // remember kids, this was long before cronuts 748475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 758475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_flan, // sholes final approach 768475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler // landing gear punted to flan 778475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler // runway foam glistens 788475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler // -- mcleron 798475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 808475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_keylimepie, // from an alternative timeline 818475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }; 828475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final int[] XXRARE_PASTRIES = { 838475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_zombiegingerbread, // thx hackbod 848475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_dandroid, // thx morrildl 858475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler R.drawable.dessert_jandycane, // thx nes 868475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }; 878475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 888475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final int NUM_PASTRIES = PASTRIES.length + RARE_PASTRIES.length 898475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler + XRARE_PASTRIES.length + XXRARE_PASTRIES.length; 908475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 918475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private SparseArray<Drawable> mDrawables = new SparseArray<Drawable>(NUM_PASTRIES); 928475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 938475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final float[] MASK = { 948475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 0f, 0f, 0f, 0f, 255f, 958475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 0f, 0f, 0f, 0f, 255f, 968475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 0f, 0f, 0f, 0f, 255f, 978475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1f, 0f, 0f, 0f, 0f 988475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }; 998475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 100f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler private static final float[] ALPHA_MASK = { 101f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler 0f, 0f, 0f, 0f, 255f, 102f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler 0f, 0f, 0f, 0f, 255f, 103f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler 0f, 0f, 0f, 0f, 255f, 104f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler 0f, 0f, 0f, 1f, 0f 105f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler }; 106f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler 1078475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final float[] WHITE_MASK = { 1088475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 0f, 0f, 0f, 0f, 255f, 1098475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 0f, 0f, 0f, 0f, 255f, 1108475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 0f, 0f, 0f, 0f, 255f, 1118475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler -1f, 0f, 0f, 0f, 255f 1128475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }; 1138475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1148475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public static final float SCALE = 0.25f; // natural display size will be SCALE*mCellSize 1158475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1168475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final float PROB_2X = 0.33f; 1178475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final float PROB_3X = 0.1f; 1188475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private static final float PROB_4X = 0.01f; 1198475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1208475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private boolean mStarted; 1218475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1228475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private int mCellSize; 1238475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private int mWidth, mHeight; 1248475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private int mRows, mColumns; 1258475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private View[] mCells; 1268475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1278475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private final Set<Point> mFreeList = new HashSet<Point>(); 1288475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1298475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private final Handler mHandler = new Handler(); 1308475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1318475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private final Runnable mJuggle = new Runnable() { 1328475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler @Override 1338475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void run() { 1348475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int N = getChildCount(); 1358475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1368475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int K = 1; //irand(1,3); 1378475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (int i=0; i<K; i++) { 1388475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final View child = getChildAt((int) (Math.random() * N)); 1398475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler place(child, true); 1408475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1418475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1428475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler fillFreeList(); 1438475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1448475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (mStarted) { 1458475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mHandler.postDelayed(mJuggle, DELAY); 1468475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1478475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1488475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }; 1498475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1508475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public DessertCaseView(Context context) { 1518475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler this(context, null); 1528475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1538475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1548475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public DessertCaseView(Context context, AttributeSet attrs) { 1558475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler this(context, attrs, 0); 1568475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1578475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1588475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public DessertCaseView(Context context, AttributeSet attrs, int defStyle) { 1598475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler super(context, attrs, defStyle); 1608475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1618475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final Resources res = getResources(); 1628475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1638475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mStarted = false; 1648475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 1658475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mCellSize = res.getDimensionPixelSize(R.dimen.dessert_case_cell_size); 1668475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final BitmapFactory.Options opts = new BitmapFactory.Options(); 1678475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (mCellSize < 512) { // assuming 512x512 images 1688475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler opts.inSampleSize = 2; 1698475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1709279d45b8d26c88c69fa917816ea396142627020Daniel Sandler opts.inMutable = true; 1719279d45b8d26c88c69fa917816ea396142627020Daniel Sandler Bitmap loaded = null; 1728475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (int[] list : new int[][] { PASTRIES, RARE_PASTRIES, XRARE_PASTRIES, XXRARE_PASTRIES }) { 1738475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (int resid : list) { 1749279d45b8d26c88c69fa917816ea396142627020Daniel Sandler opts.inBitmap = loaded; 1759279d45b8d26c88c69fa917816ea396142627020Daniel Sandler loaded = BitmapFactory.decodeResource(res, resid, opts); 1769279d45b8d26c88c69fa917816ea396142627020Daniel Sandler final BitmapDrawable d = new BitmapDrawable(res, convertToAlphaMask(loaded)); 177f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler d.setColorFilter(new ColorMatrixColorFilter(ALPHA_MASK)); 1788475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler d.setBounds(0, 0, mCellSize, mCellSize); 1798475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mDrawables.append(resid, d); 1808475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1818475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1829279d45b8d26c88c69fa917816ea396142627020Daniel Sandler loaded = null; 1838475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (DEBUG) setWillNotDraw(false); 1848475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 1858475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 186f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler private static Bitmap convertToAlphaMask(Bitmap b) { 187f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler Bitmap a = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ALPHA_8); 188f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler Canvas c = new Canvas(a); 189f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler Paint pt = new Paint(); 190f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler pt.setColorFilter(new ColorMatrixColorFilter(MASK)); 191f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler c.drawBitmap(b, 0.0f, 0.0f, pt); 192f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler return a; 193f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler } 194f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler 1958475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void start() { 1968475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (!mStarted) { 1978475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mStarted = true; 1988475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler fillFreeList(DURATION * 4); 1998475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2008475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mHandler.postDelayed(mJuggle, START_DELAY); 2018475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2028475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2038475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void stop() { 2048475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mStarted = false; 2058475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mHandler.removeCallbacks(mJuggle); 2068475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2078475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2088475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler int pick(int[] a) { 2098475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return a[(int)(Math.random()*a.length)]; 2108475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2118475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2128475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler <T> T pick(T[] a) { 2138475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return a[(int)(Math.random()*a.length)]; 2148475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2158475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2168475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler <T> T pick(SparseArray<T> sa) { 2178475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return sa.valueAt((int)(Math.random()*sa.size())); 2188475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2198475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2208475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler float[] hsv = new float[] { 0, 1f, .85f }; 2218475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler int random_color() { 2228475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler// return 0xFF000000 | (int) (Math.random() * (float) 0xFFFFFF); // totally random 2238475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int COLORS = 12; 2248475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler hsv[0] = irand(0,COLORS) * (360f/COLORS); 2258475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return Color.HSVToColor(hsv); 2268475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2278475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2288475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler @Override 2298475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler protected synchronized void onSizeChanged (int w, int h, int oldw, int oldh) { 2308475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler super.onSizeChanged(w, h, oldw, oldh); 2318475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (mWidth == w && mHeight == h) return; 2328475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2338475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final boolean wasStarted = mStarted; 2348475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (wasStarted) { 2358475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler stop(); 2368475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2378475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2388475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mWidth = w; 2398475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mHeight = h; 2408475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2418475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mCells = null; 2428475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler removeAllViewsInLayout(); 2438475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mFreeList.clear(); 2448475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2458475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mRows = mHeight / mCellSize; 2468475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mColumns = mWidth / mCellSize; 2478475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2488475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mCells = new View[mRows * mColumns]; 2498475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2508475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (DEBUG) Log.v(TAG, String.format("New dimensions: %dx%d", mColumns, mRows)); 2518475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2528475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler setScaleX(SCALE); 2538475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler setScaleY(SCALE); 2548475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler setTranslationX(0.5f * (mWidth - mCellSize * mColumns) * SCALE); 2558475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler setTranslationY(0.5f * (mHeight - mCellSize * mRows) * SCALE); 2568475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2578475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (int j=0; j<mRows; j++) { 2588475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (int i=0; i<mColumns; i++) { 2598475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mFreeList.add(new Point(i,j)); 2608475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2618475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2628475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2638475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (wasStarted) { 2648475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler start(); 2658475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2668475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2678475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2688475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void fillFreeList() { 2698475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler fillFreeList(DURATION); 2708475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2718475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2728475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public synchronized void fillFreeList(int animationLen) { 2738475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final Context ctx = getContext(); 2748475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(mCellSize, mCellSize); 2758475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2768475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler while (! mFreeList.isEmpty()) { 2778475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler Point pt = mFreeList.iterator().next(); 2788475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mFreeList.remove(pt); 2798475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int i=pt.x; 2808475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int j=pt.y; 2818475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2828475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (mCells[j*mColumns+i] != null) continue; 2838475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final ImageView v = new ImageView(ctx); 2848475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setOnClickListener(new OnClickListener() { 2858475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler @Override 2868475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void onClick(View view) { 2878475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler place(v, true); 2888475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler postDelayed(new Runnable() { public void run() { fillFreeList(); } }, DURATION/2); 2898475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 2908475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }); 2918475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2928475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int c = random_color(); 2938475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setBackgroundColor(c); 2948475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 2958475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final float which = frand(); 2968475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final Drawable d; 297f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler if (which < 0.0005f) { 2988475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler d = mDrawables.get(pick(XXRARE_PASTRIES)); 299f9f63355e3f05186a3652c0ef3f0039ed97db918Daniel Sandler } else if (which < 0.005f) { 3008475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler d = mDrawables.get(pick(XRARE_PASTRIES)); 3018475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } else if (which < 0.5f) { 3028475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler d = mDrawables.get(pick(RARE_PASTRIES)); 3038475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } else if (which < 0.7f) { 3048475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler d = mDrawables.get(pick(PASTRIES)); 3058475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } else { 3068475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler d = null; 3078475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3088475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (d != null) { 3098475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.getOverlay().add(d); 3108475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3118475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 3128475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler lp.width = lp.height = mCellSize; 3138475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler addView(v, lp); 3148475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler place(v, pt, false); 3158475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (animationLen > 0) { 3168475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final float s = (Integer) v.getTag(TAG_SPAN); 3178475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setScaleX(0.5f * s); 3188475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setScaleY(0.5f * s); 3198475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setAlpha(0f); 3209279d45b8d26c88c69fa917816ea396142627020Daniel Sandler v.animate().withLayer().scaleX(s).scaleY(s).alpha(1f).setDuration(animationLen); 3218475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3228475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3238475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3248475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 3258475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void place(View v, boolean animate) { 3268475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler place(v, new Point(irand(0, mColumns), irand(0, mRows)), animate); 3278475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3288475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 3299279d45b8d26c88c69fa917816ea396142627020Daniel Sandler // we don't have .withLayer() on general Animators 3309279d45b8d26c88c69fa917816ea396142627020Daniel Sandler private final Animator.AnimatorListener makeHardwareLayerListener(final View v) { 3319279d45b8d26c88c69fa917816ea396142627020Daniel Sandler return new AnimatorListenerAdapter() { 3329279d45b8d26c88c69fa917816ea396142627020Daniel Sandler @Override 3339279d45b8d26c88c69fa917816ea396142627020Daniel Sandler public void onAnimationStart(Animator animator) { 3349279d45b8d26c88c69fa917816ea396142627020Daniel Sandler v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 3359279d45b8d26c88c69fa917816ea396142627020Daniel Sandler v.buildLayer(); 3369279d45b8d26c88c69fa917816ea396142627020Daniel Sandler } 3379279d45b8d26c88c69fa917816ea396142627020Daniel Sandler @Override 3389279d45b8d26c88c69fa917816ea396142627020Daniel Sandler public void onAnimationEnd(Animator animator) { 3399279d45b8d26c88c69fa917816ea396142627020Daniel Sandler v.setLayerType(View.LAYER_TYPE_NONE, null); 3409279d45b8d26c88c69fa917816ea396142627020Daniel Sandler } 3419279d45b8d26c88c69fa917816ea396142627020Daniel Sandler }; 3429279d45b8d26c88c69fa917816ea396142627020Daniel Sandler } 3439279d45b8d26c88c69fa917816ea396142627020Daniel Sandler 3448475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private final HashSet<View> tmpSet = new HashSet<View>(); 3458475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public synchronized void place(View v, Point pt, boolean animate) { 3468475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int i = pt.x; 3478475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int j = pt.y; 3488475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final float rnd = frand(); 3498475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (v.getTag(TAG_POS) != null) { 3508475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (final Point oc : getOccupied(v)) { 3518475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mFreeList.add(oc); 3528475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mCells[oc.y*mColumns + oc.x] = null; 3538475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3548475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3558475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler int scale = 1; 3568475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (rnd < PROB_4X) { 3578475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (!(i >= mColumns-3 || j >= mRows-3)) { 3588475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler scale = 4; 3598475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3608475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } else if (rnd < PROB_3X) { 3618475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (!(i >= mColumns-2 || j >= mRows-2)) { 3628475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler scale = 3; 3638475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3648475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } else if (rnd < PROB_2X) { 3658475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (!(i == mColumns-1 || j == mRows-1)) { 3668475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler scale = 2; 3678475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3688475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3698475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 3708475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setTag(TAG_POS, pt); 3718475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setTag(TAG_SPAN, scale); 3728475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 3738475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler tmpSet.clear(); 3748475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 3758475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final Point[] occupied = getOccupied(v); 3768475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (final Point oc : occupied) { 3778475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final View squatter = mCells[oc.y*mColumns + oc.x]; 3788475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (squatter != null) { 3798475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler tmpSet.add(squatter); 3808475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3818475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3828475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 3838475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (final View squatter : tmpSet) { 3848475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (final Point sq : getOccupied(squatter)) { 3858475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mFreeList.add(sq); 3868475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mCells[sq.y*mColumns + sq.x] = null; 3878475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 3888475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (squatter != v) { 3898475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler squatter.setTag(TAG_POS, null); 3908475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (animate) { 3919279d45b8d26c88c69fa917816ea396142627020Daniel Sandler squatter.animate().withLayer() 3929279d45b8d26c88c69fa917816ea396142627020Daniel Sandler .scaleX(0.5f).scaleY(0.5f).alpha(0) 3938475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler .setDuration(DURATION) 3948475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler .setInterpolator(new AccelerateInterpolator()) 3958475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler .setListener(new Animator.AnimatorListener() { 3968475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void onAnimationStart(Animator animator) { } 3978475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void onAnimationEnd(Animator animator) { 3988475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler removeView(squatter); 3998475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4008475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void onAnimationCancel(Animator animator) { } 4018475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void onAnimationRepeat(Animator animator) { } 4028475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler }) 4038475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler .start(); 4048475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } else { 4058475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler removeView(squatter); 4068475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4078475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4088475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4098475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4108475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (final Point oc : occupied) { 4118475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mCells[oc.y*mColumns + oc.x] = v; 4128475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mFreeList.remove(oc); 4138475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4148475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4158475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final float rot = (float)irand(0, 4) * 90f; 4168475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4178475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (animate) { 4188475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.bringToFront(); 4199279d45b8d26c88c69fa917816ea396142627020Daniel Sandler 4208475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler AnimatorSet set1 = new AnimatorSet(); 4218475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler set1.playTogether( 4228475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler ObjectAnimator.ofFloat(v, View.SCALE_X, (float) scale), 4238475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler ObjectAnimator.ofFloat(v, View.SCALE_Y, (float) scale) 4248475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler ); 4258475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler set1.setInterpolator(new AnticipateOvershootInterpolator()); 4268475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler set1.setDuration(DURATION); 4278475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4288475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler AnimatorSet set2 = new AnimatorSet(); 4298475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler set2.playTogether( 4308475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler ObjectAnimator.ofFloat(v, View.ROTATION, rot), 4318475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler ObjectAnimator.ofFloat(v, View.X, i* mCellSize + (scale-1) * mCellSize /2), 4328475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler ObjectAnimator.ofFloat(v, View.Y, j* mCellSize + (scale-1) * mCellSize /2) 4338475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler ); 4348475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler set2.setInterpolator(new DecelerateInterpolator()); 4358475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler set2.setDuration(DURATION); 4369279d45b8d26c88c69fa917816ea396142627020Daniel Sandler 4379279d45b8d26c88c69fa917816ea396142627020Daniel Sandler set1.addListener(makeHardwareLayerListener(v)); 4389279d45b8d26c88c69fa917816ea396142627020Daniel Sandler 4399279d45b8d26c88c69fa917816ea396142627020Daniel Sandler set1.start(); 4408475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler set2.start(); 4418475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } else { 4428475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setX(i * mCellSize + (scale-1) * mCellSize /2); 4438475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setY(j * mCellSize + (scale-1) * mCellSize /2); 4448475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setScaleX((float) scale); 4458475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setScaleY((float) scale); 4468475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler v.setRotation(rot); 4478475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4488475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4498475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4508475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private Point[] getOccupied(View v) { 4518475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int scale = (Integer) v.getTag(TAG_SPAN); 4528475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final Point pt = (Point)v.getTag(TAG_POS); 4538475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (pt == null || scale == 0) return new Point[0]; 4548475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4558475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final Point[] result = new Point[scale * scale]; 4568475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler int p=0; 4578475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (int i=0; i<scale; i++) { 4588475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (int j=0; j<scale; j++) { 4598475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler result[p++] = new Point(pt.x + i, pt.y + j); 4608475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4618475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4628475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return result; 4638475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4648475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4658475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler static float frand() { 4668475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return (float)(Math.random()); 4678475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4688475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4698475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler static float frand(float a, float b) { 4708475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return (frand() * (b-a) + a); 4718475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4728475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4738475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler static int irand(int a, int b) { 4748475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return (int)(frand(a, b)); 4758475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4768475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4778475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler @Override 4788475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void onDraw(Canvas c) { 4798475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler super.onDraw(c); 4808475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler if (!DEBUG) return; 4818475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4828475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler Paint pt = new Paint(); 4838475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler pt.setStyle(Paint.Style.STROKE); 4848475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler pt.setColor(0xFFCCCCCC); 4858475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler pt.setStrokeWidth(2.0f); 4868475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4878475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final Rect check = new Rect(); 4888475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int N = getChildCount(); 4898475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler for (int i = 0; i < N; i++) { 4908475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler View stone = getChildAt(i); 4918475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4928475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler stone.getHitRect(check); 4938475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4948475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler c.drawRect(check, pt); 4958475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4968475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 4978475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 4988475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public static class RescalingContainer extends FrameLayout { 4998475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private DessertCaseView mView; 5008475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler private float mDarkness; 5018475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 5028475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public RescalingContainer(Context context) { 5038475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler super(context); 5048475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 5058475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler setSystemUiVisibility(0 5068475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler | View.SYSTEM_UI_FLAG_FULLSCREEN 5078475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 5088475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 5098475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 5105c6a781eaf5eafd5f3bba46f1cfd7e53cd0428daDaniel Sandler | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 5118475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler ); 5128475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 5138475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 5148475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void setView(DessertCaseView v) { 5158475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler addView(v); 5168475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mView = v; 5178475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 5188475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 5198475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler @Override 5208475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler protected void onLayout (boolean changed, int left, int top, int right, int bottom) { 5218475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final float w = right-left; 5228475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final float h = bottom-top; 5238475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int w2 = (int) (w / mView.SCALE / 2); 5248475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int h2 = (int) (h / mView.SCALE / 2); 5258475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int cx = (int) (left + w * 0.5f); 5268475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int cy = (int) (top + h * 0.5f); 5278475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mView.layout(cx - w2, cy - h2, cx + w2, cy + h2); 5288475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 5298475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 5308475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public void setDarkness(float p) { 5318475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler mDarkness = p; 5328475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler getDarkness(); 5338475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler final int x = (int) (p * 0xff); 5348475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler setBackgroundColor(x << 24 & 0xFF000000); 5358475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 5368475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler 5378475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler public float getDarkness() { 5388475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler return mDarkness; 5398475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 5408475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler } 5418475a74bdd9d6e1520fe66cdffb7b07c19c736e0Daniel Sandler} 542