<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GridLinked to RUX &#187; Fireworks</title>
	<atom:link href="http://www.gridlinked.info/Flex/design/fireworks/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gridlinked.info</link>
	<description>Patterns with Flex, RUX, and software</description>
	<lastBuildDate>Fri, 26 Feb 2010 22:18:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cairngorm Secret Tip #3: Responders for View Notifications</title>
		<link>http://www.gridlinked.info/cairngorm-secret-tip-3-responders-for-view-notifications/</link>
		<comments>http://www.gridlinked.info/cairngorm-secret-tip-3-responders-for-view-notifications/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 21:57:50 +0000</pubDate>
		<dc:creator>thomasb</dc:creator>
				<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[Fireworks]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[commands]]></category>
		<category><![CDATA[event dispatching]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://www.gridlinked.info/?p=287</guid>
		<description><![CDATA[In the real-world appliations, the data binding solutions espoused by Cairngorm MVC are not always sufficient. Sometimes Views dispatch business events to request data that should be available only to that specific instance of the calling view. So how does a Cairngorm presentation layer view "subscribe" for post event-processing notifications from the Command? The remarkably easy solution is to use Responders as notification mechanisms to allow Commands to notify Views… just like the way Delegates notify Commands in the control layers.<br /><div><img src="http://www.gridlinked.info/wp-content/plugins/gd-star-rating/gfx.php?value=9.5" /></div><div>Rating: 9.5/<strong>10</strong> (42 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>As Flex continues to grow as the choice RIA technology, many developers start investigating and apply Java design patterns to Flex implementations. Similar to Java Struts, Cairngorm is a  MVC (Model-View-Controller)  framework &#8211; endorsed by Adobe &#8211; that is widely popular within the community.  </p>
<p>One of issues that frequently confuses, blocks, or complicates Cairngorm implementations is the issue of &#8220;view notifications&#8221;. Every Cairngorm developer ask the following question at some point: <span style="color:#AB0000;font-size:1.1em;">How should the Cairngorm business layer best communicate with the Presentation layer?</span> </p>
<p><br/>Review Figure 1 which illustrates the recommended relationships between the view and control layers:</p>
<p><img src="http://www.gridlinked.info/images/2009/04/figure1_mvc.png" alt="Flex Cairngorm MVC " width="642" height="280" class="alignleft size-full wp-image-317" /></p>
<ul>
<li>Model is a repository for data</li>
<li>Views support user interactions and announce user gestures as dispatched events to Controllers</li>
<li>Controllers employ commands to process dispatched events</li>
<li>Commands are responsible for using Delegates to talk to the server, and updating model data (client side)</li>
<li>Views use data binding to &#8220;watch&#8221; Model data changes and self-update to dipslay formatted data. </li>
</ul>
<div class="qa"><span class="question">This sounds great. So what is the problem?</span></div>
<p>Commands are supposed to use the Model layer as the mediator between business and presentation layers. In Flex, data bindings and change watchers allow views to <em>watch</em> data models. When data is modified, hidden propertyChange events are dispatched from Models to Views and the View uses event listeners to self-update.  This is the basic premise of the Flex Cairngorm MVC framework. </p>
<p>In real-world applications, data binding solutions espoused by Cairngorm MVC are not always sufficient; since such solutions require views to watch for data changes. Some times, however, watching for data changes is complicated&#8230; perhaps the data is not globally available. Sometimes the view [that dispatches the business event] is requesting data that should  be available <em>only</em> to that specific instance of the calling view; and should not be stored in global repositories. Sometimes, we do not care so much about the data&#8230; but instead we want to execute custom code when the event succeeds and finishes.</p>
<p>PureMVC and traditional Cairngorm solutions require complex code and design patterns to solve these situations. </p>
<ul>
<li> ViewLocators could be used to try to <em>lookup</em> an instance of a view. (Requires coupling to specific view classes from the business layer&#8230;. BAD!)
<li> Views could employ/register private view controllers with the front controller, </li>
<li> Command could dispatch new &#8220;notify view&#8221; events thru the front Controller to the view controller </li>
</ul>
<p>The above approaches create a proliferation of view controllers and is useful ONLY when multiple views want to listen to the same event and be notified simultaneously. Please note that in such rare situtations, a custom event-bridge or a traditional data binding approach would be more practical [but that is another article]. In fact, in most scenarios, the view simply wants the notification directly and exclusively (only to its instance). For these situations, there is a simpler &#8211; and better &#8211; solution to the ViewController complexity. </p>
<ul>
<li>What if we cannot easily use global data models and view data binding?</li>
<li>What if we do not want to create an hierarchy of bindable properties simply to deliver data to deeply nested child views?
<li>How can we deliver data directly to a view instance without storing that data in the ModelLocator hierarchy?</li>
<li>And&#8230; if the View invokes a Command [via event dispatching] and Command/Delegate pairs process server data, how can the Command deliver the processed results back to the View only?</li>
</ul>
<p>The remarkably easy solution is to use Responders as notification mechanisms to allow Commands to <em>notify</em>  Views&#8230; just like the way Delegates notify Commands [See Cairngorm Secret Tip #2: Data Transformations within Delegates]. To understand the proposed solution, consider the Cairngorm approach where a Command instance employs a Delegate class as &#8220;API facade&#8221; to remote data services. </p>
<p>The command instance <em>submits</em> itself [or a proxy to itself] as a responder to the delegate. The delegate, in turn, simply uses the specified responder to direct dataservice responses directly to back to the command.  This allows the Command to receive <em>callbacks</em> from the Delegate or the Server. In fact, advance this same approach is used at the Delegate level to allow Delegate instances to intercept server responses, transform data, and <em>then</em> notify/pass the modified data back to the Command.</p>
<div class="qa">
With Responders, post-command notifications can be delivered agnostically to any caller [View] that has provided a ResultEvent handler and a FaultEvent handler.
</div>
<p>Using Responders, a Command can submit itself as a callback to specific Delegate calls. Views can effectively do the same with Commands. Figure 2 below illustrates this process or queueing of responses. The queue builds with (1) View waits for a response from the Command, (2) the Commands waits on the Delegate, and (3) the Delegate waits on the Server. The queue unwinds after (4) the server responds, (5) Delegate notifies the command, (6) the Command notifies the view.  Using a Responder proxy, the view is notified after the actual dataservice request/response and after Command processing; see Step (6) in Figure 2. </p>
<p><img src="http://www.gridlinked.info/images/2009/04/figure2_viewnotifications.png" alt="View Notifications using Responders" width="642" height="269" class="alignleft size-full wp-image-318" /></p>
<p><br/> &nbsp;</p>
<div class="qa"><span class="question">How exactly does the view provide a Responder to the Command  ?</span></div>
<p>Well, when we dispatch business events to commands, we create custom events. So we simply need to transport a Responder instance along with the normal event information that is dispatched to the Cairngorm control layer. If all custom events have constructors with optional responder arguments then we have a built-in mechanism to support callbacks from Commands.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #9900cc; font-weight: bold;">package</span> mx.rpc
<span style="color: #000000;">&#123;</span>
<span style="color: #3f5fbf;">/**</span>
<span style="color: #3f5fbf;">&nbsp;*  This interface provides the contract for any service</span>
<span style="color: #3f5fbf;">&nbsp;*  that needs to respond to remote or asynchronous calls.</span>
<span style="color: #3f5fbf;">&nbsp;*/</span>
<span style="color: #0033ff; font-weight: bold;">public</span> interface IResponder
<span style="color: #000000;">&#123;</span>
	<span style="color: #3f5fbf;">/**</span>
<span style="color: #3f5fbf;">	 *  This method is called by a service when the return value</span>
<span style="color: #3f5fbf;">	 *  has been received. </span>
<span style="color: #3f5fbf;">	 *  While &lt;code&gt;data&lt;/code&gt; is typed as Object, it is often</span>
<span style="color: #3f5fbf;">	 *  (but not always) an mx.rpc.events.ResultEvent.</span>
<span style="color: #3f5fbf;">	 */</span>
<span style="display:block;background-color: #ffc;">	<span style="color: #339966; font-weight: bold;">function</span> result<span style="color: #000000;">&#40;</span><span style="color: #004993;">data</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">Object</span><span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>;</span>&nbsp;
	<span style="color: #3f5fbf;">/**</span>
<span style="color: #3f5fbf;">	 *  This method is called by a service when an error has been received.</span>
<span style="color: #3f5fbf;">	 *  While &lt;code&gt;info&lt;/code&gt; is typed as Object it is often</span>
<span style="color: #3f5fbf;">	 *  (but not always) an mx.rpc.events.FaultEvent.</span>
<span style="color: #3f5fbf;">	 */</span>
	<span style="color: #339966; font-weight: bold;">function</span> fault<span style="color: #000000;">&#40;</span><span style="color: #004993;">info</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">Object</span><span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>;
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #9900cc; font-weight: bold;">package</span> com.grdlinked.samples.control.events <span style="color: #000000;">&#123;</span>
&nbsp;
    <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.events</span>.<span style="color: #004993;">Event</span>;
    <span style="color: #0033ff; font-weight: bold;">import</span> mx.rpc.IResponder;
    <span style="color: #0033ff; font-weight: bold;">import</span> com.universalmind.cairngorm.events.UMEvent;
&nbsp;
    <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #9900cc; font-weight: bold;">class</span> LoadUserDetails extends UMEvent <span style="color: #000000;">&#123;</span>
&nbsp;
        <span style="color: #0033ff; font-weight: bold;">public</span> static <span style="color: #6699cc; font-weight: bold;">var</span> EVENT_ID <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">String</span> = <span style="color: #990000;">&quot;loadUserDetailsBySSN&quot;</span>;
&nbsp;
        <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #6699cc; font-weight: bold;">var</span> ssn      <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">String</span> = <span style="color: #990000;">&quot;&quot;</span>;
        <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #6699cc; font-weight: bold;">var</span> password <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">String</span> = <span style="color: #990000;">&quot;&quot;</span>; 
&nbsp;
        <span style="color: #009900;">// Constructor </span>
<span style="display:block;background-color: #ffc;">        <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> LoadUserDetails<span style="color: #000000;">&#40;</span> ssn<span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">String</span>,</span>                                    password<span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">String</span>,
                                    callbacks<span style="color: #000000; font-weight: bold;">:</span>IResponder=<span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
            <span style="color: #0033ff; font-weight: bold;">super</span><span style="color: #000000;">&#40;</span>EVENT_ID, callbacks, <span style="color: #0033ff; font-weight: bold;">true</span>, <span style="color: #0033ff; font-weight: bold;">false</span><span style="color: #000000;">&#41;</span>;
&nbsp;
            <span style="color: #0033ff; font-weight: bold;">this</span>.ssn      = ssn;
            <span style="color: #0033ff; font-weight: bold;">this</span>.password = password;
&nbsp;
        <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>For the examples in the post, we use a custom event <CairngormEvent> <em>LoadUserDetailsEvent</em> class that accepts an optional &#8220;responder&#8221; parameter.  Using a SSN and password the view requests user details from the control layer. The control/business layer may elect to lookup the user in a client-side cache or call the server. The business layer is responsible for all these details and the presentation/UI layer need not worry. And the view does NOT know anything about who handles the event or how the event is processed. This &#8220;separation of concerns&#8221; is what MVC is all about.  </p>
<p>When the event is processed by the command, the command can temporarily cache the view responder or callback. Sometime later &#8211; after the asynchronous data service call responds &#8211; the following can happen:</p>
<ol>
<li> the command can use the dataservice response to update the ModelLocator directly, trigger databindings to update, and</li>
<li>  the command can forward the dataservice response or any OTHER data to the cached responder. Command::notifyCaller() is the method used to provide view notifications.</li>
</ol>
<div class="qa">
<span class="question">Do all my views have to implement the IResponder interface or &#8211; even worse &#8211; extend a custom parent class?&#8221;</span>
</div>
<p>If your views want to implement the IResponder interface, each one of your views would need to include public result() and fault() functions:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?</span>xml <span style="color: #004993;">version</span>=<span style="color: #990000;">&quot;1.0&quot;</span> encoding=<span style="color: #990000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>Canvas 	<span style="color: #004993;">width</span>=<span style="color: #990000;">&quot;400&quot;</span> <span style="color: #004993;">height</span>=<span style="color: #990000;">&quot;300&quot;</span> 
		implements=<span style="color: #990000;">&quot;mx.rpc.IResponder&quot;</span>
		xmlns<span style="color: #000000; font-weight: bold;">:</span>mx=<span style="color: #990000;">&quot;http://www.adobe.com/2006/mxml&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>Script<span style="color: #000000; font-weight: bold;">&gt;</span>
	<span style="color: #000000; font-weight: bold;">&lt;!</span><span style="color: #000000;">&#91;</span>CDATA<span style="color: #000000;">&#91;</span>
		<span style="color: #0033ff; font-weight: bold;">import</span> mx.rpc.IResponder;
		<span style="color: #0033ff; font-weight: bold;">import</span> mx.controls.Alert;
&nbsp;
     <span style="color: #009900;">// Methods required by the IResponder interface		</span>
      <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> result<span style="color: #000000;">&#40;</span><span style="color: #004993;">data</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">Object</span><span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span> <span style="color: #000000;">&#123;</span>
            btnLoad.<span style="color: #004993;">enabled</span> = <span style="color: #0033ff; font-weight: bold;">true</span>;
      <span style="color: #000000;">&#125;</span>
      <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> fault<span style="color: #000000;">&#40;</span><span style="color: #004993;">data</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">Object</span><span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span> <span style="color: #000000;">&#123;</span>
            Alert.<span style="color: #004993;">show</span><span style="color: #000000;">&#40;</span>event.<span style="color: #004993;">message</span><span style="color: #000000;">&#41;</span>;
            btnLoad.<span style="color: #004993;">enabled</span> = <span style="color: #0033ff; font-weight: bold;">true</span>;
      <span style="color: #000000;">&#125;</span>
&nbsp;
&nbsp;
	<span style="color: #009900;">// Private methods invoked by child controls		</span>
      <span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> loadUserDetails<span style="color: #000000;">&#40;</span>ssn<span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">String</span><span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span> <span style="color: #000000;">&#123;</span>
            btnLoad.<span style="color: #004993;">enabled</span> = <span style="color: #0033ff; font-weight: bold;">false</span>;	<span style="color: #009900;">// disable button while waiting for a response.</span>
&nbsp;
            <span style="color: #009900;">// Load the user details for the specified user</span>
            <span style="color: #009900;">//NOTE how this view will be the responder...</span>
<span style="display:block;background-color: #ffc;">            <span style="color: #6699cc; font-weight: bold;">var</span> callbacks <span style="color: #000000; font-weight: bold;">:</span> IResponder = <span style="color: #0033ff; font-weight: bold;">this</span> <span style="color: #0033ff; font-weight: bold;">as</span> IResponder;</span>            <span style="color: #6699cc; font-weight: bold;">var</span> event <span style="color: #000000; font-weight: bold;">:</span> LoadUserDetailsEvent = <span style="color: #0033ff; font-weight: bold;">new</span> LoadUserDetailsEvent<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;435-34-1283&quot;</span>, <span style="color: #990000;">&quot;anonymous&quot;</span>, callbacks<span style="color: #000000;">&#41;</span>;
		  event.<span style="color: #004993;">dispatchEvent</span><span style="color: #000000;">&#40;</span>  <span style="color: #000000;">&#41;</span>;   <span style="color: #009900;">// Cairngorm events self-dispatch directly to the business layer; </span>
      <span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #000000;">&#93;</span><span style="color: #000000;">&#93;</span><span style="color: #000000; font-weight: bold;">&gt;</span>
	<span style="color: #000000; font-weight: bold;">&lt;/</span>mx<span style="color: #000000; font-weight: bold;">:</span>Script<span style="color: #000000; font-weight: bold;">&gt;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>Button id=<span style="color: #990000;">&quot;btnLoad&quot;</span> label=<span style="color: #990000;">&quot;Load User&quot;</span> textAlign=<span style="color: #990000;">&quot;center&quot;</span> <span style="color: #004993;">x</span>=<span style="color: #990000;">&quot;145&quot;</span> <span style="color: #004993;">y</span>=<span style="color: #990000;">&quot;149&quot;</span> <span style="color: #004993;">click</span>=<span style="color: #990000;">&quot;loadUserDetails()&quot;</span> <span style="color: #004993;">width</span>=<span style="color: #990000;">&quot;147&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;/</span>mx<span style="color: #000000; font-weight: bold;">:</span>Canvas<span style="color: #000000; font-weight: bold;">&gt;</span></pre></td></tr></table></div>

<p>In our example the view needs to know when the results are available; since the load button is disabled until the business layer [and server] responds .</p>
<p>The above code sample shows, unfortunately, how each of your custom views would need to be modified to work as view responders. When the command finishes, it would call something like caller.result(). Unfortunately, the signature of the result() function is ambiguous and does not document which event triggered the result. In contrast a method like onResult_loadUserDetails() explicit documents its purpose.</p>
<div id="pullquote-con">If you see any code like that show above, then please slap the developer immediately! </div>
<p>After a thorough slapping, ask that developer this question: <span style="color:#AB0000"><br />
&#8220;What if I had two buttons that each dispatched separate business events and each needed separate response handlers? How could the result() function be the common event handler for both events? Would I have to somehow detect &#8211; inside the result() method &#8211; which event is responding?&#8221;<br />
</span></p>
<p>As you can see, this solution rapidly creates nasty code and rapidly produces nasty, convoluted, unmanageable code.</p>
<p>So instead of requiring an abomination of view interfaces or view inheritance (which is even worse), the view will instead create an instance of a Responder class that will serve as a proxy responder class. The Responder class will <em>redirect</em> result() and fault() calls to methods that we specify.   Let us look at some code for clarity. Below we see an example of custom view component created to load and display user details.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?</span>xml <span style="color: #004993;">version</span>=<span style="color: #990000;">&quot;1.0&quot;</span> encoding=<span style="color: #990000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>Canvas 	<span style="color: #004993;">width</span>=<span style="color: #990000;">&quot;400&quot;</span> <span style="color: #004993;">height</span>=<span style="color: #990000;">&quot;300&quot;</span> 
		xmlns<span style="color: #000000; font-weight: bold;">:</span>mx=<span style="color: #990000;">&quot;http://www.adobe.com/2006/mxml&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>Script<span style="color: #000000; font-weight: bold;">&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;!</span><span style="color: #000000;">&#91;</span>CDATA<span style="color: #000000;">&#91;</span>
		<span style="color: #0033ff; font-weight: bold;">import</span> mx.rpc.IResponder;
		<span style="color: #0033ff; font-weight: bold;">import</span> mx.controls.Alert;
		<span style="color: #0033ff; font-weight: bold;">import</span> mx.rpc.events.FaultEvent;
		<span style="color: #0033ff; font-weight: bold;">import</span> mx.rpc.<span style="color: #004993;">Responder</span>;
&nbsp;
&nbsp;
     <span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> loadUserDetails<span style="color: #000000;">&#40;</span>ssn<span style="color: #000000; font-weight: bold;">:</span><span style="color: #004993;">String</span><span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span> <span style="color: #000000;">&#123;</span>
          <span style="color: #009900;">// Load the user details for the specified user</span>
<span style="display:block;background-color: #ffc;">          <span style="color: #6699cc; font-weight: bold;">var</span> callbacks <span style="color: #000000; font-weight: bold;">:</span> IResponder           = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Responder</span><span style="color: #000000;">&#40;</span>onResults_loadUserDetails, onFault_loadUserDetails<span style="color: #000000;">&#41;</span>;</span>          <span style="color: #6699cc; font-weight: bold;">var</span> event     <span style="color: #000000; font-weight: bold;">:</span> LoadUserDetailsEvent = <span style="color: #0033ff; font-weight: bold;">new</span> LoadUserDetailsEvent<span style="color: #000000;">&#40;</span>user.ssn, user.password, callbacks<span style="color: #000000;">&#41;</span>;
&nbsp;
          btnLoad.<span style="color: #004993;">enabled</span> = <span style="color: #0033ff; font-weight: bold;">false</span>;	<span style="color: #009900;">// disable button while waiting for a response.</span>
          event.<span style="color: #004993;">dispatchEvent</span><span style="color: #000000;">&#40;</span>  <span style="color: #000000;">&#41;</span>;	<span style="color: #009900;">// Cairngorm events can self-dispatch to the business layer.	  </span>
     <span style="color: #000000;">&#125;</span>
&nbsp;
     <span style="color: #009900;">// ***************************************************</span>
     <span style="color: #009900;">// Private EventHandlers for the loadUserDetails()</span>
     <span style="color: #009900;">// ***************************************************</span>
&nbsp;
     <span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> onResuls_loadUserDetails<span style="color: #000000;">&#40;</span>user<span style="color: #000000; font-weight: bold;">:</span>UserVO<span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span> <span style="color: #000000;">&#123;</span>
          <span style="color: #009900;">// The SSN and password were authenticated; here are user details</span>
          _user = <span style="color: #000000; font-weight: bold;">!</span>user <span style="color: #000000; font-weight: bold;">?</span> <span style="color: #0033ff; font-weight: bold;">new</span> UserVO<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">:</span> user;
          btnLoad.<span style="color: #004993;">enabled</span> = <span style="color: #0033ff; font-weight: bold;">true</span>;
     <span style="color: #000000;">&#125;</span>	
&nbsp;
     <span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> onFault_loadUserDetails<span style="color: #000000;">&#40;</span>event<span style="color: #000000; font-weight: bold;">:</span>FaultEvent<span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span> <span style="color: #000000;">&#123;</span>
          Alert.<span style="color: #004993;">show</span><span style="color: #000000;">&#40;</span>event.<span style="color: #004993;">message</span><span style="color: #000000;">&#41;</span>;
          btnLoad.<span style="color: #004993;">enabled</span> = <span style="color: #0033ff; font-weight: bold;">true</span>;
     <span style="color: #000000;">&#125;</span>
&nbsp;
     <span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #6699cc; font-weight: bold;">var</span> _user <span style="color: #000000; font-weight: bold;">:</span> UserVO = <span style="color: #0033ff; font-weight: bold;">new</span> UserVO<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;			
&nbsp;
    <span style="color: #000000;">&#93;</span><span style="color: #000000;">&#93;</span><span style="color: #000000; font-weight: bold;">&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;/</span>mx<span style="color: #000000; font-weight: bold;">:</span>Script<span style="color: #000000; font-weight: bold;">&gt;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>Text <span style="color: #004993;">text</span>=<span style="color: #990000;">&quot;Please enter your credentials to edit your account:&quot;</span> <span style="color: #004993;">x</span>=<span style="color: #990000;">&quot;16&quot;</span> <span style="color: #004993;">y</span>=<span style="color: #990000;">&quot;30&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>FormItem label=<span style="color: #990000;">&quot;FullName:&quot;</span> <span style="color: #004993;">x</span>=<span style="color: #990000;">&quot;23&quot;</span> <span style="color: #004993;">y</span>=<span style="color: #990000;">&quot;208&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span>  
		<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>Label <span style="color: #004993;">text</span>=<span style="color: #990000;">&quot;{_user.fullName}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span> 
	<span style="color: #000000; font-weight: bold;">&lt;/</span>mx<span style="color: #000000; font-weight: bold;">:</span>FormItem<span style="color: #000000; font-weight: bold;">&gt;</span>
	<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>FormItem label=<span style="color: #990000;">&quot;SSN:&quot;</span> <span style="color: #004993;">x</span>=<span style="color: #990000;">&quot;54&quot;</span> <span style="color: #004993;">y</span>=<span style="color: #990000;">&quot;104&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span>  
		<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>TextInput id=<span style="color: #990000;">&quot;txtSSN&quot;</span>  <span style="color: #004993;">text</span>=<span style="color: #990000;">&quot;{_user.ssn}&quot;</span> <span style="color: #004993;">width</span>=<span style="color: #990000;">&quot;129&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span> 
	<span style="color: #000000; font-weight: bold;">&lt;/</span>mx<span style="color: #000000; font-weight: bold;">:</span>FormItem<span style="color: #000000; font-weight: bold;">&gt;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>FormItem label=<span style="color: #990000;">&quot;Password:&quot;</span> <span style="color: #004993;">x</span>=<span style="color: #990000;">&quot;23&quot;</span> <span style="color: #004993;">y</span>=<span style="color: #990000;">&quot;70&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span> 
		<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>TextInput id=<span style="color: #990000;">&quot;txtPassword&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span> 
	<span style="color: #000000; font-weight: bold;">&lt;/</span>mx<span style="color: #000000; font-weight: bold;">:</span>FormItem<span style="color: #000000; font-weight: bold;">&gt;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;</span>mx<span style="color: #000000; font-weight: bold;">:</span>Button id=<span style="color: #990000;">&quot;btnLoad&quot;</span> label=<span style="color: #990000;">&quot;Load User&quot;</span> textAlign=<span style="color: #990000;">&quot;center&quot;</span> <span style="color: #004993;">x</span>=<span style="color: #990000;">&quot;145&quot;</span> <span style="color: #004993;">y</span>=<span style="color: #990000;">&quot;149&quot;</span> <span style="color: #004993;">click</span>=<span style="color: #990000;">&quot;loadUserDetails()&quot;</span> <span style="color: #004993;">width</span>=<span style="color: #990000;">&quot;147&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;/</span>mx<span style="color: #000000; font-weight: bold;">:</span>Canvas<span style="color: #000000; font-weight: bold;">&gt;</span></pre></td></tr></table></div>

<div class="qa">
<span class="question">Question: And how is the view notified of the response from the server (after the command finishes)? </span>
</div>
<p>Commands &#8211; after the processing is finished &#8211; will trigger any cached IResponders::result() methods to notify the sender [View] of the event. </p>
<p>In the code example above, look at line 15  where we use a Responder instance to act as a proxy for the functions that we want to call. The Responder class does NOT know any details about the view itself. It simply has functions that may be called upon an event response. For a successful response, the view wants <span style="color:#0070C0;">onResults_loadUserDetails()</span> to be called. Likewise for failures, the view wants <span style="color:#0070C0;">onFault_loadUserDetails()</span> to be called. With responders, the view essentially provides event handlers for Command post-processing. </p>
<p>To summarize the above code snippet as psuedo-code, you (a) use a responder proxy wrapper class, (b) package the responder instance inside the event, and (c) extend the command base class to support the caching of the callback/view responder. And voila&#8217; you are done!</p>
<p>This is VERY clean:</p>
<ol>
<li> your views are still standard mxml or as classes with aggregates and composite controls,</li>
<li>  event dispatching is the same [with an optional callback] and</li>
<li>  you do NOT have to create crude view controllers to handle view notifications</li>
<li>  each view instance can have its OWN, separate callback</li>
<li>  views can then support  modal operations, undos, reverts, commits, etc&#8230; completely independent of each other.</li>
<li>  you can dispatch as many business events as desired; each with their own event/response handler methods.
</ol>
<p>Better yet, this functionality is built into the Cairngorm Extensions (CGX) using both the Callback and the mx.rpc.Responder classes.  CGX is an open-source extension to cairngorm. If you are interested in this and other Cairngorm extensions provide comments to this blog or or visit <a href="http://code.google.com/p/flexcairngorm/">Google Cairngorm Extensions</a>. </p>
<br /><div><img src="http://www.gridlinked.info/wp-content/plugins/gd-star-rating/gfx.php?value=9.5" /></div><div>Rating: 9.5/<strong>10</strong> (42 votes cast)</div><br /><hr />
<p><small>© Thomas Burleson for <a href="http://www.gridlinked.info">GridLinked to RUX</a>, 2009.   
&nbsp;	&nbsp;	&nbsp;	&nbsp;	&nbsp;	&nbsp;  
<a href="http://feedburner.google.com/fb/a/mailverify?uri=GridlinkedToRux&amp;loc=en_US"><span style="color:#900">Subscribe by Email</span></a> |
<a href="mailto:ThomasBurleson@GMail.com">Contact Author</a> 	&nbsp;	&nbsp;	&nbsp;	&nbsp;	&nbsp;	&nbsp;
<a href="http://www.gridlinked.info/cairngorm-secret-tip-3-responders-for-view-notifications/">Permalink</a> |    
<a href="http://www.gridlinked.info/cairngorm-secret-tip-3-responders-for-view-notifications/#comments">41 comments</a>
<br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.gridlinked.info/cairngorm-secret-tip-3-responders-for-view-notifications/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>Automation with Fireworks CS4 Commands &#8211; Reflections</title>
		<link>http://www.gridlinked.info/reflections-made-easy-with-fireworks-cs4-commands/</link>
		<comments>http://www.gridlinked.info/reflections-made-easy-with-fireworks-cs4-commands/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 01:08:44 +0000</pubDate>
		<dc:creator>thomasb</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Fireworks]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[commands]]></category>
		<category><![CDATA[designer]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[reflections]]></category>
		<category><![CDATA[storyboarding]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.gridlinked.info/?p=163</guid>
		<description><![CDATA[Fireworks CS4 is an amazing web design and storyboarding tool. Learn how to use Commands for automation of complex features such as Lighting and Reflections. With the Create Reflection command, you can easily add RUX concepts to your designs. Includes commented source code and introduces the Ustrive2 Sellit ShopBOT widget.  <br /><div><img src="http://www.gridlinked.info/wp-content/plugins/gd-star-rating/gfx.php?value=10.0" /></div><div>Rating: 10.0/<strong>10</strong> (6 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>While working at <a href="http://www.sellit.com/pages/for_partners" target="_blank"><span style="text-decoration: underline;">Ustrive2, Inc.</span></a> I initiated some redesign efforts for the <a href="http://www.sellit.com/pages/for_merchants" target="_blank"><span style="text-decoration: underline;">Sellit Administrator</span></a> tools. Focused on creating a fantastic, rich user experience, The dev team [DanM, JesseF, MichaelF, and MikeC] used Fireworks CS4 to quickly iterate through several design prototypes and deliver designs that satisfied many complex feature requirements. </p>
<p>One aspect of those designs was to create a sense of depth [and engage the user] by judiciously highlighting key components with lighting and <span style="color: #0070C0">reflections</span>. Many of the resulting storyboard pages contained 2 or more components with reflections. </p>
<p>Manually creating a reflection requires 20 or more steps and about 60 seconds to complete&#8230; for <span style="text-decoration: italic;">each</span> component. I will not bother listing each step&#8230; it is non-trivial and tedious [and the code at the bottom of this blog shows you the details]. There had to be a way to <span style="color: #0070C0;">automate</span> the process. I realized that a Fireworks Command was the solution! </p>
<div style="margin: 1px 0pt;" id="pullquote-con">Fireworks CS4 is an amazing <a href="http://tv.adobe.com/?promoid=DRHYB#vi+f15383v1022" target="_blank"><span style="text-decoration: underline;">web design</span></a> and <a href="http://odeo.com/episodes/22108974-Storyboarding-in-Production-Premium-CS3" target="_blank"><span style="text-decoration: underline;">storyboarding</span></a> tool. If you are not leveraging its power within your own design processes you are crazy.</div>
<p>With a Fireworks command and associated hot-key, I could automate 20+ steps and many mouse movements to a single command. And I could easily invoke that command using a hotkey. Wow! But how would I create the command if I did not know the Fireworks API?  Before we solve the automation issue, let&#8217;s first see what the <span style="color: #0070C0">Reflection</span> command actually does. Then we will learn how to create such a command. </p>
<p><span style="font-weight:bold;font-size:1.1em;">Click</span> on any of the thumbnails below to see the examples of using a &#8216;Create Reflection&#8217; command.</p>
<div class="gallery">
<dl class="gallery-item">
<dt class="gallery-icon"> <div class="img size-thumbnail wp-image-165" style="width:125px;">
	<a href="http://www.gridlinked.info/images/2009/03/reflect_1.jpg" rel="shadowbox[fireworks_reflection];options={resizeDuration:.05,fadeDuration:.05}"><img src="http://www.gridlinked.info/images/2009/03/reflect_1-150x150.jpg" alt="Sellit ShopBOT " width="125" height="125" /></a>
	<div>Sellit ShopBOT</div>
</div> </dt>
</dl>
<dl class="gallery-item">
<dt class="gallery-icon"><div class="img size-thumbnail wp-image-166" style="width:125px;">
	<a href="http://www.gridlinked.info/images/2009/03/reflect_2.jpg" rel="shadowbox[fireworks_reflection];options={resizeDuration:.05,fadeDuration:.05}"><img src="http://www.gridlinked.info/images/2009/03/reflect_2-150x150.jpg" alt="ShopBOT w/ Reflection" width="125" height="125" /></a>
	<div>ShopBOT w/ Reflection</div>
</div> </dt>
</dl>
<dl class="gallery-item">
<dt class="gallery-icon"> <div class="img size-thumbnail wp-image-169" style="width:125px;">
	<a href="http://www.gridlinked.info/images/2009/03/reflect_4.jpg" rel="shadowbox[fireworks_reflection];options={resizeDuration:.05,fadeDuration:.05}"><img src="http://www.gridlinked.info/images/2009/03/reflect_4-150x150.jpg" alt="Reflections on many ShopBOTs" width="125" height="125" /></a>
	<div>Reflections on many ShopBOTs</div>
</div> </dt>
</dl>
<dl class="gallery-item">
<dt class="gallery-icon">
<div class="img size-thumbnail wp-image-249" style="width:125px;">
	<a href="http://www.gridlinked.info/images/2009/03/4shopbots.jpg" rel="shadowbox[fireworks_reflection];options={resizeDuration:.05,fadeDuration:.05}"><img src="http://www.gridlinked.info/images/2009/03/4shopbots-150x150.jpg" alt="More Reflections on ShopBOTs" width="125" height="125" /></a>
	<div>More Reflections on ShopBOTs</div>
</div>
 </dt>
</dl>
</div>
<p><br/></p>
<p>Below is an outline of the process you can use to create your own reflection command. Let Fireworks record all your steps and save those steps as javascript code. Then you can fine-tune that code as desired:</p>
<ol>
<li>Open the History panel and make sure the history is clear,</li>
<li>Manually create a reflection with the 20 or more steps (painful details not included),</li>
<li>In the History palette, select the steps that match the process to create the reflection,</li>
<li>Using the History Menu, select the &#8216;Save as Command&#8230;&#8217; menu option,</li>
<li>Specify the name &#8216;Create Reflection&#8217; and click OK</li>
<li>Edit the javascript command code to perform as desired:
<ol>
<li>Use a text or code editor to open the &#8216;Create Reflection.jsf&#8217; file (directory location below),</li>
<li>Modify the code to programmatically support clip height, opacity, offsets, etc.</li>
<li>Save modified command file,</li>
<li>Return to Fireworks, select a object, and invoke the &#8216;Create Reflection&#8217; command</li>
</ol>
</li>
<li>Did your changes work? If not go to Step (6) make more coding changes and iterate&#8230;</li>
</ol>
<div id="pullquote-con" style="font-size:1.3em;">Did you know about the <a href="http://www.adobe.dougwinnie.com/?p=45" target="_blank"><span style="text-decoration:underline;color:0x00D000">Export Pages as PDF</span></a> feature and its click support to jump between pages. Your PDFs can be used for storyboarding, collaborating, sharing prototypes, and walkthrus.</div>
<div id='conclusion' style="vertical-align:top;">
<div id="attachment_164" class="wp-caption alignright" style="width: 160px"><a href="http://www.gridlinked.info/images/2009/03/command_loc.jpg" rel="shadowbox;options={resizeDuration:.05,fadeDuration:.05}""><img src="http://www.gridlinked.info/images/2009/03/command_loc-150x150.jpg" alt="Commands Directory (Mac OS X)" width="150" height="150" class="size-medium wp-image-164" /></a><p class="wp-caption-text">Fireworks Commands Directory (Mac OS X)</p></div><br />
But where [which directory] should you open/edit/save the &#8216;Create Reflection.jsf&#8217; command file?  Click the thumbnail on the right to zoom for details.</p>
<p>After the challenging [and fun] time invested to create my own working command, my &#8216;Create Reflection&#8217; works great. The Ustrive2 developers loved using it for their own design efforts.  </p>
<p>With the code [shown below] and a copy of the &#8216;Create Reflection.jsf&#8217; command file, it is my hope that you will also enjoy using this command.<br />
<br/>
</div>
<p>Below is the javascript code contained in the link for your own <span style="text-decoration:underline;color:0x00D000"><a href="http://www.gridlinked.info/data/CreateReflection.zip">Create Reflection.jsf</a></span> command (click to download):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/*</span>
<span style="color: #006600; font-style: italic;">&nbsp;* CreateReflection is a Fireworks Command that creates a vertical reflection [of the currently selected items].</span>
<span style="color: #006600; font-style: italic;">&nbsp;*</span>
<span style="color: #006600; font-style: italic;">&nbsp;* This is an incredible timesaver and allows the designer to quickly create reflections for anything.</span>
<span style="color: #006600; font-style: italic;">&nbsp;* When 1 or more items are selected in the current canvas area, those items are:</span>
<span style="color: #006600; font-style: italic;">&nbsp;*   1) Duplicated, flipped vertically, and flatten (original items are unchanged and deselected)</span>
<span style="color: #006600; font-style: italic;">&nbsp;*   2) The flattened copy is cropped to the top 40 pixels</span>
<span style="color: #006600; font-style: italic;">&nbsp;*   3) A gradient alpha mask is applied to the cropped image</span>
<span style="color: #006600; font-style: italic;">&nbsp;*   4) Both the mask and image are flattened and opacity set to 20%</span>
<span style="color: #006600; font-style: italic;">&nbsp;*</span>
<span style="color: #006600; font-style: italic;">&nbsp;* TODOs:</span>
<span style="color: #006600; font-style: italic;">&nbsp;*    1) Add support to skew/distort the selected images and reflection (for 3D perspective effect)</span>
<span style="color: #006600; font-style: italic;">&nbsp;*    2) Create runtime UI dialog to request clip height, offset, opacity, and skew parameters</span>
<span style="color: #006600; font-style: italic;">&nbsp;*    3) Check for no items currently selected and posting feedback to designer</span>
<span style="color: #006600; font-style: italic;">&nbsp;*</span>
<span style="color: #006600; font-style: italic;">&nbsp;* Author:  Thomas Burleson, Flex/Groovy Consultant</span>
<span style="color: #006600; font-style: italic;">&nbsp;*</span>
<span style="color: #006600; font-style: italic;">&nbsp;*          Blog    @ http://www.gridlinked.info</span>
<span style="color: #006600; font-style: italic;">&nbsp;*          Profile @ http://www.LinkedIn.com/in/ThomasBurleson</span>
<span style="color: #006600; font-style: italic;">&nbsp;*          eMail   @ ThomasBurleson@gmail.com</span>
<span style="color: #006600; font-style: italic;">&nbsp;*</span>
<span style="color: #006600; font-style: italic;">&nbsp;*</span>
<span style="color: #006600; font-style: italic;">&nbsp;* Date:  Feb 24, 2009</span>
<span style="color: #006600; font-style: italic;">&nbsp;*/</span> 
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> OFFSET         <span style="color: #339933;">=</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> REFLECT_HEIGHT <span style="color: #339933;">=</span> <span style="color: #CC0000;">40</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> dom            <span style="color: #339933;">=</span> fw.<span style="color: #660066;">getDocumentDOM</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> reflections    <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Copy and flip selection, move to OFFSET below the original, and flatten to bitmap </span>
dom.<span style="color: #660066;">clipCopy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">clipPaste</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
dom.<span style="color: #660066;">group</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">reflectSelection</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;autoTrimImages transformAttributes&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">flattenSelection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> bounds <span style="color: #339933;">=</span> dom.<span style="color: #660066;">getSelectionBounds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">moveSelectionBy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>x<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> y<span style="color: #339933;">:</span>bounds.<span style="color: #660066;">bottom</span><span style="color: #339933;">-</span>bounds.<span style="color: #660066;">top</span><span style="color: #339933;">+</span>OFFSET<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Clip image to REFLECT_HEIGHT,</span>
bounds <span style="color: #339933;">=</span> dom.<span style="color: #660066;">getSelectionBounds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
bounds.<span style="color: #660066;">bottom</span> <span style="color: #339933;">=</span> bounds.<span style="color: #660066;">top</span> <span style="color: #339933;">+</span> REFLECT_HEIGHT<span style="color: #339933;">;</span>
dom.<span style="color: #660066;">setSelectionMask</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#123;</span>  maskBounds<span style="color: #339933;">:</span>bounds<span style="color: #339933;">,</span> 
                                       maskKind<span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;rectangle&quot;</span><span style="color: #339933;">,</span> 
                                       maskEdgeMode<span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;hard edge&quot;</span><span style="color: #339933;">,</span> 
                                       featherAmount<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> 
                                       maskData<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> 
                                    <span style="color: #3366CC;">&quot;replace&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">exitPaintMode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">cropSelection</span><span style="color: #009900;">&#40;</span>bounds<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Cache the reflection...</span>
reflections.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>fw.<span style="color: #660066;">selection</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Build an alpha clip mask and set transparency to 20%</span>
dom.<span style="color: #660066;">addNewRectanglePrimitive</span><span style="color: #009900;">&#40;</span>bounds<span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">setBrushNColor</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;#ffffff00&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">setFillVectorStart</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>x<span style="color: #339933;">:</span>bounds.<span style="color: #660066;">left</span><span style="color: #339933;">,</span> y<span style="color: #339933;">:</span>bounds.<span style="color: #660066;">top</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">setFill</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#123;</span> category     <span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;fc_Linear&quot;</span><span style="color: #339933;">,</span> 
			   ditherColors <span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;#000000&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;#000000&quot;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
			   edgeType     <span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;antialiased&quot;</span><span style="color: #339933;">,</span> 
			   feather      <span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> 
			   gradient     <span style="color: #339933;">:</span><span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;cn_Custom&quot;</span><span style="color: #339933;">,</span> nodes<span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#123;</span> color<span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;#ffffff&quot;</span><span style="color: #339933;">,</span>  isOpacityNode<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> position<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> color<span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;#ffffff&quot;</span><span style="color: #339933;">,</span>  isOpacityNode<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> position<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> opacityNodes<span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#123;</span> color<span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;#000000&quot;</span><span style="color: #339933;">,</span>  isOpacityNode<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>  position<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> color<span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;#00000000&quot;</span><span style="color: #339933;">,</span>isOpacityNode<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>  position<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> 
			   <span style="color: #000066;">name</span>         <span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;fn_Linear&quot;</span><span style="color: #339933;">,</span> 
			   pattern      <span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> 
			   shape        <span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;linear&quot;</span><span style="color: #339933;">,</span> 
			   stampingMode <span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;blend opaque&quot;</span><span style="color: #339933;">,</span> 
			   textureBlend <span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> 
			   webDitherTransparent<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Cache the alpha mask</span>
reflections.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>fw.<span style="color: #660066;">selection</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Select the reflection and alpha mask, then group and set opacity...</span>
<span style="display:block;background-color: #ffc;">fw.<span style="color: #660066;">selection</span> <span style="color: #339933;">=</span> reflections<span style="color: #339933;">;</span></span>&nbsp;
dom.<span style="color: #660066;">group</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mask to image&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">flattenSelection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dom.<span style="color: #660066;">setOpacity</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// DONE!</span></pre></div></div>

<p>After this tutorial, you should explore more solutions and start creating your own cool Fireworks commands. I will let you figure out how to assign a hotkey sequence to a command. <span style="color:0x00D000;">With commands and hotkeys, your design life becomes FUN!</span></p>
<p>If you extend or enhance &#8216;Create Reflection&#8217;, please send me a copy <img src='http://www.gridlinked.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   And don&#8217;t forget, please comment and rate this article (rate by select the star levels) below.<br />
<br/></p>
<br /><div><img src="http://www.gridlinked.info/wp-content/plugins/gd-star-rating/gfx.php?value=10.0" /></div><div>Rating: 10.0/<strong>10</strong> (6 votes cast)</div><br /><hr />
<p><small>© Thomas Burleson for <a href="http://www.gridlinked.info">GridLinked to RUX</a>, 2009.   
&nbsp;	&nbsp;	&nbsp;	&nbsp;	&nbsp;	&nbsp;  
<a href="http://feedburner.google.com/fb/a/mailverify?uri=GridlinkedToRux&amp;loc=en_US"><span style="color:#900">Subscribe by Email</span></a> |
<a href="mailto:ThomasBurleson@GMail.com">Contact Author</a> 	&nbsp;	&nbsp;	&nbsp;	&nbsp;	&nbsp;	&nbsp;
<a href="http://www.gridlinked.info/reflections-made-easy-with-fireworks-cs4-commands/">Permalink</a> |    
<a href="http://www.gridlinked.info/reflections-made-easy-with-fireworks-cs4-commands/#comments">3 comments</a>
<br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.gridlinked.info/reflections-made-easy-with-fireworks-cs4-commands/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
