PageRenderTime 1807ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/sandy/haxe/tags/3.0.2/src/sandy/core/interaction/VirtualMouse.hx

http://sandy.googlecode.com/
Haxe | 242 lines | 154 code | 31 blank | 57 comment | 48 complexity | 6e13554fc9e249fa68ca81401b477957 MD5 | raw file
  1. package sandy.core.interaction;
  2. import flash.display.DisplayObject;
  3. import flash.display.DisplayObjectContainer;
  4. import flash.display.InteractiveObject;
  5. #if flash9
  6. import flash.display.SimpleButton;
  7. #end
  8. import flash.display.Sprite;
  9. import flash.events.Event;
  10. import flash.events.EventDispatcher;
  11. import flash.events.MouseEvent;
  12. import flash.geom.Point;
  13. import flash.geom.Rectangle;
  14. import flash.text.TextField;
  15. import sandy.core.data.Polygon;
  16. import sandy.core.data.UVCoord;
  17. import sandy.materials.MovieMaterial;
  18. /**
  19. * VirtualMouse interacting with MovieMaterial
  20. * Based on the VirtualMouse by senocular
  21. *
  22. * @author Xavier MARTIN - zeflasher - http://dev.webbymx.net
  23. * @author Thomas PFEIFFER - kiroukou
  24. * @author Niel Drummond - haXe port
  25. *
  26. *
  27. */
  28. class VirtualMouse extends EventDispatcher
  29. {
  30. private static var _oI : VirtualMouse;
  31. // target
  32. private var m_ioTarget : Sprite;
  33. // old target
  34. private var m_ioOldTarget : Sprite;
  35. private var location : Point;
  36. private var lastLocation : Point;
  37. private var lastWithinStage : Bool;
  38. private var _lastEvent : Event;
  39. private var lastDownTarget:InteractiveObject;
  40. /* ****************************************************************************
  41. * CONSTRUCTOR
  42. **************************************************************************** */
  43. public function new( access : PrivateConstructorAccess )
  44. {
  45. lastWithinStage = true;
  46. super();
  47. location = new Point(0, 0);
  48. lastLocation = location.clone();
  49. }
  50. public static function getInstance() : VirtualMouse
  51. {
  52. if ( _oI == null ) _oI = new VirtualMouse( new PrivateConstructorAccess() );
  53. return _oI;
  54. }
  55. /* ****************************************************************************
  56. * PUBLIC FUNCTION
  57. **************************************************************************** */
  58. public function interactWithTexture( p_oPoly : Polygon, p_uvTexture : UVCoord, p_event : Event ) : Void
  59. {
  60. // -- recuperation du material applique sur le polygone
  61. var l_oMaterial:MovieMaterial = untyped p_oPoly.visible ? p_oPoly.appearance.frontMaterial : p_oPoly.appearance.backMaterial;
  62. if( l_oMaterial == null ) return;
  63. m_ioTarget = l_oMaterial.movie;
  64. location = new Point( p_uvTexture.u * l_oMaterial.texture.width, p_uvTexture.v * l_oMaterial.texture.height );
  65. // go through each objectsUnderPoint checking:
  66. // 1) is not ignored
  67. // 2) is InteractiveObject
  68. // 3) mouseEnabled
  69. var objectsUnderPoint:Array<DisplayObject> = m_ioTarget.getObjectsUnderPoint( m_ioTarget.localToGlobal( location ) );
  70. var currentTarget:Sprite = null;
  71. var currentParent:DisplayObject;
  72. var i:Int = objectsUnderPoint.length;
  73. while ( --i > -1 )
  74. {
  75. currentParent = objectsUnderPoint[i];
  76. // go through parent hierarchy
  77. while (currentParent != null)
  78. {
  79. // invalid target if in a SimpleButton
  80. #if flash9
  81. if (currentTarget != null && Std.is(currentParent, SimpleButton))
  82. {
  83. currentTarget = null;
  84. // invalid target if a parent has a
  85. // false mouseChildren
  86. } else
  87. #end
  88. if ( currentTarget != null && Std.is(currentParent, DisplayObjectContainer) && !cast(currentParent, DisplayObjectContainer).mouseChildren )
  89. {
  90. currentTarget = null;
  91. }
  92. // define target if an InteractiveObject
  93. // and mouseEnabled is true
  94. if (currentTarget == null && Std.is(currentParent, DisplayObjectContainer) && cast(currentParent, DisplayObjectContainer).mouseEnabled)
  95. {
  96. currentTarget = cast( currentParent, Sprite );
  97. }
  98. // next parent in hierarchy
  99. currentParent = currentParent.parent;
  100. }
  101. }
  102. // if a currentTarget was not found
  103. // the currentTarget is the texture
  104. if (currentTarget == null)
  105. {
  106. currentTarget = m_ioTarget;
  107. }
  108. if ( m_ioOldTarget == null ) currentTarget.stage;
  109. // if the target is a textfield
  110. /* if ( currentTarget is TextField )
  111. {
  112. _checkLinks( currentTarget as TextField );
  113. return;
  114. }*/
  115. // get local coordinate locations
  116. var targetLocal:Point = p_oPoly.container.globalToLocal(location);
  117. var currentTargetLocal:Point = currentTarget.globalToLocal(location);
  118. // move event
  119. if (lastLocation.x != location.x || lastLocation.y != location.y)
  120. {
  121. var withinStage:Bool = (location.x >= 0 && location.y >= 0 && location.x <= p_oPoly.container.stage.stageWidth && location.y <= p_oPoly.container.stage.stageHeight);
  122. // mouse leave if left stage
  123. if ( !withinStage && lastWithinStage )
  124. {
  125. _lastEvent = new MouseEvent(Event.MOUSE_LEAVE, false, false);
  126. p_oPoly.container.stage.dispatchEvent(_lastEvent);
  127. dispatchEvent(_lastEvent);
  128. }
  129. // only mouse move if within stage
  130. if ( withinStage )
  131. {
  132. //_lastEvent = new MouseEvent( MouseEvent.MOUSE_MOVE, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, p_event.ctrlKey, p_event.altKey, p_event.shiftKey, p_event.buttonDown, p_event.delta );
  133. _lastEvent = new MouseEvent(Event.MOUSE_LEAVE, false, false);
  134. currentTarget.dispatchEvent(_lastEvent);
  135. dispatchEvent(_lastEvent);
  136. }
  137. // remember if within stage
  138. lastWithinStage = withinStage;
  139. }
  140. // roll/mouse (out and over) events
  141. if ( currentTarget != m_ioOldTarget )
  142. {
  143. // off of last target
  144. _lastEvent = new MouseEvent(MouseEvent.MOUSE_OUT, true, false, targetLocal.x, targetLocal.y, currentTarget, untyped( p_event.ctrlKey ), untyped( p_event.altKey ), untyped( p_event.shiftKey ), untyped( p_event.buttonDown ), untyped( p_event.delta ));
  145. m_ioTarget.dispatchEvent(_lastEvent);
  146. dispatchEvent(_lastEvent);
  147. // rolls do not propagate
  148. _lastEvent = new MouseEvent(MouseEvent.ROLL_OUT, false, false, targetLocal.x, targetLocal.y, currentTarget, untyped( p_event.ctrlKey ), untyped( p_event.altKey ), untyped( p_event.shiftKey ), untyped( p_event.buttonDown ), untyped( p_event.delta ));
  149. m_ioTarget.dispatchEvent(_lastEvent);
  150. dispatchEvent(_lastEvent);
  151. // on to current target
  152. _lastEvent = new MouseEvent(MouseEvent.MOUSE_OVER, true, false, currentTargetLocal.x, currentTargetLocal.y, m_ioOldTarget, untyped( p_event.ctrlKey ), untyped( p_event.altKey ), untyped( p_event.shiftKey ), untyped( p_event.buttonDown ), untyped( p_event.delta ));
  153. currentTarget.dispatchEvent(_lastEvent);
  154. dispatchEvent(_lastEvent);
  155. // rolls do not propagate
  156. _lastEvent = new MouseEvent( MouseEvent.ROLL_OVER, false, false, currentTargetLocal.x, currentTargetLocal.y, m_ioOldTarget, untyped( p_event.ctrlKey ), untyped( p_event.altKey ), untyped( p_event.shiftKey ), untyped( p_event.buttonDown ), untyped( p_event.delta ));
  157. currentTarget.dispatchEvent(_lastEvent);
  158. dispatchEvent(_lastEvent);
  159. }
  160. // click/up/down events
  161. if ( p_event.type == MouseEvent.MOUSE_DOWN )
  162. {
  163. _lastEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, untyped( p_event.ctrlKey ), untyped( p_event.altKey ), untyped( p_event.shiftKey ), untyped( p_event.buttonDown ), untyped( p_event.delta ));
  164. currentTarget.dispatchEvent(_lastEvent);
  165. dispatchEvent(_lastEvent);
  166. // remember last down
  167. lastDownTarget = currentTarget;
  168. // mouse is up
  169. }
  170. else if ( p_event.type == MouseEvent.MOUSE_UP )
  171. {
  172. _lastEvent = new MouseEvent(MouseEvent.MOUSE_UP, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, untyped( p_event.ctrlKey ), untyped( p_event.altKey ), untyped( p_event.shiftKey ), untyped( p_event.buttonDown ), untyped( p_event.delta ));
  173. currentTarget.dispatchEvent(_lastEvent);
  174. dispatchEvent(_lastEvent);
  175. }
  176. else if ( p_event.type == MouseEvent.CLICK )
  177. {
  178. _lastEvent = new MouseEvent(MouseEvent.CLICK, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, untyped( p_event.ctrlKey ), untyped( p_event.altKey ), untyped( p_event.shiftKey ), untyped( p_event.buttonDown ), untyped( p_event.delta ));
  179. currentTarget.dispatchEvent(_lastEvent);
  180. dispatchEvent(_lastEvent);
  181. // clear last down
  182. lastDownTarget = null;
  183. }
  184. #if flash9
  185. else if ( p_event.type == MouseEvent.DOUBLE_CLICK && currentTarget.doubleClickEnabled )
  186. {
  187. _lastEvent = new MouseEvent(MouseEvent.DOUBLE_CLICK, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, untyped( p_event.ctrlKey ), untyped( p_event.altKey ), untyped( p_event.shiftKey ), untyped( p_event.buttonDown ), untyped( p_event.delta ));
  188. currentTarget.dispatchEvent(_lastEvent);
  189. dispatchEvent(_lastEvent);
  190. }
  191. #end
  192. // remember last values
  193. lastLocation = location.clone();
  194. m_ioOldTarget = currentTarget;
  195. }
  196. /* ****************************************************************************
  197. * PRIVATE FUNCTIONS
  198. **************************************************************************** */
  199. private function _checkLinks( tf : TextField ) : Void
  200. {
  201. var currentTargetLocal:Point = tf.globalToLocal(location);
  202. var a : Array<TextLink> = TextLink.getTextLinks( tf );
  203. var l : Int = a.length;
  204. for ( i in 0...l )
  205. {
  206. if ( cast( ( cast( a[i], TextLink ) ).getBounds(), Rectangle ).containsPoint( currentTargetLocal ) )
  207. 1+1;
  208. }
  209. }
  210. }
  211. class PrivateConstructorAccess { public function new () {} }