Merge "Introduce animated pointer icon for STYLE_WAIT."

This commit is contained in:
Jun Mukai
2015-11-18 01:46:58 +00:00
committed by Android (Google) Code Review
82 changed files with 208 additions and 24 deletions

View File

@@ -24,6 +24,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
@@ -142,6 +143,10 @@ public final class PointerIcon implements Parcelable {
private Bitmap mBitmap;
private float mHotSpotX;
private float mHotSpotY;
// The bitmaps for the additional frame of animated pointer icon. Note that the first frame
// will be stored in mBitmap.
private Bitmap mBitmapFrames[];
private int mDurationPerFrame;
private PointerIcon(int style) {
mStyle = style;
@@ -472,6 +477,36 @@ public final class PointerIcon implements Parcelable {
} else {
drawable = context.getDrawable(bitmapRes);
}
if (drawable instanceof AnimationDrawable) {
// Extract animation frame bitmaps.
final AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
final int frames = animationDrawable.getNumberOfFrames();
drawable = animationDrawable.getFrame(0);
if (frames == 1) {
Log.w(TAG, "Animation icon with single frame -- simply treating the first "
+ "frame as a normal bitmap icon.");
} else {
// Assumes they have the exact duration.
mDurationPerFrame = animationDrawable.getDuration(0);
mBitmapFrames = new Bitmap[frames - 1];
final int width = drawable.getIntrinsicWidth();
final int height = drawable.getIntrinsicHeight();
for (int i = 1; i < frames; ++i) {
Drawable drawableFrame = animationDrawable.getFrame(i);
if (!(drawableFrame instanceof BitmapDrawable)) {
throw new IllegalArgumentException("Frame of an animated pointer icon "
+ "must refer to a bitmap drawable.");
}
if (drawableFrame.getIntrinsicWidth() != width ||
drawableFrame.getIntrinsicHeight() != height) {
throw new IllegalArgumentException("The bitmap size of " + i + "-th frame "
+ "is different. All frames should have the exact same size and "
+ "share the same hotspot.");
}
mBitmapFrames[i - 1] = ((BitmapDrawable)drawableFrame).getBitmap();
}
}
}
if (!(drawable instanceof BitmapDrawable)) {
throw new IllegalArgumentException("<pointer-icon> bitmap attribute must "
+ "refer to a bitmap drawable.");
@@ -509,8 +544,7 @@ public final class PointerIcon implements Parcelable {
case STYLE_HELP:
return com.android.internal.R.styleable.Pointer_pointerIconHelp;
case STYLE_WAIT:
// falls back to the default icon because no animation support.
return com.android.internal.R.styleable.Pointer_pointerIconArrow;
return com.android.internal.R.styleable.Pointer_pointerIconWait;
case STYLE_CELL:
return com.android.internal.R.styleable.Pointer_pointerIconCell;
case STYLE_CROSSHAIR:

View File

@@ -24,6 +24,7 @@
#include <android_runtime/Log.h>
#include <utils/Log.h>
#include <android/graphics/GraphicsJNI.h>
#include "ScopedLocalRef.h"
#include "core_jni_helpers.h"
@@ -35,6 +36,8 @@ static struct {
jfieldID mBitmap;
jfieldID mHotSpotX;
jfieldID mHotSpotY;
jfieldID mBitmapFrames;
jfieldID mDurationPerFrame;
jmethodID getSystemIcon;
jmethodID load;
} gPointerIconClassInfo;
@@ -84,6 +87,19 @@ status_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobj
env->DeleteLocalRef(bitmapObj);
}
ScopedLocalRef<jobjectArray> bitmapFramesObj(env, reinterpret_cast<jobjectArray>(
env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmapFrames)));
if (bitmapFramesObj.get()) {
outPointerIcon->durationPerFrame = env->GetIntField(
loadedPointerIconObj, gPointerIconClassInfo.mDurationPerFrame);
jsize size = env->GetArrayLength(bitmapFramesObj.get());
outPointerIcon->bitmapFrames.resize(size);
for (jsize i = 0; i < size; ++i) {
ScopedLocalRef<jobject> bitmapObj(env, env->GetObjectArrayElement(bitmapFramesObj.get(), i));
GraphicsJNI::getSkBitmap(env, bitmapObj.get(), &(outPointerIcon->bitmapFrames[i]));
}
}
env->DeleteLocalRef(loadedPointerIconObj);
return OK;
}
@@ -121,6 +137,12 @@ int register_android_view_PointerIcon(JNIEnv* env) {
gPointerIconClassInfo.mHotSpotY = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
"mHotSpotY", "F");
gPointerIconClassInfo.mBitmapFrames = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
"mBitmapFrames", "[Landroid/graphics/Bitmap;");
gPointerIconClassInfo.mDurationPerFrame = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
"mDurationPerFrame", "I");
gPointerIconClassInfo.getSystemIcon = GetStaticMethodIDOrDie(env, gPointerIconClassInfo.clazz,
"getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;");

View File

@@ -19,6 +19,8 @@
#include "jni.h"
#include <vector>
#include <utils/Errors.h>
#include <SkBitmap.h>
@@ -69,6 +71,8 @@ struct PointerIcon {
SkBitmap bitmap;
float hotSpotX;
float hotSpotY;
std::vector<SkBitmap> bitmapFrames;
int32_t durationPerFrame;
inline bool isNullIcon() {
return style == POINTER_ICON_STYLE_NULL;
@@ -79,6 +83,8 @@ struct PointerIcon {
bitmap.reset();
hotSpotX = 0;
hotSpotY = 0;
bitmapFrames.clear();
durationPerFrame = 0;
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1006 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1009 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 937 B

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="@drawable/pointer_wait_1" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_2" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_3" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_4" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_5" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_6" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_7" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_8" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_9" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_10" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_11" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_12" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_13" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_14" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_15" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_16" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_17" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_18" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_19" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_20" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_21" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_22" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_23" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_24" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_25" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_26" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_27" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_28" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_29" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_30" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_31" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_32" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_33" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_34" android:duration="25"/>
<item android:drawable="@drawable/pointer_wait_35" android:duration="25"/>
</animation-list>

View File

@@ -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_wait"
android:hotSpotX="7dp"
android:hotSpotY="7dp" />

View File

@@ -7631,6 +7631,8 @@ i
<attr name="pointerIconHand" format="reference"/>
<!-- Reference to a pointer drawable with STYLE_HELP -->
<attr name="pointerIconHelp" format="reference"/>
<!-- Reference to a pointer drawable with STYLE_WAIT -->
<attr name="pointerIconWait" format="reference"/>
<!-- Reference to a pointer drawable with STYLE_CELL -->
<attr name="pointerIconCell" format="reference"/>
<!-- Reference to a pointer drawable with STYLE_CROSSHAIR -->

View File

@@ -1339,6 +1339,7 @@ please see styles_device_defaults.xml.
<item name="pointerIconHand">@drawable/pointer_hand_icon</item>
<item name="pointerIconContextMenu">@drawable/pointer_context_menu_icon</item>
<item name="pointerIconHelp">@drawable/pointer_help_icon</item>
<item name="pointerIconWait">@drawable/pointer_wait_icon</item>
<item name="pointerIconCell">@drawable/pointer_cell_icon</item>
<item name="pointerIconCrosshair">@drawable/pointer_crosshair_icon</item>
<item name="pointerIconText">@drawable/pointer_text_icon</item>

View File

@@ -86,6 +86,9 @@ PointerController::PointerController(const sp<PointerControllerPolicyInterface>&
mLocked.pointerIconChanged = false;
mLocked.requestedPointerShape = mPolicy->getDefaultPointerIconId();
mLocked.animationFrameIndex = 0;
mLocked.lastFrameUpdatedTime = 0;
mLocked.buttonState = 0;
loadResources();
@@ -239,7 +242,8 @@ void PointerController::setPresentation(Presentation presentation) {
AutoMutex _l(mLock);
if (presentation == PRESENTATION_POINTER && mLocked.additionalMouseResources.empty()) {
mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources);
mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
&mLocked.animationResources);
}
if (mLocked.presentation != presentation) {
@@ -402,7 +406,7 @@ void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_
updatePointerLocked();
}
void PointerController::updatePointerShape(int iconId) {
void PointerController::updatePointerShape(int32_t iconId) {
AutoMutex _l(mLock);
if (mLocked.requestedPointerShape != iconId) {
mLocked.requestedPointerShape = iconId;
@@ -462,8 +466,17 @@ int PointerController::handleEvent(int /* fd */, int events, void* /* data */) {
void PointerController::doAnimate(nsecs_t timestamp) {
AutoMutex _l(mLock);
bool keepAnimating = false;
mLocked.animationPending = false;
bool keepFading = doFadingAnimationLocked(timestamp);
bool keepBitmapFlipping = doBitmapAnimationLocked(timestamp);
if (keepFading || keepBitmapFlipping) {
startAnimationLocked();
}
}
bool PointerController::doFadingAnimationLocked(nsecs_t timestamp) {
bool keepAnimating = false;
nsecs_t frameDelay = timestamp - mLocked.animationTime;
// Animate pointer fade.
@@ -501,10 +514,32 @@ void PointerController::doAnimate(nsecs_t timestamp) {
}
}
}
return keepAnimating;
}
if (keepAnimating) {
startAnimationLocked();
bool PointerController::doBitmapAnimationLocked(nsecs_t timestamp) {
std::map<int32_t, PointerAnimation>::const_iterator iter = mLocked.animationResources.find(
mLocked.requestedPointerShape);
if (iter == mLocked.animationResources.end()) {
return false;
}
if (timestamp - mLocked.lastFrameUpdatedTime > iter->second.durationPerFrame) {
mSpriteController->openTransaction();
int incr = (timestamp - mLocked.lastFrameUpdatedTime) / iter->second.durationPerFrame;
mLocked.animationFrameIndex += incr;
mLocked.lastFrameUpdatedTime += iter->second.durationPerFrame * incr;
while (mLocked.animationFrameIndex >= iter->second.animationFrames.size()) {
mLocked.animationFrameIndex -= iter->second.animationFrames.size();
}
mLocked.pointerSprite->setIcon(iter->second.animationFrames[mLocked.animationFrameIndex]);
mSpriteController->closeTransaction();
}
// Keep animating.
return true;
}
void PointerController::doInactivityTimeout() {
@@ -549,9 +584,16 @@ void PointerController::updatePointerLocked() {
if (mLocked.requestedPointerShape == mPolicy->getDefaultPointerIconId()) {
mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
} else {
std::map<int, SpriteIcon>::const_iterator iter =
std::map<int32_t, SpriteIcon>::const_iterator iter =
mLocked.additionalMouseResources.find(mLocked.requestedPointerShape);
if (iter != mLocked.additionalMouseResources.end()) {
std::map<int32_t, PointerAnimation>::const_iterator anim_iter =
mLocked.animationResources.find(mLocked.requestedPointerShape);
if (anim_iter != mLocked.animationResources.end()) {
mLocked.animationFrameIndex = 0;
mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
startAnimationLocked();
}
mLocked.pointerSprite->setIcon(iter->second);
} else {
ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerShape);

View File

@@ -20,6 +20,7 @@
#include "SpriteController.h"
#include <map>
#include <vector>
#include <ui/DisplayInfo.h>
#include <input/Input.h>
@@ -30,8 +31,6 @@
#include <utils/String8.h>
#include <gui/DisplayEventReceiver.h>
#include <SkBitmap.h>
namespace android {
/*
@@ -43,6 +42,11 @@ struct PointerResources {
SpriteIcon spotAnchor;
};
struct PointerAnimation {
std::vector<SpriteIcon> animationFrames;
nsecs_t durationPerFrame;
};
/*
* Pointer controller policy interface.
*
@@ -59,7 +63,8 @@ protected:
public:
virtual void loadPointerResources(PointerResources* outResources) = 0;
virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources) = 0;
virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
std::map<int32_t, PointerAnimation>* outAnimationResources) = 0;
virtual int32_t getDefaultPointerIconId() = 0;
};
@@ -98,7 +103,7 @@ public:
const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
virtual void clearSpots();
void updatePointerShape(int iconId);
void updatePointerShape(int32_t iconId);
void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
void setPointerIcon(const SpriteIcon& icon);
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
@@ -145,6 +150,9 @@ private:
bool animationPending;
nsecs_t animationTime;
size_t animationFrameIndex;
nsecs_t lastFrameUpdatedTime;
int32_t displayWidth;
int32_t displayHeight;
int32_t displayOrientation;
@@ -162,7 +170,8 @@ private:
SpriteIcon pointerIcon;
bool pointerIconChanged;
std::map<int, SpriteIcon> additionalMouseResources;
std::map<int32_t, SpriteIcon> additionalMouseResources;
std::map<int32_t, PointerAnimation> animationResources;
int32_t requestedPointerShape;
@@ -178,6 +187,8 @@ private:
void handleMessage(const Message& message);
int handleEvent(int fd, int events, void* data);
void doAnimate(nsecs_t timestamp);
bool doFadingAnimationLocked(nsecs_t timestamp);
bool doBitmapAnimationLocked(nsecs_t timestamp);
void doInactivityTimeout();
void startAnimationLocked();

View File

@@ -152,18 +152,23 @@ static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
getInputWindowHandleObjLocalRef(env);
}
static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
SpriteIcon* outSpriteIcon) {
PointerIcon pointerIcon;
static void loadSystemIconAsSpriteWithPointerIcon(JNIEnv* env, jobject contextObj, int32_t style,
PointerIcon* outPointerIcon, SpriteIcon* outSpriteIcon) {
status_t status = android_view_PointerIcon_loadSystemIcon(env,
contextObj, style, &pointerIcon);
contextObj, style, outPointerIcon);
if (!status) {
pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType);
outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
outPointerIcon->bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType);
outSpriteIcon->hotSpotX = outPointerIcon->hotSpotX;
outSpriteIcon->hotSpotY = outPointerIcon->hotSpotY;
}
}
static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
SpriteIcon* outSpriteIcon) {
PointerIcon pointerIcon;
loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon);
}
enum {
WM_ACTION_PASS_TO_USER = 1,
};
@@ -238,7 +243,8 @@ public:
/* --- PointerControllerPolicyInterface implementation --- */
virtual void loadPointerResources(PointerResources* outResources);
virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources);
virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
std::map<int32_t, PointerAnimation>* outAnimationResources);
virtual int32_t getDefaultPointerIconId();
private:
@@ -1041,14 +1047,31 @@ void NativeInputManager::loadPointerResources(PointerResources* outResources) {
&outResources->spotAnchor);
}
void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources) {
void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
std::map<int32_t, PointerAnimation>* outAnimationResources) {
JNIEnv* env = jniEnv();
for (int iconId = POINTER_ICON_STYLE_CONTEXT_MENU; iconId <= POINTER_ICON_STYLE_GRABBING;
++iconId) {
loadSystemIconAsSprite(env, mContextObj, iconId, &((*outResources)[iconId]));
PointerIcon pointerIcon;
loadSystemIconAsSpriteWithPointerIcon(
env, mContextObj, iconId, &pointerIcon, &((*outResources)[iconId]));
if (!pointerIcon.bitmapFrames.empty()) {
PointerAnimation& animationData = (*outAnimationResources)[iconId];
size_t numFrames = pointerIcon.bitmapFrames.size() + 1;
animationData.durationPerFrame =
milliseconds_to_nanoseconds(pointerIcon.durationPerFrame);
animationData.animationFrames.reserve(numFrames);
animationData.animationFrames.push_back(SpriteIcon(
pointerIcon.bitmap, pointerIcon.hotSpotX, pointerIcon.hotSpotY));
for (size_t i = 0; i < numFrames - 1; ++i) {
animationData.animationFrames.push_back(SpriteIcon(
pointerIcon.bitmapFrames[i], pointerIcon.hotSpotX, pointerIcon.hotSpotY));
}
}
}
loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_NULL, &((*outResources)[POINTER_ICON_STYLE_NULL]));
loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_NULL,
&((*outResources)[POINTER_ICON_STYLE_NULL]));
}
int32_t NativeInputManager::getDefaultPointerIconId() {