Permalink
Browse files

[Sprite] Implement hitArea

  • Loading branch information...
1 parent 36c1faa commit 37f7a3a28a935aa4567ccbdd5960011186de6d86 @aajanki aajanki committed Feb 12, 2013
Showing with 52 additions and 4 deletions.
  1. +48 −4 src/scripting/flash/display/flashdisplay.cpp
  2. +4 −0 src/scripting/flash/display/flashdisplay.h
@@ -576,6 +576,8 @@ void Sprite::finalize()
{
DisplayObjectContainer::finalize();
graphics.reset();
+ hitArea.reset();
+ hitTarget.reset();
}
void Sprite::sinit(Class_base* c)
@@ -586,6 +588,7 @@ void Sprite::sinit(Class_base* c)
c->setDeclaredMethodByQName("startDrag","",Class<IFunction>::getFunction(_startDrag),NORMAL_METHOD,true);
c->setDeclaredMethodByQName("stopDrag","",Class<IFunction>::getFunction(_stopDrag),NORMAL_METHOD,true);
REGISTER_GETTER_SETTER(c, buttonMode);
+ REGISTER_GETTER_SETTER(c, hitArea);
REGISTER_GETTER_SETTER(c, useHandCursor);
}
@@ -630,6 +633,27 @@ ASFUNCTIONBODY(Sprite,_stopDrag)
return NULL;
}
+ASFUNCTIONBODY_GETTER(Sprite, hitArea);
+
+ASFUNCTIONBODY(Sprite,_setter_hitArea)
+{
+ Sprite* th=Class<Sprite>::cast(obj);
+ _NR<Sprite> value;
+ ARG_UNPACK(value);
+
+ if (!th->hitArea.isNull())
+ th->hitArea->hitTarget.reset();
+
+ th->hitArea = value;
+ if (!th->hitArea.isNull())
+ {
+ th->incRef();
+ th->hitArea->hitTarget = _MNR(th);
+ }
+
+ return NULL;
+}
+
bool DisplayObjectContainer::boundsRect(number_t& xmin, number_t& xmax, number_t& ymin, number_t& ymax) const
{
bool ret = false;
@@ -756,17 +780,37 @@ _NR<DisplayObject> DisplayObjectContainer::hitTestImpl(_NR<DisplayObject> last,
_NR<DisplayObject> Sprite::hitTestImpl(_NR<DisplayObject>, number_t x, number_t y, DisplayObject::HIT_TYPE type)
{
+ //Did we hit a children?
_NR<DisplayObject> ret = NullRef;
this->incRef();
ret = DisplayObjectContainer::hitTestImpl(_MR(this),x,y, type);
- if(!ret && isHittable(type))
+
+ if (ret.isNull() && hitArea.isNull())
{
//The coordinates are locals
this->incRef();
- return TokenContainer::hitTestImpl(_MR(this),x,y, type);
+ ret = TokenContainer::hitTestImpl(_MR(this),x,y, type);
+
+ if (!ret.isNull()) //Did we hit the sprite?
+ {
+ if (!hitTarget.isNull())
+ {
+ //Another Sprite has registered us
+ //as its hitArea -> relay the hit
+ if (hitTarget->isHittable(type))
+ ret = hitTarget;
+ else
+ ret.reset();
+ }
+ else if (!isHittable(type))
+ {
+ //Hit ignored due to a disabled HIT_TYPE
+ ret.reset();
+ }
+ }
}
- else
- return ret;
+
+ return ret;
}
ASFUNCTIONBODY(Sprite,_constructor)
@@ -375,6 +375,9 @@ class Sprite: public DisplayObjectContainer, public TokenContainer
friend class DisplayObject;
private:
_NR<Graphics> graphics;
+ //hitTarget is non-null if another Sprite has registered this
+ //Sprite as its hitArea. Hits will be relayed to hitTarget.
+ _NR<Sprite> hitTarget;
protected:
bool boundsRect(number_t& xmin, number_t& xmax, number_t& ymin, number_t& ymax) const;
void renderImpl(RenderContext& ctxt) const;
@@ -389,6 +392,7 @@ friend class DisplayObject;
ASFUNCTION(_startDrag);
ASFUNCTION(_stopDrag);
ASPROPERTY_GETTER_SETTER(bool, buttonMode);
+ ASPROPERTY_GETTER_SETTER(_NR<Sprite>, hitArea);
ASPROPERTY_GETTER_SETTER(bool, useHandCursor);
int getDepth() const
{

0 comments on commit 37f7a3a

Please sign in to comment.