PageRenderTime 53ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/as3/trunk/src/org/papervision3d/core/utils/virtualmouse/VirtualMouse.as

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