Tutorials, extensions, and source files for ActionScript, Flash, and other Adobe products.

 

senocular.com ActionScript Library

StageDetection.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.senocular.events {
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	
	/**
	 * StageDetection 
	 * Lets a DisplayObject know when its been added to
	 * a display list attached to the stage.
	 *
	 * Usage:
	 * // used in the constructor where addedToStage and removedFromStage
	 * // are event handler methods
	 * var stageDetect:StageDetection = new StageDetection(this);
	 * stageDetect.addEventListener(StageDetection.ADDED_TO_STAGE, addedToStage);
	 * stageDetect.addEventListener(StageDetection.REMOVED_FROM_STAGE, removedFromStage);
	 */
	public class StageDetection extends EventDispatcher {
		
		protected var target:DisplayObject;
		protected var parents:Dictionary;
		protected var detect:String;
		
		public static const ADDED_TO_STAGE:String = "addedToStage";
		public static const REMOVED_FROM_STAGE:String = "removedFromStage";
		
		/**
		 * Constructor
		 */
		public function StageDetection(targetObject:DisplayObject) {
			target = targetObject;
			
			// determine whether need to detect for added or removed
			detect = (target.stage == null) ? Event.ADDED : Event.REMOVED; 
			
			// update parent listeners for detect events
			updateListeners();
		}
		
		/**
		 * updates listeners from which ADDED and REMOVED events are to be received
		 */
		protected function updateListeners(newDetect:String = null):void {
			
			// cleanup old listeners in parents
			if (parents) {
				for (var key:Object in parents) {
					key.removeEventListener(detect, stageCheck, false);
				}
			}
			
			// new event to detect if given
			if (newDetect) detect = newDetect;
				
			// set up detect event with current parents
			parents = new Dictionary(true);
			var parent:DisplayObject = target;
			while (parent) {
				parent.addEventListener(detect, stageCheck, false, 0, true);
				parents[parent] = true;
				parent = parent.parent;
			}
		}
		
		
		/**
		 * event handler for ADDED and REMOVED events checking for stage access
		 */
		protected function stageCheck(evt:Event):void {
			
			// only check for originating object
			if (evt.target != evt.currentTarget) return;
				
			// evt.type either ADDED or REMOVED
			switch(evt.type) {
				
				// parent added to another display object
				case Event.ADDED:
					
					// stage available, added to stage
					if (target.stage != null) {
						
						// added to stage, dispatch event, update
						dispatchEvent(new Event(ADDED_TO_STAGE));
						updateListeners(Event.REMOVED);
						
					// stage inaccessible, added to some other display object not on stage
					} else {
						
						// display list has changed, update parent listeners
						updateListeners();
					}
					break;
					
				// parent removed from stage
				case Event.REMOVED:
					
					// removed from stage, dispatch event, update
					dispatchEvent(new Event(REMOVED_FROM_STAGE));
					updateListeners(Event.ADDED);
					break;
			}
		}
	}
}