PageRenderTime 46ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/Sample/mx/managers/CursorManagerImpl.as

https://github.com/ingydotnet/yaml-oscon2009-talk
ActionScript | 1169 lines | 626 code | 136 blank | 407 comment | 99 complexity | 2b735b23cb7f8537b7b067b6f9a9101a MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // ADOBE SYSTEMS INCORPORATED
  4. // Copyright 2006-2007 Adobe Systems Incorporated
  5. // All Rights Reserved.
  6. //
  7. // NOTICE: Adobe permits you to use, modify, and distribute this file
  8. // in accordance with the terms of the license agreement accompanying it.
  9. //
  10. ////////////////////////////////////////////////////////////////////////////////
  11. package mx.managers
  12. {
  13. import flash.display.DisplayObject;
  14. import flash.display.DisplayObjectContainer;
  15. import flash.display.InteractiveObject;
  16. import flash.display.Sprite;
  17. import flash.events.ContextMenuEvent;
  18. import flash.events.Event;
  19. import flash.events.EventDispatcher;
  20. import flash.events.IEventDispatcher;
  21. import flash.events.IOErrorEvent;
  22. import flash.events.MouseEvent;
  23. import flash.events.ProgressEvent;
  24. import flash.geom.Point;
  25. import flash.text.TextField;
  26. import flash.text.TextFieldType;
  27. import flash.ui.Mouse;
  28. import mx.core.ApplicationGlobals;
  29. import mx.core.EventPriority;
  30. import mx.core.FlexSprite;
  31. import mx.core.mx_internal;
  32. import mx.core.IUIComponent;
  33. import mx.events.InterManagerRequest;
  34. import mx.events.SandboxMouseEvent;
  35. import mx.events.SWFBridgeRequest;
  36. import mx.styles.CSSStyleDeclaration;
  37. import mx.styles.StyleManager;
  38. use namespace mx_internal;
  39. [ExcludeClass]
  40. /**
  41. * @private
  42. */
  43. public class CursorManagerImpl implements ICursorManager
  44. {
  45. include "../core/Version.as";
  46. //--------------------------------------------------------------------------
  47. //
  48. // Class variables
  49. //
  50. //--------------------------------------------------------------------------
  51. /**
  52. * @private
  53. */
  54. private static var instance:ICursorManager;
  55. //--------------------------------------------------------------------------
  56. //
  57. // Class methods
  58. //
  59. //--------------------------------------------------------------------------
  60. /**
  61. * @private
  62. */
  63. public static function getInstance():ICursorManager
  64. {
  65. if (!instance)
  66. instance = new CursorManagerImpl();
  67. return instance;
  68. }
  69. //--------------------------------------------------------------------------
  70. //
  71. // Constructor
  72. //
  73. //--------------------------------------------------------------------------
  74. /**
  75. * @private
  76. */
  77. public function CursorManagerImpl(systemManager:ISystemManager = null)
  78. {
  79. super();
  80. if (instance && !systemManager)
  81. throw new Error("Instance already exists.");
  82. if (systemManager)
  83. this.systemManager = systemManager as ISystemManager;
  84. else
  85. this.systemManager = SystemManagerGlobals.topLevelSystemManagers[0] as ISystemManager;
  86. sandboxRoot = this.systemManager.getSandboxRoot();
  87. sandboxRoot.addEventListener(InterManagerRequest.CURSOR_MANAGER_REQUEST, marshalCursorManagerHandler, false, 0, true);
  88. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  89. me.name = "update";
  90. // trace("--->update request for CursorManagerImpl", sm);
  91. sandboxRoot.dispatchEvent(me);
  92. // trace("<---update request for CursorManagerImpl", sm);
  93. }
  94. //--------------------------------------------------------------------------
  95. //
  96. // Variables
  97. //
  98. //--------------------------------------------------------------------------
  99. /**
  100. * @private
  101. */
  102. private var nextCursorID:int = 1;
  103. /**
  104. * @private
  105. */
  106. private var cursorList:Array = [];
  107. /**
  108. * @private
  109. */
  110. private var busyCursorList:Array = [];
  111. /**
  112. * @private
  113. */
  114. private var initialized:Boolean = false;
  115. /**
  116. * @private
  117. */
  118. private var cursorHolder:Sprite;
  119. /**
  120. * @private
  121. */
  122. private var currentCursor:DisplayObject;
  123. /**
  124. * @private
  125. */
  126. private var listenForContextMenu:Boolean = false;
  127. /*******************************************************************
  128. * Regarding overTextField, showSystemCursor, and showCustomCursor:
  129. * Don't modify or read these variables unless you are certain
  130. * you will not create race conditions. E.g. you may get the
  131. * wrong (or no) cursor, and get stuck in an inconsistent state.
  132. */
  133. /**
  134. * @private
  135. */
  136. private var overTextField:Boolean = false;
  137. /**
  138. * @private
  139. */
  140. private var overLink:Boolean = false;
  141. /**
  142. * @private
  143. */
  144. private var showSystemCursor:Boolean = false;
  145. /**
  146. * @private
  147. */
  148. private var showCustomCursor:Boolean = false;
  149. /**
  150. * @private
  151. *
  152. * State variable -- set when there is a custom cursor and the
  153. * mouse has left the stage. Upon return, mouseMoveHandler will
  154. * restore the custom cursor and remove the system cursor.
  155. */
  156. private var customCursorLeftStage:Boolean = false;
  157. /*******************************************************************/
  158. /**
  159. * @private
  160. */
  161. private var systemManager:ISystemManager = null;
  162. /**
  163. * @private
  164. */
  165. private var sandboxRoot:IEventDispatcher = null;
  166. /**
  167. * @private
  168. */
  169. private var sourceArray:Array = [];
  170. //--------------------------------------------------------------------------
  171. //
  172. // Properties
  173. //
  174. //--------------------------------------------------------------------------
  175. //----------------------------------
  176. // currentCursorID
  177. //----------------------------------
  178. /**
  179. * @private
  180. */
  181. private var _currentCursorID:int = 0 /* CursorManager.NO_CURSOR */;
  182. /**
  183. * ID of the current custom cursor,
  184. * or CursorManager.NO_CURSOR if the system cursor is showing.
  185. */
  186. public function get currentCursorID():int
  187. {
  188. return _currentCursorID;
  189. }
  190. /**
  191. * @private
  192. */
  193. public function set currentCursorID(value:int):void
  194. {
  195. _currentCursorID = value;
  196. if (!cursorHolder)
  197. {
  198. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  199. me.name = "currentCursorID";
  200. me.value = currentCursorID;
  201. // trace("-->dispatched currentCursorID for CursorManagerImpl", sm, currentCursorID);
  202. sandboxRoot.dispatchEvent(me);
  203. // trace("<--dispatched currentCursorID for CursorManagerImpl", sm, currentCursorID);
  204. }
  205. }
  206. //----------------------------------
  207. // currentCursorXOffset
  208. //----------------------------------
  209. /**
  210. * @private
  211. */
  212. private var _currentCursorXOffset:Number = 0;
  213. /**
  214. * The x offset of the custom cursor, in pixels,
  215. * relative to the mouse pointer.
  216. *
  217. * @default 0
  218. */
  219. public function get currentCursorXOffset():Number
  220. {
  221. return _currentCursorXOffset;
  222. }
  223. /**
  224. * @private
  225. */
  226. public function set currentCursorXOffset(value:Number):void
  227. {
  228. _currentCursorXOffset = value;
  229. if (!cursorHolder)
  230. {
  231. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  232. me.name = "currentCursorXOffset";
  233. me.value = currentCursorXOffset;
  234. // trace("-->dispatched currentCursorXOffset for CursorManagerImpl", sm, currentCursorXOffset);
  235. sandboxRoot.dispatchEvent(me);
  236. // trace("<--dispatched currentCursorXOffset for CursorManagerImpl", sm, currentCursorXOffset);
  237. }
  238. }
  239. //----------------------------------
  240. // currentCursorYOffset
  241. //----------------------------------
  242. /**
  243. * @private
  244. */
  245. private var _currentCursorYOffset:Number = 0;
  246. /**
  247. * The y offset of the custom cursor, in pixels,
  248. * relative to the mouse pointer.
  249. *
  250. * @default 0
  251. */
  252. public function get currentCursorYOffset():Number
  253. {
  254. return _currentCursorYOffset;
  255. }
  256. /**
  257. * @private
  258. */
  259. public function set currentCursorYOffset(value:Number):void
  260. {
  261. _currentCursorYOffset = value;
  262. if (!cursorHolder)
  263. {
  264. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  265. me.name = "currentCursorYOffset";
  266. me.value = currentCursorYOffset;
  267. // trace("-->dispatched currentCursorYOffset for CursorManagerImpl", sm, currentCursorYOffset);
  268. sandboxRoot.dispatchEvent(me);
  269. // trace("<--dispatched currentCursorYOffset for CursorManagerImpl", sm, currentCursorYOffset);
  270. }
  271. }
  272. //--------------------------------------------------------------------------
  273. //
  274. // Methods
  275. //
  276. //--------------------------------------------------------------------------
  277. /**
  278. * Makes the cursor visible.
  279. * Cursor visibility is not reference-counted.
  280. * A single call to the <code>showCursor()</code> method
  281. * always shows the cursor regardless of how many calls
  282. * to the <code>hideCursor()</code> method were made.
  283. */
  284. public function showCursor():void
  285. {
  286. if (cursorHolder)
  287. cursorHolder.visible = true;
  288. else
  289. {
  290. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  291. me.name = "showCursor";
  292. // trace("-->dispatched showCursor for CursorManagerImpl", sm);
  293. sandboxRoot.dispatchEvent(me);
  294. // trace("<--dispatched showCursor for CursorManagerImpl", sm);
  295. }
  296. }
  297. /**
  298. * Makes the cursor invisible.
  299. * Cursor visibility is not reference-counted.
  300. * A single call to the <code>hideCursor()</code> method
  301. * always hides the cursor regardless of how many calls
  302. * to the <code>showCursor()</code> method were made.
  303. */
  304. public function hideCursor():void
  305. {
  306. if (cursorHolder)
  307. cursorHolder.visible = false;
  308. else
  309. {
  310. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  311. me.name = "hideCursor";
  312. // trace("-->dispatched hideCursor for CursorManagerImpl", sm);
  313. sandboxRoot.dispatchEvent(me);
  314. // trace("<--dispatched hideCursor for CursorManagerImpl", sm);
  315. }
  316. }
  317. /**
  318. * Creates a new cursor and sets an optional priority for the cursor.
  319. * Adds the new cursor to the cursor list.
  320. *
  321. * @param cursorClass Class of the cursor to display.
  322. *
  323. * @param priority Integer that specifies
  324. * the priority level of the cursor.
  325. * Possible values are <code>CursorManagerPriority.HIGH</code>,
  326. * <code>CursorManagerPriority.MEDIUM</code>, and <code>CursorManagerPriority.LOW</code>.
  327. *
  328. * @param xOffset Number that specifies the x offset
  329. * of the cursor, in pixels, relative to the mouse pointer.
  330. *
  331. * @param yOffset Number that specifies the y offset
  332. * of the cursor, in pixels, relative to the mouse pointer.
  333. *
  334. * @param setter The IUIComponent that set the cursor. Necessary (in multi-window environments)
  335. * to know which window needs to display the cursor.
  336. *
  337. * @return The ID of the cursor.
  338. *
  339. * @see mx.managers.CursorManagerPriority
  340. */
  341. public function setCursor(cursorClass:Class, priority:int = 2,
  342. xOffset:Number = 0,
  343. yOffset:Number = 0):int
  344. {
  345. if (initialized && !cursorHolder)
  346. {
  347. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  348. me.name = "setCursor";
  349. me.value = [ cursorClass, priority, xOffset, yOffset ];
  350. // trace("-->dispatched setCursor for CursorManagerImpl", sm, me.value);
  351. sandboxRoot.dispatchEvent(me);
  352. // trace("<--dispatched setCursor for CursorManagerImpl", sm, me.value);
  353. return me.value as int;
  354. }
  355. var cursorID:int = nextCursorID++;
  356. // Create a new CursorQueueItem.
  357. var item:CursorQueueItem = new CursorQueueItem();
  358. item.cursorID = cursorID;
  359. item.cursorClass = cursorClass;
  360. item.priority = priority;
  361. item.x = xOffset;
  362. item.y = yOffset;
  363. if (systemManager)
  364. item.systemManager = systemManager;
  365. else
  366. item.systemManager = ApplicationGlobals.application.systemManager;
  367. // Push it onto the cursor list.
  368. cursorList.push(item);
  369. // Re-sort the cursor list based on priority level.
  370. cursorList.sort(priorityCompare);
  371. // Determine which cursor to display
  372. showCurrentCursor();
  373. return cursorID;
  374. }
  375. /**
  376. * @private
  377. */
  378. private function priorityCompare(a:CursorQueueItem, b:CursorQueueItem):int
  379. {
  380. if (a.priority < b.priority)
  381. return -1;
  382. else if (a.priority == b.priority)
  383. return 0;
  384. return 1;
  385. }
  386. /**
  387. * Removes a cursor from the cursor list.
  388. * If the cursor being removed is the currently displayed cursor,
  389. * the CursorManager displays the next cursor in the list, if one exists.
  390. * If the list becomes empty, the CursorManager displays
  391. * the default system cursor.
  392. *
  393. * @param cursorID ID of cursor to remove.
  394. */
  395. public function removeCursor(cursorID:int):void
  396. {
  397. if (initialized && !cursorHolder)
  398. {
  399. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  400. me.name = "removeCursor";
  401. me.value = cursorID;
  402. // trace("-->dispatched removeCursor for CursorManagerImpl", sm, me.value);
  403. sandboxRoot.dispatchEvent(me);
  404. // trace("<--dispatched removeCursor for CursorManagerImpl", sm, me.value);
  405. return;
  406. }
  407. for (var i:Object in cursorList)
  408. {
  409. var item:CursorQueueItem = cursorList[i];
  410. if (item.cursorID == cursorID)
  411. {
  412. // Remove the element from the array.
  413. cursorList.splice(i, 1);
  414. // Determine which cursor to display.
  415. showCurrentCursor();
  416. break;
  417. }
  418. }
  419. }
  420. /**
  421. * Removes all of the cursors from the cursor list
  422. * and restores the system cursor.
  423. */
  424. public function removeAllCursors():void
  425. {
  426. if (initialized && !cursorHolder)
  427. {
  428. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  429. me.name = "removeAllCursors";
  430. // trace("-->dispatched removeAllCursors for CursorManagerImpl", sm);
  431. sandboxRoot.dispatchEvent(me);
  432. // trace("<--dispatched removeAllCursors for CursorManagerImpl", sm);
  433. return;
  434. }
  435. cursorList.splice(0);
  436. showCurrentCursor();
  437. }
  438. /**
  439. * Displays the busy cursor.
  440. * The busy cursor has a priority of CursorManagerPriority.LOW.
  441. * Therefore, if the cursor list contains a cursor
  442. * with a higher priority, the busy cursor is not displayed
  443. * until you remove the higher priority cursor.
  444. * To create a busy cursor at a higher priority level,
  445. * use the <code>setCursor()</code> method.
  446. */
  447. public function setBusyCursor():void
  448. {
  449. if (initialized && !cursorHolder)
  450. {
  451. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  452. me.name = "setBusyCursor";
  453. // trace("-->dispatched setBusyCursor for CursorManagerImpl", sm);
  454. sandboxRoot.dispatchEvent(me);
  455. // trace("<--dispatched setBusyCursor for CursorManagerImpl", sm);
  456. return;
  457. }
  458. var cursorManagerStyleDeclaration:CSSStyleDeclaration =
  459. StyleManager.getStyleDeclaration("CursorManager");
  460. var busyCursorClass:Class =
  461. cursorManagerStyleDeclaration.getStyle("busyCursor");
  462. busyCursorList.push(setCursor(busyCursorClass, CursorManagerPriority.LOW));
  463. }
  464. /**
  465. * Removes the busy cursor from the cursor list.
  466. * If other busy cursor requests are still active in the cursor list,
  467. * which means you called the <code>setBusyCursor()</code> method more than once,
  468. * a busy cursor does not disappear until you remove
  469. * all busy cursors from the list.
  470. */
  471. public function removeBusyCursor():void
  472. {
  473. if (initialized && !cursorHolder)
  474. {
  475. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  476. me.name = "removeBusyCursor";
  477. // trace("-->dispatched removeBusyCursor for CursorManagerImpl", sm);
  478. sandboxRoot.dispatchEvent(me);
  479. // trace("<--dispatched removeBusyCursor for CursorManagerImpl", sm);
  480. return;
  481. }
  482. if (busyCursorList.length > 0)
  483. removeCursor(int(busyCursorList.pop()));
  484. }
  485. /**
  486. * @private
  487. * Decides what cursor to display.
  488. */
  489. private function showCurrentCursor():void
  490. {
  491. // if there are custom cursors...
  492. if (cursorList.length > 0)
  493. {
  494. if (!initialized)
  495. {
  496. // The first time a cursor is requested of the CursorManager,
  497. // create a Sprite to hold the cursor symbol
  498. cursorHolder = new FlexSprite();
  499. cursorHolder.name = "cursorHolder";
  500. cursorHolder.mouseEnabled = false;
  501. cursorHolder.mouseChildren = false;
  502. systemManager.addChildToSandboxRoot("cursorChildren", cursorHolder);
  503. initialized = true;
  504. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  505. me.name = "initialized";
  506. // trace("-->dispatched removeBusyCursor for CursorManagerImpl", sm);
  507. sandboxRoot.dispatchEvent(me);
  508. // trace("<--dispatched removeBusyCursor for CursorManagerImpl", sm);
  509. }
  510. // Get the top most cursor.
  511. var item:CursorQueueItem = cursorList[0];
  512. // If the system cursor was being displayed, hide it.
  513. if (currentCursorID == CursorManager.NO_CURSOR)
  514. Mouse.hide();
  515. // If the current cursor has changed...
  516. if (item.cursorID != currentCursorID)
  517. {
  518. if (cursorHolder.numChildren > 0)
  519. cursorHolder.removeChildAt(0);
  520. currentCursor = new item.cursorClass();
  521. if (currentCursor)
  522. {
  523. if (currentCursor is InteractiveObject)
  524. InteractiveObject(currentCursor).mouseEnabled = false;
  525. if (currentCursor is DisplayObjectContainer)
  526. DisplayObjectContainer(currentCursor).mouseChildren = false;
  527. cursorHolder.addChild(currentCursor);
  528. addContextMenuHandlers();
  529. var pt:Point;
  530. // make sure systemManager is not other implementation of ISystemManager
  531. if (systemManager is SystemManager)
  532. {
  533. pt = new Point(SystemManager(systemManager).mouseX + item.x, SystemManager(systemManager).mouseY + item.y);
  534. pt = SystemManager(systemManager).localToGlobal(pt);
  535. pt = cursorHolder.parent.globalToLocal(pt);
  536. cursorHolder.x = pt.x;
  537. cursorHolder.y = pt.y;
  538. }
  539. // WindowedSystemManager
  540. else if (systemManager is DisplayObject)
  541. {
  542. pt = new Point(DisplayObject(systemManager).mouseX + item.x, DisplayObject(systemManager).mouseY + item.y);
  543. pt = DisplayObject(systemManager).localToGlobal(pt);
  544. pt = cursorHolder.parent.globalToLocal(pt);
  545. cursorHolder.x = DisplayObject(systemManager).mouseX + item.x;
  546. cursorHolder.y = DisplayObject(systemManager).mouseY + item.y;
  547. }
  548. // otherwise
  549. else
  550. {
  551. cursorHolder.x = item.x;
  552. cursorHolder.y = item.y;
  553. }
  554. if (systemManager.useSWFBridge())
  555. sandboxRoot.addEventListener(MouseEvent.MOUSE_MOVE,
  556. mouseMoveHandler,true,EventPriority.CURSOR_MANAGEMENT);
  557. else
  558. systemManager.stage.addEventListener(MouseEvent.MOUSE_MOVE,
  559. mouseMoveHandler,true,EventPriority.CURSOR_MANAGEMENT);
  560. sandboxRoot.addEventListener(SandboxMouseEvent.MOUSE_MOVE_SOMEWHERE,
  561. marshalMouseMoveHandler,false,EventPriority.CURSOR_MANAGEMENT);
  562. if (systemManager.useSWFBridge())
  563. sandboxRoot.addEventListener(MouseEvent.MOUSE_OUT,
  564. mouseOutHandler,true,EventPriority.CURSOR_MANAGEMENT);
  565. else
  566. systemManager.stage.addEventListener(MouseEvent.MOUSE_OUT,
  567. mouseOutHandler,true,EventPriority.CURSOR_MANAGEMENT);
  568. }
  569. currentCursorID = item.cursorID;
  570. currentCursorXOffset = item.x;
  571. currentCursorYOffset = item.y;
  572. }
  573. }
  574. else
  575. {
  576. showCustomCursor = false;
  577. if (currentCursorID != CursorManager.NO_CURSOR)
  578. {
  579. // There is no cursor in the cursor list to display,
  580. // so cleanup and restore the system cursor.
  581. currentCursorID = CursorManager.NO_CURSOR;
  582. currentCursorXOffset = 0;
  583. currentCursorYOffset = 0;
  584. cursorHolder.removeChild(currentCursor);
  585. removeSystemManagerHandlers();
  586. removeContextMenuHandlers();
  587. }
  588. Mouse.show();
  589. }
  590. }
  591. /**
  592. * @private
  593. *
  594. * This assumes systemManager != null.
  595. */
  596. private function removeSystemManagerHandlers():void
  597. {
  598. if (systemManager.useSWFBridge())
  599. sandboxRoot.removeEventListener(MouseEvent.MOUSE_MOVE,
  600. mouseMoveHandler,true);
  601. else
  602. systemManager.stage.removeEventListener(MouseEvent.MOUSE_MOVE,
  603. mouseMoveHandler,true);
  604. sandboxRoot.removeEventListener(SandboxMouseEvent.MOUSE_MOVE_SOMEWHERE,
  605. marshalMouseMoveHandler,false);
  606. if (systemManager.useSWFBridge())
  607. sandboxRoot.removeEventListener(MouseEvent.MOUSE_OUT,
  608. mouseMoveHandler,true);
  609. else
  610. systemManager.stage.removeEventListener(MouseEvent.MOUSE_OUT,
  611. mouseOutHandler,true);
  612. }
  613. /**
  614. * @private
  615. */
  616. private function addContextMenuHandlers():void
  617. {
  618. if (!listenForContextMenu)
  619. {
  620. const app:InteractiveObject = systemManager.document as InteractiveObject;
  621. const sm:InteractiveObject = systemManager as InteractiveObject;
  622. if (app && app.contextMenu)
  623. {
  624. app.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelectHandler,
  625. true, EventPriority.CURSOR_MANAGEMENT);
  626. listenForContextMenu = true;
  627. }
  628. if (sm && sm.contextMenu)
  629. {
  630. sm.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelectHandler,
  631. true, EventPriority.CURSOR_MANAGEMENT);
  632. listenForContextMenu = true;
  633. }
  634. }
  635. }
  636. /**
  637. * @private
  638. */
  639. private function removeContextMenuHandlers():void
  640. {
  641. if (listenForContextMenu)
  642. {
  643. const app:InteractiveObject = systemManager.document as InteractiveObject;
  644. const sm:InteractiveObject = systemManager as InteractiveObject;
  645. if (app && app.contextMenu)
  646. app.contextMenu.removeEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelectHandler, true);
  647. if (sm && sm.contextMenu)
  648. sm.contextMenu.removeEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelectHandler, true);
  649. listenForContextMenu = false;
  650. }
  651. }
  652. /**
  653. * @private
  654. * Called by other components if they want to display
  655. * the busy cursor during progress events.
  656. */
  657. public function registerToUseBusyCursor(source:Object):void
  658. {
  659. if (initialized && !cursorHolder)
  660. {
  661. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  662. me.name = "registerToUseBusyCursor";
  663. me.value = source;
  664. // trace("-->dispatched registerToUseBusyCursor for CursorManagerImpl", sm, me.value);
  665. sandboxRoot.dispatchEvent(me);
  666. // trace("<--dispatched registerToUseBusyCursor for CursorManagerImpl", sm, me.value);
  667. return;
  668. }
  669. if (source && source is EventDispatcher)
  670. {
  671. source.addEventListener(ProgressEvent.PROGRESS, progressHandler);
  672. source.addEventListener(Event.COMPLETE, completeHandler);
  673. source.addEventListener(IOErrorEvent.IO_ERROR, completeHandler);
  674. }
  675. }
  676. /**
  677. * @private
  678. * Called by other components to unregister
  679. * a busy cursor from the progress events.
  680. */
  681. public function unRegisterToUseBusyCursor(source:Object):void
  682. {
  683. if (initialized && !cursorHolder)
  684. {
  685. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  686. me.name = "unRegisterToUseBusyCursor";
  687. me.value = source;
  688. // trace("-->dispatched unRegisterToUseBusyCursor for CursorManagerImpl", sm, me.value);
  689. sandboxRoot.dispatchEvent(me);
  690. // trace("<--dispatched unRegisterToUseBusyCursor for CursorManagerImpl", sm, me.value);
  691. return;
  692. }
  693. if (source && source is EventDispatcher)
  694. {
  695. source.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
  696. source.removeEventListener(Event.COMPLETE, completeHandler);
  697. source.removeEventListener(IOErrorEvent.IO_ERROR, completeHandler);
  698. }
  699. }
  700. /**
  701. * @private
  702. * Called when contextMenu is opened
  703. */
  704. private function contextMenu_menuSelectHandler(event:ContextMenuEvent):void
  705. {
  706. showCustomCursor = true; // Restore the custom cursor
  707. // Standalone player doesn't initially send mouseMove when the contextMenu is closed,
  708. // so we need to listen for mouseOver as well.
  709. sandboxRoot.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
  710. }
  711. /**
  712. * @private
  713. */
  714. private function mouseOverHandler(event:MouseEvent):void
  715. {
  716. sandboxRoot.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
  717. mouseMoveHandler(event);
  718. }
  719. /**
  720. * @private
  721. */
  722. private function findSource(target:Object):int
  723. {
  724. var n:int = sourceArray.length;
  725. for (var i:int = 0; i < n; i++)
  726. {
  727. if (sourceArray[i] === target)
  728. return i;
  729. }
  730. return -1;
  731. }
  732. //--------------------------------------------------------------------------
  733. //
  734. // Event handlers
  735. //
  736. //--------------------------------------------------------------------------
  737. /**
  738. * @private
  739. */
  740. private function marshalMouseMoveHandler(event:Event):void
  741. {
  742. if (cursorHolder.visible)
  743. {
  744. // mouse is outside our sandbox, restore it.
  745. cursorHolder.visible = false;
  746. var cursorRequest:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.SHOW_MOUSE_CURSOR_REQUEST);
  747. var bridge:IEventDispatcher;
  748. if (systemManager.useSWFBridge())
  749. {
  750. bridge = systemManager.swfBridgeGroup.parentBridge;;
  751. }
  752. else
  753. bridge = systemManager;
  754. cursorRequest.requestor = bridge;
  755. bridge.dispatchEvent(cursorRequest);
  756. if (cursorRequest.data)
  757. Mouse.show();
  758. }
  759. }
  760. /**
  761. * @private
  762. *
  763. * Handles the mouse leaving the stage; hides the custom cursor and restores the system cursor.
  764. */
  765. private function mouseOutHandler(event:MouseEvent):void
  766. {
  767. // relatedObject==null implies the mouse left the stage.
  768. // this also fires when you are returning from a context menu click.
  769. //
  770. // it sometimes fires after you drag off the stage, and back to the stage quickly,
  771. // and let go of the button -- this seems like a player bug
  772. if ((event.relatedObject == null) && (cursorList.length > 0))
  773. {
  774. //trace("mouseOutHandler", event);
  775. // this will get unset in mouseMoveHandler (since that fires when
  776. // the mouse returns/glides over the stage)
  777. customCursorLeftStage = true;
  778. hideCursor();
  779. Mouse.show();
  780. }
  781. }
  782. /**
  783. * @private
  784. */
  785. private function mouseMoveHandler(event:MouseEvent):void
  786. {
  787. var pt:Point = new Point(event.stageX, event.stageY);
  788. pt = cursorHolder.parent.globalToLocal(pt);
  789. pt.x += currentCursorXOffset;
  790. pt.y += currentCursorYOffset;
  791. cursorHolder.x = pt.x;
  792. cursorHolder.y = pt.y;
  793. var target:Object = event.target;
  794. // Do target test.
  795. if (!overTextField &&
  796. target is TextField && target.type == TextFieldType.INPUT)
  797. {
  798. overTextField = true;
  799. showSystemCursor = true;
  800. }
  801. else if (overTextField &&
  802. !(target is TextField && target.type == TextFieldType.INPUT))
  803. {
  804. overTextField = false;
  805. showCustomCursor = true;
  806. }
  807. else
  808. {
  809. showCustomCursor = true
  810. }
  811. // Handle switching between system and custom cursor.
  812. if (showSystemCursor)
  813. {
  814. showSystemCursor = false;
  815. cursorHolder.visible = false;
  816. Mouse.show();
  817. }
  818. if (showCustomCursor)
  819. {
  820. showCustomCursor = false;
  821. cursorHolder.visible = true;
  822. Mouse.hide();
  823. var cursorRequest:SWFBridgeRequest = new SWFBridgeRequest(SWFBridgeRequest.HIDE_MOUSE_CURSOR_REQUEST);
  824. var bridge:IEventDispatcher;
  825. if (systemManager.useSWFBridge())
  826. {
  827. bridge = systemManager.swfBridgeGroup.parentBridge;;
  828. }
  829. else
  830. bridge = systemManager;
  831. cursorRequest.requestor = bridge;
  832. bridge.dispatchEvent(cursorRequest);
  833. }
  834. }
  835. /**
  836. * @private
  837. * Displays the busy cursor if a component is in a busy state.
  838. */
  839. private function progressHandler(event:ProgressEvent):void
  840. {
  841. // Only pay attention to the first progress call. Ignore all others.
  842. var sourceIndex:int = findSource(event.target);
  843. if (sourceIndex == -1)
  844. {
  845. // Add the target to the list of objects we are listening for.
  846. sourceArray.push(event.target);
  847. setBusyCursor();
  848. }
  849. }
  850. /**
  851. * @private
  852. */
  853. private function completeHandler(event:Event):void
  854. {
  855. var sourceIndex:int = findSource(event.target);
  856. if (sourceIndex != -1)
  857. {
  858. // Remove from the list of targets we are listening to.
  859. sourceArray.splice(sourceIndex, 1);
  860. removeBusyCursor();
  861. }
  862. }
  863. /**
  864. * Marshal cursorManager
  865. */
  866. private function marshalCursorManagerHandler(event:Event):void
  867. {
  868. if (event is InterManagerRequest)
  869. return;
  870. var marshalEvent:Object = event;
  871. switch (marshalEvent.name)
  872. {
  873. case "initialized":
  874. // trace("--marshaled initialized for CursorManagerImpl", sm, marshalEvent.value);
  875. initialized = marshalEvent.value;
  876. break;
  877. case "currentCursorID":
  878. // trace("--marshaled currentCursorID for CursorManagerImpl", sm, marshalEvent.value);
  879. _currentCursorID = marshalEvent.value;
  880. break;
  881. case "currentCursorXOffset":
  882. // trace("--marshaled currentCursorXOffset for CursorManagerImpl", sm, marshalEvent.value);
  883. _currentCursorXOffset = marshalEvent.value;
  884. break;
  885. case "currentCursorYOffset":
  886. // trace("--marshaled currentCursorYOffset for CursorManagerImpl", sm, marshalEvent.value);
  887. _currentCursorYOffset = marshalEvent.value;
  888. break;
  889. case "showCursor":
  890. if (cursorHolder)
  891. {
  892. // trace("--marshaled showCursor for CursorManagerImpl", sm);
  893. cursorHolder.visible = true;
  894. ; }
  895. break;
  896. case "hideCursor":
  897. if (cursorHolder)
  898. {
  899. // trace("--marshaled hideCursor for CursorManagerImpl", sm);
  900. cursorHolder.visible = false;
  901. ; }
  902. break;
  903. case "setCursor":
  904. // trace("--marshaled setCursor for CursorManagerImpl", sm, marshalEvent.value);
  905. if (cursorHolder)
  906. {
  907. marshalEvent.value = setCursor.apply(this, marshalEvent.value);
  908. }
  909. break;
  910. case "removeCursor":
  911. if (cursorHolder) // it is our drag
  912. {
  913. removeCursor.apply(this, [ marshalEvent.value ]);
  914. // trace("--marshaled removeCursor for CursorManagerImpl", sm, marshalEvent.value);
  915. }
  916. break;
  917. case "removeAllCursors":
  918. // trace("--marshaled removeAllCursors for CursorManagerImpl", sm);
  919. if (cursorHolder)
  920. removeAllCursors();
  921. break;
  922. case "setBusyCursor":
  923. // trace("--marshaled setBusyCursor for CursorManagerImpl", sm);
  924. if (cursorHolder)
  925. setBusyCursor();
  926. break;
  927. case "removeBusyCursor":
  928. // trace("--marshaled removeBusyCursor for CursorManagerImpl", sm);
  929. if (cursorHolder)
  930. removeBusyCursor();
  931. break;
  932. case "registerToUseBusyCursor":
  933. // trace("--marshaled registerToUseBusyCursor for CursorManagerImpl", sm, marshalEvent.value);
  934. if (cursorHolder)
  935. registerToUseBusyCursor.apply(this, marshalEvent.value);
  936. break;
  937. case "unRegisterToUseBusyCursor":
  938. // trace("--marshaled unRegisterToUseBusyCursor for CursorManagerImpl", sm, marshalEvent.value);
  939. if (cursorHolder)
  940. unRegisterToUseBusyCursor.apply(this, marshalEvent.value);
  941. break;
  942. case "update":
  943. // if we own the cursorHolder, then we're first CursorManager
  944. // so update the others
  945. if (cursorHolder)
  946. {
  947. // trace("-->marshaled update for CursorManagerImpl", sm);
  948. var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  949. me.name = "initialized";
  950. me.value = true;
  951. // trace("-->dispatched initialized for CursorManagerImpl", sm, true);
  952. sandboxRoot.dispatchEvent(me);
  953. // trace("<--dispatched initialized for CursorManagerImpl", sm, true);
  954. me = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  955. me.name = "currentCursorID";
  956. me.value = currentCursorID;
  957. // trace("-->dispatched currentCursorID for CursorManagerImpl", sm, true);
  958. sandboxRoot.dispatchEvent(me);
  959. // trace("<--dispatched currentCursorID for CursorManagerImpl", sm, true);
  960. me = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  961. me.name = "currentCursorXOffset";
  962. me.value = currentCursorXOffset;
  963. // trace("-->dispatched currentCursorXOffset for CursorManagerImpl", sm, true);
  964. sandboxRoot.dispatchEvent(me);
  965. // trace("<--dispatched currentCursorXOffset for CursorManagerImpl", sm, true);
  966. me = new InterManagerRequest(InterManagerRequest.CURSOR_MANAGER_REQUEST);
  967. me.name = "currentCursorYOffset";
  968. me.value = currentCursorYOffset;
  969. // trace("-->dispatched currentCursorYOffset for CursorManagerImpl", sm, true);
  970. sandboxRoot.dispatchEvent(me);
  971. // trace("<--dispatched currentCursorYOffset for CursorManagerImpl", sm, true);
  972. // trace("<--marshaled update for CursorManagerImpl", sm);
  973. }
  974. }
  975. }
  976. }
  977. }
  978. import mx.managers.CursorManager;
  979. import mx.managers.CursorManagerPriority;
  980. import mx.managers.ISystemManager;
  981. ////////////////////////////////////////////////////////////////////////////////
  982. //
  983. // Helper class: CursorQueueItem
  984. //
  985. ////////////////////////////////////////////////////////////////////////////////
  986. /**
  987. * @private
  988. */
  989. class CursorQueueItem
  990. {
  991. include "../core/Version.as";
  992. //--------------------------------------------------------------------------
  993. //
  994. // Constructor
  995. //
  996. //--------------------------------------------------------------------------
  997. /**
  998. * Constructor.
  999. */
  1000. public function CursorQueueItem()
  1001. {
  1002. super();
  1003. }
  1004. //--------------------------------------------------------------------------
  1005. //
  1006. // Properties
  1007. //
  1008. //--------------------------------------------------------------------------
  1009. /**
  1010. * @private
  1011. */
  1012. public var cursorID:int = CursorManager.NO_CURSOR;
  1013. /**
  1014. * @private
  1015. */
  1016. public var cursorClass:Class = null;
  1017. /**
  1018. * @private
  1019. */
  1020. public var priority:int = CursorManagerPriority.MEDIUM;
  1021. /**
  1022. * @private
  1023. */
  1024. public var systemManager:ISystemManager;
  1025. /**
  1026. * @private
  1027. */
  1028. public var x:Number;
  1029. /**
  1030. * @private
  1031. */
  1032. public var y:Number;
  1033. }