Utilities.java revision 97d85d23b013347bead4e2f5fa430a79ce69431e
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1997d85d23b013347bead4e2f5fa430a79ce69431eWinson Chungimport java.util.Random; 2097d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung 21aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.content.Context; 22aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.content.res.Resources; 2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 241291a8c236c84451321438cb68855f6f2eb24959Joe Onoratoimport android.graphics.BlurMaskFilter; 2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Canvas; 2656d8291af6a28c6ba64113120efdf84a785e816cJoe Onoratoimport android.graphics.ColorMatrix; 2756d8291af6a28c6ba64113120efdf84a785e816cJoe Onoratoimport android.graphics.ColorMatrixColorFilter; 2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Paint; 29bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.graphics.PaintFlagsDrawFilter; 301291a8c236c84451321438cb68855f6f2eb24959Joe Onoratoimport android.graphics.PorterDuff; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Rect; 32bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.graphics.RectF; 33cdd117935f51d66f6f212387300d851f81aa071fMike Reedimport android.graphics.TableMaskFilter; 34bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.graphics.Typeface; 35aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.graphics.drawable.BitmapDrawable; 36aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.graphics.drawable.Drawable; 37aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.graphics.drawable.PaintDrawable; 38bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.text.StaticLayout; 39bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.text.TextPaint; 40aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.text.Layout.Alignment; 4132ce7f17a85abf9b175f773371308876f7401547Dianne Hackbornimport android.util.DisplayMetrics; 42bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.util.Log; 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 44edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guyimport com.android.launcher.R; 45edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Various utilities shared amongst the Launcher's classes. 4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectfinal class Utilities { 501291a8c236c84451321438cb68855f6f2eb24959Joe Onorato private static final String TAG = "Launcher.Utilities"; 511291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 529392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato private static final boolean TEXT_BURN = false; 539392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato 5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static int sIconWidth = -1; 5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static int sIconHeight = -1; 567ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka private static int sIconContentSize = -1; 576665c0f1fec6ec0962896622986340081df992e7Joe Onorato private static int sIconTextureWidth = -1; 586665c0f1fec6ec0962896622986340081df992e7Joe Onorato private static int sIconTextureHeight = -1; 5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 601291a8c236c84451321438cb68855f6f2eb24959Joe Onorato private static final Paint sBlurPaint = new Paint(); 61eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato private static final Paint sGlowColorPressedPaint = new Paint(); 62c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato private static final Paint sGlowColorFocusedPaint = new Paint(); 6356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato private static final Paint sDisabledPaint = new Paint(); 6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final Rect sOldBounds = new Rect(); 6589911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy private static final Canvas sCanvas = new Canvas(); 6631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static { 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Paint.FILTER_BITMAP_FLAG)); 7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static Bitmap centerToFit(Bitmap bitmap, int width, int height, Context context) { 7331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int bitmapWidth = bitmap.getWidth(); 7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int bitmapHeight = bitmap.getHeight(); 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (bitmapWidth < width || bitmapHeight < height) { 7731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int color = context.getResources().getColor(R.color.window_background); 7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Bitmap centered = Bitmap.createBitmap(bitmapWidth < width ? width : bitmapWidth, 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project bitmapHeight < height ? height : bitmapHeight, Bitmap.Config.RGB_565); 8132ce7f17a85abf9b175f773371308876f7401547Dianne Hackborn centered.setDensity(bitmap.getDensity()); 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Canvas canvas = new Canvas(centered); 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawColor(color); 8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawBitmap(bitmap, (width - bitmapWidth) / 2.0f, (height - bitmapHeight) / 2.0f, 8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project null); 8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project bitmap = centered; 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return bitmap; 9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 936665c0f1fec6ec0962896622986340081df992e7Joe Onorato static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; 946665c0f1fec6ec0962896622986340081df992e7Joe Onorato static int sColorIndex = 0; 956665c0f1fec6ec0962896622986340081df992e7Joe Onorato 967ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka static int getIconContentSize() { 977ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka return sIconContentSize; 987ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka } 997ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka 1006665c0f1fec6ec0962896622986340081df992e7Joe Onorato /** 1016665c0f1fec6ec0962896622986340081df992e7Joe Onorato * Returns a bitmap suitable for the all apps view. The bitmap will be a power 1026665c0f1fec6ec0962896622986340081df992e7Joe Onorato * of two sized ARGB_8888 bitmap that can be used as a gl texture. 1036665c0f1fec6ec0962896622986340081df992e7Joe Onorato */ 1040589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato static Bitmap createIconBitmap(Drawable icon, Context context) { 1056665c0f1fec6ec0962896622986340081df992e7Joe Onorato synchronized (sCanvas) { // we share the statics :-( 1066665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (sIconWidth == -1) { 1076665c0f1fec6ec0962896622986340081df992e7Joe Onorato initStatics(context); 1086665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1096665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1106665c0f1fec6ec0962896622986340081df992e7Joe Onorato int width = sIconWidth; 1116665c0f1fec6ec0962896622986340081df992e7Joe Onorato int height = sIconHeight; 1126665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1136665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (icon instanceof PaintDrawable) { 1146665c0f1fec6ec0962896622986340081df992e7Joe Onorato PaintDrawable painter = (PaintDrawable) icon; 1156665c0f1fec6ec0962896622986340081df992e7Joe Onorato painter.setIntrinsicWidth(width); 1166665c0f1fec6ec0962896622986340081df992e7Joe Onorato painter.setIntrinsicHeight(height); 1176665c0f1fec6ec0962896622986340081df992e7Joe Onorato } else if (icon instanceof BitmapDrawable) { 1186665c0f1fec6ec0962896622986340081df992e7Joe Onorato // Ensure the bitmap has a density. 1196665c0f1fec6ec0962896622986340081df992e7Joe Onorato BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; 1206665c0f1fec6ec0962896622986340081df992e7Joe Onorato Bitmap bitmap = bitmapDrawable.getBitmap(); 1216665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { 1226665c0f1fec6ec0962896622986340081df992e7Joe Onorato bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics()); 1236665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1246665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1256665c0f1fec6ec0962896622986340081df992e7Joe Onorato int sourceWidth = icon.getIntrinsicWidth(); 1266665c0f1fec6ec0962896622986340081df992e7Joe Onorato int sourceHeight = icon.getIntrinsicHeight(); 1276665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1286665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (sourceWidth > 0 && sourceWidth > 0) { 1296665c0f1fec6ec0962896622986340081df992e7Joe Onorato // There are intrinsic sizes. 13089911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy if (width < sourceWidth || height < sourceHeight) { 1316665c0f1fec6ec0962896622986340081df992e7Joe Onorato // It's too big, scale it down. 1326665c0f1fec6ec0962896622986340081df992e7Joe Onorato final float ratio = (float) sourceWidth / sourceHeight; 1336665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (sourceWidth > sourceHeight) { 1346665c0f1fec6ec0962896622986340081df992e7Joe Onorato height = (int) (width / ratio); 1356665c0f1fec6ec0962896622986340081df992e7Joe Onorato } else if (sourceHeight > sourceWidth) { 1366665c0f1fec6ec0962896622986340081df992e7Joe Onorato width = (int) (height * ratio); 1376665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1386665c0f1fec6ec0962896622986340081df992e7Joe Onorato } else if (sourceWidth < width && sourceHeight < height) { 1396665c0f1fec6ec0962896622986340081df992e7Joe Onorato // It's small, use the size they gave us. 1406665c0f1fec6ec0962896622986340081df992e7Joe Onorato width = sourceWidth; 14189911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy height = sourceHeight; 1426665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1436665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1446665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1456665c0f1fec6ec0962896622986340081df992e7Joe Onorato // no intrinsic size --> use default size 1466665c0f1fec6ec0962896622986340081df992e7Joe Onorato int textureWidth = sIconTextureWidth; 1476665c0f1fec6ec0962896622986340081df992e7Joe Onorato int textureHeight = sIconTextureHeight; 1486665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1496665c0f1fec6ec0962896622986340081df992e7Joe Onorato final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, 1506665c0f1fec6ec0962896622986340081df992e7Joe Onorato Bitmap.Config.ARGB_8888); 1516665c0f1fec6ec0962896622986340081df992e7Joe Onorato final Canvas canvas = sCanvas; 1526665c0f1fec6ec0962896622986340081df992e7Joe Onorato canvas.setBitmap(bitmap); 1536665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1546665c0f1fec6ec0962896622986340081df992e7Joe Onorato final int left = (textureWidth-width) / 2; 1556665c0f1fec6ec0962896622986340081df992e7Joe Onorato final int top = (textureHeight-height) / 2; 1566665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1576665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (false) { 1586665c0f1fec6ec0962896622986340081df992e7Joe Onorato // draw a big box for the icon for debugging 1596665c0f1fec6ec0962896622986340081df992e7Joe Onorato canvas.drawColor(sColors[sColorIndex]); 1606665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (++sColorIndex >= sColors.length) sColorIndex = 0; 1616665c0f1fec6ec0962896622986340081df992e7Joe Onorato Paint debugPaint = new Paint(); 1626665c0f1fec6ec0962896622986340081df992e7Joe Onorato debugPaint.setColor(0xffcccc00); 1636665c0f1fec6ec0962896622986340081df992e7Joe Onorato canvas.drawRect(left, top, left+width, top+height, debugPaint); 1646665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1656665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1666665c0f1fec6ec0962896622986340081df992e7Joe Onorato sOldBounds.set(icon.getBounds()); 1676665c0f1fec6ec0962896622986340081df992e7Joe Onorato icon.setBounds(left, top, left+width, top+height); 1686665c0f1fec6ec0962896622986340081df992e7Joe Onorato icon.draw(canvas); 1696665c0f1fec6ec0962896622986340081df992e7Joe Onorato icon.setBounds(sOldBounds); 1706665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1716665c0f1fec6ec0962896622986340081df992e7Joe Onorato return bitmap; 1726665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1736665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1746665c0f1fec6ec0962896622986340081df992e7Joe Onorato 175c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato static void drawSelectedAllAppsBitmap(Canvas dest, int destWidth, int destHeight, 176eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato boolean pressed, Bitmap src) { 1771291a8c236c84451321438cb68855f6f2eb24959Joe Onorato synchronized (sCanvas) { // we share the statics :-( 1781291a8c236c84451321438cb68855f6f2eb24959Joe Onorato if (sIconWidth == -1) { 1791291a8c236c84451321438cb68855f6f2eb24959Joe Onorato // We can't have gotten to here without src being initialized, which 1801291a8c236c84451321438cb68855f6f2eb24959Joe Onorato // comes from this file already. So just assert. 1811291a8c236c84451321438cb68855f6f2eb24959Joe Onorato //initStatics(context); 1821291a8c236c84451321438cb68855f6f2eb24959Joe Onorato throw new RuntimeException("Assertion failed: Utilities not initialized"); 1831291a8c236c84451321438cb68855f6f2eb24959Joe Onorato } 1841291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 1851291a8c236c84451321438cb68855f6f2eb24959Joe Onorato dest.drawColor(0, PorterDuff.Mode.CLEAR); 186b4ecab24dbff6e6dc9e7929655a55199fc32e8ddJason Sams 1871291a8c236c84451321438cb68855f6f2eb24959Joe Onorato int[] xy = new int[2]; 188cdd117935f51d66f6f212387300d851f81aa071fMike Reed Bitmap mask = src.extractAlpha(sBlurPaint, xy); 1891291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 190cdd117935f51d66f6f212387300d851f81aa071fMike Reed float px = (destWidth - src.getWidth()) / 2; 191cdd117935f51d66f6f212387300d851f81aa071fMike Reed float py = (destHeight - src.getHeight()) / 2; 192c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato dest.drawBitmap(mask, px + xy[0], py + xy[1], 193eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato pressed ? sGlowColorPressedPaint : sGlowColorFocusedPaint); 1941291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 1951291a8c236c84451321438cb68855f6f2eb24959Joe Onorato mask.recycle(); 1961291a8c236c84451321438cb68855f6f2eb24959Joe Onorato } 1971291a8c236c84451321438cb68855f6f2eb24959Joe Onorato } 1986665c0f1fec6ec0962896622986340081df992e7Joe Onorato 19931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 20031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Returns a Bitmap representing the thumbnail of the specified Bitmap. 20131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The size of the thumbnail is defined by the dimension 20231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * android.R.dimen.launcher_application_icon_size. 20331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 20431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param bitmap The bitmap to get a thumbnail of. 20531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 20631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 20731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return A thumbnail for the specified bitmap or the bitmap itself if the 20831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * thumbnail could not be created. 20931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 2100589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato static Bitmap resampleIconBitmap(Bitmap bitmap, Context context) { 2119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (sCanvas) { // we share the statics :-( 2129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (sIconWidth == -1) { 2136665c0f1fec6ec0962896622986340081df992e7Joe Onorato initStatics(context); 2149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 21531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2160589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (bitmap.getWidth() == sIconWidth && bitmap.getHeight() == sIconHeight) { 2170589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return bitmap; 2180589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } else { 2190589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return createIconBitmap(new BitmapDrawable(bitmap), context); 22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 223bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 22456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato static Bitmap drawDisabledBitmap(Bitmap bitmap, Context context) { 22556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato synchronized (sCanvas) { // we share the statics :-( 22656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (sIconWidth == -1) { 22756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato initStatics(context); 22856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 22956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final Bitmap disabled = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), 23056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap.Config.ARGB_8888); 23156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final Canvas canvas = sCanvas; 23256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato canvas.setBitmap(disabled); 23356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 23456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato canvas.drawBitmap(bitmap, 0.0f, 0.0f, sDisabledPaint); 23556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 23656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return disabled; 23756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 23856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 23956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 2406665c0f1fec6ec0962896622986340081df992e7Joe Onorato private static void initStatics(Context context) { 2416665c0f1fec6ec0962896622986340081df992e7Joe Onorato final Resources resources = context.getResources(); 2421291a8c236c84451321438cb68855f6f2eb24959Joe Onorato final DisplayMetrics metrics = resources.getDisplayMetrics(); 2431291a8c236c84451321438cb68855f6f2eb24959Joe Onorato final float density = metrics.density; 2441291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 245c9a961952d1a057029874f8426b90181f6876034Michael Jurka sIconWidth = sIconHeight = (int) resources.getDimension(R.dimen.app_icon_size); 2467ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka if (LauncherApplication.isScreenXLarge()) { 2477ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka sIconContentSize = (int) resources.getDimension(R.dimen.app_icon_content_size); 2487ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka } 249b4ecab24dbff6e6dc9e7929655a55199fc32e8ddJason Sams sIconTextureWidth = sIconTextureHeight = sIconWidth + 2; 2501291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 251a4c0cb965575b7a0832d92bc0b33e06c7c66cb10Joe Onorato sBlurPaint.setMaskFilter(new BlurMaskFilter(5 * density, BlurMaskFilter.Blur.NORMAL)); 252eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato sGlowColorPressedPaint.setColor(0xffffc300); 253eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato sGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 254c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato sGlowColorFocusedPaint.setColor(0xffff8e00); 255c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato sGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 25656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 25756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato ColorMatrix cm = new ColorMatrix(); 25856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato cm.setSaturation(0.2f); 25956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato sDisabledPaint.setColorFilter(new ColorMatrixColorFilter(cm)); 26056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato sDisabledPaint.setAlpha(0x88); 2616665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 2626665c0f1fec6ec0962896622986340081df992e7Joe Onorato 263bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato static class BubbleText { 264bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private static final int MAX_LINES = 2; 265bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 26688f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final TextPaint mTextPaint; 267bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 26888f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final RectF mBubbleRect = new RectF(); 269bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 27088f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final float mTextWidth; 27188f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final int mLeading; 27288f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final int mFirstLineY; 27388f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final int mLineHeight; 27488f38d186bcba897ef4222d23515f127c77358aaRomain Guy 27588f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final int mBitmapWidth; 27688f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final int mBitmapHeight; 27788f38d186bcba897ef4222d23515f127c77358aaRomain Guy private final int mDensity; 278bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 279bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato BubbleText(Context context) { 280bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato final Resources resources = context.getResources(); 281bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 28288f38d186bcba897ef4222d23515f127c77358aaRomain Guy final DisplayMetrics metrics = resources.getDisplayMetrics(); 28388f38d186bcba897ef4222d23515f127c77358aaRomain Guy final float scale = metrics.density; 28488f38d186bcba897ef4222d23515f127c77358aaRomain Guy mDensity = metrics.densityDpi; 285bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 286970516430064068a1513b7489848339829b7971aKenny Root final float paddingLeft = 2.0f * scale; 287970516430064068a1513b7489848339829b7971aKenny Root final float paddingRight = 2.0f * scale; 288442eda2cc1956003b2366c3060f8c0dbae024710Romain Guy final float cellWidth = resources.getDimension(R.dimen.title_texture_width); 289bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 290bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato RectF bubbleRect = mBubbleRect; 291bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato bubbleRect.left = 0; 292bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato bubbleRect.top = 0; 293c0c4fe39166b3ed8b9bb19129a890922d93f7a92Romain Guy bubbleRect.right = (int) cellWidth; 294bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 295970516430064068a1513b7489848339829b7971aKenny Root mTextWidth = cellWidth - paddingLeft - paddingRight; 296bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 297bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato TextPaint textPaint = mTextPaint = new TextPaint(); 298efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato textPaint.setTypeface(Typeface.DEFAULT); 299efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato textPaint.setTextSize(13*scale); 300bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato textPaint.setColor(0xffffffff); 30143e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato textPaint.setAntiAlias(true); 3029392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato if (TEXT_BURN) { 3039392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato textPaint.setShadowLayer(8, 0, 0, 0xff000000); 3049392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato } 305bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 306bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato float ascent = -textPaint.ascent(); 307bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato float descent = textPaint.descent(); 30843e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato float leading = 0.0f;//(ascent+descent) * 0.1f; 309bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mLeading = (int)(leading + 0.5f); 310bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mFirstLineY = (int)(leading + ascent + 0.5f); 311bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mLineHeight = (int)(leading + ascent + descent + 0.5f); 312bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 313442eda2cc1956003b2366c3060f8c0dbae024710Romain Guy mBitmapWidth = (int)(mBubbleRect.width() + 0.5f); 31443e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato mBitmapHeight = roundToPow2((int)((MAX_LINES * mLineHeight) + leading + 0.5f)); 315bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 316fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato mBubbleRect.offsetTo((mBitmapWidth-mBubbleRect.width())/2, 0); 317fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato 318080d9b614e609826dce2606f9e474af674ead933Joe Onorato if (false) { 319080d9b614e609826dce2606f9e474af674ead933Joe Onorato Log.d(TAG, "mBitmapWidth=" + mBitmapWidth + " mBitmapHeight=" 320080d9b614e609826dce2606f9e474af674ead933Joe Onorato + mBitmapHeight + " w=" + ((int)(mBubbleRect.width() + 0.5f)) 321080d9b614e609826dce2606f9e474af674ead933Joe Onorato + " h=" + ((int)((MAX_LINES * mLineHeight) + leading + 0.5f))); 322080d9b614e609826dce2606f9e474af674ead933Joe Onorato } 323bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 324bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 325bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato /** You own the bitmap after this and you must call recycle on it. */ 326bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato Bitmap createTextBitmap(String text) { 3276ec11bc3a80341206be9506619deb7f9171d38c9Jason Sams Bitmap b = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ALPHA_8); 32888f38d186bcba897ef4222d23515f127c77358aaRomain Guy b.setDensity(mDensity); 329bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato Canvas c = new Canvas(b); 330bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 331bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato StaticLayout layout = new StaticLayout(text, mTextPaint, (int)mTextWidth, 332bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato Alignment.ALIGN_CENTER, 1, 0, true); 333bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato int lineCount = layout.getLineCount(); 334bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato if (lineCount > MAX_LINES) { 335bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato lineCount = MAX_LINES; 336bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 337fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //if (!TEXT_BURN && lineCount > 0) { 338fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //RectF bubbleRect = mBubbleRect; 339fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //bubbleRect.bottom = height(lineCount); 340fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //c.drawRoundRect(bubbleRect, mCornerRadius, mCornerRadius, mRectPaint); 341fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //} 342bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato for (int i=0; i<lineCount; i++) { 343fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato //int x = (int)((mBubbleRect.width() - layout.getLineMax(i)) / 2.0f); 344fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato //int y = mFirstLineY + (i * mLineHeight); 34588f38d186bcba897ef4222d23515f127c77358aaRomain Guy final String lineText = text.substring(layout.getLineStart(i), layout.getLineEnd(i)); 346fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato int x = (int)(mBubbleRect.left 34788f38d186bcba897ef4222d23515f127c77358aaRomain Guy + ((mBubbleRect.width() - mTextPaint.measureText(lineText)) * 0.5f)); 348bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato int y = mFirstLineY + (i * mLineHeight); 34988f38d186bcba897ef4222d23515f127c77358aaRomain Guy c.drawText(lineText, x, y, mTextPaint); 350bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 351bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 352bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato return b; 353bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 35443e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 35543e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato private int height(int lineCount) { 35643e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return (int)((lineCount * mLineHeight) + mLeading + mLeading + 0.0f); 35743e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 35843e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 35943e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato int getBubbleWidth() { 36043e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return (int)(mBubbleRect.width() + 0.5f); 36143e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 36243e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 36343e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato int getMaxBubbleHeight() { 36443e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return height(MAX_LINES); 36543e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 36643e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 36743e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato int getBitmapWidth() { 36843e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return mBitmapWidth; 36943e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 37043e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 37143e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato int getBitmapHeight() { 37243e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return mBitmapHeight; 37343e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 374bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 375bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 376bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato /** Only works for positive numbers. */ 377bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato static int roundToPow2(int n) { 378bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato int orig = n; 379bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato n >>= 1; 380bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato int mask = 0x8000000; 381bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato while (mask != 0 && (n & mask) == 0) { 382bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mask >>= 1; 383bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 384bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato while (mask != 0) { 385bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato n |= mask; 386bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mask >>= 1; 387bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 388bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato n += 1; 389bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato if (n != orig) { 390bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato n <<= 1; 391bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 392bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato return n; 393bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 39497d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung 39597d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung static int generateRandomId() { 39697d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung return new Random(System.currentTimeMillis()).nextInt(1 << 24); 39797d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung } 39831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 399