1/** 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v4.view; 18 19import android.content.Context; 20import android.content.res.Resources; 21import android.graphics.Bitmap; 22import android.support.v4.os.BuildCompat; 23 24/** 25 * Helper for accessing features in {@link android.view.PointerIcon} introduced after API 26 * level 4 in a backwards compatible fashion. 27 */ 28public final class PointerIconCompat { 29 /** Synonym for {@link android.view.PointerIcon#TYPE_NULL} */ 30 public static final int TYPE_NULL = 0; 31 32 /** Synonym for {@link android.view.PointerIcon#TYPE_ARROW} */ 33 public static final int TYPE_ARROW = 1000; 34 35 /** Synonym for {@link android.view.PointerIcon#TYPE_CONTEXT_MENU} */ 36 public static final int TYPE_CONTEXT_MENU = 1001; 37 38 /** Synonym for {@link android.view.PointerIcon#TYPE_HAND} */ 39 public static final int TYPE_HAND = 1002; 40 41 /** Synonym for {@link android.view.PointerIcon#TYPE_HELP} */ 42 public static final int TYPE_HELP = 1003; 43 44 /** Synonym for {@link android.view.PointerIcon#TYPE_WAIT} */ 45 public static final int TYPE_WAIT = 1004; 46 47 /** Synonym for {@link android.view.PointerIcon#TYPE_CELL} */ 48 public static final int TYPE_CELL = 1006; 49 50 /** Synonym for {@link android.view.PointerIcon#TYPE_CROSSHAIR} */ 51 public static final int TYPE_CROSSHAIR = 1007; 52 53 /** Synonym for {@link android.view.PointerIcon#TYPE_TEXT} */ 54 public static final int TYPE_TEXT = 1008; 55 56 /** Synonym for {@link android.view.PointerIcon#TYPE_VERTICAL_TEXT} */ 57 public static final int TYPE_VERTICAL_TEXT = 1009; 58 59 /** Synonym for {@link android.view.PointerIcon#TYPE_ALIAS} */ 60 public static final int TYPE_ALIAS = 1010; 61 62 /** Synonym for {@link android.view.PointerIcon#TYPE_COPY} */ 63 public static final int TYPE_COPY = 1011; 64 65 /** Synonym for {@link android.view.PointerIcon#TYPE_NO_DROP} */ 66 public static final int TYPE_NO_DROP = 1012; 67 68 /** Synonym for {@link android.view.PointerIcon#TYPE_ALL_SCROLL} */ 69 public static final int TYPE_ALL_SCROLL = 1013; 70 71 /** Synonym for {@link android.view.PointerIcon#TYPE_HORIZONTAL_DOUBLE_ARROW} */ 72 public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; 73 74 /** Synonym for {@link android.view.PointerIcon#TYPE_VERTICAL_DOUBLE_ARROW} */ 75 public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; 76 77 /** Synonym for {@link android.view.PointerIcon#TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW} */ 78 public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; 79 80 /** Synonym for {@link android.view.PointerIcon#TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW} */ 81 public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; 82 83 /** Synonym for {@link android.view.PointerIcon#TYPE_ZOOM_IN} */ 84 public static final int TYPE_ZOOM_IN = 1018; 85 86 /** Synonym for {@link android.view.PointerIcon#TYPE_ZOOM_OUT} */ 87 public static final int TYPE_ZOOM_OUT = 1019; 88 89 /** Synonym for {@link android.view.PointerIcon#TYPE_GRAB} */ 90 public static final int TYPE_GRAB = 1020; 91 92 /** Synonym for {@link android.view.PointerIcon#TYPE_GRABBING} */ 93 public static final int TYPE_GRABBING = 1021; 94 95 /** Synonym for {@link android.view.PointerIcon#TYPE_DEFAULT} */ 96 public static final int TYPE_DEFAULT = TYPE_ARROW; 97 98 99 private Object mPointerIcon; 100 101 private PointerIconCompat(Object pointerIcon) { 102 mPointerIcon = pointerIcon; 103 } 104 105 /** 106 * @hide 107 */ 108 public Object getPointerIcon() { 109 return mPointerIcon; 110 } 111 112 interface PointerIconCompatImpl { 113 Object getSystemIcon(Context context, int style); 114 Object create(Bitmap bitmap, float hotSpotX, float hotSpotY); 115 Object load(Resources resources, int resourceId); 116 } 117 118 static class BasePointerIconCompatImpl implements PointerIconCompatImpl { 119 @Override 120 public Object getSystemIcon(Context context, int style) { 121 return null; 122 } 123 124 @Override 125 public Object create(Bitmap bitmap, float hotSpotX, float hotSpotY) { 126 return null; 127 } 128 129 @Override 130 public Object load(Resources resources, int resourceId) { 131 return null; 132 } 133 } 134 135 static class Api24PointerIconCompatImpl extends BasePointerIconCompatImpl { 136 @Override 137 public Object getSystemIcon(Context context, int style) { 138 return PointerIconCompatApi24.getSystemIcon(context, style); 139 } 140 141 @Override 142 public Object create(Bitmap bitmap, float hotSpotX, float hotSpotY) { 143 return PointerIconCompatApi24.create(bitmap, hotSpotX, hotSpotY); 144 } 145 146 @Override 147 public Object load(Resources resources, int resourceId) { 148 return PointerIconCompatApi24.load(resources, resourceId); 149 } 150 } 151 152 static final PointerIconCompatImpl IMPL; 153 static { 154 if (BuildCompat.isAtLeastN()) { 155 IMPL = new Api24PointerIconCompatImpl(); 156 } else { 157 IMPL = new BasePointerIconCompatImpl(); 158 } 159 } 160 161 /** 162 * Gets a system pointer icon for the given style. 163 * If style is not recognized, returns the default pointer icon. 164 * 165 * @param context The context. 166 * @param style The pointer icon style. 167 * @return The pointer icon. 168 * 169 * @throws IllegalArgumentException if context is null. 170 */ 171 public static PointerIconCompat getSystemIcon(Context context, int style) { 172 return new PointerIconCompat(IMPL.getSystemIcon(context, style)); 173 } 174 175 /** 176 * Creates a custom pointer from the given bitmap and hotspot information. 177 * 178 * @param bitmap The bitmap for the icon. 179 * @param hotSpotX The X offset of the pointer icon hotspot in the bitmap. 180 * Must be within the [0, bitmap.getWidth()) range. 181 * @param hotSpotY The Y offset of the pointer icon hotspot in the bitmap. 182 * Must be within the [0, bitmap.getHeight()) range. 183 * @return A pointer icon for this bitmap. 184 * 185 * @throws IllegalArgumentException if bitmap is null, or if the x/y hotspot 186 * parameters are invalid. 187 */ 188 public static PointerIconCompat create(Bitmap bitmap, float hotSpotX, float hotSpotY) { 189 return new PointerIconCompat(IMPL.create(bitmap, hotSpotX, hotSpotY)); 190 } 191 192 /** 193 * Loads a custom pointer icon from an XML resource. 194 * <p> 195 * The XML resource should have the following form: 196 * <code> 197 * <?xml version="1.0" encoding="utf-8"?> 198 * <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android" 199 * android:bitmap="@drawable/my_pointer_bitmap" 200 * android:hotSpotX="24" 201 * android:hotSpotY="24" /> 202 * </code> 203 * </p> 204 * 205 * @param resources The resources object. 206 * @param resourceId The resource id. 207 * @return The pointer icon. 208 * 209 * @throws IllegalArgumentException if resources is null. 210 * @throws Resources.NotFoundException if the resource was not found or the drawable 211 * linked in the resource was not found. 212 */ 213 public static PointerIconCompat load(Resources resources, int resourceId) { 214 return new PointerIconCompat(IMPL.load(resources, resourceId)); 215 } 216} 217