<?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>qnotemedia</title>
	<atom:link href="http://blog.qnotemedia.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.qnotemedia.com</link>
	<description></description>
	<lastBuildDate>Sat, 26 Jun 2010 02:59:58 +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>Election Maps @ Haley camp</title>
		<link>http://blog.qnotemedia.com/?p=296</link>
		<comments>http://blog.qnotemedia.com/?p=296#comments</comments>
		<pubDate>Sat, 26 Jun 2010 02:57:59 +0000</pubDate>
		<dc:creator>webmaster</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=296</guid>
		<description><![CDATA[A pic of our election maps up on a big projector taken from one of our POLITICO reporters on the scene at the Haley headquarters. Haley (R) went on to win the South Carolina GOP runoff that evening.

]]></description>
			<content:encoded><![CDATA[<p>A pic of our election maps up on a big projector taken from one of our POLITICO reporters on the scene at the Haley headquarters. Haley (R) went on to <a href="http://www.politico.com/2010/maps/#/Governor/2010/SC">win the South Carolina GOP runoff</a> that evening.</p>
<p><a href="http://blog.qnotemedia.com/wp-content/uploads/2010/06/electionmaps-SC.jpg"><img src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/electionmaps-SC-300x225.jpg" alt="" title="electionmaps-SC" width="300" height="225" class="aligncenter size-medium wp-image-298" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=296</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Buzz! wireless buzzers with Windows</title>
		<link>http://blog.qnotemedia.com/?p=275</link>
		<comments>http://blog.qnotemedia.com/?p=275#comments</comments>
		<pubDate>Mon, 14 Jun 2010 05:46:04 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[hack]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=275</guid>
		<description><![CDATA[POLITICO was one of the major sponsors at this year&#8217;s Komen Race for the Cure. We wanted to do something fun and interesting to attract people to the booth and came up with the idea to have a simple, quick, political quiz game people could play before receiving our awesome incredible swag. I put together [...]]]></description>
			<content:encoded><![CDATA[<p>POLITICO was one of the major sponsors at this year&#8217;s Komen Race for the Cure. We wanted to do something fun and interesting to attract people to the booth and came up with the idea to have a simple, quick, political quiz game people could play before receiving our awesome incredible swag. I put together a simple quiz game in Flash and thought it would be great to have wireless &#8220;buzzers&#8221; for two people to answer with competitively.</p>
<p>So if you currently own one of the many <a href="http://en.wikipedia.org/wiki/Buzz!">Buzz! branded games</a> with wireless buzzers for the PS3, and you want to make your own PC-based quiz game&#8230;here&#8217;s how to do it!</p>
<p>First you need to get the buzzers working as standard game controllers on a PC. Then we&#8217;ll map those buttons to keyboard keys. From there you can use the devices just as you would a normal keyboard &#8211; in my case, via Flash. This process was tested successfully on WinXP SP3, Vista, and Windows7. There&#8217;s a way to do this on OSX as well, but I won&#8217;t vouch for it.</p>
<p>You&#8217;ll first need to download two simple programs. <a href="http://www.electracode.com/4/joy2key/JoyToKey%20English%20Version.htm">Joy2Key</a> and <a href="http://www.lvr.com/hidpage.htm">SimpleHIDWrite</a>.</p>
<p>1) Plug the USB Buzz! reciever into your PC.<br />
2) Wait for it&#8230;<br />
3) Windows should automatically install a driver labelled WBuzz. It&#8217;ll show up in your Game Controllers Control Panel, but nothing will work just yet.<br />
4) Sync each of the buzzers you&#8217;ll be using. This is done the same way you would on the PS3. Turn on each buzzer. Wait a second or two. Then hold the power button up for 4-seconds. The blue light at the bottom of the buzzer will come on and hold blue. While its on, press and hold the small button on the USB receiver for four seconds. The controller and the receiver&#8217;s lights should blink eight times confirming that they&#8217;ve been synced. Repeat this for each buzzer you want to use. I found that sometimes, after doing the first buzzer, each buzzer I turned on afterwards would automatically sync.<br />
5) Run SimpleHIDWrite.<br />
6) Select WBuzz in the top portion of the application.<br />
7) Fill each of the boxes at the very bottom of the application with zeros &#8211; I don&#8217;t believe zeros in the &#8220;ReportID&#8221; box is needed.<br />
8 ) Click the Write button &#8211; this sends a control signal that &#8220;activates&#8221; the buzzers. You should see all of the synced buzzers blink.<br />
9) Press some buzzer buttons. You should see events logged for each button press in the bottom portion of the HID application.<br />
10) In the Game Controllers Control Panel, click WBuzz, then click properties. Pressing the buttons on the buzzers should light up the appropriate buttons in the control panel. These are joystick buttons that you can now map to any program you want. Note that there are enough buttons for up to four buzzers per USB receiver.<br />
11) Write down each joystick button number and what they are mapped to on each of the Buzz buzzers.<br />
12) Write up a <a href="http://qnotemedia.com/projects/keycodetrace.swf">simple piece of Flash</a> that accepts keyboard commands.<br />
13) Now run Joy2Key.<br />
14) Double-click a joystick button, tap a key on the keyboard that you want to assign, and click OK.<br />
15) Run the Flash game you&#8217;ve made and tap away on the buzzers. You should now be seeing real working results!<br />
16) Save your profile in Joy2Key. It will become the default settings the next time you run it. You&#8217;ll otherwise lose all of the mapped settings when you close the program.</p>
<p>Troubleshooting:<br />
 &#8211; I learned the hard way that when a computer returns from standby, you have to turn off all of the buzzers, turn them back on, and then resend the control signal from HID.<br />
 &#8211; If the buzzers are synced and the control signal has been sent, you should see the button presses being logged in HID. Its a good feeling when you do.<br />
 &#8211; If the Game Controller Control Panel is not actually the top focused window, you won&#8217;t see the buttons being pressed.  i.e. you have to physically click on the panel in order to see the button presses. Why? Ask Microsoft.</p>
<p>Here&#8217;s some pics from the booth!<br />

<a href='http://blog.qnotemedia.com/?attachment_id=287' title='32464_392876527477_603377477_4181459_2406907_n'><img width="150" height="150" src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/32464_392876527477_603377477_4181459_2406907_n-150x150.jpg" class="attachment-thumbnail" alt="" title="32464_392876527477_603377477_4181459_2406907_n" /></a>
<a href='http://blog.qnotemedia.com/?attachment_id=286' title='32464_392876482477_603377477_4181454_4712064_n'><img width="150" height="150" src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/32464_392876482477_603377477_4181454_4712064_n-150x150.jpg" class="attachment-thumbnail" alt="" title="32464_392876482477_603377477_4181454_4712064_n" /></a>
<a href='http://blog.qnotemedia.com/?attachment_id=285' title='32464_392876447477_603377477_4181449_4158764_n'><img width="150" height="150" src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/32464_392876447477_603377477_4181449_4158764_n-150x150.jpg" class="attachment-thumbnail" alt="" title="32464_392876447477_603377477_4181449_4158764_n" /></a>
<a href='http://blog.qnotemedia.com/?attachment_id=284' title='32464_392876437477_603377477_4181447_7051824_n'><img width="150" height="150" src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/32464_392876437477_603377477_4181447_7051824_n-150x150.jpg" class="attachment-thumbnail" alt="" title="32464_392876437477_603377477_4181447_7051824_n" /></a>
<a href='http://blog.qnotemedia.com/?attachment_id=283' title='32464_392876427477_603377477_4181446_7027278_n'><img width="150" height="150" src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/32464_392876427477_603377477_4181446_7027278_n-150x150.jpg" class="attachment-thumbnail" alt="" title="32464_392876427477_603377477_4181446_7027278_n" /></a>
<a href='http://blog.qnotemedia.com/?attachment_id=282' title='32464_392876417477_603377477_4181445_5435784_n'><img width="150" height="150" src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/32464_392876417477_603377477_4181445_5435784_n-150x150.jpg" class="attachment-thumbnail" alt="" title="32464_392876417477_603377477_4181445_5435784_n" /></a>
<a href='http://blog.qnotemedia.com/?attachment_id=281' title='30914_393325287477_603377477_4197247_1923250_n'><img width="150" height="150" src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/30914_393325287477_603377477_4197247_1923250_n-150x150.jpg" class="attachment-thumbnail" alt="" title="30914_393325287477_603377477_4197247_1923250_n" /></a>
<a href='http://blog.qnotemedia.com/?attachment_id=279' title='200px-Buzz-logo'><img width="150" height="150" src="http://blog.qnotemedia.com/wp-content/uploads/2010/06/200px-Buzz-logo-150x150.png" class="attachment-thumbnail" alt="" title="200px-Buzz-logo" /></a>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=275</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>POLITICO 2010 Coverage</title>
		<link>http://blog.qnotemedia.com/?p=266</link>
		<comments>http://blog.qnotemedia.com/?p=266#comments</comments>
		<pubDate>Wed, 03 Feb 2010 04:39:04 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=266</guid>
		<description><![CDATA[After endless, uncountable hours, the POLITICO 2010 Election Maps are finally available. Keep coming back for each primary throughout the year to see live results. This was a huge project for me and I&#8217;m just really really glad its over, and at the same time, looking forward to what&#8217;s next.    Enjoy!
http://www.politico.com/2010/maps/
]]></description>
			<content:encoded><![CDATA[<p>After endless, uncountable hours, the <a href="http://www.politico.com/2010/maps/">POLITICO 2010 Election Maps</a> are finally available. Keep coming back for each primary throughout the year to see live results. This was a huge project for me and I&#8217;m just really really glad its over, and at the same time, looking forward to what&#8217;s next. <img src='http://blog.qnotemedia.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />   Enjoy!</p>
<p><a href="http://www.politico.com/2010/maps/">http://www.politico.com/2010/maps/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=266</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Craziness with the JSFL API</title>
		<link>http://blog.qnotemedia.com/?p=237</link>
		<comments>http://blog.qnotemedia.com/?p=237#comments</comments>
		<pubDate>Wed, 02 Dec 2009 21:52:48 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jsfl]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=237</guid>
		<description><![CDATA[Little known fact &#8211; JSFL is awesome.  Unfortunately, its also a bit buggy and is not entirely straightforward.
For those who don&#8217;t know, the JSFL API (Javascript Flash API), included with the Flash IDE, allows you to script *almost* anything you would normally do manually in Flash. Click here, change that option, change this color, [...]]]></description>
			<content:encoded><![CDATA[<p>Little known fact &#8211; JSFL is awesome.  Unfortunately, its also a bit buggy and is not entirely straightforward.</p>
<p>For those who don&#8217;t know, the JSFL API (Javascript Flash API), included with the Flash IDE, allows you to script *almost* anything you would normally do manually in Flash. Click here, change that option, change this color, select this, etc &#8211; all of it can be written up in a script that you can then run at any point in time.</p>
<p>I&#8217;ve been working with it on and off for the past and thought I&#8217;d share a few snags.</p>
<p>The API is especially incredibly useful for anything that needs to be done in bulk.  For instance, say you have tons of shapes on the stage and they all need to be uniquely named movieclips?  In JSFL you could loop through all of the shapes, and for each one &#8211; create a movieclip, create a class linkages, name the instance, etc.</p>
<p>In one project, similar to the above, I had thousands of completed strokes, each in a separate layer, and wanted to add a fill to each one.  Unfortunately, this isn&#8217;t something JSFL can apparently do.  I ran into two major issues.</p>
<p>The first few tests resulted in a crash, for instance, something like the following:</p>
<pre>fl.getDocumentDOM().selectAll();
var fill = fl.getDocumentDOM().getCustomFill();
fill.style = "solid";
fill.color = 0x00FF33;
fl.getDocumentDOM().setCustomFill(fill);</pre>
<p>According to some, this results in a crash because all of the fill parameters must be set before doing setCustomFill().  Not sure if that&#8217;s true or not.</p>
<p>The real issue here is that you can&#8217;t &#8220;add&#8221; a fill to a stroke if the stroke doesn&#8217;t already have a fill, or if you&#8217;re not creating the object with JSFL.  In fact, in Flash, if you were to add a fill manually, you&#8217;d have to select the paint bucket tool and click inside the stroke.</p>
<p>But what I found, in Flash, is that if I first do the Union command on a stroke (which converts it to a &#8220;drawing object&#8221;) and then change the fill setting, it will &#8220;add&#8221; a fill.  So I tried just that in JSFL:</p>
<pre>fl.getDocumentDOM().selectAll();
fl.getDocumentDOM().union();
var fill = fl.getDocumentDOM().getCustomFill();
fill.style = "solid";
fill.color = 0x00FF33;
fl.getDocumentDOM().setCustomFill(fill);</pre>
<p>This unfortunately still causes a crash in Flash.</p>
<p>So how about an example straight out of the Flash CS3 Help?</p>
<pre>fl.getDocumentDOM().selectAll();
fl.getDocumentDOM().union();
var fill = fl.getDocumentDOM().getCustomFill();
fill.style = 'radialGradient';
fill.colorArray = ['#00ff00','#ff00ff'];
fill.posArray = [0, 255];
fill.focalPoint = 100;
fill.linearRGB = false;
fill.overflow = 'repeat';
fl.getDocumentDOM().setCustomFill(fill);</pre>
<p>Shockingly, this actually works, but produces only a black fill.  Broken down, I learned that this would produce the same thing, without crashing Flash:</p>
<pre>fl.getDocumentDOM().selectAll();
fl.getDocumentDOM().union();
var fill = fl.getDocumentDOM().getCustomFill();
fill.style = 'radialGradient';
fl.getDocumentDOM().setCustomFill(fill);</pre>
<p>So the key is setting fill.style to something other than solid.</p>
<p>So to produce a solid fill, simply do the fill twice:</p>
<pre>
fl.getDocumentDOM().selectAll();
fl.getDocumentDOM().union();

var fillA = fl.getDocumentDOM().getCustomFill();
fillA.style = 'radialGradient';
fl.getDocumentDOM().setCustomFill(fillA);

var fillB = fl.getDocumentDOM().getCustomFill();
fillB.style = "solid";
fillB.color = 0x00FF33;
fl.getDocumentDOM().setCustomFill(fillB);</pre>
<p>IMHO ridiculous, but it works.</p>
<p>The final script looked something like this, where each closed stroke was on a separate layer:</p>
<pre>
var doc = fl.getDocumentDOM()
var tl = doc.getTimeline()
var layers = tl.layers;

tl.setSelectedLayers(0);

for (var l=0; l&lt;layers.length; l++) {
	doc.selectNone();

	doc.selection = layers[l].frames[0].elements;
	doc.union();

	if (doc.selection != null) {
		doFill();
	} else {
		fl.trace("no selection")
	}
}

function doFill() {
	var fillA = doc.getCustomFill();
	fillA.style = 'radialGradient';
	doc.setCustomFill(fillA);

	var fillB = doc.getCustomFill();
	fillB.style = "solid";
	fillB.color = 0x00FF33;
	doc.setCustomFill(fillB);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=237</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redispatching custom events</title>
		<link>http://blog.qnotemedia.com/?p=215</link>
		<comments>http://blog.qnotemedia.com/?p=215#comments</comments>
		<pubDate>Fri, 16 Oct 2009 18:38:49 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=215</guid>
		<description><![CDATA[If you didn&#8217;t know already, its very important to always clone any custom events you create. Otherwise, when redispatching an event, it won&#8217;t be typed correctly and will use the default Event class&#8217; properties. Meaning any data or event type you might&#8217;ve been passing along will be lost in the redispatch.
Another slight annoyance however is [...]]]></description>
			<content:encoded><![CDATA[<p>If you didn&#8217;t know already, its very important to always clone any custom events you create. Otherwise, when redispatching an event, it won&#8217;t be typed correctly and will use the default Event class&#8217; properties. Meaning any data or event type you might&#8217;ve been passing along will be lost in the redispatch.</p>
<p>Another slight annoyance however is that event.target is <em>overwritten</em> when an event is redispatched. As far as I can tell, there&#8217;s no way around this.</p>
<p>For instance, I might have a custom class (MyDispatcher) dispatching a custom event (CustomEvent) to its parent (FirstListener), where it needs to know some property of the original dispatcher.  But perhaps its parent (SecondListener) also needs the same event. I&#8217;ll typically just redispatch the event. But what you&#8217;ll find is that event.target will always be the class that has done the last dispatch, regardless of who originally dispatched the event, so in the case of the root parent, SecondListener, event.target will be FirstListener, not MyDispatcher. Sure you still have any data relevant to the event and can create as many properties as you might need in the custom event, but that seems rather bothersome to me if there&#8217;s alot of properties to access in the original dispatcher.</p>
<p>As a workaround, I start with a single, generic property in my custom class that can take any data type (_data:* = null).  I then pass into that the this keyword when I first dipsatch the event, taking with it the entire instance of the original dispatcher &#8211; as long as the original dispatcher isn&#8217;t a huge memory beast.</p>
<p>The benefit here is instead of using event.target I can <strong>always</strong> use event.data and know that I&#8217;m getting all of the public properties of the original dispatcher. Its also correctly typed, even if you haven&#8217;t imported the dispatcher&#8217;s class.</p>
<pre><code>
public class CustomEvent extends Event {
	import flash.events.Event;
	private static const MY_EVENT:String = "myEvent";
	private var _data:*;
	public function CustomEvent(type:String,data:*=null) {
		_data = data;
		super(type,data);
	}
	public override function clone():Event  {
		return new CustomEvent(type,data);
	}
	public function get data():* {
		return _data;
	}
}

public class MyDispatcher extends Sprite {
	import flash.display.Sprite;
	import CustomEvent;
	private var myVar:String = "some public property";
	public function MyDispatcher() {
	}
	public function sendEvent():void {
		dispatchEvent(new CustomEvent(CustomEvent.MY_EVENT,this));
	}
	public function get myVar():String {
		return myVar;
	}
}

public class FirstListener extends Sprite {
	import flash.display.Sprite;
	import MyDispatcher;
	import CustomEvent;
	public function FirstListener() {
		var myDispatcher:MyDispatcher = new MyDispatcher();
		myDispatcher.name = "myDispatcher";
		myDispatcher.addEventListener(CustomEvent.MY_EVENT,myEventHandler,false,0,true);
	}
	public function init():void {
		myDispatcher.sendEvent();
	}

	private function myEventHandler(evt:CustomEvent):void {
		trace(this.name,"received an event");
		trace("evt.target.name is ",evt.target.name); // is MyDispatcher
		trace("evt.data.name is ",evt.data.name); // is MyDispatcher
		dispatchEvent(evt);
	}
}

public class SecondListener extends Sprite {
	import flash.display.Sprite;
	import CustomEvent;
	public function SecondListener() {
		var firstListener:FirstListener = new FirstListener();
		firstListener.name = "firstListener";
		firstListener.addEventListener(CustomEvent.MY_EVENT,myEventHandler,false,0,true);
		firstListener.init();
	}
	private function myEventHandler(evt:CustomEvent):void {
		trace(this.name,"received an event");
		trace("evt.target.name is ",evt.target.name); // is NOT MyDispatcher, but FirstDispatcher instead
		trace("evt.data.name is ",evt.data.name); // is MyDispatcher
	}
}</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=215</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Protecting who can embed your SWF</title>
		<link>http://blog.qnotemedia.com/?p=208</link>
		<comments>http://blog.qnotemedia.com/?p=208#comments</comments>
		<pubDate>Fri, 17 Jul 2009 13:05:28 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=208</guid>
		<description><![CDATA[While most video players nowadays are all about the &#8220;Share&#8221; button, sometimes you want to keep a SWF as protected as possible.  Obviously password protecting it is an easy method, but what if you want the world to view your SWF, but not allow just anyone to embed it?
I&#8217;ve found a fairly simple solution [...]]]></description>
			<content:encoded><![CDATA[<p>While most video players nowadays are all about the &#8220;Share&#8221; button, sometimes you want to keep a SWF as protected as possible.  Obviously password protecting it is an easy method, but what if you want the world to view your SWF, but not allow just anyone to embed it?</p>
<p>I&#8217;ve found a fairly simple solution to this particular issue &#8211; i.e. a case where the user has their own webpage, on their own domain, their own embed code, and where the URL to the SWF is linking directly to your host or where they&#8217;ve copied your SWF to their host.  This is only one of many ways in securing your publicly available SWFs.</p>
<pre><code>
var referrer:String = String(ExternalInterface.call("self.location.href.toString"));
if (referrer == "http://www.mydomain.com/mySWFlocation/mywebpage.html") {
     // continue loading
} else {
     // halt loading
}
</code></pre>
<p>This is a bit kludgy, but it works.  it makes a call to javascript in the browser to see what domain the webpage is on that is embedding the SWF.  If the SWF has been copied and is embedded on a different domain, it will fail.  If the SWF is simply linked to from some other domain, it will still fail, because javascript is specifically checking the domain of the HTML the browser is currently at, not the URL of the SWF.</p>
<p>If you don&#8217;t want to specify the entire URL to the SWF, but only a domain instead, the <a href="http://docs.sun.com/source/816-6408-10/location.htm">Javascript Reference</a> shows other useful possibilities, such as self.location.host, which will only return the domain.</p>
<p>My question to the world is can self.location be spoofed?  I know window.location can (i.e. iframes), but I haven&#8217;t been able to figure out a way for self.location to be changed without the user being redirected.</p>
<p>Perhaps there&#8217;s a way to retrieve the domain of the embedding webpage in actionscript only?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=208</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Flex hacking: Alert control</title>
		<link>http://blog.qnotemedia.com/?p=196</link>
		<comments>http://blog.qnotemedia.com/?p=196#comments</comments>
		<pubDate>Thu, 02 Jul 2009 21:56:18 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[hack]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=196</guid>
		<description><![CDATA[I hate using the Alert control in Flex, but sometimes you just need a quickie prompt, and for the most part, it does what you need it to do, has some easy to edit skinning possibilities, etc.
I ran into a random annoyance though &#8211; I wanted to edit the text of an Alert control, after [...]]]></description>
			<content:encoded><![CDATA[<p>I hate using the Alert control in Flex, but sometimes you just need a quickie prompt, and for the most part, it does what you need it to do, has some easy to edit skinning possibilities, etc.</p>
<p>I ran into a random annoyance though &#8211; I wanted to edit the text of an Alert control, after it was made, without removing it and recreating it.  In my case, simply showing the counting down of a timer in an Alert&#8217;s text.</p>
<p>As mentioned in the docs, the show() method of Alert is static.  But in looking through the Alert and AlertForm classes (mx\controls\Alert.as and mx\controls\alertClasses\AlertForm.as) you&#8217;ll find that some variables have the mx_internal namespace.</p>
<p>Sure enough, you can in fact access properties with this namespace (see code) and open quite a bit of editing that Adobe probably wouldn&#8217;t necessarily want to have available.</p>
<pre><code>var timeoutPrompt:Alert;
timeoutPrompt = Alert.show("Added...");
timeoutPrompt.mx_internal::alertForm.mx_internal::textField.text = "Edited...";
timeoutPrompt.mx_internal::alertForm.mx_internal::textField.selectable = false;</code>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=196</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Formatting ColdFusion Dates with AS3</title>
		<link>http://blog.qnotemedia.com/?p=192</link>
		<comments>http://blog.qnotemedia.com/?p=192#comments</comments>
		<pubDate>Wed, 29 Apr 2009 20:31:41 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[coldfusion]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=192</guid>
		<description><![CDATA[I rarely enjoy programming ColdFusion, but have worked around it for quite some time. To make things a bit easier when communicating with ColdFusion-based dates and timestamps, I wrote two AS3 classes that I&#8217;d like to share:
CF Timestamp to AS3 Date
This function will take a ColdFusion formatted timestamp (i.e. {ts &#8216;2009-04-29 15:59:36.11&#8242;}) and return an [...]]]></description>
			<content:encoded><![CDATA[<p>I rarely enjoy programming ColdFusion, but have worked around it for quite some time. To make things a bit easier when communicating with ColdFusion-based dates and timestamps, I wrote two AS3 classes that I&#8217;d like to share:</p>
<p><b>CF Timestamp to AS3 Date</b></p>
<p>This function will take a ColdFusion formatted timestamp (i.e. {ts &#8216;2009-04-29 15:59:36.11&#8242;}) and return an AS3 Date Object.</p>
<pre>
package com.qnotemedia.utils
{
	public class CFtimestamp
	{
		public static function toDate(rawCFtimestamp:String):Date {
			var date:String = rawCFtimestamp.split("'")[1].split(" ")[0];
			var time:String = rawCFtimestamp.split("'")[1].split(" ")[1].split("'")[0];
			var year:uint = date.split("-")[0];
			var month:uint = date.split("-")[1] - 1;
			var day:uint = date.split("-")[2];
			var hour:uint = time.split(":")[0];
			var minute:uint = time.split(":")[1];
			var second:uint = time.split(":")[2].split(".")[0];
			var millisecond:uint = time.split(":")[2].split(".")[2];
			return new Date(year,month,day,hour,minute,second,millisecond);
		}
	}
}
</pre>
<p>Using it is quite simple:</p>
<pre>
var myCFtimestamp = "{ts '2009-04-29 15:59:36.11'}";
var as3Date = CFtimestamp.toDate(myCFtimestamp);
</pre>
<p><b>AS3 Date formatted with ColdFusion&#8217;s DateFormat function</b></p>
<p>Another useful function. It takes an AS3 Date Object and returns a string, where the masking syntax is based on ColdFusion&#8217;s DateFormat() function.</p>
<p>Note that short, medium, long, and full are included.</p>
<pre>
package com.qnotemedia.utils {
	public class DateFormatter {
		private static var monthNames:Array = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
		private static var dayNames:Array = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");

		private static var monthAbbrs:Array = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec");
		private static var dayAbbrs:Array = new Array("Sun","Mon","Tues","Wed","Thurs","Fri","Sat");

		public static function monthByName(num:uint):String {
			return monthNames[num];
		}
		public static function monthByAbbr(num:uint):String {
			return monthAbbrs[num];
		}
		public static function dayByName(num:uint):String {
			return dayNames[num];
		}
		public static function dayByAbbr(num:uint):String {
			return dayAbbrs[num];
		}
		public static function includeZero(num:uint):String {
			var numStr:String = num.toString();
			if (num > -1 &#038;&#038; num < 10) {
				numStr = "0" + numStr;
			}
			return numStr;
		}

		public static function toCFdateString(dt:Date,msk:String):String {
			// d: Day of the month as digits; no leading zero for single-digit days.
			// dd: Day of the month as digits; leading zero for single-digit days.
			// ddd: Day of the week as a three-letter abbreviation.
			// dddd: Day of the week as its full name.
			// m: Month as digits; no leading zero for single-digit months.
			// mm: Month as digits; leading zero for single-digit months.
			// mmm: Month as a three-letter abbreviation.
			// mmmm: Month as its full name.
			// yy: Year as last two digits; leading zero for years less than 10.
			// yyyy: Year represented by four digits.

			// The following masks tell how to format the full date and cannot be combined with other masks:
			// short: equivalent to m/d/y
			// medium: equivalent to mmm d, yyyy
			// long: equivalent to mmmm d, yyyy
			// full: equivalent to dddd, mmmm d, yyyy

			switch (msk) {
				case "short":
					msk = "m/d/yy";
					break;
				case "medium":
					msk = "mmm d, yyyy";
					break;
				case "long":
					msk = "mmmm d, yyyy";
					break;
				case "full":
					msk = "dddd, mmmm d, yyyy";
					break;
			}

			var returnedString:String = "";
			var currChar:String = "";
			var currIndex:uint = 0;
			var arMSK:Array = new Array();
			for (var i:uint=0; i < msk.length; i++) {
				var char:String = msk.charAt(i);
				if (char == currChar) {
					arMSK[currIndex] = arMSK[currIndex] + char;
				} else {
					currIndex += 1;
					currChar = char;
					arMSK[currIndex] = currChar;
				}
			}
			for (var j:uint=0; j < arMSK.length; j++) {
				var mskItem:* = (arMSK[j] == undefined) ? "" : arMSK[j];
				switch (mskItem) {
					case "dddd":
						mskItem = dayByName(dt.getDay());
						break;
					case "mmmm":
						mskItem = monthByName(dt.getMonth());
						break;
					case "yyyy":
						mskItem = dt.getFullYear();
						break;
					case "ddd":
						mskItem = dayByAbbr(dt.getDay());
						break;
					case "mmm":
						mskItem = monthByAbbr(dt.getMonth());
						break;
					case "dd":
						mskItem = includeZero(dt.getDate());
						break;
					case "mm":
						mskItem = includeZero(dt.getMonth()+1);
						break;
					case "yy":
						mskItem = dt.getFullYear().toString().slice(2,4);
						break;
					case "d":
						mskItem = dt.getDate();
						break;
					case "m":
						mskItem = dt.getMonth()+1;
						break;
					case "y":
						mskItem = dt.getFullYear().toString().slice(2,4); // same as "yy"
						break;
				}
				arMSK[j] = mskItem;
			}

			return arMSK.join("");
		}
	}
}
</pre>
<p>Again - easy to use:</p>
<pre>
var myAS3date:Date = new Date(2009,3,29,15,59,36,11);
var myAs3dateFormatted:String = DateFormatter.toCFdateString(myAS3date,"mm dd, yyyy")
</pre>
<p>Or combine them both!:</p>
<pre>
var myCFtimestamp = "{ts '2009-04-29 15:59:36.11'}";
var myAs3dateFormatted:String = DateFormatter.toCFdateString(CFtimestamp.toDate(myCFtimestamp),"mm dd, yyyy")
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=192</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using JPGEncoder without stalling</title>
		<link>http://blog.qnotemedia.com/?p=184</link>
		<comments>http://blog.qnotemedia.com/?p=184#comments</comments>
		<pubDate>Fri, 24 Apr 2009 17:45:16 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Air]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[AS3CoreLib]]></category>
		<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=184</guid>
		<description><![CDATA[Was racking my head against my desk today trying to figure this out.
I&#8217;m using JPGEncoder from AS3CoreLib to properly encode and save images with Air and realized that the app was stalling during JPGEncoder&#8217;s encode().
Fortunately, a fellow forum member at actionscript.org, Jerion, had also experienced this and wrote a simple fix &#8211; use events!
Here&#8217;s the [...]]]></description>
			<content:encoded><![CDATA[<p>Was racking my head against my desk today trying to figure this out.</p>
<p>I&#8217;m using JPGEncoder from <a href="http://code.google.com/p/as3corelib/">AS3CoreLib</a> to properly encode and save images with Air and realized that the app was stalling during JPGEncoder&#8217;s encode().</p>
<p>Fortunately, a fellow forum member at actionscript.org, Jerion, had also experienced this and wrote a simple fix &#8211; use events!</p>
<p>Here&#8217;s the how to use JPGEncoder as originally designed:</p>
<pre>
package {
	...
	import com.adobe.images.JPGEncoder;
	...
	public class ImageSaver() {
		...
		public function saveImage(bitmapData):void {
			var jpgEncoder:JPGEncoder = new JPGEncoder(85);

			// application stalls until the following line is complete
			var jpgStream:ByteArray = jpgEncoder.encode(bitmapData);

			// continues fine from here...
			var imageFile:File = File.desktopDirectory.resolvePath("imagesFolder");

			try {
				var filestream:FileStream = new FileStream();
				filestream.open(imageFile,FileMode.WRITE);
				filestream.writeBytes(jpgStream);
				filestream.close();
			} catch(e:Error) {
				trace("Error saving image: " + e)
			}
		}
		...
	}
}
</pre>
<p>Works great, but everything in the application stops while jpgEncoder.encode() is run. If the image is large, the user experiences a &#8220;halted&#8221; application. In my case, I&#8217;m looping many small images, and the experience is a constant &#8220;stutter&#8221; as the images are looped. Nicely animated preloaders become stop animations.</p>
<p>The solution is to rewrite JPGEncoder so that it fires an event when it is done encoding.</p>
<p>Simply <a href="http://blog.qnotemedia.com/wp-content/uploads/2009/04/jpgencoder_from_jerion.zip">download this new JPGEncoder code</a> and replace the original from AS3CoreLib &#8211; again, a special thanks to Jerion for coding this!</p>
<p>Once replaced, here&#8217;s what the new encode code would look like, and the app just runs along nice and smooth!</p>
<pre>
package {
	...
	import com.adobe.images.JPGEncoder;
	...
	public class ImageSaver() {
		...
		private var _bitmapData;
		...
		public function saveImage(bitmapData):void {
			_bitmapData = bitmapData;

			var jpgEncoder:JPGEncoder = new JPGEncoder();
			jpgEncoder.addEventListener("ImageDone",imageEncodeComplete);
			jpgEncoder.encode(_bitmapData,85);
		}
		private function imageEncodeComplete(evt:Event):void {
			var jpgStream:ByteArray = evt.currentTarget.imageBytes;
			var imageFile:File = File.desktopDirectory.resolvePath("imagesFolder");

			try {
				var filestream:FileStream = new FileStream();
				filestream.open(imageFile,FileMode.WRITE);
				filestream.writeBytes(jpgStream);
				filestream.close();
			} catch(e:Error) {
				trace("Error saving image: " + e)
			}
		}
		...
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=184</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>AS3 My Way: A little bit of MVC</title>
		<link>http://blog.qnotemedia.com/?p=136</link>
		<comments>http://blog.qnotemedia.com/?p=136#comments</comments>
		<pubDate>Fri, 17 Apr 2009 11:20:12 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[AS3 My Way]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://blog.qnotemedia.com/?p=136</guid>
		<description><![CDATA[Again &#8211; must preface as always with not the expert!
I spent alot of time last year learning design patterns, specifically MVC. The basic premise is having a Model that holds and controls the non-visual or data-based stuff, a bunch of Views that make up the visual pieces we interact with, and a Controller that manages [...]]]></description>
			<content:encoded><![CDATA[<p>Again &#8211; must preface as always with <em>not the expert</em>!</p>
<p>I spent alot of time last year learning design patterns, specifically MVC. The basic premise is having a <strong><em>Model</em></strong> that holds and controls the non-visual or data-based stuff, a bunch of <strong><em>Views</em></strong> that make up the visual pieces we interact with, and a <strong><em>Controller</em></strong> that manages the state of the system and what needs to happen when. The general theory &#8211; I think &#8211; is that the Model is the data and the Controller manages the graphics (Views). Unfortunately, most design pattern descriptions then go straight into much more detailed definitions of precisely what these things should look like in code, what each class MUST and MUST NOT do and that if you don&#8217;t follow such rules, you&#8217;re a moron.</p>
<p>But what I&#8217;ve learned is that these rules are meant to be broken. Building a strict design pattern can be alot of work, making your simple little project take alot longer than it should.</p>
<p>Fortunately, I&#8217;ve found ways to implement these theories slowly without going too deep into pattern mechanics. And yes, you should absolutely learn the detailed stuff about patterns because it teaches you when to divvy up into classes and when not to &#8211; but I&#8217;ll show here some basic code here that I use to keep a small sized project small, manageable, and easily updateable and scalable.</p>
<p><strong>The &#8220;Main&#8221; class</strong><br />
Open a new FLA file and save it someplace.</p>
<p>The first wierdness when it comes to developing with Flash and MVC is how the Document class plays a part. Most design pattern books I&#8217;ve read do not cover this very well. When building apps with Flash and AS3, its typically best to have all of your code external from the FLA itself, including the Document class. This is linked to in one of three places:</p>
<ul>
<li>the Properties Panel of the FLA Document &#8211; left click a blank area of the stage, and open the Properties Panel</li>
<li>choose the Modify Menu -> Document</li>
<li>choose the File Menu -> Publish Settings&#8230; -> Flash Tab -> Settings&#8230; button next to the &#8220;Actionscript version&#8221; drop-down box</li>
</ul>
<p>The file you&#8217;re linking to in the Document box is going to be the base class for the FLA. Its an external file that will setup the bare root of the entire project. Most of the time, this is &#8220;Main.as&#8221; or &#8220;Document.as,&#8221; but you need to type in only the class itself, not the full filename. Almost 99% of the time this is the filename without the extension.</p>
<div id="attachment_142" class="wp-caption aligncenter" style="width: 450px"><img src="http://blog.qnotemedia.com/wp-content/uploads/2009/04/as3docclass.gif" alt="Assigning the Document Class in the Actionscript 3.0 Settings Panel" title="Assigning the Document Class in the Actionscript 3.0 Settings Panel" width="440" height="441" class="size-full wp-image-142" /><p class="wp-caption-text">Assigning the Document Class in the Actionscript 3.0 Settings Panel</p></div>
<p>Now that the class is linked, we have to create the file &#8220;Main.as&#8221; and place it in the same folder as the FLA. Its going to start out like this:</p>
<pre>
package {
	import flash.display.MovieClip;
	public class Main extends MovieClip {
		public function Main() {

		}
	}
}
</pre>
<p>This is a bare class that does nothing but get constructed. Note that since we&#8217;re developing in the Flash IDE, we must extend the MovieClip class for the document class.</p>
<p>The basic flow for our MVC is the Document class is going to instantiate our Model and Controller, and the Controller, with direct reference to the Model, is going to instantiate the Views. Lets start with the Model.</p>
<p><strong>The &#8220;Model&#8221; class</strong><br />
Create a new actionscript file called &#8220;Model.as&#8221; in the same folder as your FLA. This is going to handle our data and it might look something like this:</p>
<pre>
package {
	import flash.events.Event;
	import flash.events.EventDispatcher;
	public class Model extends EventDispatcher {
		private var _data:Array = new Array();

		public function Model() {

		}
		public function initData():void {
			for (var i:uint=50; i<59; i++) {
				var lineOfData:uint = i;
				_data.push(lineOfData);
			}
			dispatchEvent(new Event(Event.COMPLETE));
		}
		public function get data():Array {
			return _data;
		}
	}
}
</pre>
<p>Model is non-visual so it really doesn't need to extend anything. But since we are going to dispatch Events from it with dispatchEvent(), we have to extend the class from EventDispatcher.</p>
<p>When the Model is instantiated, it'll do nothing. But when initData() is run, the Model will populate the _data array with some data (consisting of 10 values with the numbers 50 through 59), and dispatch a Complete event when its done. Our Main class is going to listen for that Complete event. This allows us to have a chain of events (no pun intended) occur so that things get done in a specific order. More on that later.</p>
<p>Note also the get data function. This is done so that our _data Array is easily accessible to other classes. We don't need a set _data because we only want the Model to control it - basically a read-only permission to the Array.</p>
<p>Lets look at the Controller next.</p>
<p><strong>The "Controller" class</strong><br />
Create a new Actionscript file and call it "Controller.as" in the same folder as your FLA. Our Controller is going to create views when they need to be created and tell them what to do as we interact with our project. Here's a starting point:</p>
<pre>
package {
	import flash.display.Sprite;
	import flash.events.Event;
	public class Controller extends Sprite {
		private var _model:Model;
		private var _views:Object = new Object();

		public function Controller(model:Model) {
			_model = model;
		}
		public function initViews():void {
			// setup default views here
			dispatchEvent(new Event(Event.COMPLETE));
		}

		private function addView(view):void {
			_views[view.name] = view;
			addChild(view);
		}
		private function removeView(view):void {
			removeChild(view);
			delete _views[view.name];
			view = null;
		}
	}
}
</pre>
<p>Firstly, note the addView and removeView functions, as mentioned in my previous posting. We need to extend the Sprite class because the Controller is going to hold visual stuff. Note also that the Controller is getting a reference to the Model in its constructor, and its placed in a variable that can be accessed from anywhere in the class. We are creating a direct link to the Model from our Controller, even though the Model knows nothing about the Controller.</p>
<p>Finally, lets add a View.</p>
<p><strong>The first "View" - a Circle class</strong><br />
We'll call this view "Circle.as" and all it'll do is draw a circle:</p>
<pre>
package {
	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.events.Event;
	public class Circle extends Sprite {
		private var _views:Object = new Object();

		public function Circle() {

		}
		public function drawCircle(radius,color):void {
			var circle:Shape = new Shape();
			circle.name = "circleA";
			circle.graphics.beginFill(color,1);
			circle.graphics.drawCircle(0,0,radius);
			circle.graphics.endFill();
			addView(circle);
			dispatchEvent(new Event(Event.COMPLETE));
		}

		private function addView(view):void {
			_views[view.name] = view;
			addChild(view);
		}
		private function removeView(view):void {
			removeChild(view);
			delete _views[view.name];
			view = null;
		}
	}
}
</pre>
<p>Once again, we have addView() and removeView() and are extending the Sprite class. drawCircle() is expecting two arguments to decide what the radius and color of the circle is going to be. The x and y values are zero, but we can simply assign x and y on the circle class when its instantiated by the Controller. Not much else to our circle.</p>
<p><strong>Completing the circle of events</strong><br />
Now, let's move backwards and start instantiating everything. In the Controller's initViews(), we'll instantiate the Circle class, add a listener for its Complete event, and run the drawCircle method. We also need a new function, viewsInited, to handle the Complete event:</p>
<pre>
		...
		public function initViews():void {
			var myCircle:Circle = new Circle();
			myCircle.name = "myCircle";
			myCircle.x = 100;
			myCircle.y = 100;
			myCircle.addEventListener(Event.COMPLETE,viewsInited,false,0,true);
			addView(myCircle);

			myCircle.drawCircle(50,0x000000);
		}
		private function viewsInited(evt:Event):void {
			dispatchEvent(new Event(Event.COMPLETE));
		}
		...
</pre>
<p>So - when Controller's initViews() runs, it instantiates the circle and waits for the Complete event. When the circle sends its Complete event, the Controller in turn sends its own Complete event in viewsInited() to its parent, Main.</p>
<p>So, in the Main class, we need to instantiate the Model and Controller and listen and handle Complete events from both. Here's our new Main.as:</p>
<pre>
package {
	import flash.display.MovieClip;
	import flash.events.Event;
	public class Main extends MovieClip {
		private var _model:Model;
		private var _controller:Controller;

		public function Main() {
			_model = new Model();
			_model.addEventListener(Event.COMPLETE,modelInited,false,0,true);

			_controller = new Controller(_model);
			_controller.addEventListener(Event.COMPLETE,controllerInited,false,0,true);
			addChild(_controller);

			_model.initData();
		}
		private function modelInited(evt:Event):void {
			_controller.initViews();
		}
		private function controllerInited(evt:Event):void {
			// all done!
		}
	}
}
</pre>
<p>Notice that I've turned to the path of simplicity here with using addChild() instead of addView(), because, as of now, I know I'll never do much of anything else with the Document Class (which has actually backfired on me before, but lets keep it simple...). I will never need to remove either the Model nor the Controller since they form the structure of my project. Note too that the Model is being passed as an argument into the Controller's constructor to create that direct communication between the Model and Controller. You're ready to run your project and should see a circle on the stage.</p>
<p><strong>Keep it sequential!</strong><br />
So you might be wondering what exactly is going on here. So much work for a single circle? And why all of the Events?</p>
<p>Again, the goal is to keep things sequential and leave room for scalability. Lets look at keeping it sequential first.</p>
<p>Say the radius value of the circle is something we want to have dynamically in the data array of the Model. Maybe each of our data Array's values are different radii of circles? Since we have a reference of the Model in the Controller, we could get those values directly from it and use it when we draw the circle in the Controller:</p>
<pre>
...
myCircle.drawCircle(_model.data[0],0x000000);
...
</pre>
<p>The first value in the Model's data Array is 50, so that's going to be the radius of the circle. But what if the Model's initData() function hasn't run yet? You'll get an error. Thus the need for this chain of events to occur.</p>
<p>So here's the final order of things:</p>
<ol>
<li>The Document Class, Main, is constructed</li>
<li>Model is constructed</li>
<li>Controller is constructed</li>
<li>Main tells the Model to retrieve and build some data and waits for a response</li>
<li>Model sends a Complete event to Main when its done</li>
<li>Document tells Controller to initialize its views and waits for a response</li>
<li>Controller constructs a Circle and waits for a response</li>
<li>Circle sends a Complete event to Controller</li>
<li>Controller sends a Complete event to Main</li>
</ol>
<p>And that's about it! In my next post, we'll add more views, talk about scalability, and create a new circle of direct communication from Views to the Model as well as create Sub-Controllers of the Controller.</p>
<p>Here's a zip of the source for this post:<br />
<a href='http://blog.qnotemedia.com/wp-content/uploads/2009/04/a_little_bit_of_mvc.zip'>A Little Bit of MVC Source Files</a></p>
<ul>
<li><strong><a href="http://blog.qnotemedia.com/?p=94">AS3 My Way: Intro</a></strong></li>
<li><strong><a href="http://blog.qnotemedia.com/?p=129">AS3 My Way: Name Everything!</a></strong></li>
<li><strong><a href="http://blog.qnotemedia.com/?p=152">AS3 My Way: Adding, Removing, and Memory Usage</a></strong></li>
<li><strong><a href="http://blog.qnotemedia.com/?p=136">AS3 My Way: A little bit of MVC</a></strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.qnotemedia.com/?feed=rss2&amp;p=136</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
