diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/PointerIcon.aidl | 19 | ||||
-rw-r--r-- | core/java/android/view/PointerIcon.java | 435 | ||||
-rw-r--r-- | core/jni/Android.mk | 1 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_view_PointerIcon.cpp | 149 | ||||
-rw-r--r-- | core/jni/android_view_PointerIcon.h | 80 | ||||
-rw-r--r-- | core/res/res/drawable-mdpi/pointer_spot_anchor.png | bin | 0 -> 6817 bytes | |||
-rw-r--r-- | core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml | 5 | ||||
-rw-r--r-- | core/res/res/drawable-mdpi/pointer_spot_hover.png | bin | 0 -> 9669 bytes | |||
-rw-r--r-- | core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml | 5 | ||||
-rw-r--r-- | core/res/res/drawable-mdpi/pointer_spot_touch.png | bin | 0 -> 2880 bytes | |||
-rw-r--r-- | core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml | 5 | ||||
-rwxr-xr-x | core/res/res/values/attrs.xml | 18 | ||||
-rw-r--r-- | core/res/res/values/styles.xml | 8 | ||||
-rw-r--r-- | core/res/res/values/themes.xml | 2 |
15 files changed, 729 insertions, 0 deletions
diff --git a/core/java/android/view/PointerIcon.aidl b/core/java/android/view/PointerIcon.aidl new file mode 100644 index 0000000..b09340b --- /dev/null +++ b/core/java/android/view/PointerIcon.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +parcelable PointerIcon; diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java new file mode 100644 index 0000000..bb7ed41 --- /dev/null +++ b/core/java/android/view/PointerIcon.java @@ -0,0 +1,435 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import com.android.internal.util.XmlUtils; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * Represents an icon that can be used as a mouse pointer. + * <p> + * Pointer icons can be provided either by the system using system styles, + * or by applications using bitmaps or application resources. + * </p> + * + * @hide + */ +public final class PointerIcon implements Parcelable { + private static final String TAG = "PointerIcon"; + + /** Style constant: Custom icon with a user-supplied bitmap. */ + public static final int STYLE_CUSTOM = -1; + + /** Style constant: Null icon. It has no bitmap. */ + public static final int STYLE_NULL = 0; + + /** Style constant: Arrow icon. (Default mouse pointer) */ + public static final int STYLE_ARROW = 1000; + + /** {@hide} Style constant: Spot hover icon for touchpads. */ + public static final int STYLE_SPOT_HOVER = 2000; + + /** {@hide} Style constant: Spot touch icon for touchpads. */ + public static final int STYLE_SPOT_TOUCH = 2001; + + /** {@hide} Style constant: Spot anchor icon for touchpads. */ + public static final int STYLE_SPOT_ANCHOR = 2002; + + // OEM private styles should be defined starting at this range to avoid + // conflicts with any system styles that may be defined in the future. + private static final int STYLE_OEM_FIRST = 10000; + + // The default pointer icon. + private static final int STYLE_DEFAULT = STYLE_ARROW; + + private static final PointerIcon gNullIcon = new PointerIcon(STYLE_NULL); + + private final int mStyle; + private int mSystemIconResourceId; + private Bitmap mBitmap; + private float mHotSpotX; + private float mHotSpotY; + + private PointerIcon(int style) { + mStyle = style; + } + + /** + * Gets a special pointer icon that has no bitmap. + * + * @return The null pointer icon. + * + * @see #STYLE_NULL + */ + public static PointerIcon getNullIcon() { + return gNullIcon; + } + + /** + * Gets the default pointer icon. + * + * @param context The context. + * @return The default pointer icon. + * + * @throws IllegalArgumentException if context is null. + */ + public static PointerIcon getDefaultIcon(Context context) { + return getSystemIcon(context, STYLE_DEFAULT); + } + + /** + * Gets a system pointer icon for the given style. + * If style is not recognized, returns the default pointer icon. + * + * @param context The context. + * @param style The pointer icon style. + * @return The pointer icon. + * + * @throws IllegalArgumentException if context is null. + */ + public static PointerIcon getSystemIcon(Context context, int style) { + if (context == null) { + throw new IllegalArgumentException("context must not be null"); + } + + if (style == STYLE_NULL) { + return gNullIcon; + } + + int styleIndex = getSystemIconStyleIndex(style); + if (styleIndex == 0) { + styleIndex = getSystemIconStyleIndex(STYLE_DEFAULT); + } + + TypedArray a = context.obtainStyledAttributes(null, + com.android.internal.R.styleable.Pointer, + com.android.internal.R.attr.pointerStyle, 0); + int resourceId = a.getResourceId(styleIndex, -1); + a.recycle(); + + if (resourceId == -1) { + Log.w(TAG, "Missing theme resources for pointer icon style " + style); + return style == STYLE_DEFAULT ? gNullIcon : getSystemIcon(context, STYLE_DEFAULT); + } + + PointerIcon icon = new PointerIcon(style); + if ((resourceId & 0xff000000) == 0x01000000) { + icon.mSystemIconResourceId = resourceId; + } else { + icon.loadResource(context.getResources(), resourceId); + } + return icon; + } + + /** + * Creates a custom pointer from the given bitmap and hotspot information. + * + * @param bitmap The bitmap for the icon. + * @param hotspotX The X offset of the pointer icon hotspot in the bitmap. + * Must be within the [0, bitmap.getWidth()) range. + * @param hotspotY The Y offset of the pointer icon hotspot in the bitmap. + * Must be within the [0, bitmap.getHeight()) range. + * @return A pointer icon for this bitmap. + * + * @throws IllegalArgumentException if bitmap is null, or if the x/y hotspot + * parameters are invalid. + */ + public static PointerIcon createCustomIcon(Bitmap bitmap, float hotSpotX, float hotSpotY) { + if (bitmap == null) { + throw new IllegalArgumentException("bitmap must not be null"); + } + validateHotSpot(bitmap, hotSpotX, hotSpotY); + + PointerIcon icon = new PointerIcon(STYLE_CUSTOM); + icon.mBitmap = bitmap; + icon.mHotSpotX = hotSpotX; + icon.mHotSpotY = hotSpotY; + return icon; + } + + /** + * Loads a custom pointer icon from an XML resource. + * <p> + * The XML resource should have the following form: + * <code> + * <?xml version="1.0" encoding="utf-8"?> + * <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android" + * android:bitmap="@drawable/my_pointer_bitmap" + * android:hotSpotX="24" + * android:hotSpotY="24" /> + * </code> + * </p> + * + * @param resources The resources object. + * @param resourceId The resource id. + * @return The pointer icon. + * + * @throws IllegalArgumentException if resources is null. + * @throws Resources.NotFoundException if the resource was not found or the drawable + * linked in the resource was not found. + */ + public static PointerIcon loadCustomIcon(Resources resources, int resourceId) { + if (resources == null) { + throw new IllegalArgumentException("resources must not be null"); + } + + PointerIcon icon = new PointerIcon(STYLE_CUSTOM); + icon.loadResource(resources, resourceId); + return icon; + } + + /** + * Loads the bitmap and hotspot information for a pointer icon, if it is not already loaded. + * Returns a pointer icon (not necessarily the same instance) with the information filled in. + * + * @param context The context. + * @return The loaded pointer icon. + * + * @throws IllegalArgumentException if context is null. + * @see #isLoaded() + * @hide + */ + public PointerIcon load(Context context) { + if (context == null) { + throw new IllegalArgumentException("context must not be null"); + } + + if (mSystemIconResourceId == 0 || mBitmap != null) { + return this; + } + + PointerIcon result = new PointerIcon(mStyle); + result.mSystemIconResourceId = mSystemIconResourceId; + result.loadResource(context.getResources(), mSystemIconResourceId); + return result; + } + + /** + * Returns true if the pointer icon style is {@link #STYLE_NULL}. + * + * @return True if the pointer icon style is {@link #STYLE_NULL}. + */ + public boolean isNullIcon() { + return mStyle == STYLE_NULL; + } + + /** + * Returns true if the pointer icon has been loaded and its bitmap and hotspot + * information are available. + * + * @return True if the pointer icon is loaded. + * @see #load(Context) + */ + public boolean isLoaded() { + return mBitmap != null || mStyle == STYLE_NULL; + } + + /** + * Gets the style of the pointer icon. + * + * @return The pointer icon style. + */ + public int getStyle() { + return mStyle; + } + + /** + * Gets the bitmap of the pointer icon. + * + * @return The pointer icon bitmap, or null if the style is {@link #STYLE_NULL}. + * + * @throws IllegalStateException if the bitmap is not loaded. + * @see #isLoaded() + * @see #load(Context) + */ + public Bitmap getBitmap() { + throwIfIconIsNotLoaded(); + return mBitmap; + } + + /** + * Gets the X offset of the pointer icon hotspot. + * + * @return The hotspot X offset. + * + * @throws IllegalStateException if the bitmap is not loaded. + * @see #isLoaded() + * @see #load(Context) + */ + public float getHotSpotX() { + throwIfIconIsNotLoaded(); + return mHotSpotX; + } + + /** + * Gets the Y offset of the pointer icon hotspot. + * + * @return The hotspot Y offset. + * + * @throws IllegalStateException if the bitmap is not loaded. + * @see #isLoaded() + * @see #load(Context) + */ + public float getHotSpotY() { + throwIfIconIsNotLoaded(); + return mHotSpotY; + } + + private void throwIfIconIsNotLoaded() { + if (!isLoaded()) { + throw new IllegalStateException("The icon is not loaded."); + } + } + + public static final Parcelable.Creator<PointerIcon> CREATOR + = new Parcelable.Creator<PointerIcon>() { + public PointerIcon createFromParcel(Parcel in) { + int style = in.readInt(); + if (style == STYLE_NULL) { + return getNullIcon(); + } + + int systemIconResourceId = in.readInt(); + if (systemIconResourceId != 0) { + PointerIcon icon = new PointerIcon(style); + icon.mSystemIconResourceId = systemIconResourceId; + return icon; + } + + Bitmap bitmap = Bitmap.CREATOR.createFromParcel(in); + float hotSpotX = in.readFloat(); + float hotSpotY = in.readFloat(); + return PointerIcon.createCustomIcon(bitmap, hotSpotX, hotSpotY); + } + + public PointerIcon[] newArray(int size) { + return new PointerIcon[size]; + } + }; + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mStyle); + + if (mStyle != STYLE_NULL) { + out.writeInt(mSystemIconResourceId); + if (mSystemIconResourceId == 0) { + mBitmap.writeToParcel(out, flags); + out.writeFloat(mHotSpotX); + out.writeFloat(mHotSpotY); + } + } + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (other == null || !(other instanceof PointerIcon)) { + return false; + } + + PointerIcon otherIcon = (PointerIcon) other; + if (mStyle != otherIcon.mStyle + || mSystemIconResourceId != otherIcon.mSystemIconResourceId) { + return false; + } + + if (mSystemIconResourceId == 0 && (mBitmap != otherIcon.mBitmap + || mHotSpotX != otherIcon.mHotSpotX + || mHotSpotY != otherIcon.mHotSpotY)) { + return false; + } + + return true; + } + + private void loadResource(Resources resources, int resourceId) { + XmlResourceParser parser = resources.getXml(resourceId); + final int bitmapRes; + final float hotSpotX; + final float hotSpotY; + try { + XmlUtils.beginDocument(parser, "pointer-icon"); + + TypedArray a = resources.obtainAttributes( + parser, com.android.internal.R.styleable.PointerIcon); + bitmapRes = a.getResourceId(com.android.internal.R.styleable.PointerIcon_bitmap, 0); + hotSpotX = a.getFloat(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0); + hotSpotY = a.getFloat(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0); + a.recycle(); + } catch (Exception ex) { + throw new IllegalArgumentException("Exception parsing pointer icon resource.", ex); + } finally { + parser.close(); + } + + if (bitmapRes == 0) { + throw new IllegalArgumentException("<pointer-icon> is missing bitmap attribute."); + } + + Drawable drawable = resources.getDrawable(bitmapRes); + if (!(drawable instanceof BitmapDrawable)) { + throw new IllegalArgumentException("<pointer-icon> bitmap attribute must " + + "refer to a bitmap drawable."); + } + + // Set the properties now that we have successfully loaded the icon. + mBitmap = ((BitmapDrawable)drawable).getBitmap(); + mHotSpotX = hotSpotX; + mHotSpotY = hotSpotY; + } + + private static void validateHotSpot(Bitmap bitmap, float hotSpotX, float hotSpotY) { + if (hotSpotX < 0 || hotSpotX >= bitmap.getWidth()) { + throw new IllegalArgumentException("x hotspot lies outside of the bitmap area"); + } + if (hotSpotY < 0 || hotSpotY >= bitmap.getHeight()) { + throw new IllegalArgumentException("y hotspot lies outside of the bitmap area"); + } + } + + private static int getSystemIconStyleIndex(int style) { + switch (style) { + case STYLE_ARROW: + return com.android.internal.R.styleable.Pointer_pointerIconArrow; + case STYLE_SPOT_HOVER: + return com.android.internal.R.styleable.Pointer_pointerIconSpotHover; + case STYLE_SPOT_TOUCH: + return com.android.internal.R.styleable.Pointer_pointerIconSpotTouch; + case STYLE_SPOT_ANCHOR: + return com.android.internal.R.styleable.Pointer_pointerIconSpotAnchor; + default: + return 0; + } + } +} diff --git a/core/jni/Android.mk b/core/jni/Android.mk index f8f8761..290f528 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -54,6 +54,7 @@ LOCAL_SRC_FILES:= \ android_view_KeyCharacterMap.cpp \ android_view_GLES20Canvas.cpp \ android_view_MotionEvent.cpp \ + android_view_PointerIcon.cpp \ android_view_VelocityTracker.cpp \ android_text_AndroidCharacter.cpp \ android_text_AndroidBidi.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index b628b9d..a4a229a 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -170,6 +170,7 @@ extern int register_android_view_InputChannel(JNIEnv* env); extern int register_android_view_InputQueue(JNIEnv* env); extern int register_android_view_KeyEvent(JNIEnv* env); extern int register_android_view_MotionEvent(JNIEnv* env); +extern int register_android_view_PointerIcon(JNIEnv* env); extern int register_android_view_VelocityTracker(JNIEnv* env); extern int register_android_content_res_ObbScanner(JNIEnv* env); extern int register_android_content_res_Configuration(JNIEnv* env); @@ -1212,6 +1213,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_view_InputQueue), REG_JNI(register_android_view_KeyEvent), REG_JNI(register_android_view_MotionEvent), + REG_JNI(register_android_view_PointerIcon), REG_JNI(register_android_view_VelocityTracker), REG_JNI(register_android_content_res_ObbScanner), diff --git a/core/jni/android_view_PointerIcon.cpp b/core/jni/android_view_PointerIcon.cpp new file mode 100644 index 0000000..091341a --- /dev/null +++ b/core/jni/android_view_PointerIcon.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "PointerIcon-JNI" + +#include "JNIHelp.h" + +#include "android_view_PointerIcon.h" + +#include <android_runtime/AndroidRuntime.h> +#include <utils/Log.h> +#include <android/graphics/GraphicsJNI.h> + +namespace android { + +static struct { + jclass clazz; + jfieldID mStyle; + jfieldID mBitmap; + jfieldID mHotSpotX; + jfieldID mHotSpotY; + jmethodID getSystemIcon; + jmethodID load; +} gPointerIconClassInfo; + + +// --- Global Functions --- + +jobject android_view_PointerIcon_getSystemIcon(JNIEnv* env, jobject contextObj, int32_t style) { + jobject pointerIconObj = env->CallStaticObjectMethod(gPointerIconClassInfo.clazz, + gPointerIconClassInfo.getSystemIcon, contextObj, style); + if (env->ExceptionCheck()) { + LOGW("An exception occurred while getting a pointer icon with style %d.", style); + LOGW_EX(env); + env->ExceptionClear(); + return NULL; + } + return pointerIconObj; +} + +status_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobject contextObj, + PointerIcon* outPointerIcon) { + outPointerIcon->reset(); + + if (!pointerIconObj) { + return OK; + } + + jobject loadedPointerIconObj = env->CallObjectMethod(pointerIconObj, + gPointerIconClassInfo.load, contextObj); + if (env->ExceptionCheck() || !loadedPointerIconObj) { + LOGW("An exception occurred while loading a pointer icon."); + LOGW_EX(env); + env->ExceptionClear(); + return UNKNOWN_ERROR; + } + + outPointerIcon->style = env->GetIntField(loadedPointerIconObj, + gPointerIconClassInfo.mStyle); + outPointerIcon->hotSpotX = env->GetFloatField(loadedPointerIconObj, + gPointerIconClassInfo.mHotSpotX); + outPointerIcon->hotSpotY = env->GetFloatField(loadedPointerIconObj, + gPointerIconClassInfo.mHotSpotY); + + jobject bitmapObj = env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmap); + if (bitmapObj) { + SkBitmap* bitmap = GraphicsJNI::getNativeBitmap(env, bitmapObj); + if (bitmap) { + outPointerIcon->bitmap = *bitmap; // use a shared pixel ref + } + env->DeleteLocalRef(bitmapObj); + } + + env->DeleteLocalRef(loadedPointerIconObj); + return OK; +} + +status_t android_view_PointerIcon_loadSystemIcon(JNIEnv* env, jobject contextObj, + int32_t style, PointerIcon* outPointerIcon) { + jobject pointerIconObj = android_view_PointerIcon_getSystemIcon(env, contextObj, style); + if (!pointerIconObj) { + outPointerIcon->reset(); + return UNKNOWN_ERROR; + } + + status_t status = android_view_PointerIcon_load(env, pointerIconObj, + contextObj, outPointerIcon); + env->DeleteLocalRef(pointerIconObj); + return status; +} + + +// --- JNI Registration --- + +#define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(! var, "Unable to find class " className); \ + var = jclass(env->NewGlobalRef(var)); + +#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \ + var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find method " methodName); + +#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ + var = env->GetMethodID(clazz, methodName, methodDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find method " methodName); + +#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ + var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find field " fieldName); + +int register_android_view_PointerIcon(JNIEnv* env) { + FIND_CLASS(gPointerIconClassInfo.clazz, "android/view/PointerIcon"); + + GET_FIELD_ID(gPointerIconClassInfo.mBitmap, gPointerIconClassInfo.clazz, + "mBitmap", "Landroid/graphics/Bitmap;"); + + GET_FIELD_ID(gPointerIconClassInfo.mStyle, gPointerIconClassInfo.clazz, + "mStyle", "I"); + + GET_FIELD_ID(gPointerIconClassInfo.mHotSpotX, gPointerIconClassInfo.clazz, + "mHotSpotX", "F"); + + GET_FIELD_ID(gPointerIconClassInfo.mHotSpotY, gPointerIconClassInfo.clazz, + "mHotSpotY", "F"); + + GET_STATIC_METHOD_ID(gPointerIconClassInfo.getSystemIcon, gPointerIconClassInfo.clazz, + "getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;"); + + GET_METHOD_ID(gPointerIconClassInfo.load, gPointerIconClassInfo.clazz, + "load", "(Landroid/content/Context;)Landroid/view/PointerIcon;"); + + return 0; +} + +} // namespace android diff --git a/core/jni/android_view_PointerIcon.h b/core/jni/android_view_PointerIcon.h new file mode 100644 index 0000000..3bfd645 --- /dev/null +++ b/core/jni/android_view_PointerIcon.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_VIEW_POINTER_ICON_H +#define _ANDROID_VIEW_POINTER_ICON_H + +#include "jni.h" + +#include <utils/Errors.h> +#include <SkBitmap.h> + +namespace android { + +/* Pointer icon styles. + * Must match the definition in android.view.PointerIcon. + */ +enum { + POINTER_ICON_STYLE_CUSTOM = -1, + POINTER_ICON_STYLE_NULL = 0, + POINTER_ICON_STYLE_ARROW = 1000, + POINTER_ICON_STYLE_SPOT_HOVER = 2000, + POINTER_ICON_STYLE_SPOT_TOUCH = 2001, + POINTER_ICON_STYLE_SPOT_ANCHOR = 2002, +}; + +/* + * Describes a pointer icon. + */ +struct PointerIcon { + inline PointerIcon() { + reset(); + } + + int32_t style; + SkBitmap bitmap; + float hotSpotX; + float hotSpotY; + + inline bool isNullIcon() { + return style == POINTER_ICON_STYLE_NULL; + } + + inline void reset() { + style = POINTER_ICON_STYLE_NULL; + bitmap.reset(); + hotSpotX = 0; + hotSpotY = 0; + } +}; + +/* Gets a system pointer icon with the specified style. */ +extern jobject android_view_PointerIcon_getSystemIcon(JNIEnv* env, + jobject contextObj, int32_t style); + +/* Loads the bitmap associated with a pointer icon. + * If pointerIconObj is NULL, returns OK and a pointer icon with POINTER_ICON_STYLE_NULL. */ +extern status_t android_view_PointerIcon_load(JNIEnv* env, + jobject pointerIconObj, jobject contextObj, PointerIcon* outPointerIcon); + +/* Loads the bitmap associated with a pointer icon by style. + * If pointerIconObj is NULL, returns OK and a pointer icon with POINTER_ICON_STYLE_NULL. */ +extern status_t android_view_PointerIcon_loadSystemIcon(JNIEnv* env, + jobject contextObj, int32_t style, PointerIcon* outPointerIcon); + +} // namespace android + +#endif // _ANDROID_OS_POINTER_ICON_H diff --git a/core/res/res/drawable-mdpi/pointer_spot_anchor.png b/core/res/res/drawable-mdpi/pointer_spot_anchor.png Binary files differnew file mode 100644 index 0000000..d7aca36 --- /dev/null +++ b/core/res/res/drawable-mdpi/pointer_spot_anchor.png diff --git a/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml new file mode 100644 index 0000000..2222b8e --- /dev/null +++ b/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android" + android:bitmap="@drawable/pointer_spot_anchor" + android:hotSpotX="33" + android:hotSpotY="33" /> diff --git a/core/res/res/drawable-mdpi/pointer_spot_hover.png b/core/res/res/drawable-mdpi/pointer_spot_hover.png Binary files differnew file mode 100644 index 0000000..5041aa3 --- /dev/null +++ b/core/res/res/drawable-mdpi/pointer_spot_hover.png diff --git a/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml new file mode 100644 index 0000000..dc62a69 --- /dev/null +++ b/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android" + android:bitmap="@drawable/pointer_spot_hover" + android:hotSpotX="33" + android:hotSpotY="33" /> diff --git a/core/res/res/drawable-mdpi/pointer_spot_touch.png b/core/res/res/drawable-mdpi/pointer_spot_touch.png Binary files differnew file mode 100644 index 0000000..64a42a1 --- /dev/null +++ b/core/res/res/drawable-mdpi/pointer_spot_touch.png diff --git a/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml new file mode 100644 index 0000000..4bffee6 --- /dev/null +++ b/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android" + android:bitmap="@drawable/pointer_spot_touch" + android:hotSpotX="24" + android:hotSpotY="24" /> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 819ce58..e8767d8 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -757,6 +757,13 @@ <!-- Default style for the Switch widget. --> <attr name="switchStyle" format="reference" /> + <!-- ============== --> + <!-- Pointer styles --> + <!-- ============== --> + <eat-comment /> + + <!-- Reference to the Pointer style --> + <attr name="pointerStyle" format="reference" /> </declare-styleable> <!-- **************************************************************** --> @@ -4921,6 +4928,17 @@ <attr name="switchPadding" format="dimension" /> </declare-styleable> + <declare-styleable name="Pointer"> + <!-- Reference to a pointer icon drawable with STYLE_ARROW --> + <attr name="pointerIconArrow" format="reference" /> + <!-- Reference to a pointer icon drawable with STYLE_SPOT_HOVER --> + <attr name="pointerIconSpotHover" format="reference" /> + <!-- Reference to a pointer icon drawable with STYLE_SPOT_TOUCH --> + <attr name="pointerIconSpotTouch" format="reference" /> + <!-- Reference to a pointer icon drawable with STYLE_SPOT_ANCHOR --> + <attr name="pointerIconSpotAnchor" format="reference" /> + </declare-styleable> + <declare-styleable name="PointerIcon"> <!-- Drawable to use as the icon bitmap. --> <attr name="bitmap" format="reference" /> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index bf4c6d7..b4042c0 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -2210,4 +2210,12 @@ <item name="android:borderLeft">0dip</item> <item name="android:borderRight">0dip</item> </style> + + <!-- Pointer styles --> + <style name="Pointer"> + <item name="android:pointerIconArrow">@android:drawable/pointer_arrow_icon</item> + <item name="android:pointerIconSpotHover">@android:drawable/pointer_spot_hover_icon</item> + <item name="android:pointerIconSpotTouch">@android:drawable/pointer_spot_touch_icon</item> + <item name="android:pointerIconSpotAnchor">@android:drawable/pointer_spot_anchor_icon</item> + </style> </resources> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index b1e4f0f..0748b10 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -323,6 +323,8 @@ <item name="fastScrollOverlayPosition">floating</item> <item name="fastScrollTextColor">@android:color/primary_text_dark</item> + <!-- Pointer style --> + <item name="pointerStyle">@android:style/Pointer</item> </style> <!-- Variant of the default (dark) theme with no title bar --> |