1////////////////////////////////////////////////////////////////////////////////
2//
3//  ADOBE SYSTEMS INCORPORATED
4//  Copyright 2005-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
12package mx.effects.effectClasses
13{
14
15import flash.events.Event;
16import mx.core.UIComponent;
17import mx.core.mx_internal;
18import mx.events.ChildExistenceChangedEvent;
19import mx.events.FlexEvent;
20import mx.graphics.RoundedRectangle;
21import mx.styles.StyleManager;
22
23/**
24 *  The DissolveInstance class implements the instance class
25 *  for the Dissolve effect.
26 *  Flex creates an instance of this class when it plays a Dissolve effect;
27 *  you do not create one yourself.
28 *
29 *  <p>Every effect class that is a subclass of the TweenEffect class
30 *  supports the following events:</p>
31 *
32 *  <ul>
33 *    <li><code>tweenEnd</code>: Dispatched when the tween effect ends. </li>
34 *
35 *    <li><code>tweenUpdate</code>: Dispatched every time a TweenEffect
36 *      class calculates a new value.</li>
37 *  </ul>
38 *
39 *  <p>The event object passed to the event listener for these events is of type TweenEvent.
40 *  The TweenEvent class  defines the property <code>value</code>, which contains
41 *  the tween value calculated by the effect.
42 *  For the Dissolve effect,
43 *  the <code>TweenEvent.value</code> property contains a Number between the values of the
44 *  <code>Dissolve.alphaFrom</code> and <code>Dissolve.alphaTo</code> properties.</p>
45 *
46 *  @see mx.effects.Dissolve
47 *  @see mx.events.TweenEvent
48 */
49public class DissolveInstance extends TweenEffectInstance
50{
51    include "../../core/Version.as";
52
53	//--------------------------------------------------------------------------
54	//
55	//  Constructor
56	//
57	//--------------------------------------------------------------------------
58
59	/**
60	 *  Constructor.
61	 *
62	 *  @param target The Object to animate with this effect.
63	 */
64	public function DissolveInstance(target:Object)
65	{
66		super(target);
67	}
68
69	//--------------------------------------------------------------------------
70	//
71	//  Variables
72	//
73	//--------------------------------------------------------------------------
74
75	/**
76	 *  @private
77	 */
78	private var overlay:UIComponent;
79
80	//--------------------------------------------------------------------------
81	//
82	//  Properties
83	//
84	//--------------------------------------------------------------------------
85
86	//----------------------------------
87	//  alphaFrom
88	//----------------------------------
89
90	/**
91	 *  Initial transparency level between 0.0 and 1.0,
92	 *  where 0.0 means transparent and 1.0 means fully opaque.
93	 */
94	public var alphaFrom:Number;
95
96	//----------------------------------
97	//  alphaTo
98	//----------------------------------
99
100	/**
101	 *  Final transparency level between 0.0 and 1.0,
102	 *  where 0.0 means transparent and 1.0 means fully opaque.
103	 */
104	public var alphaTo:Number;
105
106	//----------------------------------
107	//  color
108	//----------------------------------
109
110	/**
111	 *  Hex value that represents the color of the floating rectangle
112	 *  that the effect displays over the target object.
113	 *
114	 *  The default value is the color specified by the target component's
115	 *  <code>backgroundColor</code> style property, or 0xFFFFFF, if
116	 *  <code>backgroundColor</code> is not set.
117	 */
118	public var color:uint = StyleManager.NOT_A_COLOR;
119
120	//----------------------------------
121	//  persistAfterEnd
122	//----------------------------------
123
124	/**
125	 *  @private
126	 */
127	mx_internal var persistAfterEnd:Boolean = false;
128
129	//----------------------------------
130	//  targetArea
131	//----------------------------------
132
133	/**
134	 *  The area of the target to play the effect upon.
135	 *  The dissolve overlay is drawn using this property's dimensions.
136	 *  UIComponents create an overlay over the entire component.
137	 *  Containers create an overlay over their content area,
138	 *  but not their chrome.
139	 */
140	public var targetArea:RoundedRectangle;
141
142	//--------------------------------------------------------------------------
143	//
144	//  Overridden methods
145	//
146	//--------------------------------------------------------------------------
147
148	/**
149	 *  @private
150	 */
151	override public function initEffect(event:Event):void
152	{
153		super.initEffect(event);
154
155		switch (event.type)
156		{
157			case "childrenCreationComplete":
158			case FlexEvent.CREATION_COMPLETE:
159			case "resizeEnd":
160			case FlexEvent.SHOW:
161			case Event.ADDED:
162			{
163				if (isNaN(alphaFrom))
164					alphaFrom = 0;
165				if (isNaN(alphaTo))
166					alphaTo = target.alpha;
167				break;
168			}
169
170			case FlexEvent.HIDE:
171			case "resizeStart":
172			case Event.REMOVED:
173			{
174				if (isNaN(alphaFrom))
175					alphaFrom = target.alpha;
176				if (isNaN(alphaTo))
177					alphaTo = 0;
178				break;
179			}
180		}
181	}
182
183	/**
184	 *  @private
185	 */
186	override public function play():void
187	{
188		super.play();
189
190		var values:PropertyChanges = propertyChanges;
191
192		// If nobody assigned a value, make this a "show" effect.
193		if (isNaN(alphaFrom) && isNaN(alphaTo))
194		{
195			// If we are in transition mode
196			if (values && values.end["alpha"] !== undefined)
197			{
198				alphaFrom = target.alpha;
199				alphaTo = values.end["alpha"];
200			}
201			else if (values && values.end["visible"] !== undefined)
202			{
203				alphaFrom = values.start["visible"] ? target.alpha : 0;
204				alphaTo = values.end["visible"] ? target.alpha : 0;
205			}
206			else
207			{
208				alphaFrom = 0;
209				alphaTo = target.alpha;
210			}
211		}
212		else if (isNaN(alphaFrom))
213		{
214			alphaFrom = (alphaTo == 0) ? target.alpha : 0;
215		}
216		else if (isNaN(alphaTo))
217		{
218			if (values && values.end["alpha"] !== undefined)
219				alphaTo = values.end["alpha"];
220			else
221				alphaTo = (alphaFrom == 0) ? target.alpha : 0;
222		}
223
224		// If nobody assigned a color, then use the target's background color.
225		if (color == StyleManager.NOT_A_COLOR)
226		{
227			color = 0xFFFFFF;
228			var bgColor:Number = target.getStyle("backgroundColor");
229			if (isNaN(bgColor) && target.parent)
230			{
231				bgColor = target.parent.getStyle("backgroundColor");
232			}
233			if (!isNaN(bgColor))
234			{
235				color = uint(bgColor);
236			}
237		}
238
239		// Capture the target's width and height before creating the overlay.
240		// Label is a subclass of UIComponent, so creating an overlay
241		// for the label will change the label's width and height.
242		var targetWidth:Number = target.width;
243		var targetHeight:Number = target.height;
244
245		target.addEventListener(ChildExistenceChangedEvent.OVERLAY_CREATED,
246								overlayCreatedHandler);
247
248		target.mx_internal::addOverlay(color, targetArea);
249		//overlay.cacheAsBitmap = true;
250	}
251
252	/**
253	 *  @private
254	 */
255	override public function onTweenUpdate(value:Object):void
256	{
257		overlay.alpha = Number(value);
258	}
259
260	/**
261	 *  @private
262	 */
263	override public function onTweenEnd(value:Object):void
264	{
265		super.onTweenEnd(value);
266
267		if (!mx_internal::persistAfterEnd)
268			target.mx_internal::removeOverlay();
269	}
270
271	//--------------------------------------------------------------------------
272	//
273	//  Event handlers
274	//
275	//--------------------------------------------------------------------------
276
277	/**
278	 *	@private
279	 */
280	private function overlayCreatedHandler(event:ChildExistenceChangedEvent):void
281	{
282		target.removeEventListener(ChildExistenceChangedEvent.OVERLAY_CREATED,
283								   overlayCreatedHandler);
284
285		event.stopImmediatePropagation();
286
287		overlay = UIComponent(event.relatedObject);
288
289		// Create a tween.
290		tween = createTween(this, 1.0 - alphaFrom,
291										 1.0 - alphaTo, duration);
292
293		// Set the animation to the initial value before the screen refreshes.
294		mx_internal::applyTweenStartValues();
295	}
296
297}
298}
299