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