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

/as3/tags/1_7/src/org/papervision3d/utils/virtualmouse/VirtualMouse.as

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