<?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>AaronHardy.com :: For all your Aaron Hardy needs.</title>
	<atom:link href="http://aaronhardy.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://aaronhardy.com</link>
	<description>For all your Aaron Hardy needs.</description>
	<lastBuildDate>Mon, 30 Aug 2010 18:29:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Free Flex Classes in Utah</title>
		<link>http://aaronhardy.com/flex/free-flex-classes-in-utah/</link>
		<comments>http://aaronhardy.com/flex/free-flex-classes-in-utah/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 18:29:21 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[learn]]></category>
		<category><![CDATA[Utah]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=773</guid>
		<description><![CDATA[If you&#8217;re interesting in learning Flex and live in Utah, feel free to join us in American Fork for free classes.  Visit our Utah Flex Class Google group to learn more.
]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re interesting in learning Flex and live in Utah, feel free to join us in American Fork for free classes.  Visit our <a href="http://groups.google.com/group/utahflexclass" target="_blank">Utah Flex Class</a> Google group to learn more.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/free-flex-classes-in-utah/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DisplayObject Quirks and Tips</title>
		<link>http://aaronhardy.com/flex/displayobject-quirks-and-tips/</link>
		<comments>http://aaronhardy.com/flex/displayobject-quirks-and-tips/#comments</comments>
		<pubDate>Sat, 28 Aug 2010 22:12:26 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[cacheAsBitmap]]></category>
		<category><![CDATA[DisplayObject]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[mask]]></category>
		<category><![CDATA[mouse]]></category>
		<category><![CDATA[rotation]]></category>
		<category><![CDATA[scale]]></category>
		<category><![CDATA[transparent]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=736</guid>
		<description><![CDATA[After having worked a great deal on the Rain SVG library, I&#8217;ve come to learn and re-learn some of the quirks and workarounds of DisplayObject, the fundamental UI class in ActionScript.  For your benefit and mine, here they are.  It&#8217;s only a short list of the many so if you&#8217;d like to add [...]]]></description>
			<content:encoded><![CDATA[<p>After having worked a great deal on the <a href="http://aaronhardy.com/flex/rain-svg/">Rain SVG</a> library, I&#8217;ve come to learn and re-learn some of the quirks and workarounds of DisplayObject, the fundamental UI class in ActionScript.  For your benefit and mine, here they are.  It&#8217;s only a short list of the many so if you&#8217;d like to add on, feel free to post a comment.<span id="more-736"></span></p>
<h3>CacheAsBitmap with a mask breaks mouse events</h3>
<p>If you have a sprite that has a mask and cacheAsBitmap set the true, the display object will no longer dispatch mouse events.</p>
<p>In this example, I&#8217;m using a PNG that&#8217;s partially transparent as a mask and it&#8217;s masking a black square.  This type of mask only works when cacheAsBitmap is set to true for both the mask and the maskee.  The result is a working mask, but the maskee will no longer dispatch mouse events.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript actionscript" style="font-family:monospace;"><span style="color: #66cc66;">&#91;</span>Embed<span style="color: #66cc66;">&#40;</span>source=<span style="color: #ff0000;">&quot;books.png&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
protected <span style="color: #000000; font-weight: bold;">var</span> Books:<span style="color: #000000; font-weight: bold;">Class</span>;
&nbsp;
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> CacheAsBitmapAndMask<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">var</span> books:Bitmap = <span style="color: #000000; font-weight: bold;">new</span> Books<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> square:Sprite = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0x000000<span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0, 0, books.<span style="color: #0066CC;">width</span>, books.<span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	square.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span>books<span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">mask</span> = books;
	square.<span style="color: #006600;">cacheAsBitmap</span> = <span style="color: #000000; font-weight: bold;">true</span>;
	books.<span style="color: #006600;">cacheAsBitmap</span> = <span style="color: #000000; font-weight: bold;">true</span>;
	addChild<span style="color: #66cc66;">&#40;</span>square<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	square.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>MouseEvent.<span style="color: #006600;">CLICK</span>, clickHandler<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
protected <span style="color: #000000; font-weight: bold;">function</span> clickHandler<span style="color: #66cc66;">&#40;</span>event:MouseEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'click'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h3>Filter and a mask breaks mouse events</h3>
<p>At its core, this quirk seems to be the same as the previous one. In this example I have a shape masking a sprite and the sprite has a drop shadow. It&#8217;s important to remember that adding a filter to a display object will automatically set cacheAsBitmap to true. The display object again will not dispatch mouse events.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> FilterAndMask <span style="color: #0066CC;">extends</span> Sprite
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> FilterAndMask<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #66cc66;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">var</span> mask:Shape = <span style="color: #000000; font-weight: bold;">new</span> Shape<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		mask.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0xff0000<span style="color: #66cc66;">&#41;</span>;
		mask.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">25</span>, <span style="color: #cc66cc;">25</span>, <span style="color: #cc66cc;">50</span>, <span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span>;
		mask.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #000000; font-weight: bold;">var</span> maskee:Sprite = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		maskee.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0x000000<span style="color: #66cc66;">&#41;</span>;
		maskee.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0, 0, <span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span>;
		maskee.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		maskee.<span style="color: #006600;">filters</span> = <span style="color: #66cc66;">&#91;</span><span style="color: #000000; font-weight: bold;">new</span> DropShadowFilter<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
		maskee.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span>mask<span style="color: #66cc66;">&#41;</span>;
		maskee.<span style="color: #006600;">mask</span> = mask;
		addChild<span style="color: #66cc66;">&#40;</span>maskee<span style="color: #66cc66;">&#41;</span>;
&nbsp;
		maskee.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>MouseEvent.<span style="color: #006600;">CLICK</span>, clickHandler<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
&nbsp;
	protected <span style="color: #000000; font-weight: bold;">function</span> clickHandler<span style="color: #66cc66;">&#40;</span>event:MouseEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
	<span style="color: #66cc66;">&#123;</span>
		<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'click'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>See <a href="https://bugs.adobe.com/jira/browse/FP-61" target="_blank">https://bugs.adobe.com/jira/browse/FP-61</a> and <a href="https://bugs.adobe.com/jira/browse/FP-3818" target="_blank">https://bugs.adobe.com/jira/browse/FP-3818</a> for the bug reports.</p>
<p>You can work around this issue by wrapping the maskee in another sprite.  Rather than setting the filter on the maskee, set it on the wrapper.  Here&#8217;s an example:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> FilterAndMaskWorkaround<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">var</span> mask:Shape = <span style="color: #000000; font-weight: bold;">new</span> Shape<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	mask.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0xff0000<span style="color: #66cc66;">&#41;</span>;
	mask.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0, 0, <span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span>;
	mask.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> maskee:Sprite = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	maskee.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0x000000<span style="color: #66cc66;">&#41;</span>;
	maskee.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0, 0, <span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span>;
	maskee.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	maskee.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span>mask<span style="color: #66cc66;">&#41;</span>;
	maskee.<span style="color: #006600;">mask</span> = mask;
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> maskeeWrapper:Sprite = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	maskeeWrapper.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span>maskee<span style="color: #66cc66;">&#41;</span>;
	maskeeWrapper.<span style="color: #006600;">filters</span> = <span style="color: #66cc66;">&#91;</span><span style="color: #000000; font-weight: bold;">new</span> DropShadowFilter<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
	addChild<span style="color: #66cc66;">&#40;</span>maskeeWrapper<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	maskee.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>MouseEvent.<span style="color: #006600;">CLICK</span>, clickHandler<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
protected <span style="color: #000000; font-weight: bold;">function</span> clickHandler<span style="color: #66cc66;">&#40;</span>event:MouseEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'click'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h3>CacheAsBitmap breaks concatenatedMatrix and hitTestPoint()</h3>
<p>When an ancestor of a given display object has cacheAsBitmap set to true, the display object&#8217;s concatenated matrix is incorrect.  This also affects the validity of hitTestPoint() and probably some other functions as well.</p>
<p>In this example the ancestor has a filter which in turn sets cacheAsBitmap to true.  When clicking on the child, the concatenated matrix reports tx=1 and ty=1.  In this case, tx and ty are incorrect.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> CacheAsBitmapConcatMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">var</span> ancestor:Sprite = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	ancestor.<span style="color: #006600;">x</span> = <span style="color: #cc66cc;">50</span>;
	ancestor.<span style="color: #006600;">y</span> = <span style="color: #cc66cc;">50</span>;
	ancestor.<span style="color: #006600;">filters</span> = <span style="color: #66cc66;">&#91;</span><span style="color: #000000; font-weight: bold;">new</span> DropShadowFilter<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
	addChild<span style="color: #66cc66;">&#40;</span>ancestor<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> child:Sprite = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	child.<span style="color: #006600;">x</span> = <span style="color: #cc66cc;">25</span>;
	child.<span style="color: #006600;">y</span> = <span style="color: #cc66cc;">25</span>;
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> g:Graphics = child.<span style="color: #006600;">graphics</span>;
&nbsp;
	g.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0x00dd00<span style="color: #66cc66;">&#41;</span>;
	g.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0,0,<span style="color: #cc66cc;">200</span>,<span style="color: #cc66cc;">200</span><span style="color: #66cc66;">&#41;</span>;
	g.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	child.<span style="color: #006600;">cacheAsBitmap</span> = <span style="color: #000000; font-weight: bold;">true</span>;
	child.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>MouseEvent.<span style="color: #006600;">CLICK</span>, child_clickHandler<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	ancestor.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span>child<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
protected <span style="color: #000000; font-weight: bold;">function</span> child_clickHandler<span style="color: #66cc66;">&#40;</span>event:MouseEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">var</span> child:DisplayObject = DisplayObject<span style="color: #66cc66;">&#40;</span>event.<span style="color: #0066CC;">target</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span>child.<span style="color: #006600;">transform</span>.<span style="color: #006600;">concatenatedMatrix</span><span style="color: #66cc66;">&#41;</span>; 
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The workaround is fairly simple:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript actionscript" style="font-family:monospace;">protected <span style="color: #000000; font-weight: bold;">function</span> getConcatenatedMatrix<span style="color: #66cc66;">&#40;</span>source:DisplayObject<span style="color: #66cc66;">&#41;</span>:Matrix
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">var</span> concatenated:Matrix = source.<span style="color: #006600;">transform</span>.<span style="color: #006600;">concatenatedMatrix</span>.<span style="color: #006600;">clone</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; 
	<span style="color: #000000; font-weight: bold;">var</span> p:Point = source.<span style="color: #0066CC;">localToGlobal</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Point<span style="color: #66cc66;">&#40;</span>0, 0<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; 
	concatenated.<span style="color: #006600;">tx</span> = p.<span style="color: #006600;">x</span>; 
	concatenated.<span style="color: #006600;">ty</span> = p.<span style="color: #006600;">y</span>;
	<span style="color: #b1b100;">return</span> concatenated;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>See <a href="https://bugs.adobe.com/jira/browse/FP-121" target="_blank">https://bugs.adobe.com/jira/browse/FP-121</a> for the bug report.  This post is also helpful: <a href="http://www.sephiroth.it/weblog/archives/2008/03/cacheasbitmap_hell.php target="_blank">http://www.sephiroth.it/weblog/archives/2008/03/cacheasbitmap_hell.php</a>.</p>
<h3>Mouse events dispatched for transparent portions of bitmaps</h3>
<p>Add a bitmap with some transparent pixels to a sprite.  If you then click the tranparent portions of the bitmap, the sprite will dispatch a click event just as it would if you clicked opaque portions.  This is often not desired behavior as you may want the click to &#8220;fall through&#8221; to whatever display object is behind it.  There&#8217;s no easy way to toggle this functionality either.  Most workarounds are limited by the other quirks mentioned so far or are not dynamic enough for general use.  The best workaround I&#8217;ve used so far is <a href="http://blog.mosessupposes.com/?p=40" target="_blank">InteractivePNG</a> created by Moses Gunesch.</p>
<h3>Possibly unexpected dimensions after rotation and scaling</h3>
<p>Take a 100&#215;100 square and rotated it 45 degrees.  What&#8217;s the width of the shape?  In Flash-world, it&#8217;s 141.4, or in other words, the &#8220;bounds&#8221; of the rotated rectangle is 141.4 pixels across.  What if I want to access the unrotated width again?  For one, you can set the rotation back to 0 and then request the width.  That&#8217;s generally not the greatest option.  Another option is to get the bounds of the square within its own coordinate space.  Here&#8217;s an example:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> RotatedDimensions<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">var</span> square:Shape = <span style="color: #000000; font-weight: bold;">new</span> Shape<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0xff0000<span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0, 0, <span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">rotation</span> = <span style="color: #cc66cc;">45</span>;
	addChild<span style="color: #66cc66;">&#40;</span>square<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span>square.<span style="color: #0066CC;">width</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Traces 141.4</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> internalBounds:Rectangle = square.<span style="color: #0066CC;">getBounds</span><span style="color: #66cc66;">&#40;</span>square<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span>internalBounds.<span style="color: #0066CC;">width</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Traces 100</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The best way I can describe what getBounds() is doing here is that it&#8217;s seeing the square without regard to its scale or rotation within its parent.  It&#8217;s important to understand what this does when scale is introduced.  Let&#8217;s take this example:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> RotatedScaledDimensions<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">var</span> square:Shape = <span style="color: #000000; font-weight: bold;">new</span> Shape<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0xff0000<span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0, 0, <span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	square.<span style="color: #006600;">scaleX</span> = square.<span style="color: #006600;">scaleY</span> = .5;
	square.<span style="color: #006600;">rotation</span> = <span style="color: #cc66cc;">45</span>;
	addChild<span style="color: #66cc66;">&#40;</span>square<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span>square.<span style="color: #0066CC;">width</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Traces 70.7</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> internalBounds:Rectangle = square.<span style="color: #0066CC;">getBounds</span><span style="color: #66cc66;">&#40;</span>square<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span>internalBounds.<span style="color: #0066CC;">width</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Traces 100</span>
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span>internalBounds.<span style="color: #0066CC;">width</span> <span style="color: #66cc66;">*</span> square.<span style="color: #006600;">scaleX</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Traces 50</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>In this case the square&#8217;s been scaled down to half its original size and is rotated 45 degrees.  If you ask for the width, flash reports 70.7.  If you get the dimensions of the square within its own coordinate space, it will report 100 for the width.  In other words, these are the unscaled, unrotated dimensions of the square.  The third trace is an example of how to get the scaled but unrotated width of the square.</p>
<h3>Invisible children contribute to parent&#8217;s dimensions</h3>
<p>Create a child shape, set it to be invisible, and add it to a sprite.  Even though the child is not visible, its dimensions still contribute to the parent&#8217;s dimensions.  This may or may not be what you&#8217;re expecting, but there&#8217;s no way to easily toggle the inclusion of invisible children when calculating a display object&#8217;s dimensions.</p>
<p>Take this example:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> InvisibleBounds<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">var</span> container:Sprite = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> <span style="color: #0066CC;">left</span>:Shape = <span style="color: #000000; font-weight: bold;">new</span> Shape<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">left</span>.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0xff0000<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">left</span>.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0, 0, <span style="color: #cc66cc;">50</span>, <span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">left</span>.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	container.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">left</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> <span style="color: #0066CC;">right</span>:Shape = <span style="color: #000000; font-weight: bold;">new</span> Shape<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">right</span>.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0xff0000<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">right</span>.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawRect</span><span style="color: #66cc66;">&#40;</span>0, 0, <span style="color: #cc66cc;">50</span>, <span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">right</span>.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #0066CC;">right</span>.<span style="color: #006600;">x</span> = <span style="color: #cc66cc;">50</span>;
	<span style="color: #0066CC;">right</span>.<span style="color: #0066CC;">visible</span> = <span style="color: #000000; font-weight: bold;">false</span>;
	container.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">right</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span>container.<span style="color: #0066CC;">width</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// Traces 100</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Even though the child on the right is invisible, the container still includes it in its dimensions.</p>
<p>See <a href="https://bugs.adobe.com/jira/browse/FP-741" target="_blank">https://bugs.adobe.com/jira/browse/FP-741</a> for the bug report and some workarounds that work well but can be slow.</p>
<p>I hope that helps anyone running into the same issues.  Please post a comment if you have quirks or tips of your own.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/displayobject-quirks-and-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaUtils: Detecting and Installing Java from AIR</title>
		<link>http://aaronhardy.com/flex/javautils-detecting-and-installing-java-from-air/</link>
		<comments>http://aaronhardy.com/flex/javautils-detecting-and-installing-java-from-air/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 05:27:17 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[General Programming]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[detection]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[installer]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[java runtime environment]]></category>
		<category><![CDATA[JRE]]></category>
		<category><![CDATA[native process]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=706</guid>
		<description><![CDATA[Adobe AIR is a great way to bring the sexiness of Flash to the desktop.  However, sometimes you need more low-level power for things like connecting to peripherals.  For this reason, AIR applications are sometimes paired with Java applications to accomplish such tasks.  But first, the user&#8217;s system must have an adequate [...]]]></description>
			<content:encoded><![CDATA[<p>Adobe AIR is a great way to bring the sexiness of Flash to the desktop.  However, sometimes you need more low-level power for things like connecting to peripherals.  For this reason, AIR applications are sometimes paired with Java applications to accomplish such tasks.  But first, the user&#8217;s system must have an adequate Java Runtime Environment (JRE) installed in order for the Java application to run in the first place.<span id="more-706"></span></p>
<p>Before we get too far, be aware that these JavaUtils are currently for Windows only.  Macs have their own version of the JRE that&#8217;s deployed through the Software Update feature so the process of detecting and installing the JRE is very different and is left for another day.</p>
<h3>The Short Story</h3>
<p>To get started with the utilities, first download the source by <a href="http://github.com/Aaronius/JavaUtils" target="_blank">checking out the git repository</a> or <a href="http://aaronhardy.com/samples/javautils/JavaUtils.exe">installing the sample application</a>.  If you choose to install the sample application, run the app and right-click on the stage to view the source.</p>
<p>The utilities include two executables: </p>
<ol>
<li>whereis.exe &#8211; This is used internally by the tools.  See the juicy details below if you care to learn more about this.</li>
<li>jre-blah-blah-blah.exe &#8211; This is the Windows JRE online installer found here: <a href="http://www.java.com/en/download/manual.jsp" target="_blank">http://www.java.com/en/download/manual.jsp</a>.  This is the installer that is used to install a JRE of your choice if the user&#8217;s system does not have an adequate JRE already installed.  Because it&#8217;s the &#8220;online&#8221; installer, it&#8217;s lightweight and lets you avoid bundling an entire JRE with your AIR app.</li>
</ol>
<p>There are two main utility classes:</p>
<ol>
<li>JavaValidationUtil &#8211; This is used to determine if the user has an adequate JRE installed.  Call validate() and it will dispatch an event letting you know if the user has a JRE installed and if the version is sufficient.</li>
<li>JavaInstallUtil &#8211; This is used to install the JRE if needed.  Call install() and it will dispatch an event letting you know when the installation is complete.
</ol>
<h3>The Juicy Details</h3>
<p>Let&#8217;s dig into the details of how this works.  Support for running other executables as described below comes from the new <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/desktop/NativeProcess.html" target="_blank">NativeProcess</a> in AIR 2.0. </p>
<p><strong>Validation.</strong>  The first chore is to validate whether the user has a JRE installed and, if so, whether the JRE is sufficient for the application&#8217;s needs.  The developer provides the validation utility with a minimum acceptable version broken into four segments: major, minor, revision, and update.</p>
<p>Now we need to find the version of the installed JRE to compare.  But first we need to find out where the JRE is installed if one exists.  On Windows there&#8217;s an environment variable called PATH which contains several directories that should be searched to find an application when a command is executed in the command shell.  When you open up cmd, for example, you can type &#8220;notepad&#8221; and hit enter.  The fact that it&#8217;s able to open notepad isn&#8217;t magic.  Windows simply searches the PATH directories for notepad.exe and then executes it.</p>
<p>We need to do the same thing to find the java executable (java.exe).  On *nix operating systems this is pretty easy.  There&#8217;s a simple tool called whereis that comes with the operating system that searches the paths to find a given executable.  On Windows, not so much.  Luckily, our friends over at <a href="http://www.synesis.com.au/systools.html" target="_blank">Synesis</a> have released a similar tool for Windows that allows us to do the same thing.  We bundle whereis.exe with our AIR application.</p>
<p>We execute whereis.exe, passing in name of the executable we&#8217;d like to find (java.exe) as an argument.  If we don&#8217;t find java.exe, the user doesn&#8217;t have a JRE installed&#8211;at least not in the PATH paths.  And if a JRE does exist that&#8217;s not in those paths it could take a long time to find and we probably don&#8217;t want to mess with it anyway.  If java.exe is found, we then execute it passing in the -version argument.  Java will then output the version in a <a href="http://java.sun.com/j2se/versioning_naming.html" target="_blank">specified format</a> that we can then parse.  After we parse the version, we compare with the minimum acceptable version and dispatch appropriate events.</p>
<p><strong>Installation.</strong>  If no JRE is installed or the one installed isn&#8217;t adequate, the application would then generally notify the user they need a newer JRE and ask if they&#8217;d like to proceed with the installation.</p>
<p>If the user chooses to proceed, it&#8217;s time to execute the installer.  But there&#8217;s a catch.  In Windows, installer applications require &#8220;elevated privileges&#8221; before executing which means Windows nags the user asking for permission to install the JRE.  If I were to double-click the installer when it was on the desktop, it would appropriately nag.  However, if I execute the installer using AIR&#8217;s NativeProcess, nothing happens.  No error, no output, no nagging, no installing, nothing.  Is this a bug in AIR?  Eight ball says signs point to yes, but who knows, maybe Windows is to blame.</p>
<p>In my search for a workaround I found that by executing the installer from the command shell, Windows again appropriately nagged.  So then I tried executing cmd from AIR and having cmd execute the JRE installer by passing the path of the installer into cmd as an argument.  What do you know&#8211;Windows nagged appropriately and off goes the installation as planned.  When <a href="http://forums.adobe.com/thread/661442" target="_blank">presenting this problem on the Adobe AIR forums</a>, not receiving a response, then proposing the workaround, a member of the AIR engineering team seemed to think it was a good trick&#8211;nay, a great trick&#8211;so I guess that&#8217;s just the way we have to do things for now.</p>
<p>So first we use our trusty whereis.exe to find the location to cmd.exe.  Then we use cmd.exe to execute our Java installer by passing the installer path into cmd as an argument.  Windows prompts the user for permission and after permission is granted the installation proceeds as expected.  After the installation is complete, we dispatch an appropriate event.  Of course we also stay aware of fringe cases (like if the user cancels the installation) and likewise dispatch appropriate events.</p>
<p>Hopefully that&#8217;ll give you some good direction as you start your journey pairing your AIR app with Java.  Now go make something freaking fetching awesome.</p>
<div class="goodies"><a href="/samples/javautils/JavaUtils.exe">View Demo</a><a href="http://github.com/Aaronius/JavaUtils" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/javautils-detecting-and-installing-java-from-air/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Washer and Dryer Pedestals</title>
		<link>http://aaronhardy.com/life-in-general/washer-and-dryer-pedestals/</link>
		<comments>http://aaronhardy.com/life-in-general/washer-and-dryer-pedestals/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 04:28:45 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Life in General]]></category>
		<category><![CDATA[dryer]]></category>
		<category><![CDATA[pedestal]]></category>
		<category><![CDATA[stand]]></category>
		<category><![CDATA[washer]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=689</guid>
		<description><![CDATA[This week I took on another man project.  Our washer broke after a whole 1 1/2 years of use.  Considering we were planning on getting a replacement, I figured it would be a good time to make pedestals for the washer and dryer.
A pedestal elevates a washer or dryer so you don&#8217;t have [...]]]></description>
			<content:encoded><![CDATA[<p>This week I took on another man project.  Our washer broke after a whole 1 1/2 years of use.  Considering we were planning on getting a replacement, I figured it would be a good time to make pedestals for the washer and dryer.</p>
<p>A pedestal elevates a washer or dryer so you don&#8217;t have to bend down as far.  Yes, we&#8217;re that lazy.  And tall.  And the wifers has a bad back.  And apparently the rest of America is in the same boat because you can purchase them at your nearest appliance store for a mere $200 or more per pedestal.  No thanks.  Instead, I bought a bunch of wood, screws, and paint from Home Depot and made our own.  Homemade they cost around $30 per pedestal.<span id="more-689"></span></p>
<p>Here&#8217;s a tour:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" height="340" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="data" value="http://www.youtube.com/v/bsnxKO6VFQg&amp;hl=en&amp;fs=1&#038;rel=0" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/bsnxKO6VFQg&amp;hl=en&amp;fs=1&#038;rel=0" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="560" height="340" src="http://www.youtube.com/v/bsnxKO6VFQg&amp;hl=en&amp;fs=1&#038;rel=0" allowscriptaccess="always" allowfullscreen="true" data="http://www.youtube.com/v/bsnxKO6VFQg&amp;hl=en&amp;fs=1&#038;rel=0"></embed></object></p>
<p><a href="http://aaronhardy.com/wp-content/uploads/2010/06/IMG_4428.jpg"><img class="alignleft size-medium wp-image-691" title="Standalone Pedestals" src="http://aaronhardy.com/wp-content/uploads/2010/06/IMG_4428-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p><a href="http://aaronhardy.com/wp-content/uploads/2010/06/IMG_4433.jpg"><img class="alignleft size-medium wp-image-693" title="Pedestal with Washer and Dryer" src="http://aaronhardy.com/wp-content/uploads/2010/06/IMG_4433-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>Here&#8217;s the material I used for a single pedestal:</p>
<ul>
<li>(1) Top board: 27&#8243; x 27&#8243; x 23/32&#8243; CDX plywood</li>
<li>(1) Back board: 27&#8243; x 15&#8243; x 23/32&#8243; CDX plywood</li>
<li>(2) Side boards: 26 9/32&#8243; x 15&#8243; x 23/32&#8243; CDX plywood</li>
<li>(3) Top supports: 25 18/32&#8243; x 3.5&#8243; x 1.5&#8243; aka two-by-fours</li>
<li>(6) Side supports: 13 1/2&#8243; x 3.5&#8243; x 1.5&#8243; aka two-by-fours</li>
<li>3&#8243; and 2&#8243; wood screws</li>
<li>1 liter black paint</li>
<li>3&#8243; paintbrush</li>
</ul>
<p>When I purchased the wood at Home Depot, they also cut the wood for me for free which was a huge score and saved me a bunch of trouble.  I also used my electric sander to make sure the legs and supports were all even and get rid of any slivers. To help protect the floor and cushion any shaking, I glued straps of carpet to the bottom of the pedestal legs using Gorilla Glue.</p>
<p>Overall, we&#8217;re really pleased with the outcome.  They do a great job holding the weight of the washer and dryer, look great, and saved us a bundle of money.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/life-in-general/washer-and-dryer-pedestals/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>RedLiteGreenLite</title>
		<link>http://aaronhardy.com/flex/redlitegreenlite/</link>
		<comments>http://aaronhardy.com/flex/redlitegreenlite/#comments</comments>
		<pubDate>Sun, 30 May 2010 21:44:42 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[General Programming]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[amf]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[Google Apps Engine]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[messaging]]></category>
		<category><![CDATA[polling]]></category>
		<category><![CDATA[remoting]]></category>
		<category><![CDATA[RobotLegs]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=658</guid>
		<description><![CDATA[Please upgrade your Flash Player This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed.



What is it?
RedLiteGreenLite is a small, simple app that allows a group of people to communicate the status of something.  The status can be either red or green and the [...]]]></description>
			<content:encoded><![CDATA[<p><div id="flashcontent1611" style="width:215px; height:180px;"><strong>Please upgrade your Flash Player</strong> This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed.</div><script type="text/javascript">
<!-- // <![CDATA[
var so = new SWFObject("http://aaronhardy.com/wp-content/plugins/air-badge/AIRInstallBadge.swf", "Badge", "215", "180", "9.0.115", "#343434");
so.useExpressInstall("http://aaronhardy.com/wp-content/plugins/air-badge/expressinstall.swf");
so.addVariable("airversion", "1.0");
so.addVariable("appname", "RedLiteGreenLite");
so.addVariable("appurl", "http://aaronhardy.com/rlgl/RedLiteGreenLite.air");
so.addVariable("appid", "RedLiteGreenLite");
so.addVariable("pubid", "");
so.addVariable("appversion", ".5");
so.addVariable("imageurl", "/rlgl/rlglinstallbadge.jpg");
so.addVariable("appinstallarg", "installed from web");
so.addVariable("applauncharg", "launched from web");
so.addVariable("helpurl", "help.html");
so.addVariable("hidehelp", "true");
so.addVariable("skiptransition", "false");
so.addVariable("titlecolor", "#00AAFF");
so.addVariable("buttonlabelcolor", "#00AAFF");
so.addVariable("appnamecolor", "#00AAFF");
so.addVariable("str_err_airswf", "<u>Running locally?</u><br/><br/>The AIR proxy swf won't load properly when this is run from the local file system.");
so.write("flashcontent1611");
// ]]&gt; -->
</script>
</p>
<h3>What is it?</h3>
<p>RedLiteGreenLite is a small, simple app that allows a group of people to communicate the status of something.  The status can be either red or green and the subject can be whatever.  That may sound a bit general, but that&#8217;s the point.  It can be used for whatever purpose your crazy mind can come up with.  I&#8217;ll get you started:</p>
<ol>
<li>At work, we have a single shower and a lot of shweaty guys after soccer.  So we know when the shower&#8217;s available, someone can turn the status red when he enters the shower and turn it green when he exits.  This way nobody has to keep stopping by the shower to see if it&#8217;s available.  When it&#8217;s green, it&#8217;s available.   When it&#8217;s red, it&#8217;s not.</li>
<li>At a call center, representatives are split into groups. When one group is on break, no other group is allowed to go on break.  Again, when the status is red, a group is on break and other groups must continue attending the phones.  When the lite is green, the next group is free to take a break.</li>
</ol>
<p>The process is pretty simple: join a group.  Other people join the same group.  When others in the group change the status, you&#8217;ll be notified.  When you change the status, others in the group will be notified.  The status of the group will be persisted across sessions.  In other words, if everyone logs out and then logs back in a week later, the status will remain as it was the last time it was set.<span id="more-658"></span></p>
<p>There&#8217;s no need to explicitly create a group.  When you attempt to join a group, the group will automatically be created if it does not already exist.</p>
<p>The app is free.  As in free free.</p>
<h3>What technologies are used?</h3>
<p>RedLiteGreenLite has a client portion and a server portion.</p>
<p>The client is the app users download and install on their computers.  It&#8217;s built in <a href="http://www.adobe.com/products/flex/" target="_blank">Flex</a> and published for <a href="http://www.adobe.com/products/air/" target="_blank">AIR</a>.  It uses the <a href="http://www.robotlegs.org/" target="_blank">RobotLegs</a> MVCS framework and makes use of <a href="http://en.wikipedia.org/wiki/Action_Message_Format" target="_blank">AMF</a> remoting and messaging.</p>
<p>The server portion is built in <a href="http://www.java.com/en/" target="_blank">Java</a> using <a href="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/" target="_blank">BlazeDS</a> and is hosted on <a href="http://code.google.com/appengine/" target="_blank">Google Apps Engine</a>.</p>
<h3>Ooh, that&#8217;s simply juicy.  Tell me more.</h3>
<p>Don&#8217;t mind if I do.  First of all, BlazeDS is an open source implementation of AMF-based remoting and messaging.  Natively it&#8217;s not compatible with Google Apps Engine, but I wanted to use GAE because it&#8217;s extremely scalable, it&#8217;s free (let&#8217;s be honest&#8211;I&#8217;m cheap like that&#8211;this is the main reason), and I wanted the challenge.</p>
<p>To get BlazeDS working on GAE, I recommend following <a href="http://martinzoldano.blogspot.com/2009/04/appengine-adobe-blazeds-fix.html" target="_blank">Martin Zoldano&#8217;s blog post</a>.  Not only does he outline the steps you&#8217;ll need to take but he provides a critical patch to flex-messaging-core.jar as well.  While you can find this patch re-distributed elsewhere, I recommend posting a comment requesting that he email you the patched jar.  That&#8217;s how he seems to want to distribute his patch and I respect that.  He&#8217;s really helpful and quick to respond so it shouldn&#8217;t be much trouble.</p>
<p>Once BlazeDS was set up and configured, I started to plan the architecture.  First of all, I needed one client in the group to be able to send a message to the rest of the clients in the group.  This could be achieved through the messaging service BlazeDS provides.  However, messaging doesn&#8217;t store state; it just redistributes messages to clients.  I needed the group&#8217;s status to be persisted to storage so (1) when a new client joins a group it can retrieve the group&#8217;s current status and (2) the group&#8217;s status can be retained even when no clients are connected.</p>
<p>By default, BlazeDS&#8217;s messaging configuration uses ActionScriptAdapter to receive and distribute messages between clients.  It doesn&#8217;t persist messages.  To do so, I extend ActionScriptAdapter and persist the status to Google Storage before sending the message out to the other clients.  When clients connect to BlazeDS, they use remoting (not messaging) to retrieve the most recently persisted status for the group.  After the initial status is retrieved, the client talks to other clients using the messaging service.  You can see how this is set up in messaging-config.xml and PersistentASAdapter.java in the <a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">server code</a>.</p>
<p>While GAE has been really nice to get the app up and running, it does have its downsides.  To send messages between clients, BlazeDS can use a few different techniques:</p>
<ul>
<li>Simple polling. The client, at a standard interval, simply asks the server if there is any new information.  The server responds to the request immediately regardless of whether there is new information.</li>
<li>Long polling. The client sends a request to the server.  The server holds onto the request until it has something useful to tell the client at which time it sends back the response.</li>
<li>Streaming.  The client opens an HTTP connection and the connection remains open.  The server shoots messages down the connection whenever it has something to say.  It&#8217;s an &#8220;infinate response&#8221;.</li>
</ul>
<p>While <a href="http://www.dcooper.org/blog/client/index.cfm?mode=entry&#038;entry=8E1439AD-4E22-1671-58710DD528E9C2E7" target="_blank">each approach has its pros and cons</a>, simple polling leaves a lot to be desired as it creates a lot of HTTP traffic.  Unfortunately, from my testing and research, GAE doesn&#8217;t seem to support either of the other two methods.  But hey, it&#8217;s free.  If any of you have a java environment and would like to host RedLiteGreenLite so we can step up our game, let me know.</p>
<p>Last but not least, RedLiteGreenLite is open source.  I&#8217;d love for you to <a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">fork the project</a> and do something cool with it.</p>
<p>Now go have fun!  Install the client using the badge at the top of the post or fork the project using the link below.</p>
<div class="goodies"><a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/redlitegreenlite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ImageInspector: An Image Zoom &amp; Pan Component</title>
		<link>http://aaronhardy.com/flex/imageinspector-an-image-zoom-pan-component/</link>
		<comments>http://aaronhardy.com/flex/imageinspector-an-image-zoom-pan-component/#comments</comments>
		<pubDate>Wed, 12 May 2010 03:11:15 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[inspect]]></category>
		<category><![CDATA[pan]]></category>
		<category><![CDATA[photo]]></category>
		<category><![CDATA[scroll]]></category>
		<category><![CDATA[zoom]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=606</guid>
		<description><![CDATA[This type of component is becoming quite popular these days and for good reason: it makes it extremely easy to quickly zoom in and pan around an image.  I imagine most all of us have seen an example of this but I&#8217;ve never found the code for one that suits my fancy.  So [...]]]></description>
			<content:encoded><![CDATA[<p>This type of component is becoming quite popular these days and for good reason: it makes it extremely easy to quickly zoom in and pan around an image.  I imagine most all of us have seen an example of this but I&#8217;ve never found the code for one that suits my fancy.  So here you go.  Here are some possibly unique features I wanted and implemented along with the usual goodies:<span id="more-606"></span></p>
<p>ImageInspector works with images of any aspect ratio.  Also, you&#8217;ll notice the picture-in-picture will size itself to the aspect ratio of the image.  Just set maxWidth and maxHeight and it won&#8217;t get larger than those dimensional limits.</p>
<p>The focal point is maintained during scaling.  For example, zoom in, move the focal point to the corner of the image, zoom out, then zoom in.  Notice that, as you zoom out and in, the focal point is maintained as much as possible.</p>
<p>The focal point and relative scale are both maintained during resizing.  For example, if an image inside ImageInspector is at 200% of its &#8220;fit&#8221; size, ImageInspector is 100% width and height of the window, and the user starts making the window larger, ImageInspector will continue to scale up the image inside it, attempting to keep it at 200% of its &#8220;fit&#8221; size.  Likewise, the focal point will be maintained while resizing the window as well.</p>
<p>Right-click <a href="/samples/imageinspector/Main.html" target="_blank">the demo app</a> to view the source.  The app might take a little while to load because it contains two embedded high-res images.</p>
<div class="goodies"><a href="/samples/imageinspector/Main.html" target="_blank">View Demo</a><a href="http://github.com/Aaronius/ImageInspector" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/imageinspector-an-image-zoom-pan-component/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Size Text to Container</title>
		<link>http://aaronhardy.com/flex/size-text-to-container/</link>
		<comments>http://aaronhardy.com/flex/size-text-to-container/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 01:46:44 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[auto-size]]></category>
		<category><![CDATA[fit]]></category>
		<category><![CDATA[scale]]></category>
		<category><![CDATA[Text Layout Framework]]></category>
		<category><![CDATA[textflow]]></category>
		<category><![CDATA[TLF]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=598</guid>
		<description><![CDATA[The new Text Layout Framework for Flash Player is a huge improvement over the historic TextField.  Even so, it&#8217;s still not easy to have text auto-size to fit its container(s).  In the demo app below I&#8217;ve implemented one solution that makes the text as large as possible without being cropped.  Go head, [...]]]></description>
			<content:encoded><![CDATA[<p>The new Text Layout Framework for Flash Player is a huge improvement over the historic TextField.  Even so, it&#8217;s still not easy to have text auto-size to fit its container(s).  In the demo app below I&#8217;ve implemented one solution that makes the text as large as possible without being cropped.  Go head, type something in the box.  Right-click the app to get to the source.</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_Main_487746301"
			class="flashmovie"
			width="100%"
			height="200">
	<param name="movie" value="/samples/sizetexttocontainer/Main.swf" />
	<param name="base" value="/samples/sizetexttocontainer/" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/samples/sizetexttocontainer/Main.swf"
			name="fm_Main_487746301"
			width="100%"
			height="200">
		<param name="base" value="/samples/sizetexttocontainer/" />
	<!--<![endif]-->
		
<p><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p>The basic methodology is very similar to the Guess the Number game where you whittle down the options until you get to the one you&#8217;re after.  With a few smart guesses, this can be decently efficient (~20ms).  If you can come up with a more efficient or elegant way to accomplish the same task, post a comment below!</p>
<div class="goodies"><a href="http://github.com/Aaronius/SizeTextToContainer" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/size-text-to-container/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Processes and Responsibility</title>
		<link>http://aaronhardy.com/life-in-general/processes-and-responsibility/</link>
		<comments>http://aaronhardy.com/life-in-general/processes-and-responsibility/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 03:54:49 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Life in General]]></category>
		<category><![CDATA[beaurocracy]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[responsibility]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=571</guid>
		<description><![CDATA[If there&#8217;s one thing I&#8217;ve learned to both love and hate in life it&#8217;s the concept of processes and responsibility.  I&#8217;ve learned they can be either invaluable or detrimental depending on when and how they&#8217;re used.  A few experiences come to mind:
Exhibit A
As a boy scout I remember being taught principles of emergency [...]]]></description>
			<content:encoded><![CDATA[<p>If there&#8217;s one thing I&#8217;ve learned to both love and hate in life it&#8217;s the concept of processes and responsibility.  I&#8217;ve learned they can be either invaluable or detrimental depending on when and how they&#8217;re used.  A few experiences come to mind:</p>
<h3>Exhibit A</h3>
<p>As a boy scout I remember being taught principles of emergency preparedness.  One of the principles stated that, when in an emergency, never say &#8220;Someone call 9-1-1!&#8221;  Instead, point to a specific person and say, &#8220;You&#8211;call 9-1-1!&#8221;</p>
<p>The principle was simple and the difference small, but the effect of assigning specific responsibility could be a matter of life and death.<span id="more-571"></span>  </p>
<p>At my church I&#8217;ve been charged with the role of keeping membership records up to date.  This includes updating the computer system when members move in or out of the church unit, receive or are released from callings, are baptized, are ordained to priesthood offices, etc.  In order to get this information into the computer system, I first must receive or track down the required information.  This is also the most difficult part of what I do.</p>
<p>When I was called to the position, very few, if any, processes existed for this exchange of information.  Soon enough, I began to discover that several baptisms went unrecorded.  The list of callings soon became outdated.  The reason?  A lack of processes and responsibility.</p>
<p>Who was responsible for delivering the information to me?  Or was I responsible for asking someone else?  If I should ask someone else, who should I ask?  Who else needs to know?</p>
<p>When asking the advice of a superior, I received the following instruction.  Forgive me if you&#8217;re not acquainted with LDS lingo.</p>
<p>(1) The clerk should give you the information.<br />
(2) Or one of the bishopric.<br />
(3) Or you could ask the president or secretary of the organization.<br />
(4) Or you could write it down if it&#8217;s announced.</p>
<p>And that&#8217;s also the problem.  Nobody knew who was supposed to do what and everyone thought everyone else was doing it.  More avenues of communication can, and in this case did, actually decrease the effectiveness of communication.  Just like telling everyone to call 9-1-1 in an emergency, a lack of declared responsibility resulted in no responsibility and what should have occurred didn&#8217;t occur at all.</p>
<p>Since then, we&#8217;ve begun a process where a certain form flows from one entity to another until it reaches my box.  This is very effective in helping people know where the buck is&#8211;who currently is responsible for taking the next action.  If everyone does his/her part, the paper should end up in my box and I make the appropriate updates.  Unfortunately, this only covers a portion of the information that needs to be entered into the system, but it&#8217;s a good start.</p>
<h3>Exhibit B</h3>
<p>At work, we use programming frameworks to help out with our application development.  After having worked at the company for six months, I noticed the framework we were using had been patched and plugged one too many times.  In my &#8220;spare&#8221; time, I re-wrote the framework to give us a clean start.  Although I had been charged with providing direction on that specific framework, I wasn&#8217;t ever declared the keeper of frameworks.  Even so, other employees began asking why we weren&#8217;t using X framework or why we weren&#8217;t using Y standard.</p>
<p>Hmm&#8230;interesting question.  The direct answer was probably that the company as a whole never decided otherwise.  But maybe the question was deeper than that.  Maybe the questioner wanted to know my personal thoughts on X framework.  Thoughts I have and thoughts I can share.  Or maybe the questioner wanted to know if we could use X framework?  I don&#8217;t know.  I wouldn&#8217;t mind making that decision, but I wasn&#8217;t really given the authority and frankly I didn&#8217;t want to steal authority from someone who had or thought they had such authority.</p>
<p>Fortunately, the company had some structural reorganization where a co-worker was officially assigned the responsibility of managing frameworks and standards.  The immediate benefits are:</p>
<p>(1) Employees now know who they can lobby for change in frameworks and standards.<br />
(2) The keeper of frameworks and standards knows he/she holds the responsibility and is empowered to effect change.<br />
(3) The concerns and needs regarding frameworks and standards can be represented in appropriate meetings.<br />
(4) The keeper of frameworks and standards can hopefully be recognized for service rendered.</p>
<h3>Exhibit C</h3>
<p>A few years ago I was an intern at ExxonMobil as a software engineer.  Prior to the internship, I was used to start-ups and small businesses where I had a huge amount of control over most aspects of my work.  If I ever needed an application on my computer, I installed it.  No questions asked.</p>
<p>At ExxonMobil, I quickly discovered this wasn&#8217;t going to be the case. We quite literally had one person to set up authentication, one to set up computer hardware, one to set up the operating system, one to set up specific software, one to handle networking, one to handle support requests, and so on.  On top of that, employees would have to funnel required forms through management to get approval for most any action.</p>
<p>My responsibility was to create a business application in ASP.NET.  Incidentally, it was to implement yet another permissions-based process.  To develop the application effectively, I needed Visual Studio on my machine.  The paperwork had already started its journey before I arrived for the internship.  By the end of the internship four months later, there was still no sign of Visual Studio on my machine.  For four months I remote desktopped into a computer residing on another floor of the building that happened to have Visual Studio.  Installing Firefox or the Firebug plugin to debug the application?  There&#8217;s a form for that too.</p>
<p>There was a form for everything.  To be fair, a lot of this &#8220;bureaucracy&#8221; was probably created in an effort to decrease legal risk and avoid yet another Enron scandal.  Even so, the processes really hampered productivity and in the end influenced my decision not to join the company full-time.</p>
<h3>Exhibit D</h3>
<p>Several years back I worked for a company developing user interfaces for in-cab taxi internet and the company&#8217;s website.  I worked directly under two co-founders who, to my knowledge, had the same level of decision-making power.</p>
<p>After developing a portion of the interface, I would show it to co-founder A who would request a change.  I&#8217;d make the change, then show it to co-founder B who would then request a change in the opposite direction.  I&#8217;d make the change, then show it to co-founder A who would request the opposite of what co-founder B requested.  It wasn&#8217;t my intent to go back and forth between the two co-founders; it just so happened that one co-founder would be around when the other wasn&#8217;t.  Rather than sitting around for the co-founder who made the request, I wanted to get quick approval so I could move onto the next task.  This resulted in huge amounts of time going back and forth between opposing demands.</p>
<p>To some extent, this has happened at every job I&#8217;ve held.  It&#8217;s almost inevitable, but the occasions should be few.  In this case, it wasn&#8217;t a huge personal detriment because I was being paid hourly, but the company unnecessarily lost money and nobody likes being unproductive.</p>
<p>Find out who makes the decisions early on and which decisions they make.  If the client doesn&#8217;t know, help them find out.  If you as the consultant have been given decision-making authority, know which decisions that responsibility covers.   And remember&#8211;even if someone has been delegated decision-making responsibility, they still almost always have a boss that can override their decision.  A VP is still subordinate to the CEO.  The CEO is still subordinate to the board of directors.  The board of directors is still subordinate to the shareholders.  The shareholders are still, in effect, subordinate to the customers.  Even if someone has been delegated responsibility, the chances are you&#8217;ll still find someone &#8220;higher-up&#8221; that disagrees.  Know who makes the decisions and be nimble.</p>
<p>Have experiences of your own?  Care to share?</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/life-in-general/processes-and-responsibility/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Universal Health Care: Because You&#8217;re Worth It</title>
		<link>http://aaronhardy.com/politics/universal-health-care-because-youre-worth-it/</link>
		<comments>http://aaronhardy.com/politics/universal-health-care-because-youre-worth-it/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 21:28:30 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Politics]]></category>
		<category><![CDATA[deserve it]]></category>
		<category><![CDATA[insurance]]></category>
		<category><![CDATA[L'Oreal]]></category>
		<category><![CDATA[pre-existing condition]]></category>
		<category><![CDATA[universal health care]]></category>
		<category><![CDATA[worth it]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=545</guid>
		<description><![CDATA[A few months ago my TV told me something that has quite possibly become my favorite product tagline ever.  Whilst L&#8217;Oréal women tossed their hair to and fro in the shimmering light of the photo room, the British, always-sophisticated accent reached out to me with this final bold, convincing statement that absolutely sealed the [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago my TV told me something that has quite possibly become my favorite product tagline ever.  Whilst <a href="http://www.youtube.com/watch?v=84SUfl8Yv4k" target="_blank">L&#8217;Oréal women tossed their hair to and fro</a> in the shimmering light of the photo room, the British, always-sophisticated accent reached out to me with this final bold, convincing statement that absolutely sealed the deal: &#8220;Because you&#8217;re worth it.&#8221;</p>
<p>That&#8217;s right!  I&#8217;m worth it!  I&#8217;m worth L&#8217;Oréal beauty product and nobody can take that away from me.  What else must I need for convincing?  Why buy anything else?  I&#8217;m going bold with L&#8217;Oréal and never coming back because I&#8217;m worth it.</p>
<p>But that&#8217;s not all.  This morning my TV once again reminded me I&#8217;m worth it.<span id="more-545"></span>  CNN, <a href="http://aaronhardy.com/wp-content/uploads/2010/03/osama.jpg" target="_blank">America&#8217;s most trusted news source</a>, interviewed a man in his 50s-ish who decided he was healthy enough to play the odds without health insurance.  That&#8217;s not just my assessment; he literally acknowledged he was playing the odds.  Good for him.  Soon enough, he found out he had a cancerous growth in his neck and the operations to remove it would cost hundreds of thousands of dollars.  Fortunately for him, he found a charitable organization that allowed him to get the operations he needed to remove the cancer.  In the end, it cost the man $50,000 and the rest was paid on his behalf.  What would he have done if that charitable organization did not exist?  Poignant to rip the tears right out of my eyes, he, with some help from the reporter, finished up the interview with his delight that the health care bill passed because nobody should be placed in his situation&#8211;everyone deserves health care.  Everyone deserves it.  You deserve it.  I deserve it.  He deserves it.  Because we&#8217;re all worth it.</p>
<p>Does a gambler deserve to be reimbursed for gambling his life&#8217;s savings away?  Then why does this man, or anyone like this man, <strong>deserve</strong> (<a href="http://en.wiktionary.org/wiki/deserve" target="_blank">to have earned or merited</a>) health care?  For the mere act of breathing sweet air into his lungs?  According to the reporter, this man was able to, and did, pay the $50,000 required of him.  If he could pay $50,000, he could afford insurance.  As <a href="http://www.dennismillerradio.com" target="_blank">Dennis Miller</a> put it so plainly, &#8220;I want to help the helpless, but I could care less about the clueless.&#8221;</p>
<p>I feel bad the guy got cancer.  I don&#8217;t feel bad he&#8217;s out $50,000.  <a href="http://aaronhardy.com/politics/insurance-and-pre-existing-conditions/">If you&#8217;re prepared to gamble, you better be prepared to lose.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/politics/universal-health-care-because-youre-worth-it/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Container Panner</title>
		<link>http://aaronhardy.com/flex/container-panner/</link>
		<comments>http://aaronhardy.com/flex/container-panner/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 04:03:47 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[drag]]></category>
		<category><![CDATA[pan]]></category>
		<category><![CDATA[scroll]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=535</guid>
		<description><![CDATA[In Flex, the ability to scroll a container is commonplace.  The ability to pan a container is not.  By panning a container, I mean clicking down and dragging the content area, effectively scrolling the container.
I present the container panner.  It&#8217;s a single class.  Instantiate it and set the container property.  [...]]]></description>
			<content:encoded><![CDATA[<p>In Flex, the ability to scroll a container is commonplace.  The ability to pan a container is not.  By panning a container, I mean clicking down and dragging the content area, effectively scrolling the container.</p>
<p>I present the container panner.  It&#8217;s a single class.  Instantiate it and set the container property.  That&#8217;s it.  If you want, you can toggle the panning functionality and set custom cursors.  Right-click to view the source.  Go make something crazy.</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_Main_1359619275"
			class="flashmovie"
			width="100%"
			height="300">
	<param name="movie" value="/samples/containerpanner/Main.swf" />
	<param name="base" value="/samples/containerpanner/" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/samples/containerpanner/Main.swf"
			name="fm_Main_1359619275"
			width="100%"
			height="300">
		<param name="base" value="/samples/containerpanner/" />
	<!--<![endif]-->
		
<p><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="goodies"><a href="http://github.com/Aaronius/ContainerPanner" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/container-panner/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
