PageRenderTime 62ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/cs4/src/org/papervision3d/core/utils/virtualmouse/VirtualMouse.as

http://papervision3d.googlecode.com/
ActionScript | 753 lines | 329 code | 77 blank | 347 comment | 64 complexity | 888286deee93999b350421be02db4b2e MD5 | raw file
  1. /**
  2. * @author Trevor McCauley
  3. * @link www.senocular.com
  4. */
  5. package org.papervision3d.core.utils.virtualmouse
  6. {
  7. import com.blitzagency.xray.logger.XrayLog;
  8. import flash.display.DisplayObject;
  9. import flash.display.DisplayObjectContainer;
  10. import flash.display.InteractiveObject;
  11. import flash.display.SimpleButton;
  12. import flash.display.Sprite;
  13. import flash.display.Stage;
  14. import flash.events.Event;
  15. import flash.events.EventDispatcher;
  16. import flash.events.KeyboardEvent;
  17. import flash.events.MouseEvent;
  18. import flash.geom.Point;
  19. import flash.utils.Dictionary;
  20. import org.papervision3d.core.components.as3.utils.CoordinateTools;
  21. /**
  22. * Dispatched when the virtual mouse state is updated.
  23. * @eventType flash.events.Event
  24. */
  25. [Event(name="update", type="flash.events.Event")]
  26. /**
  27. * Dispatched when the virtual mouse fires an
  28. * Event.MOUSE_LEAVE event.
  29. * @eventType flash.events.Event
  30. */
  31. [Event(name="mouseLeave", type="flash.events.Event")]
  32. /**
  33. * Dispatched when the virtual mouse fires an
  34. * MouseEvent.MOUSE_MOVE event.
  35. * @eventType flash.events.MouseEvent
  36. */
  37. [Event(name="mouseMove", type="flash.events.MouseEvent")]
  38. /**
  39. * Dispatched when the virtual mouse fires an
  40. * MouseEvent.MOUSE_OUT event.
  41. * @eventType flash.events.MouseEvent
  42. */
  43. [Event(name="mouseOut", type="flash.events.MouseEvent")]
  44. /**
  45. * Dispatched when the virtual mouse fires an
  46. * MouseEvent.ROLL_OUT event.
  47. * @eventType flash.events.MouseEvent
  48. */
  49. [Event(name="rollOut", type="flash.events.MouseEvent")]
  50. /**
  51. * Dispatched when the virtual mouse fires an
  52. * MouseEvent.MOUSE_OVER event.
  53. * @eventType flash.events.MouseEvent
  54. */
  55. [Event(name="mouseOver", type="flash.events.MouseEvent")]
  56. /**
  57. * Dispatched when the virtual mouse fires an
  58. * MouseEvent.ROLL_OVER event.
  59. * @eventType flash.events.MouseEvent
  60. */
  61. [Event(name="rollOver", type="flash.events.MouseEvent")]
  62. /**
  63. * Dispatched when the virtual mouse fires an
  64. * MouseEvent.MOUSE_DOWN event.
  65. * @eventType flash.events.MouseEvent
  66. */
  67. [Event(name="mouseDown", type="flash.events.MouseEvent")]
  68. /**
  69. * Dispatched when the virtual mouse fires an
  70. * MouseEvent.MOUSE_UP event.
  71. * @eventType flash.events.MouseEvent
  72. */
  73. [Event(name="mouseUp", type="flash.events.MouseEvent")]
  74. /**
  75. * Dispatched when the virtual mouse fires an
  76. * MouseEvent.CLICK event.
  77. * @eventType flash.events.MouseEvent
  78. */
  79. [Event(name="click", type="flash.events.MouseEvent")]
  80. /**
  81. * Dispatched when the virtual mouse fires an
  82. * MouseEvent.DOUBLE_CLICK event.
  83. * @eventType flash.events.MouseEvent
  84. */
  85. [Event(name="doubleClick", type="flash.events.MouseEvent")]
  86. /**
  87. * The VirtualMouse class is used to create a programmatic
  88. * version of the users mouse that can be moved about the
  89. * Flash player stage firing off mouse events of the display
  90. * objects it interacts with. This can allow you to simulate
  91. * interaction with buttons and movie clips through ActionScript.
  92. * <br />
  93. * Handled events include:
  94. * Event.MOUSE_LEAVE,
  95. * MouseEvent.MOUSE_MOVE,
  96. * MouseEvent.MOUSE_OUT,
  97. * MouseEvent.ROLL_OUT,
  98. * MouseEvent.MOUSE_OVER,
  99. * MouseEvent.ROLL_OVER,
  100. * MouseEvent.MOUSE_DOWN,
  101. * MouseEvent.MOUSE_UP.
  102. * MouseEvent.CLICK, and,
  103. * MouseEvent.DOUBLE_CLICK.
  104. * Along with dispatching those events for their respective
  105. * targets, the VirtualMouse instance will also dispatch the
  106. * event on itself allowing to capture which events are being
  107. * fired by the virtual mouse. The last event fired can also
  108. * be referenced in the lastEvent property.
  109. * <br />
  110. * VirtualMouse mouse cannot:
  111. * activate states of SimpleButton instances,
  112. * change object focus,
  113. * handle mouseWheel related events,
  114. * change the system's cursor location, or
  115. * spoof the location of the mouseX and mouseY properties
  116. * (which some components rely on).
  117. */
  118. public class VirtualMouse extends EventDispatcher {
  119. public static const UPDATE:String = "update";
  120. private var altKey:Boolean = false;
  121. private var ctrlKey:Boolean = false;
  122. private var shiftKey:Boolean = false;
  123. private var delta:int = 0; // mouseWheel unsupported
  124. private var _stage:Stage;
  125. private var _container:Sprite;
  126. private var target:InteractiveObject;
  127. private var location:Point;
  128. private var isLocked:Boolean = false;
  129. private var isDoubleClickEvent:Boolean = false;
  130. private static var _mouseIsDown:Boolean = false;
  131. private var disabledEvents:Object = new Object();
  132. private var ignoredInstances:Dictionary = new Dictionary(true);
  133. private var _lastEvent:Event;
  134. private var lastMouseDown:Boolean = false;
  135. private var updateMouseDown:Boolean = false;
  136. private var lastLocation:Point;
  137. private var lastDownTarget:DisplayObject;
  138. private var lastWithinStage:Boolean = true;
  139. private var _useNativeEvents:Boolean = false;
  140. private var eventEvent:Class = VirtualMouseEvent;
  141. private var mouseEventEvent:Class = VirtualMouseMouseEvent;
  142. private var log:XrayLog = new XrayLog();
  143. /**
  144. * A reference to the Stage instance. This
  145. * reference needs to be passed to the
  146. * VirtualMouse instance either in its constructor
  147. * or through assigning it's stage property.
  148. * Without a valid reference to the stage, the
  149. * virtual mouse will not function.
  150. * @see VirtualMouse()
  151. */
  152. public function get stage():Stage {
  153. return _stage;
  154. }
  155. public function set stage(s:Stage):void {
  156. var hadStage:Boolean;
  157. if (_stage){
  158. hadStage = true;
  159. _stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
  160. _stage.removeEventListener(KeyboardEvent.KEY_UP, keyHandler);
  161. }else{
  162. hadStage = false;
  163. }
  164. _stage = s;
  165. if (_stage) {
  166. _stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
  167. _stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler);
  168. target = _stage;
  169. if (!hadStage) update();
  170. }
  171. }
  172. /**
  173. *
  174. * @param value Sprite container you want VirtualMouse to use with its testing of sub containers
  175. * @return
  176. */
  177. public function set container(value:Sprite):void
  178. {
  179. _container = value;
  180. }
  181. public function get container():Sprite { return _container; }
  182. /**
  183. * The last event dispatched by the VirtualMouse
  184. * instance. This can be useful for preventing
  185. * event recursion if performing VirtualMouse
  186. * operations within MouseEvent handlers.
  187. */
  188. public function get lastEvent():Event {
  189. return _lastEvent;
  190. }
  191. /**
  192. * True if the virtual mouse is being
  193. * pressed, false if not. The mouse is
  194. * down for the virtual mouse if press()
  195. * was called.
  196. * @see press()
  197. * @see release()
  198. */
  199. public function get mouseIsDown():Boolean {
  200. return _mouseIsDown;
  201. }
  202. /**
  203. * The x location of the virtual mouse. If you are
  204. * setting both the x and y properties of the
  205. * virtual mouse at the same time, you would probably
  206. * want to lock the VirtualMouse instance to prevent
  207. * additional events from firing.
  208. * @see lock
  209. * @see unlock
  210. * @see y
  211. * @see setLocation()
  212. * @see getLocation()
  213. */
  214. public function get x():Number {
  215. return location.x;
  216. }
  217. public function set x(n:Number):void {
  218. location.x = n;
  219. if (!isLocked) update();
  220. }
  221. /**
  222. * The y location of the virtual mouse. If you are
  223. * setting both the x and y properties of the
  224. * virtual mouse at the same time, you would probably
  225. * want to lock the VirtualMouse instance to prevent
  226. * additional events from firing.
  227. * @see lock
  228. * @see unlock
  229. * @see x
  230. * @see setLocation()
  231. * @see getLocation()
  232. */
  233. public function get y():Number {
  234. return location.y;
  235. }
  236. public function set y(n:Number):void {
  237. location.y = n;
  238. if (!isLocked) update();
  239. }
  240. /**
  241. * Determines if the events dispatched by the
  242. * VirtualMouse instance are IVirualMouseEvent
  243. * Events (wrapping Event and MouseEvent) or events
  244. * of the native Event and MouseEvent type. When using
  245. * non-native events, you can check to see if the
  246. * events originated from VirtualMouse by seeing if
  247. * the events are of the type IVirualMouseEvent.
  248. * @see lastEvent
  249. */
  250. public function get useNativeEvents():Boolean {
  251. return _useNativeEvents;
  252. }
  253. public function set useNativeEvents(b:Boolean):void {
  254. if (b == _useNativeEvents) return;
  255. _useNativeEvents = b;
  256. if (_useNativeEvents){
  257. eventEvent = VirtualMouseEvent;
  258. mouseEventEvent = VirtualMouseMouseEvent;
  259. }else{
  260. eventEvent = Event;
  261. mouseEventEvent = MouseEvent;
  262. }
  263. }
  264. /**
  265. * Initializes a new VirtualMouse instance.
  266. * @param stage A reference to the stage instance.
  267. * @param startX The initial x location of
  268. * the virtual mouse.
  269. * @param startY The initial y location of
  270. * the virtual mouse.
  271. */
  272. public function VirtualMouse(stage:Stage = null, container:Sprite = null, startX:Number = 0, startY:Number = 0) {
  273. this.stage = stage;
  274. this.container = container;
  275. location = new Point(startX, startY);
  276. lastLocation = location.clone();
  277. addEventListener(UPDATE, handleUpdate);
  278. update();
  279. }
  280. /**
  281. * Returns the location (x and y) of the current
  282. * VirtualMouse instance. The location of the
  283. * virtual mouse is based in the global
  284. * coordinate space.
  285. * @return A Point instance representing the
  286. * location of the virtual mouse in
  287. * global coordinate space.
  288. * @see x
  289. * @see y
  290. * @see setLocation()
  291. */
  292. public function getLocation():Point {
  293. return location.clone();
  294. }
  295. /**
  296. * Sets the location (x and y) of the current
  297. * VirtualMouse instance. There are two ways to
  298. * call setLocation, either passing in a single
  299. * Point instance, or by passing in two Number
  300. * instances representing x and y coordinates.
  301. * The location of the virtual mouse is based in
  302. * the global coordinate space.
  303. * @param a A Point instance or x Number value.
  304. * @param b A y Number value if a is a Number.
  305. * @see x
  306. * @see y
  307. * @see getLocation()
  308. */
  309. public function setLocation(a:*, b:* = null):void
  310. {
  311. //log.debug("VM setLocation", a, b);
  312. if (a is Point) {
  313. var loc:Point = a as Point;
  314. trace(loc);
  315. location.x = loc.x;
  316. location.y = loc.y;
  317. }else{
  318. location.x = Number(a);
  319. location.y = Number(b);
  320. }
  321. if (!isLocked) update();
  322. }
  323. /**
  324. * Locks the current VirtualMouse instance
  325. * preventing updates from being made as
  326. * properties change within the instance.
  327. * To release and allow an update, call unlock().
  328. * @see lock()
  329. * @see update()
  330. */
  331. public function lock():void {
  332. isLocked = true;
  333. }
  334. /**
  335. * Unlocks the current VirtualMouse instance
  336. * allowing updates to be made for the
  337. * dispatching of virtual mouse events. After
  338. * unlocking the instance, it will update and
  339. * additional calls to press(), release(), or
  340. * changing the location of the virtual mouse
  341. * will also invoke updates.
  342. * @see lock()
  343. * @see update()
  344. */
  345. public function unlock():void {
  346. isLocked = false;
  347. update();
  348. }
  349. /**
  350. * Allows you to disable an event by type
  351. * preventing the virtual mouse from
  352. * dispatching that event during an update.
  353. * @param type The type for the event to
  354. * disable, e.g. MouseEvent.CLICK
  355. * @see enableEvent()
  356. */
  357. public function disableEvent(type:String):void {
  358. disabledEvents[type] = true;
  359. }
  360. /**
  361. * Re-enables an event disabled with
  362. * disableEvent.
  363. * @param type The type for the event to
  364. * enable, e.g. MouseEvent.CLICK
  365. * @see disableEvent()
  366. */
  367. public function enableEvent(type:String):void {
  368. if (type in disabledEvents) {
  369. delete disabledEvents[type];
  370. }
  371. }
  372. /**
  373. * Ignores a display object preventing that
  374. * object from recieving events from the
  375. * virtual mouse. This is useful for instances
  376. * used for cursors which may always be under
  377. * the virtual mouse's location.
  378. * @param instance A reference to the
  379. * DisplayObject instance to ignore.
  380. * @see unignore()
  381. */
  382. public function ignore(instance:DisplayObject):void {
  383. ignoredInstances[instance] = true;
  384. }
  385. /**
  386. * Removes an instance from the ignore list
  387. * defined by ignore(). When an ingored
  388. * object is passed into unignore(), it will
  389. * be able to receive events from the virtual
  390. * mouse.
  391. * @param instance A reference to the
  392. * DisplayObject instance to unignore.
  393. * @see ignore()
  394. */
  395. public function unignore(instance:DisplayObject):void {
  396. if (instance in ignoredInstances){
  397. delete ignoredInstances[instance];
  398. }
  399. }
  400. /**
  401. * Simulates the pressing of the left
  402. * mouse button. To release the mouse
  403. * button, use release().
  404. * @see release()
  405. * @see click()
  406. */
  407. public function press():void {
  408. //if (_mouseIsDown) return;
  409. updateMouseDown = true;
  410. _mouseIsDown = true;
  411. if (!isLocked) update();
  412. }
  413. /**
  414. * Simulates the release of the left
  415. * mouse button. This method has no
  416. * effect unless press() was called first.
  417. * @see press()
  418. * @see click()
  419. */
  420. public function release():void {
  421. //if (!_mouseIsDown) return;
  422. updateMouseDown = true;
  423. _mouseIsDown = false;
  424. if (!isLocked) update();
  425. }
  426. /**
  427. * Simulates a click of the left
  428. * mouse button (press and release)
  429. * @see press()
  430. * @see release()
  431. * @see click()
  432. * @see doubleClick()
  433. */
  434. public function click():void {
  435. press();
  436. release();
  437. }
  438. /**
  439. * Simulates a double-click of the left
  440. * mouse button (press and release twice).
  441. * Calling this command is the only way to
  442. * simulate a double-click for the virtual
  443. * mouse. Calling press() and release() or
  444. * click() is rapid succession will not
  445. * invoke a double-click event. The double-click
  446. * event will also only fire for an instance
  447. * if it's doubleClickEnabled property is
  448. * set to true.
  449. * @see click()
  450. */
  451. public function doubleClick():void {
  452. // if locked, doubleClick will
  453. // not fire but the mouse will
  454. // be released if not already
  455. if (isLocked) {
  456. release();
  457. }else{
  458. // call update with a click, press, then release
  459. // and double-click notification for release
  460. click();
  461. press();
  462. isDoubleClickEvent = true;
  463. release();
  464. isDoubleClickEvent = false;
  465. }
  466. }
  467. /*Added by Jim Kremens kremens@gmail.com 08/16/07 */
  468. public function exitContainer():void {
  469. var targetLocal:Point = target.globalToLocal(location);
  470. //log.debug("Targetlocal", target != container);
  471. if (!disabledEvents[MouseEvent.MOUSE_OUT]) {
  472. _lastEvent = new mouseEventEvent(MouseEvent.MOUSE_OUT, true, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  473. container.dispatchEvent(new mouseEventEvent(MouseEvent.MOUSE_OUT, true, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta));
  474. dispatchEvent(new mouseEventEvent(MouseEvent.MOUSE_OUT, true, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta));
  475. }
  476. if (!disabledEvents[MouseEvent.ROLL_OUT]) { // rolls do not propagate
  477. _lastEvent = new mouseEventEvent(MouseEvent.ROLL_OUT, false, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  478. container.dispatchEvent(new mouseEventEvent(MouseEvent.ROLL_OUT, false, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta));
  479. dispatchEvent(new mouseEventEvent(MouseEvent.ROLL_OUT, false, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta));
  480. }
  481. if (target != container) {
  482. if (!disabledEvents[MouseEvent.MOUSE_OUT]) {
  483. _lastEvent = new mouseEventEvent(MouseEvent.MOUSE_OUT, true, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  484. target.dispatchEvent(new mouseEventEvent(MouseEvent.MOUSE_OUT, true, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta));
  485. dispatchEvent(new mouseEventEvent(MouseEvent.MOUSE_OUT, true, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta));
  486. }
  487. if (!disabledEvents[MouseEvent.ROLL_OUT]) { // rolls do not propagate
  488. _lastEvent = new mouseEventEvent(MouseEvent.ROLL_OUT, false, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  489. target.dispatchEvent(new mouseEventEvent(MouseEvent.ROLL_OUT, false, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta));
  490. dispatchEvent(new mouseEventEvent(MouseEvent.ROLL_OUT, false, false, targetLocal.x, targetLocal.y, container, ctrlKey, altKey, shiftKey, _mouseIsDown, delta));
  491. }
  492. }
  493. //reset the target to the stage, which is the value it starts at.
  494. target = _stage;
  495. }
  496. /**
  497. * Updates the VirtualMouse instance's state
  498. * to reflect a change in the virtual mouse.
  499. * Within this method all events will be dispatched.
  500. * update() is called any time a VirtualMouse
  501. * property is changed unless lock() was used to
  502. * lock the instance. update() will then not be
  503. * called until unlock() is used to unlock
  504. * the instance. Typically you would never call
  505. * update() directly; it is called automatically
  506. * by the VirtualMouse class. Calling update()
  507. * manually will override lock(). Whenever update()
  508. * is called, the UPDATE event is dispatched.
  509. * @see lock()
  510. * @see unlock()
  511. */
  512. public function update():void {
  513. // dispatch an update event indicating that
  514. // an update has occured
  515. dispatchEvent(new Event(UPDATE, false, false));
  516. }
  517. private function handleUpdate(event:Event):void
  518. {
  519. if (!container) return;
  520. // go through each objectsUnderPoint checking:
  521. // 1) is not ignored
  522. // 2) is InteractiveObject
  523. // 3) mouseEnabled
  524. // 4) all parents have mouseChildren
  525. // if not interactive object, defer interaction to next object in list
  526. // if is interactive and enabled, give interaction and ignore rest
  527. var p:Point = CoordinateTools.localToLocal(container, stage, location);
  528. var objectsUnderPoint:Array = container.getObjectsUnderPoint(location); //container.getObjectsUnderPoint(p);
  529. var currentTarget:InteractiveObject;
  530. var currentParent:DisplayObject;
  531. var i:int = objectsUnderPoint.length;
  532. while (i--) {
  533. currentParent = objectsUnderPoint[i];
  534. // go through parent hierarchy
  535. while (currentParent) {
  536. // don't use ignored instances as the target
  537. if (ignoredInstances[currentParent]
  538. ) {
  539. currentTarget = null;
  540. break;
  541. }
  542. // invalid target if in a SimpleButton
  543. if (currentTarget && currentParent is SimpleButton)
  544. {
  545. //log.debug("found SimpleButton - setting currentTarget to null");
  546. currentTarget = null;
  547. // invalid target if a parent has a
  548. // false mouseChildren
  549. } else if (currentTarget && !DisplayObjectContainer(currentParent).mouseChildren)
  550. {
  551. //log.debug("parent false mouseChildren - setting currentTarget to null");
  552. currentTarget = null;
  553. }
  554. // define target if an InteractiveObject
  555. // and mouseEnabled is true
  556. if (!currentTarget && currentParent is InteractiveObject && InteractiveObject(currentParent).mouseEnabled)
  557. {
  558. //log.debug("found InteractiveObject && mouseEnabled = true - setting currentTarget");
  559. currentTarget = InteractiveObject(currentParent);
  560. }
  561. // next parent in hierarchy
  562. currentParent = currentParent.parent;
  563. }
  564. // if a currentTarget was found
  565. // ignore all other objectsUnderPoint
  566. if (currentTarget){
  567. break;
  568. }
  569. }
  570. // if a currentTarget was not found
  571. // the currentTarget is the stage
  572. if (!currentTarget){
  573. currentTarget = _stage;
  574. //log.debug("no new target found, using stage");
  575. }
  576. // get local coordinate locations
  577. var targetLocal:Point = target.globalToLocal(location);
  578. var currentTargetLocal:Point = currentTarget.globalToLocal(location);
  579. //trace("targetLocal");
  580. //trace("currentTargetLocal");
  581. // move event
  582. if (lastLocation.x != location.x || lastLocation.y != location.y)
  583. {
  584. var withinStage:Boolean = false;
  585. if(stage) withinStage = (location.x >= 0 && location.y >= 0 && location.x <= stage.stageWidth && location.y <= stage.stageHeight);
  586. // mouse leave if left stage
  587. if (!withinStage && lastWithinStage && !disabledEvents[Event.MOUSE_LEAVE]){
  588. _lastEvent = new eventEvent(Event.MOUSE_LEAVE, false, false);
  589. stage.dispatchEvent(_lastEvent);
  590. dispatchEvent(_lastEvent);
  591. }
  592. // only mouse move if within stage
  593. if (withinStage && !disabledEvents[MouseEvent.MOUSE_MOVE]){
  594. _lastEvent = new mouseEventEvent(MouseEvent.MOUSE_MOVE, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  595. currentTarget.dispatchEvent(_lastEvent);
  596. dispatchEvent(_lastEvent);
  597. }
  598. // remember if within stage
  599. lastWithinStage = withinStage;
  600. }
  601. // roll/mouse (out and over) events
  602. //trace("targets match?", target == _stage, currentTarget == target, currentTarget == _stage, target.name, currentTarget.name, ObjectTools.getImmediateClassPath(currentTarget));
  603. if (currentTarget != target)
  604. {
  605. // off of last target
  606. if (!disabledEvents[MouseEvent.MOUSE_OUT]){
  607. _lastEvent = new mouseEventEvent(MouseEvent.MOUSE_OUT, true, false, targetLocal.x, targetLocal.y, currentTarget, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  608. target.dispatchEvent(_lastEvent);
  609. dispatchEvent(_lastEvent);
  610. }
  611. if (!disabledEvents[MouseEvent.ROLL_OUT]){ // rolls do not propagate
  612. _lastEvent = new mouseEventEvent(MouseEvent.ROLL_OUT, false, false, targetLocal.x, targetLocal.y, currentTarget, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  613. target.dispatchEvent(_lastEvent);
  614. dispatchEvent(_lastEvent);
  615. }
  616. // on to current target
  617. if (!disabledEvents[MouseEvent.MOUSE_OVER]){
  618. //log.debug("*** MOUSEOVER****");
  619. _lastEvent = new mouseEventEvent(MouseEvent.MOUSE_OVER, true, false, currentTargetLocal.x, currentTargetLocal.y, target, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  620. currentTarget.dispatchEvent(_lastEvent);
  621. dispatchEvent(_lastEvent);
  622. }
  623. if (!disabledEvents[MouseEvent.ROLL_OVER]){ // rolls do not propagate
  624. //log.debug("*** ROLLOVER****");
  625. _lastEvent = new mouseEventEvent(MouseEvent.ROLL_OVER, false, false, currentTargetLocal.x, currentTargetLocal.y, target, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  626. currentTarget.dispatchEvent(_lastEvent);
  627. dispatchEvent(_lastEvent);
  628. }
  629. }
  630. // click/up/down events
  631. if (updateMouseDown) {
  632. if (_mouseIsDown) {
  633. if (!disabledEvents[MouseEvent.MOUSE_DOWN]){
  634. _lastEvent = new mouseEventEvent(MouseEvent.MOUSE_DOWN, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  635. currentTarget.dispatchEvent(_lastEvent);
  636. dispatchEvent(_lastEvent);
  637. }
  638. // remember last down
  639. lastDownTarget = currentTarget;
  640. updateMouseDown = false;
  641. // mouse is up
  642. }else{
  643. if (!disabledEvents[MouseEvent.MOUSE_UP]){
  644. _lastEvent = new mouseEventEvent(MouseEvent.MOUSE_UP, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  645. currentTarget.dispatchEvent(_lastEvent);
  646. dispatchEvent(_lastEvent);
  647. }
  648. if (!disabledEvents[MouseEvent.CLICK] && currentTarget == lastDownTarget) {
  649. _lastEvent = new mouseEventEvent(MouseEvent.CLICK, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  650. currentTarget.dispatchEvent(_lastEvent);
  651. dispatchEvent(_lastEvent);
  652. }
  653. // clear last down
  654. lastDownTarget = null;
  655. updateMouseDown = false;
  656. }
  657. }
  658. // explicit call to doubleClick()
  659. if (isDoubleClickEvent && !disabledEvents[MouseEvent.DOUBLE_CLICK] && currentTarget.doubleClickEnabled) {
  660. _lastEvent = new mouseEventEvent(MouseEvent.DOUBLE_CLICK, true, false, currentTargetLocal.x, currentTargetLocal.y, currentTarget, ctrlKey, altKey, shiftKey, _mouseIsDown, delta);
  661. currentTarget.dispatchEvent(_lastEvent);
  662. dispatchEvent(_lastEvent);
  663. }
  664. // remember last values
  665. lastLocation = location.clone();
  666. lastMouseDown = _mouseIsDown;
  667. target = currentTarget;
  668. }
  669. private function keyHandler(event:KeyboardEvent):void {
  670. // update properties used in MouseEvents
  671. altKey = event.altKey;
  672. ctrlKey = event.ctrlKey;
  673. shiftKey = event.shiftKey;
  674. }
  675. }
  676. }