Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a1fab95 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Update View docs for pointer icon and default resolution behavior

We now support showing a pointer icon for styluses in Android. When
a device is configured to show pointer icons for styluses, apps can
select the pointer icon to be used for the stylus pointer by overriding
onResolvePointerIcon.

Previously, onResolvePointerIcon was only called for mouse events, but
now it's possible that it will be called for stylus pointers as well.
To limit unexpected behavior in existing apps that only expect pointer
icons to be shown for mouse devices, a pointer icon set using
View#setPointerIcon will now only apply to mouse pointers. We update
the docs to reflect these changes, and add instructions for explicitly
resolving stylus pointers.

Bug: 215436642
Test: atest PointerIconTest
Change-Id: I40364cb01277cb9c98704dfc1cbee9dbfd526000
parent 82465873
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -57,8 +57,9 @@ public final class PointerIcon implements Parcelable {
    /** Type constant: Null icon.  It has no bitmap. */
    public static final int TYPE_NULL = 0;

    /** Type constant: no icons are specified. If all views uses this, then falls back
     * to the default type, but this is helpful to distinguish a view explicitly want
    /**
     * Type constant: no icons are specified. If all views uses this, then the pointer icon falls
     * back to the default type, but this is helpful to distinguish a view that explicitly wants
     * to have the default icon.
     * @hide
     */
+57 −13
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.input.InputManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -5413,7 +5414,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    /**
     * The pointer icon when the mouse hovers on this view. The default is null.
     */
    private PointerIcon mPointerIcon;
    private PointerIcon mMousePointerIcon;
    /**
     * @hide
@@ -29506,30 +29507,71 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    }
    /**
     * Returns the pointer icon for the motion event, or null if it doesn't specify the icon.
     * The default implementation does not care the location or event types, but some subclasses
     * may use it (such as WebViews).
     * @param event The MotionEvent from a mouse
     * @param pointerIndex The index of the pointer for which to retrieve the {@link PointerIcon}.
     *                     This will be between 0 and {@link MotionEvent#getPointerCount()}.
     * Resolve the pointer icon that should be used for specified pointer in the motion event.
     *
     * The default implementation will resolve the pointer icon to one set using
     * {@link #setPointerIcon(PointerIcon)} for mouse devices. Subclasses may override this to
     * customize the icon for the given pointer.
     *
     * For example, the pointer icon for a stylus pointer can be resolved in the following way:
     * <code><pre>
     * &#64;Override
     * public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
     *     final int toolType = event.getToolType(pointerIndex);
     *     if (!event.isFromSource(InputDevice.SOURCE_MOUSE)
     *             && event.isFromSource(InputDevice.SOURCE_STYLUS)
     *             && (toolType == MotionEvent.TOOL_TYPE_STYLUS
     *                     || toolType == MotionEvent.TOOL_TYPE_ERASER)) {
     *         // Show this pointer icon only if this pointer is a stylus.
     *         return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_WAIT);
     *     }
     *     // Use the default logic for determining the pointer icon for other non-stylus pointers,
     *     // like for the mouse cursor.
     *     return super.onResolvePointerIcon(event, pointerIndex);
     * }
     * </pre></code>
     *
     * @param event The {@link MotionEvent} that requires a pointer icon to be resolved for one of
     *              pointers.
     * @param pointerIndex The index of the pointer in {@code event} for which to retrieve the
     *     {@link PointerIcon}. This will be between 0 and {@link MotionEvent#getPointerCount()}.
     * @return the pointer icon to use for specified pointer, or {@code null} if a pointer icon
     *     is not specified and the default icon should be used.
     * @see PointerIcon
     * @see InputManager#isStylusPointerIconEnabled()
     */
    public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
        final float x = event.getX(pointerIndex);
        final float y = event.getY(pointerIndex);
        if (isDraggingScrollBar() || isOnScrollbarThumb(x, y)) {
            return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_ARROW);
            // Use the default pointer icon.
            return null;
        }
        // Note: A drawing tablet will have both SOURCE_MOUSE and SOURCE_STYLUS, but it would use
        // TOOL_TYPE_STYLUS. For now, treat drawing tablets the same way as a mouse or touchpad.
        if (event.isFromSource(InputDevice.SOURCE_MOUSE)) {
            return mMousePointerIcon;
        }
        return mPointerIcon;
        return null;
    }
    /**
     * Set the pointer icon for the current view.
     * Set the pointer icon to be used for a mouse pointer in the current view.
     *
     * Passing {@code null} will restore the pointer icon to its default value.
     * Note that setting the pointer icon using this method will only set it for events coming from
     * a mouse device (i.e. with source {@link InputDevice#SOURCE_MOUSE}). To resolve
     * the pointer icon for other device types like styluses, override
     * {@link #onResolvePointerIcon(MotionEvent, int)}.
     *
     * @param pointerIcon A PointerIcon instance which will be shown when the mouse hovers.
     * @see #onResolvePointerIcon(MotionEvent, int)
     * @see PointerIcon
     */
    public void setPointerIcon(PointerIcon pointerIcon) {
        mPointerIcon = pointerIcon;
        mMousePointerIcon = pointerIcon;
        if (mAttachInfo == null || mAttachInfo.mHandlingPointerEvent) {
            return;
        }
@@ -29540,11 +29582,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    }
    /**
     * Gets the pointer icon for the current view.
     * Gets the mouse pointer icon for the current view.
     *
     * @see #setPointerIcon(PointerIcon)
     */
    @InspectableProperty
    public PointerIcon getPointerIcon() {
        return mPointerIcon;
        return mMousePointerIcon;
    }
    /**