12352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown/* 22352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Copyright (C) 2011 The Android Open Source Project 32352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 42352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 52352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * you may not use this file except in compliance with the License. 62352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * You may obtain a copy of the License at 72352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 82352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 92352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Unless required by applicable law or agreed to in writing, software 112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * See the License for the specific language governing permissions and 142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * limitations under the License. 152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownpackage android.view; 182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 19d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukaiimport android.annotation.NonNull; 20d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukaiimport android.util.SparseArray; 212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport com.android.internal.util.XmlUtils; 222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 237b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbyeimport android.annotation.XmlRes; 242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.content.Context; 252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.content.res.Resources; 262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.content.res.TypedArray; 272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.content.res.XmlResourceParser; 282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.graphics.Bitmap; 29808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukaiimport android.graphics.drawable.AnimationDrawable; 302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.graphics.drawable.BitmapDrawable; 312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.graphics.drawable.Drawable; 322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.os.Parcel; 332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.os.Parcelable; 342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.util.Log; 352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown/** 372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Represents an icon that can be used as a mouse pointer. 382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * <p> 39f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright * Pointer icons can be provided either by the system using system types, 402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * or by applications using bitmaps or application resources. 412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * </p> 422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownpublic final class PointerIcon implements Parcelable { 442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown private static final String TAG = "PointerIcon"; 452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 46f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** {@hide} Type constant: Custom icon with a user-supplied bitmap. */ 47f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_CUSTOM = -1; 482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 49f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: Null icon. It has no bitmap. */ 50f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_NULL = 0; 512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 52f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: no icons are specified. If all views uses this, then falls back 53f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright * to the default type, but this is helpful to distinguish a view explicitly want 541db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai * to have the default icon. 55d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai * @hide 561db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai */ 57f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_NOT_SPECIFIED = 1; 581db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 59f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: Arrow icon. (Default mouse pointer) */ 60f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_ARROW = 1000; 612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 62f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** {@hide} Type constant: Spot hover icon for touchpads. */ 63f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_SPOT_HOVER = 2000; 642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 65f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** {@hide} Type constant: Spot touch icon for touchpads. */ 66f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_SPOT_TOUCH = 2001; 672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 68f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** {@hide} Type constant: Spot anchor icon for touchpads. */ 69f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_SPOT_ANCHOR = 2002; 702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 71f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright // Type constants for additional predefined icons for mice. 72f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: context-menu. */ 73f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_CONTEXT_MENU = 1001; 741db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 75f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: hand. */ 76f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_HAND = 1002; 771db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 78f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: help. */ 79f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_HELP = 1003; 801db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 81f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: wait. */ 82f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_WAIT = 1004; 831db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 84f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: cell. */ 85f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_CELL = 1006; 861db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 87f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: crosshair. */ 88f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_CROSSHAIR = 1007; 891db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 90f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: text. */ 91f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_TEXT = 1008; 921db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 93f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: vertical-text. */ 94f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_VERTICAL_TEXT = 1009; 951db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 96f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: alias (indicating an alias of/shortcut to something is 971db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai * to be created. */ 98f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_ALIAS = 1010; 991db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 100f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: copy. */ 101f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_COPY = 1011; 1021db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 103f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: no-drop. */ 104f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_NO_DROP = 1012; 1051db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 106f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: all-scroll. */ 107f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_ALL_SCROLL = 1013; 1081db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 109f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: horizontal double arrow mainly for resizing. */ 110f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; 1111db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 112f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: vertical double arrow mainly for resizing. */ 113f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; 1141db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 115f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: diagonal double arrow -- top-right to bottom-left. */ 116f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; 1171db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 118f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: diagonal double arrow -- top-left to bottom-right. */ 119f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; 1201db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 121f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: zoom-in. */ 122f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_ZOOM_IN = 1018; 1231db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 124f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: zoom-out. */ 125f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_ZOOM_OUT = 1019; 1261db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 127f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: grab. */ 128f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_GRAB = 1020; 1291db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 130f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright /** Type constant: grabbing. */ 131f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_GRABBING = 1021; 1321db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 133f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright // OEM private types should be defined starting at this range to avoid 134f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright // conflicts with any system types that may be defined in the future. 135f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright private static final int TYPE_OEM_FIRST = 10000; 1362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 137d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai /** The default pointer icon. */ 138f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static final int TYPE_DEFAULT = TYPE_ARROW; 1392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 140f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright private static final PointerIcon gNullIcon = new PointerIcon(TYPE_NULL); 141d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai private static final SparseArray<PointerIcon> gSystemIcons = new SparseArray<PointerIcon>(); 1421f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai private static boolean sUseLargeIcons = false; 143e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai 144f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright private final int mType; 1452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown private int mSystemIconResourceId; 1462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown private Bitmap mBitmap; 1472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown private float mHotSpotX; 1482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown private float mHotSpotY; 149808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai // The bitmaps for the additional frame of animated pointer icon. Note that the first frame 150808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai // will be stored in mBitmap. 151808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai private Bitmap mBitmapFrames[]; 152808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai private int mDurationPerFrame; 1532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 154f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright private PointerIcon(int type) { 155f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright mType = type; 1562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 1572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown /** 1592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Gets a special pointer icon that has no bitmap. 1602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 1612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @return The null pointer icon. 1622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 163f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright * @see #TYPE_NULL 164d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai * @hide 1652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 1662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown public static PointerIcon getNullIcon() { 1672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return gNullIcon; 1682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 1692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown /** 1712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Gets the default pointer icon. 1722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 1732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @param context The context. 1742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @return The default pointer icon. 1752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 1762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @throws IllegalArgumentException if context is null. 177d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai * @hide 1782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 179d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai public static PointerIcon getDefaultIcon(@NonNull Context context) { 180f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright return getSystemIcon(context, TYPE_DEFAULT); 1812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 1822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown /** 184f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright * Gets a system pointer icon for the given type. 185f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright * If typeis not recognized, returns the default pointer icon. 1862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 1872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @param context The context. 188f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright * @param type The pointer icon type. 1892352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @return The pointer icon. 1902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 1912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @throws IllegalArgumentException if context is null. 1922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 193f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static PointerIcon getSystemIcon(@NonNull Context context, int type) { 1942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (context == null) { 1952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("context must not be null"); 1962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 1972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 198f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright if (type == TYPE_NULL) { 1992352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return gNullIcon; 2002352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 2012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 202f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright PointerIcon icon = gSystemIcons.get(type); 203d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai if (icon != null) { 204d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai return icon; 205d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai } 206d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai 207f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright int typeIndex = getSystemIconTypeIndex(type); 208f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright if (typeIndex == 0) { 209f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright typeIndex = getSystemIconTypeIndex(TYPE_DEFAULT); 2102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 2112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 212e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai int defStyle = sUseLargeIcons ? 21319a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai com.android.internal.R.style.LargePointer : com.android.internal.R.style.Pointer; 2142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown TypedArray a = context.obtainStyledAttributes(null, 2152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown com.android.internal.R.styleable.Pointer, 21619a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai 0, defStyle); 217f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright int resourceId = a.getResourceId(typeIndex, -1); 2182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown a.recycle(); 2192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 2202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (resourceId == -1) { 221f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright Log.w(TAG, "Missing theme resources for pointer icon type " + type); 222f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright return type == TYPE_DEFAULT ? gNullIcon : getSystemIcon(context, TYPE_DEFAULT); 2232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 2242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 225f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright icon = new PointerIcon(type); 2262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if ((resourceId & 0xff000000) == 0x01000000) { 2272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown icon.mSystemIconResourceId = resourceId; 2282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } else { 2298eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette icon.loadResource(context, context.getResources(), resourceId); 2302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 231f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright gSystemIcons.append(type, icon); 2322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return icon; 2332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 2342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 2352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown /** 2361f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai * Updates wheter accessibility large icons are used or not. 2371f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai * @hide 2381f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai */ 2391f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai public static void setUseLargeIcons(boolean use) { 2401f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai sUseLargeIcons = use; 2411f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai gSystemIcons.clear(); 2421f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai } 2431f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai 2441f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai /** 245f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright * Creates a custom pointer icon from the given bitmap and hotspot information. 2462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 2472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @param bitmap The bitmap for the icon. 248376d10e99e7db597fdff8a4e8f396161017c243cAlan Viverette * @param hotSpotX The X offset of the pointer icon hotspot in the bitmap. 2492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Must be within the [0, bitmap.getWidth()) range. 250376d10e99e7db597fdff8a4e8f396161017c243cAlan Viverette * @param hotSpotY The Y offset of the pointer icon hotspot in the bitmap. 2512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Must be within the [0, bitmap.getHeight()) range. 2522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @return A pointer icon for this bitmap. 2532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 2542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @throws IllegalArgumentException if bitmap is null, or if the x/y hotspot 2552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * parameters are invalid. 2562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 257f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static PointerIcon create(@NonNull Bitmap bitmap, float hotSpotX, float hotSpotY) { 2582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (bitmap == null) { 2592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("bitmap must not be null"); 2602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 2612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown validateHotSpot(bitmap, hotSpotX, hotSpotY); 2622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 263f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright PointerIcon icon = new PointerIcon(TYPE_CUSTOM); 2642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown icon.mBitmap = bitmap; 2652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown icon.mHotSpotX = hotSpotX; 2662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown icon.mHotSpotY = hotSpotY; 2672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return icon; 2682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 2692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 2702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown /** 2712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Loads a custom pointer icon from an XML resource. 2722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * <p> 2732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * The XML resource should have the following form: 2742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * <code> 2752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * <?xml version="1.0" encoding="utf-8"?> 2762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android" 2772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * android:bitmap="@drawable/my_pointer_bitmap" 2782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * android:hotSpotX="24" 2792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * android:hotSpotY="24" /> 2802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * </code> 2812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * </p> 2822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 2832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @param resources The resources object. 2842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @param resourceId The resource id. 2852352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @return The pointer icon. 2862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 2872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @throws IllegalArgumentException if resources is null. 2882352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @throws Resources.NotFoundException if the resource was not found or the drawable 2892352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * linked in the resource was not found. 2902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 291f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public static PointerIcon load(@NonNull Resources resources, @XmlRes int resourceId) { 2922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (resources == null) { 2932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("resources must not be null"); 2942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 2952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 296f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright PointerIcon icon = new PointerIcon(TYPE_CUSTOM); 2978eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette icon.loadResource(null, resources, resourceId); 2982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return icon; 2992352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3002352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown /** 3022352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Loads the bitmap and hotspot information for a pointer icon, if it is not already loaded. 3032352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Returns a pointer icon (not necessarily the same instance) with the information filled in. 3042352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 3052352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @param context The context. 3062352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @return The loaded pointer icon. 3072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 3082352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @throws IllegalArgumentException if context is null. 3092352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * @hide 3102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 311d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai public PointerIcon load(@NonNull Context context) { 3122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (context == null) { 3132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("context must not be null"); 3142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (mSystemIconResourceId == 0 || mBitmap != null) { 3172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return this; 3182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 320f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright PointerIcon result = new PointerIcon(mType); 3212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown result.mSystemIconResourceId = mSystemIconResourceId; 3228eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette result.loadResource(context, context.getResources(), mSystemIconResourceId); 3232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return result; 3242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 326d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai /** @hide */ 327f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public int getType() { 328f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright return mType; 3292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown public static final Parcelable.Creator<PointerIcon> CREATOR 3322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown = new Parcelable.Creator<PointerIcon>() { 3332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown public PointerIcon createFromParcel(Parcel in) { 334f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright int type = in.readInt(); 335f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright if (type == TYPE_NULL) { 3362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return getNullIcon(); 3372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown int systemIconResourceId = in.readInt(); 3402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (systemIconResourceId != 0) { 341f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright PointerIcon icon = new PointerIcon(type); 3422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown icon.mSystemIconResourceId = systemIconResourceId; 3432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return icon; 3442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown Bitmap bitmap = Bitmap.CREATOR.createFromParcel(in); 3472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown float hotSpotX = in.readFloat(); 3482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown float hotSpotY = in.readFloat(); 349f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright return PointerIcon.create(bitmap, hotSpotX, hotSpotY); 3502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown public PointerIcon[] newArray(int size) { 3532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return new PointerIcon[size]; 3542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown }; 3562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown public int describeContents() { 3582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return 0; 3592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown public void writeToParcel(Parcel out, int flags) { 362f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright out.writeInt(mType); 3632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 364f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright if (mType != TYPE_NULL) { 3652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown out.writeInt(mSystemIconResourceId); 3662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (mSystemIconResourceId == 0) { 3672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown mBitmap.writeToParcel(out, flags); 3682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown out.writeFloat(mHotSpotX); 3692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown out.writeFloat(mHotSpotY); 3702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown @Override 3752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown public boolean equals(Object other) { 3762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (this == other) { 3772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return true; 3782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (other == null || !(other instanceof PointerIcon)) { 3812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return false; 3822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown PointerIcon otherIcon = (PointerIcon) other; 385f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright if (mType != otherIcon.mType 3862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown || mSystemIconResourceId != otherIcon.mSystemIconResourceId) { 3872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return false; 3882352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3892352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (mSystemIconResourceId == 0 && (mBitmap != otherIcon.mBitmap 3912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown || mHotSpotX != otherIcon.mHotSpotX 3922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown || mHotSpotY != otherIcon.mHotSpotY)) { 3932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return false; 3942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return true; 3972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 3982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 3997b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye private void loadResource(Context context, Resources resources, @XmlRes int resourceId) { 400376d10e99e7db597fdff8a4e8f396161017c243cAlan Viverette final XmlResourceParser parser = resources.getXml(resourceId); 4012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown final int bitmapRes; 4022352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown final float hotSpotX; 4032352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown final float hotSpotY; 4042352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown try { 4052352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown XmlUtils.beginDocument(parser, "pointer-icon"); 4062352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 407376d10e99e7db597fdff8a4e8f396161017c243cAlan Viverette final TypedArray a = resources.obtainAttributes( 4082352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown parser, com.android.internal.R.styleable.PointerIcon); 4092352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown bitmapRes = a.getResourceId(com.android.internal.R.styleable.PointerIcon_bitmap, 0); 410376d10e99e7db597fdff8a4e8f396161017c243cAlan Viverette hotSpotX = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0); 411376d10e99e7db597fdff8a4e8f396161017c243cAlan Viverette hotSpotY = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0); 4122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown a.recycle(); 4132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } catch (Exception ex) { 4142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("Exception parsing pointer icon resource.", ex); 4152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } finally { 4162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown parser.close(); 4172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 4182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 4192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (bitmapRes == 0) { 4202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("<pointer-icon> is missing bitmap attribute."); 4212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 4222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 4238eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette Drawable drawable; 4248eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette if (context == null) { 4258eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette drawable = resources.getDrawable(bitmapRes); 4268eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette } else { 4278eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette drawable = context.getDrawable(bitmapRes); 4288eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette } 429808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai if (drawable instanceof AnimationDrawable) { 430808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai // Extract animation frame bitmaps. 431808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai final AnimationDrawable animationDrawable = (AnimationDrawable) drawable; 432808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai final int frames = animationDrawable.getNumberOfFrames(); 433808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai drawable = animationDrawable.getFrame(0); 434808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai if (frames == 1) { 435808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai Log.w(TAG, "Animation icon with single frame -- simply treating the first " 436808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai + "frame as a normal bitmap icon."); 437808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai } else { 438808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai // Assumes they have the exact duration. 439808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai mDurationPerFrame = animationDrawable.getDuration(0); 440808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai mBitmapFrames = new Bitmap[frames - 1]; 441808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai final int width = drawable.getIntrinsicWidth(); 442808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai final int height = drawable.getIntrinsicHeight(); 443808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai for (int i = 1; i < frames; ++i) { 444808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai Drawable drawableFrame = animationDrawable.getFrame(i); 445808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai if (!(drawableFrame instanceof BitmapDrawable)) { 446808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai throw new IllegalArgumentException("Frame of an animated pointer icon " 447808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai + "must refer to a bitmap drawable."); 448808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai } 449808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai if (drawableFrame.getIntrinsicWidth() != width || 450808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai drawableFrame.getIntrinsicHeight() != height) { 451808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai throw new IllegalArgumentException("The bitmap size of " + i + "-th frame " 452808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai + "is different. All frames should have the exact same size and " 453808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai + "share the same hotspot."); 454808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai } 455808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai mBitmapFrames[i - 1] = ((BitmapDrawable)drawableFrame).getBitmap(); 456808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai } 457808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai } 458808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai } 4592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!(drawable instanceof BitmapDrawable)) { 4602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("<pointer-icon> bitmap attribute must " 4612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown + "refer to a bitmap drawable."); 4622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 4632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 4642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown // Set the properties now that we have successfully loaded the icon. 4652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown mBitmap = ((BitmapDrawable)drawable).getBitmap(); 4662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown mHotSpotX = hotSpotX; 4672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown mHotSpotY = hotSpotY; 4682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 4692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 4702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown private static void validateHotSpot(Bitmap bitmap, float hotSpotX, float hotSpotY) { 4712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (hotSpotX < 0 || hotSpotX >= bitmap.getWidth()) { 4722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("x hotspot lies outside of the bitmap area"); 4732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 4742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (hotSpotY < 0 || hotSpotY >= bitmap.getHeight()) { 4752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown throw new IllegalArgumentException("y hotspot lies outside of the bitmap area"); 4762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 4772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 4782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 479f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright private static int getSystemIconTypeIndex(int type) { 480f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright switch (type) { 481f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_ARROW: 4822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return com.android.internal.R.styleable.Pointer_pointerIconArrow; 483f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_SPOT_HOVER: 4842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return com.android.internal.R.styleable.Pointer_pointerIconSpotHover; 485f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_SPOT_TOUCH: 4862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return com.android.internal.R.styleable.Pointer_pointerIconSpotTouch; 487f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_SPOT_ANCHOR: 4882352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return com.android.internal.R.styleable.Pointer_pointerIconSpotAnchor; 489f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_HAND: 4901db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconHand; 491f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_CONTEXT_MENU: 4921db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconContextMenu; 493f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_HELP: 4941db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconHelp; 495f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_WAIT: 496808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconWait; 497f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_CELL: 4981db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconCell; 499f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_CROSSHAIR: 5001db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconCrosshair; 501f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_TEXT: 5021db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconText; 503f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_VERTICAL_TEXT: 5041db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconVerticalText; 505f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_ALIAS: 5061db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconAlias; 507f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_COPY: 5081db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconCopy; 509f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_ALL_SCROLL: 5101db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconAllScroll; 511f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_NO_DROP: 5121db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconNodrop; 513f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_HORIZONTAL_DOUBLE_ARROW: 5141db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconHorizontalDoubleArrow; 515f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_VERTICAL_DOUBLE_ARROW: 5161db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconVerticalDoubleArrow; 517f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW: 5181db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable. 5191db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai Pointer_pointerIconTopRightDiagonalDoubleArrow; 520f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW: 5211db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable. 5221db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai Pointer_pointerIconTopLeftDiagonalDoubleArrow; 523f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_ZOOM_IN: 5241db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconZoomIn; 525f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_ZOOM_OUT: 5261db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconZoomOut; 527f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_GRAB: 5281db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconGrab; 529f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright case TYPE_GRABBING: 5301db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai return com.android.internal.R.styleable.Pointer_pointerIconGrabbing; 5312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown default: 5322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return 0; 5332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 5342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 5352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 536