topical media & game development

talk show tell print

actionscript-util-StageDetector.ax

actionscript-util-StageDetector.ax [swf] flex


  package {
    import flash.display.*;
    import flash.events.*;
    
    // Monitors a specified display object to see when it is added to or 
    // removed from the Stage, and broadcasts the correspoding custom events 
    // @ax-actionscript-util-StageDetector.ADDED_TO_STAGE and @ax-actionscript-util-StageDetector.REMOVED_FROM_STAGE.
    
    // USAGE:
    // var stageDetector:@ax-actionscript-util-StageDetector = new @ax-actionscript-util-StageDetector(someDisplayObject);
    // stageDetector.addEventListener(@ax-actionscript-util-StageDetector.ADDED_TO_STAGE, 
    //                                addedToStageListenerFunction);
    // stageDetector.addEventListener(@ax-actionscript-util-StageDetector.REMOVED_FROM_STAGE,
    //                                removedFromStageListenerFunction);
    public class @ax-actionscript-util-StageDetector extends EventDispatcher {
      // Event constants
      public static const ADDED_TO_STAGE:String = "ADDED_TO_STAGE";
      public static const REMOVED_FROM_STAGE:String = "REMOVED_FROM_STAGE";
      
      // The object for which ADDED_TO_STAGE and REMOVED_FROM_STAGE events
      // will be generated
      private var watchedObject:DisplayObject = null;
      
      // The root of the display hierarchy that contains watchedObject
      private var watchedRoot:DisplayObject = null;
      
      // Flag indicating whether watchedObject is currently on the
      // display list
      private var onStage:Boolean = false;
  
      // Constructor
      public function @ax-actionscript-util-StageDetector (objectToWatch:DisplayObject) {
        // Begin monitoring the specified object
        setWatchedObject(objectToWatch);
      }
  
      // Begins monitoring the specified object to see when it is added to or 
      // removed from the display list
      public function setWatchedObject (objectToWatch:DisplayObject):void {
        // Store the object being monitored
        watchedObject = objectToWatch;
        
        // Note whether watchedObject is currently on the display list
        if (watchedObject.stage != null) {
          onStage = true;
        }
  
        // Find the root of the display hierarchy containing the 
        // watchedObject, and register with it for ADDED/REMOVED events.
        // By observing where watchedObject's root is added and removed, 
        // we'll determine whether watchedObject is on or off the 
        // display list.
        setWatchedRoot(findWatchedObjectRoot());
      }
      
      // Returns a reference to the object being monitored
      public function getWatchedObject ():DisplayObject {
        return watchedObject;
      }    
  
      // Frees this @ax-actionscript-util-StageDetector object's resources. Call this method before 
      // discarding a @ax-actionscript-util-StageDetector object.
      public function dispose ():void {
        clearWatchedRoot();
        watchedObject = null;
      }
  
      // Handles Event.ADDED events targeted at the root of
      // watchedObject's display hierarchy 
      private function addedListener (e:Event):void {
        // If the current watchedRoot was added...
        if (e.eventPhase == EventPhase.AT_TARGET) {
          // ...check if watchedObject is now on the display list
          if (watchedObject.stage != null) {
            // Note that watchedObject is now on the display list
            onStage = true;
            // Notify listeners that watchedObject is now 
            // on the display list
            dispatchEvent(new Event(@ax-actionscript-util-StageDetector.ADDED_TO_STAGE));
          }
          // watchedRoot was added to another container, so there's
          // now a new root of the display hierarchy containing
          // watchedObject. Find that new root, and register with it
          // for ADDED and REMOVED events.
          setWatchedRoot(findWatchedObjectRoot());
        }
      }
  
      // Handles Event.REMOVED events for the root of 
      // watchedObject's display hierarchy
      private function removedListener (e:Event):void {
        // If watchedObject is on the display list...
        if (onStage) {
          // ...check if watchedObject or one of its ancestors was removed
          var wasRemoved:Boolean = false;
          var ancestor:DisplayObject = watchedObject;
          var target:DisplayObject = DisplayObject(e.target);
          while (ancestor != null) {
            if (target == ancestor) {
              wasRemoved = true;
              break;
            }
            ancestor = ancestor.parent;
          }      
          
          // If watchedObject or one of its ancestors was removed...
          if (wasRemoved) {
            // ...register for ADDED and REMOVED events from the removed
            // object (which is the new root of watchedObject's display 
            // hierarchy).
            setWatchedRoot(target);
           
            // Note that watchedObject is not on the display list anymore
            onStage = false;
           
            // Notify listeners that watchedObject was removed from the Stage
            dispatchEvent(new Event(@ax-actionscript-util-StageDetector.REMOVED_FROM_STAGE));
          }
        }
      }
      
      // Returns the root of the display hierarchy that currently contains
      // watchedObject
      private function findWatchedObjectRoot ():DisplayObject {
        var watchedObjectRoot:DisplayObject = watchedObject;
        while (watchedObjectRoot.parent != null) {
          watchedObjectRoot = watchedObjectRoot.parent;
        }
        return watchedObjectRoot;
      }
  
      // Begins listening for ADDED and REMOVED events targeted at the root of
      // watchedObject's display hierarchy
      private function setWatchedRoot (newWatchedRoot:DisplayObject):void {
        clearWatchedRoot();
        watchedRoot = newWatchedRoot;
        registerListeners(watchedRoot);
      }
      
      // Removes event listeners from watchedRoot, and removes
      // this @ax-actionscript-util-StageDetector object's reference to watchedRoot
      private function clearWatchedRoot ():void {
        if (watchedRoot != null) {
          unregisterListeners(watchedRoot);
          watchedRoot = null;
        }
      }    
  
      // Registers ADDED and REMOVED event listeners with watchedRoot
      private function registerListeners (target:DisplayObject):void {
        target.addEventListener(Event.ADDED, addedListener);
        target.addEventListener(Event.REMOVED, removedListener);
      }
  
      // Unregisters ADDED and REMOVED event listeners from watchedRoot
      private function unregisterListeners (target:DisplayObject):void {
        target.removeEventListener(Event.ADDED, addedListener);
        target.removeEventListener(Event.REMOVED, removedListener);
      }
    }
  }


(C) Æliens 27/08/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.