michael@0: /* michael@0: * Copyright (C) 2010 The Android Open Source Project michael@0: * michael@0: * Licensed under the Apache License, Version 2.0 (the "License"); michael@0: * you may not use this file except in compliance with the License. michael@0: * You may obtain a copy of the License at michael@0: * michael@0: * http://www.apache.org/licenses/LICENSE-2.0 michael@0: * michael@0: * Unless required by applicable law or agreed to in writing, software michael@0: * distributed under the License is distributed on an "AS IS" BASIS, michael@0: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. michael@0: * See the License for the specific language governing permissions and michael@0: * limitations under the License. michael@0: */ michael@0: michael@0: #ifndef _UI_POINTER_CONTROLLER_H michael@0: #define _UI_POINTER_CONTROLLER_H michael@0: michael@0: #include "SpriteController.h" michael@0: michael@0: #include michael@0: #include "Input.h" michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include michael@0: michael@0: namespace android { michael@0: michael@0: /** michael@0: * Interface for tracking a mouse / touch pad pointer and touch pad spots. michael@0: * michael@0: * The spots are sprites on screen that visually represent the positions of michael@0: * fingers michael@0: * michael@0: * The pointer controller is responsible for providing synchronization and for tracking michael@0: * display orientation changes if needed. michael@0: */ michael@0: class PointerControllerInterface : public virtual RefBase { michael@0: protected: michael@0: PointerControllerInterface() { } michael@0: virtual ~PointerControllerInterface() { } michael@0: michael@0: public: michael@0: /* Gets the bounds of the region that the pointer can traverse. michael@0: * Returns true if the bounds are available. */ michael@0: virtual bool getBounds(float* outMinX, float* outMinY, michael@0: float* outMaxX, float* outMaxY) const = 0; michael@0: michael@0: /* Move the pointer. */ michael@0: virtual void move(float deltaX, float deltaY) = 0; michael@0: michael@0: /* Sets a mask that indicates which buttons are pressed. */ michael@0: virtual void setButtonState(int32_t buttonState) = 0; michael@0: michael@0: /* Gets a mask that indicates which buttons are pressed. */ michael@0: virtual int32_t getButtonState() const = 0; michael@0: michael@0: /* Sets the absolute location of the pointer. */ michael@0: virtual void setPosition(float x, float y) = 0; michael@0: michael@0: /* Gets the absolute location of the pointer. */ michael@0: virtual void getPosition(float* outX, float* outY) const = 0; michael@0: michael@0: enum Transition { michael@0: // Fade/unfade immediately. michael@0: TRANSITION_IMMEDIATE, michael@0: // Fade/unfade gradually. michael@0: TRANSITION_GRADUAL, michael@0: }; michael@0: michael@0: /* Fades the pointer out now. */ michael@0: virtual void fade(Transition transition) = 0; michael@0: michael@0: /* Makes the pointer visible if it has faded out. michael@0: * The pointer never unfades itself automatically. This method must be called michael@0: * by the client whenever the pointer is moved or a button is pressed and it michael@0: * wants to ensure that the pointer becomes visible again. */ michael@0: virtual void unfade(Transition transition) = 0; michael@0: michael@0: enum Presentation { michael@0: // Show the mouse pointer. michael@0: PRESENTATION_POINTER, michael@0: // Show spots and a spot anchor in place of the mouse pointer. michael@0: PRESENTATION_SPOT, michael@0: }; michael@0: michael@0: /* Sets the mode of the pointer controller. */ michael@0: virtual void setPresentation(Presentation presentation) = 0; michael@0: michael@0: /* Sets the spots for the current gesture. michael@0: * The spots are not subject to the inactivity timeout like the pointer michael@0: * itself it since they are expected to remain visible for so long as michael@0: * the fingers are on the touch pad. michael@0: * michael@0: * The values of the AMOTION_EVENT_AXIS_PRESSURE axis is significant. michael@0: * For spotCoords, pressure != 0 indicates that the spot's location is being michael@0: * pressed (not hovering). michael@0: */ michael@0: virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, michael@0: BitSet32 spotIdBits) = 0; michael@0: michael@0: /* Removes all spots. */ michael@0: virtual void clearSpots() = 0; michael@0: }; michael@0: michael@0: michael@0: /* michael@0: * Pointer resources. michael@0: */ michael@0: struct PointerResources { michael@0: SpriteIcon spotHover; michael@0: SpriteIcon spotTouch; michael@0: SpriteIcon spotAnchor; michael@0: }; michael@0: michael@0: michael@0: /* michael@0: * Pointer controller policy interface. michael@0: * michael@0: * The pointer controller policy is used by the pointer controller to interact with michael@0: * the Window Manager and other system components. michael@0: * michael@0: * The actual implementation is partially supported by callbacks into the DVM michael@0: * via JNI. This interface is also mocked in the unit tests. michael@0: */ michael@0: class PointerControllerPolicyInterface : public virtual RefBase { michael@0: protected: michael@0: PointerControllerPolicyInterface() { } michael@0: virtual ~PointerControllerPolicyInterface() { } michael@0: michael@0: public: michael@0: virtual void loadPointerResources(PointerResources* outResources) = 0; michael@0: }; michael@0: michael@0: michael@0: /* michael@0: * Tracks pointer movements and draws the pointer sprite to a surface. michael@0: * michael@0: * Handles pointer acceleration and animation. michael@0: */ michael@0: class PointerController : public PointerControllerInterface, public MessageHandler { michael@0: protected: michael@0: virtual ~PointerController(); michael@0: michael@0: public: michael@0: enum InactivityTimeout { michael@0: INACTIVITY_TIMEOUT_NORMAL = 0, michael@0: INACTIVITY_TIMEOUT_SHORT = 1, michael@0: }; michael@0: michael@0: PointerController(const sp& policy, michael@0: const sp& looper, const sp& spriteController); michael@0: michael@0: virtual bool getBounds(float* outMinX, float* outMinY, michael@0: float* outMaxX, float* outMaxY) const; michael@0: virtual void move(float deltaX, float deltaY); michael@0: virtual void setButtonState(int32_t buttonState); michael@0: virtual int32_t getButtonState() const; michael@0: virtual void setPosition(float x, float y); michael@0: virtual void getPosition(float* outX, float* outY) const; michael@0: virtual void fade(Transition transition); michael@0: virtual void unfade(Transition transition); michael@0: michael@0: virtual void setPresentation(Presentation presentation); michael@0: virtual void setSpots(const PointerCoords* spotCoords, michael@0: const uint32_t* spotIdToIndex, BitSet32 spotIdBits); michael@0: virtual void clearSpots(); michael@0: michael@0: void setDisplayViewport(int32_t width, int32_t height, int32_t orientation); michael@0: void setPointerIcon(const SpriteIcon& icon); michael@0: void setInactivityTimeout(InactivityTimeout inactivityTimeout); michael@0: michael@0: private: michael@0: static const size_t MAX_RECYCLED_SPRITES = 12; michael@0: static const size_t MAX_SPOTS = 12; michael@0: michael@0: enum { michael@0: MSG_ANIMATE, michael@0: MSG_INACTIVITY_TIMEOUT, michael@0: }; michael@0: michael@0: struct Spot { michael@0: static const uint32_t INVALID_ID = 0xffffffff; michael@0: michael@0: uint32_t id; michael@0: sp sprite; michael@0: float alpha; michael@0: float scale; michael@0: float x, y; michael@0: michael@0: inline Spot(uint32_t id, const sp& sprite) michael@0: : id(id), sprite(sprite), alpha(1.0f), scale(1.0f), michael@0: x(0.0f), y(0.0f), lastIcon(NULL) { } michael@0: michael@0: void updateSprite(const SpriteIcon* icon, float x, float y); michael@0: michael@0: private: michael@0: const SpriteIcon* lastIcon; michael@0: }; michael@0: michael@0: mutable Mutex mLock; michael@0: michael@0: sp mPolicy; michael@0: sp mLooper; michael@0: sp mSpriteController; michael@0: sp mHandler; michael@0: michael@0: PointerResources mResources; michael@0: michael@0: struct Locked { michael@0: bool animationPending; michael@0: nsecs_t animationTime; michael@0: michael@0: int32_t displayWidth; michael@0: int32_t displayHeight; michael@0: int32_t displayOrientation; michael@0: michael@0: InactivityTimeout inactivityTimeout; michael@0: michael@0: Presentation presentation; michael@0: bool presentationChanged; michael@0: michael@0: int32_t pointerFadeDirection; michael@0: float pointerX; michael@0: float pointerY; michael@0: float pointerAlpha; michael@0: sp pointerSprite; michael@0: SpriteIcon pointerIcon; michael@0: bool pointerIconChanged; michael@0: michael@0: int32_t buttonState; michael@0: michael@0: Vector spots; michael@0: Vector > recycledSprites; michael@0: } mLocked; michael@0: michael@0: bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const; michael@0: void setPositionLocked(float x, float y); michael@0: michael@0: void handleMessage(const Message& message); michael@0: void doAnimate(); michael@0: void doInactivityTimeout(); michael@0: michael@0: void startAnimationLocked(); michael@0: michael@0: void resetInactivityTimeoutLocked(); michael@0: void removeInactivityTimeoutLocked(); michael@0: void updatePointerLocked(); michael@0: michael@0: Spot* getSpotLocked(uint32_t id); michael@0: Spot* createAndAddSpotLocked(uint32_t id); michael@0: Spot* removeFirstFadingSpotLocked(); michael@0: void releaseSpotLocked(Spot* spot); michael@0: void fadeOutAndReleaseSpotLocked(Spot* spot); michael@0: void fadeOutAndReleaseAllSpotsLocked(); michael@0: michael@0: void loadResources(); michael@0: }; michael@0: michael@0: } // namespace android michael@0: michael@0: #endif // _UI_POINTER_CONTROLLER_H