<?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>Activetuts+ &#187; AIR</title>
	<atom:link href="http://active.tutsplus.com/category/tutorials/air/feed/" rel="self" type="application/rss+xml" />
	<link>http://active.tutsplus.com</link>
	<description>Flash, Flex &#38; ActionScript Tutorials</description>
	<lastBuildDate>Sun, 21 Mar 2010 19:54:54 +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>Create a Drag and Drop MP3 Player with Adobe AIR</title>
		<link>http://active.tutsplus.com/tutorials/air/create-a-drag-and-drop-mp3-player-with-adobe-air/</link>
		<comments>http://active.tutsplus.com/tutorials/air/create-a-drag-and-drop-mp3-player-with-adobe-air/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 12:00:45 +0000</pubDate>
		<dc:creator>Jeremy Green</dc:creator>
				<category><![CDATA[AIR]]></category>

		<guid isPermaLink="false">http://flash.tutsplus.com/?p=2070</guid>
		<description><![CDATA[<img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Preview/preview.jpg" alt="">]]></description>
			<content:encoded><![CDATA[<p>In this tutorial, we&#8217;ll create an AIR drag and drop mp3 player. We&#8217;ll work with the NativeDragManager class to handle the drag and drop, the NativeWindow class for the playlist, and some SQLLite to store information about our mp3 files to build a playlist.</p>
<p><span id="more-2070"></span></p>
<p>	<!-- SWFObject embed by Geoff Stearns geoff@deconcept.com http://blog.deconcept.com/swfobject/ --><br />
	<script type="text/javascript" src="http://flashtuts.s3.amazonaws.com/air_install/swfobject.js"></script></p>
<div class="tutorial_image"  style="height:165px; position:relative">
<p><!-- BEGIN EMBED CODE --></p>
<div id="flashcontent" style="width:215px; height:180px; position: absolute; top: 0; left:115px">
		<strong>Please upgrade your Flash Player</strong>
	</div>
<p>	<script type="text/javascript">
		// <![CDATA[</p>
<p>		// version 9.0.115 or greater is required for launching AIR apps.
		var so = new SWFObject("http://flashtuts.s3.amazonaws.com/air_install/AIRInstallBadge.swf", "Badge", "215", "180", "9.0.115", "#f0f0f0");
		so.useExpressInstall('http://flashtuts.s3.amazonaws.com/air_install/expressinstall.swf');</p>
<p>		// these parameters are required for badge install:
		so.addVariable("airversion", "1.0"); // version of AIR runtime required
		so.addVariable("appname", "Drag and Drop MP3 Player"); // application name to display to the user
		so.addVariable("appurl", "http://flashtuts.s3.amazonaws.com/103_AIRmp3/Source/drag_drop_mp3.air"); // absolute URL (beginning with http or https) of the application ".air" file</p>
<p>		// these parameters are required to support launching apps from the badge (but optional for install):
		so.addVariable("appid", "the app"); // the qualified application ID (ex. com.gskinner.air.MyApplication)
		so.addVariable("pubid", ""); // publisher id</p>
<p>		// this parameter is required in addition to the above to support upgrading from the badge:
		so.addVariable("appversion", "1.0.2"); // AIR application version</p>
<p>		// these parameters are optional:
		so.addVariable("image", "http://flashtuts.s3.amazonaws.com/air_install/installImage.jpg"); // URL for an image (JPG, PNG, GIF) or SWF to display in the badge (205px wide, 170px high)
		so.addVariable("appinstallarg", "installed from web"); // passed to the application when it is installed from the badge
		so.addVariable("applauncharg", "launched from web"); // passed to the application when it is launched from the badge
		so.addVariable("helpurl", "null"); // optional url to a page containing additional help, displayed in the badge's help screen
		so.addVariable("hidehelp", "false"); // hides the help icon if "true"
		so.addVariable("skiptransition", "false"); // skips the initial transition if "true"
		so.addVariable("titlecolor", "#00AAFF"); // changes the color of titles
		so.addVariable("buttonlabelcolor", "#323232"); // changes the color of the button label
		so.addVariable("appnamecolor", "#00AAFF"); // changes the color of the application name if the image is not specified or loaded</p>
<p>		// these parameters allow you to override the default text in the badge:
		// supported strings: str_error, str_err_params, str_err_airunavailable, str_err_airswf, str_loading, str_install, str_launch, str_upgrade, str_close, str_launching, str_launchingtext, str_installing, str_installingtext, str_tryagain, str_beta3, str_beta3text, str_help, str_helptext
		so.addVariable("str_err_airswf", "<u>Running locally?</u><br/><br/>The AIR proxy swf won't load properly when this demo is run from the local file system."); // overrides the error text when the AIR proxy swf fails to load</p>
<p>		so.write("flashcontent");</p>
<p>		// ]]&gt;
	</script></p>
<p><!-- END EMBED CODE --></p>
<p><a href="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Source.zip" target="_blank" style=" position: absolute; top: 60px; left:335px"><br />
<img src="http://flashtuts.s3.amazonaws.com/source.jpg" alt="" style="border:none"></a></p>
<div class="clearfix"></div>
</div>
<h2>Step 1: Create a New AIR Document</h2>
<p>Start Flash, create a new Adobe AIR document and save the document as &#8220;drag_drop_mp3.fla&#8221;.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/1.jpg" alt="" /></div>
<p>If you already have a blank Actionscript 3.0 document open, simply go to Commands &gt; AIR &#8211; Application and Installer Settings. Flash will give an alert saying that it will target all the appropriate files for you. Click &#8220;Ok&#8221; at the prompt, Flash will then show the application publish settings. Click &#8220;Ok&#8221; again and we&#8217;re ready to start.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/2.jpg" alt="" /></div>
<h2>Step 2: Setting up the Stage and Document Class</h2>
<p>Go to File &gt; New and create a new ActionScript file. Save the blank file as &#8220;drag_drop_mp3.as&#8221;. In the &#8220;Properties&#8221; panel, resize the stage to 210 x 110 pixels. Next, in the &#8220;Document class&#8221; text box, type in the name of the newly created actionscript file; leaving out the file extension.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/3.jpg" alt="" /></div>
<h2>Step 3: Creating the Player Background</h2>
<p>Select the rectangle tool. In the rectangle tool options of the &#8220;Properties&#8221; panel, click the lock to unlock the rounded corners option. Enter 5 for the top corners and 0 for the bottom corners. Also, make the fill color black and give the stroke a color of #CCCCCC.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/4.jpg" alt="" /></div>
<p>Next, draw a rectangle that is 200 x 100 pixels. Make sure nothing is selected. Select the bottom line of the stroke and delete it. Now, there should be a rectangle with rounded corners at the top, square corners at the bottom and a stroke that wraps around the top of the rectangle but not the bottom. If the stroke is hanging down past the bottom of the black square, simply double click on the stroke. With the stroke selected, in the &#8220;Properties&#8221; panel, click on &#8220;Cap:&#8221; and select &#8220;None&#8221;. Select the square and stroke, then place them at an x position of 5 and a y position of 2.5.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/5.jpg" alt="" /></div>
<h2>Step 4: Giving the Background its Look and Feel</h2>
<p>Select the entire rectangle and stroke, then hit F8 to convert it into a symbol. Turn it into a Movieclip and give it a name of &#8220;background&#8221;. In the &#8220;Properties&#8221; panel, give the newly created movieclip an instance name of background.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/6.jpg" alt="" /></div>
<p>Double-click on the movieclip to go into edit mode. Select the stroke and go to Edit &gt; Cut to cut the stroke out. Then go to Insert &gt; Timeline &gt; Layer to create a new layer. When the new layer is created, go to Edit &gt; Paste in Place. This will put the stroke on the top layer. Lock the stroke layer. Next, create a new layer and place it between the stroke layer and rectangle layer. Now, select the rectangle, go to Edit &gt; Copy. Select the empty middle layer and &#8220;Paste in Place&#8221; a copy of the rectangle. With the new rectangle selected, change its color to something bright (I use bright green) to remind us that we need to change this color at some point.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/7.jpg" alt="" /></div>
<h2>Step 5: Continuing with the Background</h2>
<p>Now we need to add another layer ontop of the green rectangle layer. In this layer, create a black 5 x 5 circle with no stroke. Hit &#8220;Ctrl-k&#8221; to bring up the align options. With the stage icon selected, align the circle to the top-left corner of the movieclips stage. With the circle selected, hold down &#8220;Alt&#8221; and drag out another instance of the circle. Place the cirlce at 10 for x and 0 for y. Continue to drag new copies of the circle out, placing them 10 pixels apart from each other until you reach the end of the green rectangle.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/8.jpg" alt="" /></div>
<p>Now select all the circles, hold down &#8220;Alt&#8221; and drag down new copies. Offset the x postion of the new circles by 5px and give them a y position of 5. Continue to do this copy/paste technique until the whole green movieclip is covered. Delete any circles that aren&#8217;t covering the green rectangle.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/9.jpg" alt="" /></div>
<p>Next, select all the circles in the layer. With all the circles selected, cut them out of the layer. In the green rectangle layer, &#8220;Paste in Place&#8221; all the circles and deselect everything. This will turn the entire layer into one shape. Now click the keyframe in the green rectangle layer to select everything. With everything selected, hold down &#8220;Shift&#8221; on the keyboard and click the green shape. This will deselect the green rectangle; leaving only the black circles selected. Then hit &#8220;Delete&#8221; to delete the black circles. We now have the top layer of our grate look. To view this, you can turn off the visibility of the black layer underneath.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/10.jpg" alt="" /></div>
<h2>Step 6: Finishing the Background</h2>
<p>The next step is to select the green rectangle. Copy the green rectangle, and &#8220;Paste in Place&#8221; on the bottom black rectangle layer. When you paste the layer, you&#8217;ll probably get some weird empty holes. Just fill in those holes with black using the paint bucket tool.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/11.jpg" alt="" /></div>
<p>When all the black holes are filled, once again make sure nothing is selected, so that the layer will turn everything into one shape. Click on the green part of the layer and delete. Now we should have a bottom layer of holes and the layer above should have the fill.</p>
<p>Next, select the green rectangle in the layer above the black circles. In the &#8220;Color&#8221; panel, select the fill color picker and select the black-to-white circular gradient. Change the color of the white end to #5E5E5E and give it an alpha of 60%. Next, select the black end and give it an alpha of 88% and turn it into a movieclip. Give it an instance name of &#8220;winBack&#8221;. Now in the &#8220;Filters&#8221; panel, click the plus sign and assign it a new bevel filter. Give the bevel 1 for the blur x and y, a strength of 50%, a quality of high, an angle of 210 and a distance of 1. Delete all the empty layers, lock the rest and exit the movieclips editing mode.</p>
<p>On the stage of the main file, select the movieclip and go to the &#8220;Filters&#8221; panel. In the filters panel, give the movieclip a dropshadow. Give the dropshadow 4 for the blur x and y, a strength of 66%, a quality of high, an angle of 90 and a distance of 4.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/12.jpg" alt="" /></div>
<h2>Step 7: Building the Playback Buttons</h2>
<p>Next, select the rectangle tool. In the &#8220;Properties&#8221; panel, make sure that all the rounded corners are locked together with a value of 2.5. Draw out a rectangle that is approximately 28.5 pixels wide and 19.5 pixels in height without any stroke. In the &#8220;Color&#8221; panel, select the linear black-to-white gradient. With the shape selected, hit &#8220;f&#8221; on the keyboard to bring up the &#8220;Gradient Transform Tool&#8221;. Rotate the gradient 90 degrees, so that the white is at the top of the shape. Adjust the color sliders, so that each color is about half way. Now double-click on the little black square and enter in #BFBFBF as the color.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/13.jpg" alt="" /></div>
<p>Select the rectangle shape and convert it to a movieclip. Give it a name of &#8220;buttonBackground&#8221;. Now create a new layer above the background layer. Drag out three instances of the &#8220;buttonBackground&#8221; movieclip. Give the first one an x position of 41.2 and a y position of 76.8. Give the second one an x position of 42.8 and a y position of 76.8. Give the third one an x position of 72.8 and a y position of 76.8. This will align all the buttons to the same y position and slightly space them out.</p>
<p>Next with &#8220;Webdings&#8221; font, the static text tool, and on top of the &#8220;buttonBackground&#8221; movieclip, give the first one the symbol for &#8220;Previous&#8221;. The middle button has the symbol for &#8220;Play&#8221; and the last button has the symbol for &#8220;Next&#8221;. Select all the newly created text boxes, and hit &#8220;Ctrl-b&#8221; until the text is broken into shapes. Select the first &#8220;buttonBackground&#8221; movieclip and the &#8220;Previous&#8221; shape and convert them into a movieclip. Do the same for the other two. Give the left movieclip an instance name of &#8220;prevBtn&#8221;. Next, select the movieclip in the middle and give it an instance name of &#8216;&#8221;playBtn&#8221;. Finally, select the button on the right and give it an instance name of &#8220;nextBtn&#8221;.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/14.jpg" alt="" /></div>
<h2>Step 8: The Playlist Button</h2>
<p>The next step is to create the playlist button. Select the rectangle tool. Give it a rounded corner of 5 and make a shape that is 80.5 pixels in width and 19.9 pixels in height. Give the shape the same fill color as the previously created buttons. Place the shape at 108.2 for x and 76.8 for y. Select the shape and convert it to a movieclip. Inside the new movieclip, select the type tool and create a dynamic text box over the shape that says &#8220;Show Playlist&#8221;. Make the text box 80.3 in width and 16.2 in height with an x position of 0.0 and a y position of 1.8.</p>
<p>Give the text box an instance name of &#8220;ty&#8221;.  Give the movieclip an instance name of &#8220;playToggle&#8221;.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/15.jpg" alt="" /></div>
<h2>Step 9: The Volume Slider</h2>
<p>Now we&#8217;ll create the volume slider. Select the line tool, make sure that the color is set to #999999 and the stroke thickness is 1. Draw a line out that is 45 pixels tall. Select the line and convert it into a movieclip with an instance name of &#8220;volControl&#8221;. Next, double-click the movieclip to enter its edit mode. Copy/paste the line and change the color to white. Move the line over 1 pixel. Next select the rectangle tool and make sure that the rounded corners are set to 0. Draw a rectangle that is 10 pixels wide and 5 pixels in height. Place the rectangle at -4.5 for x and 0 for y. Select the rectangle, convert it into a movieclip and give it an instance name of &#8220;slider&#8221;.</p>
<p>With the &#8220;slider&#8221; movieclip selected, go to the &#8220;Filters&#8221; panel and give it a dropshadow with a 1 for the blur x and y, 66% for its strength, a quality of high, an angle of 90 and a distance of 1. Finally, exit the edit mode of the movieclip and on the stage of the main file, place the &#8220;volControl&#8221; movieclip at 195.6 for x and 45.4 for y.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/16.jpg" alt="" /></div>
<h2>Step 10: Finalizing the Top Half of the App</h2>
<p>The next step is to create two buttons.  The first button is for minimizing the application, and the second is for closing it.</p>
<p>Select the rectangle tool, give the rounded corners a value of 2, and create a square that is 10.9 pixels. Apply the same fill settings as the other buttons on the stage and convert it to a movieclip. Drag out two instances for the new movieclip onto the stage. With the &#8220;Webdings&#8221; font, place the minimize character over one of the movieclips. Break apart the font until it becomes a shape, select both the new shape and the movieclip below it, and convert it to a Button. Give the new button an instance name of &#8216;mini,&#8217; a x position of 178.4 and a y position of 5.5. Do the same process for the second movieclip, only give it a close character, an x position of 190.4 and a y position of 5.5.</p>
<p>Finally, create a blank dynamic text field on the stage. Give the textfield an instance name of &#8220;tf&#8221;, a color of #0000FF, a width of 188, a height of 14.1, a font size of 9, an alignment of center, an x value of 11 and a y value of 20.3.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/17.jpg" alt="" /></div>
<h2>Step 11: Setting up the Play Button</h2>
<p>Next we&#8217;re going to set up the ability to toggle the play button. Double click on the &#8220;playBtn&#8221; movieclip to enter its edit mode. Make sure that the &#8220;Play&#8221; character is on a separate layer. Go to frame 6 on the &#8220;Play&#8221; characters layer and hit F6 to create a new keyframe. Delete the &#8220;Play&#8221; character, and, using the &#8220;Webdings&#8221; font, place a &#8220;Stop&#8221; character there. Break the character apart until it becomes a shape.</p>
<p>Next, click to frame ten and hit F5 on both layers. Now add two more layers above the character layer. On the layer directly above the character layer, place a keyframe on frame 6 and extend it to frame 10. Click back to frame 1, and in the &#8220;Frame&#8221; text box, give it a label of &#8220;play&#8221;. Now click to frame six and give it a label of &#8220;stop&#8221;. Finally, on the top most layer, hit &#8220;F9&#8243; on the keyboard to bring up the actions panel. In the actions panel, type:</p>
<pre name="code" class="javascript">
stop();
</pre>
<p>Now, we&#8217;ll be able to toggle back and forth depending on whether a song is playing or not.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/18.jpg" alt="" /></div>
<h2>Step 12: The Playlist Window</h2>
<p>Let&#8217;s create the playlist window. We&#8217;ll be able to control this window later from actionscript. Go to Insert &gt; New Symbol&#8230; to create a new symbol. Select &#8220;Movie clip&#8221; and give it a name of &#8220;window&#8221;. Next, under &#8220;Linkage&#8221;, check &#8220;Export for ActionScript&#8221; and give it a class name of &#8220;Window&#8221;. Click &#8220;Ok&#8221;, this will bring up a blank stage.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/19.jpg" alt="" /></div>
<p>Next, select the rectangle tool. Now, make sure to unlock the rounded corners. Give the rectangle top corners a value of 0 and the bottom corners 5. Make sure the fill color is black and the stroke color is #CCCCCC. Draw out a rectangle that is 200 pixels wide and 400 pixels tall. Select the rectangle and its stroke, then convert them to a movieclip. Give the movieclip an instance name of &#8220;windowBackground&#8221;. Now double-click on the movieclip to enter its editing mode. Inside the movieclip, go through steps 3 &#8211; 6 again until the  movieclip is similar to the main player&#8217;s background movieclip. Also, just like the first one, make sure to give  the movieclip with the bevel an instance name of &#8220;winBack&#8221;.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/20.jpg" alt="" /></div>
<p>So now, to clarify, inside the &#8220;Window&#8221; class, there should be one movieclip with an instance name of &#8220;windowBackground&#8221;. Inside &#8220;windowBackground&#8221;, there should be a movieclip with an instance name of &#8220;winBack&#8221;. Finally, there should be no instance of the &#8220;Window&#8221; class on the stage at all. This will all be controlled dynamically.</p>
<h2>Step 13: Adding the Datagrid Component</h2>
<p>We&#8217;ll use the datagrid component to control our playlist. In the &#8220;Window&#8221; movieclip class, add a new layer. From the components panel, drag out an instance of the Datagrid. Give it an instance name of &#8220;grid&#8221; and an x position of 10.8 and a y position of 42.5. Resize the datagrid component to a width of 178 and a height of 314.9. Finally, in a new layer under the grid component, create a white rectangle the same size as the datagrid component. This is helpful with any transparency issues that the component has without having to reskin it.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/21.jpg" alt="" /></div>
<h2>Step 14: Finalizing the Design</h2>
<p>The last thing we need to add to the Window is the ability to delete items from out playlist. Drag out a copy of the &#8220;Show Playlist&#8221; button. Give the movieclip an instance name of &#8220;deli&#8221;, an x position of 108.6 and a y position of 366.9. Don&#8217;t worry about the text box saying &#8220;Show Playlist&#8221;, we&#8217;ll control that via actionscript.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/22.jpg" alt="" /></div>
<h2>Step 15: The Document Skeleton</h2>
<p>Open up the blank actionscript file that we created. Here&#8217;s the skeleton for the document class we&#8217;ll be using.</p>
<pre name="code" class="javascript">
package {

	public class drag_drop_mp3 extends Sprite {

		public function drag_drop_mp3()
		{

		}
	}
}
</pre>
<h2>Step 16: The Imports</h2>
<p>Here are the import statements that we&#8217;ll be using..</p>
<pre name="code" class="javascript">
	import fl.controls.DataGrid;
	import fl.data.DataProvider;

	import flash.data.SQLConnection;
	import flash.data.SQLStatement;
	import flash.desktop.Clipboard;
	import flash.desktop.ClipboardFormats;
	import flash.desktop.NativeDragManager;
	import flash.display.MovieClip;
	import flash.display.NativeWindow;
	import flash.display.NativeWindowInitOptions;
	import flash.display.NativeWindowSystemChrome;
	import flash.display.NativeWindowType;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.NativeDragEvent;
	import flash.events.TimerEvent;
	import flash.filesystem.File;
	import flash.filters.DropShadowFilter;
	import flash.media.ID3Info;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundMixer;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.utils.Timer;
</pre>
<h2>Step 17: The Variables</h2>
<p>..and here&#8217;s a list of the variables that we&#8217;ll be using. We&#8217;ll be using an SQLConnection to feed information about our mp3&#8217;s into the SQLLite database. Also, we&#8217;ll be using a sound object to track which song we&#8217;re currently playing. There is also a variable for us to create a NativeWindow object for our playlist. That way we can move the window anywhere on the screen we want, as well as have it be independent of the main window. We also create a tracer variable. This will help keep track of which song is playing.</p>
<pre name="code" class="javascript">
private var connect:SQLConnection;
		private var currentSound:Sound;
		private var yOffset:Number;
		private var st:SoundTransform;
		private var nw:NativeWindow;
		private var window:MovieClip;
		private var tracer:int;
		private var channel:SoundChannel;
		private var tfText:String;
		private var len:int;
</pre>
<h2>Step 18: The Init Functions</h2>
<p>When the app launches, it&#8217;ll call these two functions: init and listeners. The init function calls for the database to be set up, as well as creates the new window instance. Finally, it calls the function that sets buttonModes and visibilty of objects. After the init function, the listeners function is called which adds the event listeners to everything. Most importantly, it calls the NativeDragEvent. This allows us to drag mp3&#8217;s from our desktop (from anywhere really) to the app.</p>
<pre name="code" class="javascript">
public function drag_drop_mp3()
		{
			init();
			listeners();
		}
		private function init():void
		{
			initDB();
			buildWindow();
			initObjects();
		}
private function listeners():void
		{
			closer.addEventListener(MouseEvent.CLICK, handleWindow);
			mini.addEventListener(MouseEvent.CLICK, handleWindow);
			background.addEventListener(MouseEvent.MOUSE_DOWN, moveWindow);
			playToggle.addEventListener(MouseEvent.CLICK, togglePlayList);
			volControl.slider.addEventListener(MouseEvent.MOUSE_DOWN, sliderDown);
			prevBtn.addEventListener(MouseEvent.CLICK, buttonClick);
			playBtn.addEventListener(MouseEvent.CLICK, buttonClick);
			nextBtn.addEventListener(MouseEvent.CLICK, buttonClick);
			this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, dragEnter);
		}
</pre>
<h2>Step 19: The Secondary Init Functions</h2>
<p>Here are the functions that will set up the database, the properties of the objects on the stage and the function that creates a new NativeWindow.</p>
<p>The initObject is fairly self explanatory. I use a try/catch statement just in case the database is empty. In the initDB function, the database file is created, if it doesn&#8217;t already exsist. It then creates a table called &#8220;Playlist&#8221; with three columns; one for the artist, one for the song and the last is for the url of the song. Finally, we create a new instance of the &#8220;Window&#8221; object that we created earlier. The text of the delete button is changed. A dropshadow to match the top portion of the app is created as well. The window is chromeless and it creates a lightweight type of window. That means that the playlist window won&#8217;t have any system chrome and when it&#8217;s opened, there won&#8217;t be any option for it in the toolbar.</p>
<pre name="code" class="javascript">
private function initObjects():void
		{
			background.winBack.mouseEnabled = false;
			playToggle.buttonMode = true;
			playToggle.mouseChildren = false;
			tf.background = true;
			tf.backgroundColor = 0x000000;
			tf.mouseEnabled = false;
			tf.text = "Drag and Drop an MP3 File Here";
			prevBtn.buttonMode = true;
			playBtn.buttonMode = true;
			nextBtn.buttonMode = true;
			st = new SoundTransform(1, 0);
			channel = new SoundChannel();
			try
			{
				currentSound = new Sound(new URLRequest(window.grid.getItemAt(0).Location));
			}
			catch(event:Error)
			{
				//
			}
		}
		private function initDB():void
		{
			var file:File = File.applicationStorageDirectory.resolvePath("playlist.db");
			connect = new SQLConnection();
			connect.open(file);
			var statement:SQLStatement = new SQLStatement();
			statement.sqlConnection = connect;
			statement.text = "CREATE TABLE IF NOT EXISTS PLAYLIST (Artist TEXT, Song TEXT, Location TEXT)";
			statement.execute();
		}
private function buildWindow():void
		{
			var nwo:NativeWindowInitOptions = new NativeWindowInitOptions();
			nwo.maximizable = false;
			nwo.resizable = false;
			nwo.transparent = true;
			nwo.systemChrome = NativeWindowSystemChrome.NONE
			nwo.type = NativeWindowType.LIGHTWEIGHT;
			nw = new NativeWindow(nwo);
			nw.title = "Playlist";
			window = new Window();
			window.deli.ty.text = "Delete";
			window.windowBackground.winBack.mouseEnabled = false;
			window.windowBackground.addEventListener(MouseEvent.MOUSE_DOWN, moveNatWin);
			nw.stage.stageWidth = window.width+10;
			nw.stage.stageHeight = window.height+10;
			nw.stage.scaleMode = StageScaleMode.NO_SCALE;
			nw.stage.align = StageAlign.TOP_LEFT;
			window.filters = [new DropShadowFilter(4, 90, 0x000000, 1, 4 ,4, 0.66, 3)];
			window.x = 5;
			window.y = 0;
			nw.stage.addChild(window);
			setCoords();
			window.grid.addEventListener(Event.CHANGE, gridChange);
			window.deli.addEventListener(MouseEvent.CLICK, deliClick);
			loadData();
		}
</pre>
<h2>Step 20: The Other Functions</h2>
<p>The setCoords function is called when showing the playlist window. It resets the x and y of the playlist window, so that it&#8217;s easier to find when you toggle the visibility. The loadData function selects all the information from the database and populates the datagrid component.</p>
<pre name="code" class="javascript">
private function setCoords():void
		{
			nw.x = stage.nativeWindow.x;
			var theY:Number = (stage.nativeWindow.y + stage.nativeWindow.height)
			nw.y = theY;
		}
private function loadData():void
		{
			var statement:SQLStatement = new SQLStatement();
			statement.sqlConnection = connect;
			statement.text = "SELECT * FROM PLAYLIST";
			statement.execute();
			try
			{
				var dp:DataProvider = new DataProvider(statement.getResult().data);
				window.grid.dataProvider = dp;
			}
			catch(event:Error)
			{
				//
			}
			len = window.grid.length;
		}
</pre>
<h2>Step 21: Handling the Drag and Drop</h2>
<p>The first function, dragEnter, is called when someone tries to drag a file onto the stage. The file checks to see if the extension is correct. If it is, the drag is accepted. If someone decides that they don&#8217;t want to drag a file, the dragExit function is called. It resets the text on the main window of the application. However, if the user picks the right file format and decides that they want to add the file to their playlist, the dragDrop function is called and the sound is loaded.</p>
<pre name="code" class="javascript">
private function dragEnter(event:NativeDragEvent):void
		{
			this.removeEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, dragEnter);
			this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, dragDrop);
			this.addEventListener(NativeDragEvent.NATIVE_DRAG_EXIT, dragExit);
			var clip:Clipboard = event.clipboard;
			var object:Object = clip.getData(ClipboardFormats.FILE_LIST_FORMAT);
			tfText = tf.text;
			if (object[0].extension.toLowerCase() == "mp3")
			{
				NativeDragManager.acceptDragDrop(this);

			tf.text = "GIVE IT TO ME BABY...";
			}
			else
			{
				tf.text = "EWW...GET THAT AWAY FROM ME!";
			}
		}
		private function dragExit(event:NativeDragEvent):void
		{
			this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, dragEnter);
			this.removeEventListener(NativeDragEvent.NATIVE_DRAG_EXIT, dragExit);
			tf.text = tfText;
		}
		private function dragDrop(event:NativeDragEvent):void
		{
			this.removeEventListener(NativeDragEvent.NATIVE_DRAG_EXIT, dragExit);
			this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, dragEnter);
			this.removeEventListener(NativeDragEvent.NATIVE_DRAG_DROP, dragDrop);
			var clip:Clipboard = event.clipboard;
			var object:Object = clip.getData(ClipboardFormats.FILE_LIST_FORMAT);
			var req:URLRequest = new URLRequest(object[0].url);
			var sound:Sound = new Sound();
			sound.addEventListener(Event.COMPLETE, soundLoaded);
			sound.load(req);
			tf.text = "LOADING...";
		}
</pre>
<h2>Step 22: Loading the Sound</h2>
<p>After the sound is loaded, we take the artist and song information from the ID3Info object. We then insert it into the database, as well as the url of the song we just loaded. We then reload the datagrid with the new sound data.</p>
<pre name="code" class="javascript">
private function soundLoaded(event:Event):void
		{
			currentSound = event.target as Sound;
			var id:ID3Info = currentSound.id3;
			var artist:String = id.artist;
			var song:String = id.songName;
			var url:String = currentSound.url
			var statement:SQLStatement = new SQLStatement();
			statement.sqlConnection = connect;
			statement.text = "INSERT INTO PLAYLIST (Artist, Song, Location) VALUES (?, ?, ?)";
			statement.parameters[0] = artist;
			statement.parameters[1] = song;
			statement.parameters[2] = url;
			statement.execute();
			loadData();
			window.grid.selectedIndex = len-1;
			tracer = -1;
			tf.text = "THANK YOU!";
			var timer:Timer = new Timer(1000);
			timer.addEventListener(TimerEvent.TIMER, onTimer);
			timer.start();
		}
		private function onTimer(event:TimerEvent):void
		{
			if(tf.text == "THANK YOU!")
			{
				tf.text = tfText;
			}
			var timer:Timer = event.target as Timer;
			timer.stop();
		}
</pre>
<h2>Step 23: Working with the Button Controls</h2>
<p>We&#8217;ll control the song control buttons with one function. We check to see if the &#8220;playBtn&#8221; was clicked, if so, we check to see which label the button is currently on and, if the currentSound object isn&#8217;t null, we call the playSong function. If one of the other buttons was clicked, we call the appropriate function.</p>
<pre name="code" class="javascript">
private function buttonClick(event:MouseEvent):void
		{
			var mc:MovieClip = event.target as MovieClip;
			var string:String = mc.name;
			switch(string)
			{
				case "playBtn" :
				if(mc.currentLabel == "play")
				{
					try
					{
						playSong(currentSound.url);
					}
					catch(event:Error)
					{
						//
					}
				}
				else
				{
					mc.gotoAndStop("play");
					SoundMixer.stopAll();
				}
				break;
				case "nextBtn" :
				playNextSong();
				break;
				case "prevBtn" :
				playPrevSong();
				break;
			}
		}
</pre>
<h2>Step 24: The Song Functions</h2>
<p>Here are the functions for working with the sound. Both the playNextSong and playPrevSong functions call the handleNextPrev function. This function uses the tracer variable to keep track of which song is playing. The handleNextPrev function then assigns the selected sound to the currentSound object. After that, we call the playSong function. In the playSong function, we tell the datagrid to highlight which song is playing, we set the text field to show the artist and song information from the database, and we listen for the SOUND_COMPLETE event. When the sound is complete, we load the next song.</p>
<pre name="code" class="javascript">
private function playNextSong():void
		{
			if(tracer == len)
			{
				tracer = 0;
			}
			else
			{
				tracer++;
			}
			handleNextPrev();
		}
		private function playPrevSong():void
		{
			if(tracer == 0)
			{
				tracer = len;
			}
			tracer--;
			handleNextPrev();
		}
		private function handleNextPrev():void
		{
			var string:String;
			try
			{
				string = window.grid.getItemAt(tracer).Location;
				currentSound = new Sound(new URLRequest(string));
				SoundMixer.stopAll();
				playSong(string);
			}
			catch(event:Error)
			{
				string = window.grid.getItemAt(0).Location;
				currentSound = new Sound(new URLRequest(string));
				SoundMixer.stopAll();
				playSong(string);
			}
		}
		private function playSong(string:String):void
		{
			try {
				playBtn.gotoAndStop("stop");
				for(var i:int; i&lt;len; i++)
				{
					if(string == window.grid.getItemAt(i).Location)
					{
						tracer = i;
						window.grid.selectedIndex = i;
					}
				}
				var object:Object = window.grid.getItemAt(tracer);
				if(object.Artist == null)
				{
					object.Artist = "";
				}
				if(object.Song == null)
				{
					object.Song = "";
				}
				tf.text = object.Artist + " - " + object.Song;
				channel = currentSound.play();
				channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
			}
			catch(event:Error)
			{
				//
			}
		}
private function onSoundComplete(event:Event):void
		{
			playNextSong();
		}
</pre>
<h2>Step 25: Volume Control</h2>
<p>What good would an mp3 player be without the ability to control the volume? Here we set up the slider to control the volume. We pass the value of the slider to the updateVolume function which updates the volume.</p>
<pre name="code" class="javascript">
private function sliderDown(event:MouseEvent):void
		{
			volControl.slider.removeEventListener(MouseEvent.MOUSE_DOWN, sliderDown);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, sliderMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, sliderUp);
			yOffset = mouseY - event.target.y;
		}
		private function sliderMove(event:MouseEvent):void
		{
			var mc:MovieClip = volControl.slider;
			mc.y = mouseY - yOffset;
			if(mc.y <= 0)
			{
				mc.y = 0;
			}
			else if(mc.y >= (50))
			{
				mc.y = (50);
			}
			updateVolume(mc.y);
			event.updateAfterEvent();
		}
		private function sliderUp(event:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, sliderMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP, sliderUp);
			volControl.slider.addEventListener(MouseEvent.MOUSE_DOWN, sliderDown);
		}
		private function updateVolume(num:Number):void
		{
			var vol:Number = (100 - (num*2))/100;
			SoundMixer.soundTransform = st;
			st.volume = vol;
		}
</pre>
<h2>Step 26: Handling the Main Window</h2>
<p>Here is the functions for controlling the main window. When the mouse is down on the &#8220;background&#8221; movieclip, we call the startMove method of the nativeWindow object. This is why we had to give our grate movieclip an instance name of &#8220;winBack&#8221;; we had to set the mouseEnabled property to false, eliminating any confusion. If we hadn&#8217;t done that, we would only be able to drag on the black circles, not the whole movieclip. The handleWindow function handles both the minimize and close buttons. Also, when we call thaose function, we set some control for our playlist window.</p>
<pre name="code" class="javascript">
private function moveWindow(event:MouseEvent):void
		{
			stage.nativeWindow.startMove();
		}
		private function handleWindow(event:MouseEvent):void
		{
			if(event.target == closer)
			{
				stage.nativeWindow.close();
				nw.close();
			}
			else
			{
				stage.nativeWindow.minimize();
				nw.minimize();
			}
		}
</pre>
<h2>Step 27: The Final Functions</h2>
<p>Here are final functions for our player. When we decide that we no longer want a song on our playlist, we can simply press the delete button to remove the song. When we press the &#8220;deli&#8221; button, we call the deliClick function. The function removes the item from the database, as well as lining up another song if the deleted song was the next song to play. The gridChange function is called everytime we add or remove an item from the database. This way the playlist will always stay up-to-date.</p>
<p>Finally, we need to be able to move the playlist around as well. We can call the moveNatWin function which works the same way as the functions for moving the main player window. Now the playlist can move all over screen without any limitation set by the stage of the main player window.</p>
<pre name="code" class="javascript">
private function deliClick(event:MouseEvent):void
		{
			try
			{
				var statement:SQLStatement = new SQLStatement();
				statement.sqlConnection = connect;
				statement.text = "DELETE FROM PLAYLIST WHERE Location = ?";
				statement.parameters[0] = window.grid.selectedItem.Location;
				var string:String = window.grid.selectedItem.Location;
				var item:int = window.grid.selectedIndex;
				statement.execute();
				loadData();
				if(currentSound.url == string)
				{
					currentSound = new Sound(new URLRequest(window.grid.getItemAt(0).Location));
				}
				len = window.grid.length;
				try
				{
					window.grid.selectedItem = window.grid.getItemAt(item-1);
				}
				catch(event:Error)
				{
					window.grid.selectedItem = window.grid.getItemAt(0);
				}
			} catch (event:Error) {
				//
			}
		}
		private function gridChange(event:Event):void
		{
			var dg:DataGrid = event.target as DataGrid;
			currentSound = new Sound(new URLRequest(dg.selectedItem.Location));
		}
		private function moveNatWin(event:MouseEvent):void
		{
			var mc:MovieClip = event.target as MovieClip;
			var st:Stage = mc.parent.parent as Stage;
			st.nativeWindow.startMove();
		}
</pre>
<h2>Step 28: Publishing the Application</h2>
<p>The final step to this tutorial is to publish your application. Once it is tested and you&#8217;re satisfied with it, go to Commands &gt; AIR &#8211; Application and Installer Settings. Make sure to set the &#8220;Window style&#8221; to &#8220;Custom Chrome (transparent)&#8221;. This way, we can see our dropshadows and the alpha we applied to the window backgrounds.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/103_AIRmp3/Tutorial/23.jpg" alt="" /></div>
<p>Once all your settings are applied, click the publish button, sign the application with our certificate and your new AIR mp3 player is ready to be installed.</p>
<h2>Conclusion</h2>
<p>We covered quite a few new techniques in this tutorial. Each one can be applied in its own way or combined to produce something completely different. I hope this tutorial has sparked some ideas. Read up on AIR in the Adobe LiveDocs and don&#8217;t forget to subscribe to the <a href="http://tutsplus.com/feed">Tuts+ feed</a>. Thanks for reading!</p>
]]></content:encoded>
			<wfw:commentRss>http://active.tutsplus.com/tutorials/air/create-a-drag-and-drop-mp3-player-with-adobe-air/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Build a Custom File Extension AIR App</title>
		<link>http://active.tutsplus.com/tutorials/air/build-a-custom-file-extension-air-app/</link>
		<comments>http://active.tutsplus.com/tutorials/air/build-a-custom-file-extension-air-app/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 12:00:40 +0000</pubDate>
		<dc:creator>Jeremy Green</dc:creator>
				<category><![CDATA[AIR]]></category>

		<guid isPermaLink="false">http://flash.tutsplus.com/?p=1734</guid>
		<description><![CDATA[<img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Preview/preview.jpg" alt="">]]></description>
			<content:encoded><![CDATA[<p>This tutorial will explain how to make your own file extensions in Adobe AIR. I&#8217;ll show you how to build a small application, save the positions of a couple movieclips within it, and reload them when the application is launched.</p>
<p>Follow along and see if you can come up with your own uses for Custom File Extensions..</p>
<p><span id="more-1734"></span></p>
<p>	<!-- SWFObject embed by Geoff Stearns geoff@deconcept.com http://blog.deconcept.com/swfobject/ --><br />
	<script type="text/javascript" src="http://flashtuts.s3.amazonaws.com/air_install/swfobject.js"></script></p>
<div class="tutorial_image"  style="height:165px; position:relative">
<p><!-- BEGIN EMBED CODE --></p>
<div id="flashcontent" style="width:215px; height:180px; position: absolute; top: 0; left:115px">
		<strong>Please upgrade your Flash Player</strong>
	</div>
<p>	<script type="text/javascript">
		// <![CDATA[</p>
<p>		// version 9.0.115 or greater is required for launching AIR apps.
		var so = new SWFObject("http://flashtuts.s3.amazonaws.com/air_install/AIRInstallBadge.swf", "Badge", "215", "180", "9.0.115", "#f0f0f0");
		so.useExpressInstall('http://flashtuts.s3.amazonaws.com/air_install/expressinstall.swf');</p>
<p>		// these parameters are required for badge install:
		so.addVariable("airversion", "1.0"); // version of AIR runtime required
		so.addVariable("appname", "the demo"); // application name to display to the user
		so.addVariable("appurl", "http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Source/saveFile.air"); // absolute URL (beginning with http or https) of the application ".air" file</p>
<p>		// these parameters are required to support launching apps from the badge (but optional for install):
		so.addVariable("appid", "the app"); // the qualified application ID (ex. com.gskinner.air.MyApplication)
		so.addVariable("pubid", ""); // publisher id</p>
<p>		// this parameter is required in addition to the above to support upgrading from the badge:
		so.addVariable("appversion", "1.0.2"); // AIR application version</p>
<p>		// these parameters are optional:
		so.addVariable("image", "http://flashtuts.s3.amazonaws.com/air_install/installImage.jpg"); // URL for an image (JPG, PNG, GIF) or SWF to display in the badge (205px wide, 170px high)
		so.addVariable("appinstallarg", "installed from web"); // passed to the application when it is installed from the badge
		so.addVariable("applauncharg", "launched from web"); // passed to the application when it is launched from the badge
		so.addVariable("helpurl", "null"); // optional url to a page containing additional help, displayed in the badge's help screen
		so.addVariable("hidehelp", "false"); // hides the help icon if "true"
		so.addVariable("skiptransition", "false"); // skips the initial transition if "true"
		so.addVariable("titlecolor", "#00AAFF"); // changes the color of titles
		so.addVariable("buttonlabelcolor", "#323232"); // changes the color of the button label
		so.addVariable("appnamecolor", "#00AAFF"); // changes the color of the application name if the image is not specified or loaded</p>
<p>		// these parameters allow you to override the default text in the badge:
		// supported strings: str_error, str_err_params, str_err_airunavailable, str_err_airswf, str_loading, str_install, str_launch, str_upgrade, str_close, str_launching, str_launchingtext, str_installing, str_installingtext, str_tryagain, str_beta3, str_beta3text, str_help, str_helptext
		so.addVariable("str_err_airswf", "<u>Running locally?</u><br/><br/>The AIR proxy swf won't load properly when this demo is run from the local file system."); // overrides the error text when the AIR proxy swf fails to load</p>
<p>		so.write("flashcontent");</p>
<p>		// ]]&gt;
	</script></p>
<p><!-- END EMBED CODE --></p>
<p><a href="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Source/Source.zip" target="_blank" style=" position: absolute; top: 60px; left:335px"><br />
<img src="http://flashtuts.s3.amazonaws.com/source.jpg" alt="" style="border:none"></a></p>
<div class="clearfix"></div>
</div>
<h2>Step 1: Setting up the Document</h2>
<p>Open a new Flash Air document, name it &#8220;saveFile&#8221;, and save it in a new folder. Then, open a new ActionScript file, give it the same name, and save it into the same folder as the newly created Flash document.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/1.jpg" alt=”” /></div>
<p>If the prompt screen doesn&#8217;t appear when Flash starts, simply create a new Flash ActionScript 3 document.  Save the file, then go to Commands &gt; AIR &#8211; Application and Installer Settings. Flash will convert the file to an Air document.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/2.jpg" alt=”” /></div>
<p>In the properties panel of the Flash document, type &#8220;saveFile&#8221; into the Document class field. This will associate the new ActionScript file (our document class) with the Flash document.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/3.jpg" alt=”” /></div>
<h2>Step 2: Adding the Controls</h2>
<p>Create a black square with a height of 52, set the width to be the stage width, and align it to the bottom-left of the stage. Give the square an alpha of 33. In the components panel, drag out three buttons and place them on top of the black square.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/4.jpg" alt=”” /></div>
<p>Give one of the buttons an instance name of &#8220;open&#8221; and change its label to say &#8220;Open&#8221;. The next button will have an instance name of &#8220;save&#8221; and its label will be &#8220;Save&#8221;. The third buttons name will be &#8220;image&#8221; and have a label of &#8220;Image&#8221;. Spread them out however you want, select all three buttons and the black square and turn them into a single movieclip that has an instance name of &#8220;footer&#8221;.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/5.jpg" alt=”” /></div>
<h2>Step 3: Little Circles</h2>
<p>On the stage, create a red circle with a height and width of 50px. Convert it to a movieclip, then in the dialog box, press the &#8220;Advanced&#8221; button.  Under &#8220;Linkage&#8221; check the &#8220;Export for ActionScript&#8221; box. Give it a class name of &#8220;Red&#8221; and click &#8220;OK&#8221;.</p>
<p>Next, create a blue circle that is the same size as the red circle. Convert it to a movieclip, export it for ActionScript and give it a class name of &#8220;Blue&#8221;. Delete the two circles from the stage, so that the only remaining movieclip is the footer movieclip.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/6.jpg" alt=”” /></div>
<h2>Step 4: Download the Adobe JPEG Encoder</h2>
<p>Go to <a href="http://code.google.com/p/as3corelib/" target="_blank">http://code.google.com/p/as3corelib/</a> and download the as3corelib zip folder. With the JPEG encoder, we&#8217;ll be able to save an image of our little cirlces.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/7.jpg" alt=”” /></div>
<h2>Step 5: The Document Class Skeleton</h2>
<p>This is the basic frame where we&#8217;ll put all our code.</p>
<pre name="code" class="javascript">
package {
	import flash.display.Sprite;

	public class saveFile extends Sprite
	{

		public function saveFile()
		{

		}
	}
}
</pre>
<h2>Step 6: The Imports</h2>
<p>Here are the import statements to make the Air application work. These will go in the file right below the package declaration and above the public class statement.</p>
<pre name="code" class="javascript">
import com.adobe.images.JPGEncoder;

	import flash.desktop.NativeApplication;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.InvokeEvent;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.FileFilter;
	import flash.utils.ByteArray;
</pre>
<h2>Step 7: The Variables and Set up Functions</h2>
<p>Here are the variables that we&#8217;re using to create the two little circles on the stage. The offset variables will be used later for the dragging and dropping of the circles.</p>
<p>I have also assigned an invoke event listener to the NativeApplication. This will fire when the application is either launched or when the custom file is clicked. The invoke function will check to see how the app was launched. If it was from a file, it will load the file.  If not, it will call the init function.</p>
<pre name="code" class="javascript">
public class saveFile extends Sprite
	{
		private var red:MovieClip;
		private var blue:MovieClip;
		private var currentClip:MovieClip;
		private var xOffset:Number;
		private var yOffset:Number;

		public function saveFile()
		{
			NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke);
			movieClips();
			listeners();
		}
		private function init():void
		{
			var sw:int = stage.stageWidth;
			var sh:int = stage.stageHeight-footer.height;
			red.x = sw * Math.random();
			red.y = sh * Math.random();
			blue.x = sw * Math.random();
			blue.y = sh * Math.random();
		}
		private function movieClips():void
		{
			red= new Red();
			blue = new Blue();
			this.addChildAt(red, 0);
			this.addChildAt(blue, 1);
			this.addChildAt(footer, 2);
		}
</pre>
<h2>Step 8: The Listeners Function</h2>
<p>This function simply sets up the event listeners for all the buttons and circles on the stage.</p>
<pre name="code" class="javascript">
private function listeners():void
		{
			red.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			blue.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			footer.open.addEventListener(MouseEvent.CLICK, openClick);
			footer.save.addEventListener(MouseEvent.CLICK, saveClick);
			footer.image.addEventListener(MouseEvent.CLICK, imageClick);
		}
</pre>
<h2>Step 9: Moving the Little Circles</h2>
<p>Here we set up the functions to move the circles around the stage.</p>
<pre name="code" class="javascript">
private function onDown(event:MouseEvent):void
		{
			currentClip = event.target as MovieClip;
			xOffset = mouseX - currentClip.x;
			yOffset = mouseY - currentClip.y;
			currentClip.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
			this.addEventListener(MouseEvent.MOUSE_UP, onUp, false, 0, true);
			this.addEventListener(MouseEvent.MOUSE_MOVE, onMove, false, 0, true);
		}
		private function onMove(event:MouseEvent):void
		{
			currentClip.x = mouseX - xOffset;
			currentClip.y = mouseY - yOffset;
			event.updateAfterEvent();
		}
		private function onUp(event:MouseEvent):void
		{
			this.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
			this.removeEventListener(MouseEvent.MOUSE_UP, onUp);
			currentClip.addEventListener(MouseEvent.MOUSE_DOWN, onDown, false, 0, true);
		}
</pre>
<h2>Step 10: Saving the Image</h2>
<p>When the &#8220;Image&#8221; button is clicked, it will call the &#8220;imageClick&#8221; function. This function opens up a dialog save box and you can give your image any name you want.  When the user names the image, it will call the &#8220;imageSave&#8221; function. Inside that function, we use the JPGEncoder class to create the image.  The Air app then saves the image and listens for the &#8220;onClose&#8221; function.  That function simply reassigns the little circles to the stage from the temp sprite that was created.</p>
<pre name="code" class="javascript">
private function imageClick(event:MouseEvent):void
		{
			var file:File = File.desktopDirectory;
			file.browseForSave("Save Image");
			file.addEventListener(Event.SELECT, imageSave);
		}
		private function imageSave(event:Event):void
		{
			var temp:Sprite = new Sprite();
			var len:int = this.numChildren;
			temp.addChild(red);
			temp.addChild(blue);
			var bitmapData:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
			bitmapData.draw(temp);
			var jpg:JPGEncoder = new JPGEncoder(100);
			var byteArray:ByteArray = jpg.encode(bitmapData);
			var saveFile:File = File(event.target);
			var directory:String = saveFile.url;
			if(directory.indexOf(".jpg") == -1)
			{
				directory += ".jpg";
			}
			var file:File = new File();
			file = file.resolvePath(directory);
			var fileStream:FileStream = new FileStream();
			fileStream.addEventListener(Event.CLOSE, onClose);
			fileStream.openAsync(file, FileMode.WRITE);
			fileStream.writeBytes(byteArray);
			fileStream.close();
		}
		private function onClose(event:Event):void
		{
			this.addChildAt(red, 0);
			this.addChildAt(blue, 1);
		}
</pre>
<h2>Step 11: Saving the File</h2>
<p>After we&#8217;ve moved the little circles around a bit, we can then save their location for further editing. Here we create our custom file. First we put coordinates into an array, then the arrays are put inside an object. The object is written to a file with our custom file extension. You can give it any extension you want.</p>
<p>After that, we set the app to be the default application for the newly created file extension.</p>
<pre name="code" class="javascript">
private function saveClick(event:Event):void
		{
			var file:File = File.desktopDirectory
			file.browseForSave("Save");
			file.addEventListener(Event.SELECT, onSaveSelect);
		}
		private function onSaveSelect(event:Event):void
		{
			var object:Object = {};
			var redArray:Array = [red.x, red.y];
			var blueArray:Array = [blue.x, blue.y];
			object.RED = redArray;
			object.BLUE = blueArray;
			var saveFile:File = File(event.target);
			var directory:String = saveFile.url
			if(directory.indexOf(".tuts") == -1)
			{
				directory += ".tuts";
			}
			var file:File = new File();
			file = file.resolvePath(directory);
			var fileStream:FileStream = new FileStream();
			fileStream.open(file, FileMode.WRITE);
			fileStream.writeObject(object);
			fileStream.close();
			NativeApplication.nativeApplication.setAsDefaultApplication("tuts");
		}
</pre>
<h2>Step 12: Opening the File</h2>
<p>If you want to open your newly created file, simply click the &#8220;Open&#8221; button. A dialog box appears that looks only for that file extension. The app will then read the object inside the file and places the little circles accordingly.</p>
<pre name="code" class="javascript">
private function openClick(event:MouseEvent):void
		{
			var file:File = File.desktopDirectory;
			file.addEventListener(Event.SELECT, onSelect);
			file.browseForOpen("Open",[new FileFilter("Tuts Files (*.tuts)", "*.tuts")]);
		}
		private function onSelect(event:Event):void
		{
			var file:File = File(event.target);
			var fileStream:FileStream = new FileStream();
			fileStream.open(file, FileMode.READ);
			var object:Object = fileStream.readObject();
			red.x = object.RED[0];
			red.y = object.RED[1];
			blue.x = object.BLUE[0];
			blue.y = object.BLUE[1];
			fileStream.close();
		}
</pre>
<h2>Step 13: Invoking the App</h2>
<p>This is the invoke function. Without this function, if you were to launch the application from your new file, it wouldn&#8217;t know to load it. This function checks to see what told it to open.  If it was a file, then it will load that file. If it wasn&#8217;t, then it simply calls the &#8220;init&#8221; function which gives the circles a random placement.</p>
<pre name="code" class="javascript">
private function onInvoke(event:InvokeEvent):void
		{
			if(event.currentDirectory != null &#038;&#038; event.arguments.length > 0)
			{
				var directory:File = event.currentDirectory;
				var file:File = directory.resolvePath(event.arguments[0]);
				var fileStream:FileStream = new FileStream();
				fileStream.open(file, FileMode.READ);
				var object:Object = fileStream.readObject();
				red.x = object.RED[0];
				red.y = object.RED[1];
				blue.x = object.BLUE[0];
				blue.y = object.BLUE[1];
				fileStream.close();
			} else
			{
				init();
			}
		}
</pre>
<h2>Step 14: The Publish Settings</h2>
<p>When the file is all tested and working correctly, we are ready to publish. Go to Commands &gt; AIR &#8211; Application and Installer Settings, and bring up the publish settings.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/8.jpg" alt=”” /></div>
<h2>Step 15: Setting up the Custom File Extension</h2>
<p>In the Air publish settings, click on the advanced settings.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/9.jpg" alt=”” /></div>
<p>It will bring up another dialog box. Click on the &#8220;plus&#8221; button to add a file extension.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/10.jpg" alt=”” /></div>
<p>Fill out the file descriptions, select your custom icons, and click &#8220;OK&#8221; until you&#8217;re back to the first publish settings window.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/11.jpg" alt=”” /></div>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/12.jpg" alt=”” /></div>
<h2>Step 16: Publish Your File</h2>
<p>The last thing to do is to publish your file. Click on the &#8220;Publish AIR File&#8221; button. You will need to create a certificate to sign the app with. Simply click &#8220;Create&#8221; to bring up the settings.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/13.jpg" alt=”” /></div>
<p>Fill out the form and click &#8220;OK&#8221;. Flash will prompt you when the certificate is created. When the certificate is made, enter the password and your file will be created.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/083_AIRCustomExtension/Tutorial/14.jpg" alt=”” /></div>
<h2>Conclusion</h2>
<p>This was just a basic example of what can be done with this technique. You could also create some kind of drawing application where you could either save out what you&#8217;ve drawn, or keep editing it. Or if you wanted to create a custom MP3 player, and have your own playlist file format. The possibilities are endless..</p>
<p>I hope you enjoyed following the tut.</p>
]]></content:encoded>
			<wfw:commentRss>http://active.tutsplus.com/tutorials/air/build-a-custom-file-extension-air-app/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Create Your Own Adobe AIR Application with Flash</title>
		<link>http://active.tutsplus.com/tutorials/air/create-your-own-adobe-air-application-with-flash/</link>
		<comments>http://active.tutsplus.com/tutorials/air/create-your-own-adobe-air-application-with-flash/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 12:00:07 +0000</pubDate>
		<dc:creator>Dario Gutierrez</dc:creator>
				<category><![CDATA[AIR]]></category>

		<guid isPermaLink="false">http://flash.tutsplus.com/?p=1221</guid>
		<description><![CDATA[<img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/preview.jpg" alt="">]]></description>
			<content:encoded><![CDATA[<p>In this tutorial we&#8217;ll create a Twitter Reader application, fed from your own Twitter updates.  We&#8217;ll look at some of the features of the nativeWindow class, how to sign it and make an install package.</p>
<p><span id="more-1221"></span></p>
<div class="tutorial_image">
<a href="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/source.zip" target="_blank"><br />
<img src="http://flashtuts.s3.amazonaws.com/source.jpg" alt="" style="border:none"></a>
</div>
<h3>Final Result Preview</h3>
<p>Let&#8217;s take a look at the final application we&#8217;ll be working towards:</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/final-preview.jpg" /></div>
<h2>Step 1: Install Adobe AIR Runtime</h2>
<p>With this player we can run any application with the .air extension, like the new <a href="http://get.adobe.com/amp/" target="_blank">Adobe Media Player</a>. First we need install the Adobe AIR player, so go to <a href="http://get.adobe.com/AIR/" target="_blank">Adobe and download the player</a>. Choose your operating system and click download. When the download&#8217;s complete, install it.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-1.jpg" alt=""/></div>
<h2>Step 2: Install Adobe AIR Extension for Flash CS3 and CS4</h2>
<p>Now we need our second element to develop AIR applications: the extension. In this case I&#8217;m using the one for Flash CS3 but it&#8217;s available for Flash CS4 too. Go to the Adobe Flash Support Center. Before you install the Flash update for Adobe AIR, you need to  download and install the latest Flash Player update (9.0.2), which you can download here: <a href="http://www.adobe.com/support/flash/downloads.html#902">http://www.adobe.com/support/flash/downloads.html#902</a>.</p>
<p>Then you need to download and install the Adobe AIR Update for Flash CS3 Professional: <a href="http://www.adobe.com/support/flash/downloads.html">http://www.adobe.com/support/flash/downloads.html</a>.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-2.jpg" alt=""/></div>
<h2>Step 3: Document Setup</h2>
<p>At this point, when you start Flash CS3 or CS4, on the welcome screen you&#8217;ll have the option of creating an Adobe AIR Flash file.  Do it! Set the stage size to 300px wide and 500px high with 30 fps. I&#8217;ve chosen a white color  for the background. Save it as &quot;my-twitter-updates.fla&quot;.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-3.jpg" alt=""/></div>
<h2>Step 4: Creating the Background</h2>
<p>We&#8217;re going to use an iPhone image as the background, so go to Sam Brown&#8217;s website (nice vectors) and <a href="http://samgbrown.net/?p=558" target="_blank">download the package of iPhone images</a>. Open the file with Fireworks or Photoshop and choose any size (without text) then export as &quot;bg_iphone.png&quot;. </p>
<p>In Flash, choose File &gt; Import then import the &quot;bg_iphone.png&quot; to stage. Select it and align it vertically and horizontally center. Convert this image to a movieclip symbol  named &quot;mcIphone&quot;, then go to properties and assign &quot;twitterApp&quot; as its instance name. Double-click the symbol and rename the first layer as &quot;bg_iphone&quot;. You should now have something like the following image:</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-4.jpg" alt="" /></div>
<h2>Step 5: Creating the Dynamic Textfields</h2>
<p> Now go and create a new layer for the title of our application. Draw a dynamic text field and assign it &quot;title_app&quot; as an instance name.</p>
<p>Then add two new layers; the first named &quot;my updates&quot; and the second named &quot;follow me&quot;. Create a multiline dynamic text field on the &quot;my updates&quot; layer with the following properties:</p>
<ul>
<li>11 font size</li>
<li>multiline textfield</li>
<li>white color</li>
<li>activate render text as html</li>
<li>assign &quot;myUpdates&quot; as the instance name</li>
</ul>
<p>We&#8217;ll need a button for <em>Follow Me</em> on the &quot;follow me&quot; layer, so go to draw a rectangle at the bottom of the iPhone area and convert it to a button symbol with the text &quot;Follow Me&quot;. Afterwards, assign &quot;btFollowme&quot; as the instance name.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-5.jpg" /></div>
<h2> Step 6: Add Scroll Buttons</h2>
<p>At this point we need two buttons; up and down for scrolling the content of the &quot;my updates&quot; textfield. Go to the timeline panel and add a new layer. Type the name &quot;scroll buttons&quot;, then draw an arrow on stage and convert it to a movieclip symbol. For the other button copy, paste and flip it verticaly. Assign &quot;btUp&quot; and &quot;btDown&quot; as an instance name. Finally, go back to the main timeline. When you finish you should have something like the following image.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-6.jpg" alt=""/></div>
<h2> Step 7: Getting Twitter Feed URL</h2>
<p>Firstly, we need your RSS feed URL, so go to your Twitter home page. Now click on the Profile button in the top bar navigation. Go to the right panel, right-click on &quot;Rss Feed of <em>username</em>&quot; and copy the URL. </p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-7.jpg" alt=""/></div>
<h2>Step 8: Anatomy of Twitter RSS Feed</h2>
<p>Let&#8217;s examine the structure of our Twitter RSS updates. The first part is the  channel rss info  and the second part is the loop of updates. We&#8217;ll use some basics nodes: the link of the first part, title, pubDate and the link of the loop item. </p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-8.jpg" alt=""/></div>
<h2> Step 9: Begin Scripting XML</h2>
<p>Go back to Flash and create a new layer for the actions, it&#8217;s time to start coding. As you can see, the first variable contains the RSS feed URL from your Twitter profile, so paste in yours:</p>
<pre name="code" class="javascript">var twitterURL:String = &quot;http://twitter.com/statuses/user_timeline/16211488.rss&quot;;
  var twitterXML:URLRequest = new URLRequest(twitterURL);
  var myLoader:URLLoader = new URLLoader(twitterXML);
myLoader.addEventListener(&quot;complete&quot;, xmlLoaded);
</pre>
<h2>Step 10: Begin the XmlLoaded Function </h2>
<p>With this function we can load the RSS and each node listed, before starting to define the variables of the xml nodes:</p>
<pre name="code" class="javascript">function xmlLoaded(evtObj:Event) {
var twitter:XML = new XML(myLoader.data);
var TwitterTitle:String = twitter.child(0).description;
var UserUrl:String = twitter.child(0).link;
</pre>
<h2>Step 11: The Updates Loop</h2>
<p>In this part we need to get the values of the xml nodes  and assign them to a myUpdates variable. Use a <em>for statement</em> to do so.</p>
<pre name="code" class="javascript">var myUpdates:String = &quot;&quot;; 

  for each (var nodo:XML in twitter..item) {
  myUpdates += &quot;&lt;a href='&quot;+nodo.link+&quot;'&gt;&lt;font color='#a4917c'&gt;&quot;+nodo.title+&quot;&lt;/font&gt;&lt;/a&gt;&lt;br&gt;&quot;+&quot;&lt;font color='#a4bc34'&gt;&quot;+nodo.pubDate +&quot;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;&quot;;
}</pre>
<h2>Step 12: Text Fields and Event for Follow Button</h2>
<p>First we display the title of the application, then we get the updates and finally add a EventListener for the follow button with the user&#8217;s url (Example: http://twitter.com/_dariux).</p>
<pre name="code" class="javascript">//THE TITLE APP &gt; &quot;Twitter updates from Darío Gutiérrez / _dariux.&quot;
twitterApp.titleApp.text = TwitterTitle; 

//Display the value of myUpdates into the textfield
twitterApp.myUpdates.htmlText = myUpdates; 

//Actions for Follow Me button
twitterApp.btFollowme.addEventListener(MouseEvent.CLICK, btFollowme_CLICK);

  function btFollowme_CLICK(e:MouseEvent):void{
  var targetURL:URLRequest = new URLRequest(UserUrl);
  navigateToURL(targetURL);
  } 

  }</pre>
<h2>Step 13: Actions for the Scroll Buttons</h2>
<p>Simple code for the scroll buttons, check this code:</p>
<pre name="code" class="javascript">//Listeners and functions for scroll buttons
  twitterApp.btUp.addEventListener(MouseEvent.CLICK, scrollUp);
twitterApp.btDown.addEventListener(MouseEvent.CLICK, scrollDown);

  function scrollUp(Event:MouseEvent):void {
  twitterApp.myUpdates.scrollV -=5;
  }

  function scrollDown(Event:MouseEvent):void {
  twitterApp.myUpdates.scrollV +=5;
  }</pre>
<h2>Step 14: Testing the Application</h2>
<p>Test the movie (Menu Control + Test movie or cmd + enter). As you can see, it&#8217;s a normal window just as when you use the typical flash player. In the following step we&#8217;ll customize our application and you&#8217;ll notice the difference..</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-9.jpg" alt=""/></div>
<h2>Step 15: Application and Installer AIR Settings</h2>
<p>For the AIR Settings in Flash CS4 go to File &gt; AIR Settings and for Flash CS3 go to Commands &gt; AIR Application and Installer Settings. In this window we&#8217;ll begin to customize the application, so let&#8217;s go to the description field and write some general info. </p>
<p><strong>Window Style</strong> <br />
The Window Style is interesting. There are three styles: chrome, opaque and transparent. The Chrome style is like a simple window with buttons, background and border, the Opaque is a window with background but without buttons and the last style Transparent is a window without buttons and background. In our case, choose the Transparent style.</p>
<p><strong>Icon</strong><br />
Choose an icon (or design one) for your application in differents sizes 16px, 32px, 48px, 128px with .png extension.</p>
<p><strong>Advanced</strong><br />
In this option you can select the differents settings for the window when your application is launched, options for folders to install and updates.</p>
<p><strong>Digital Signature</strong><br />
When you want to ship your AIR application, you&#8217;ll need a digital signature for the installer to install in other user&#8217;s systems. In this case we&#8217;ll sign our application with untrusted certificate to allow  runtime AIR to install as Unverified publisher. If you need more details on how to get a certificate visit the following link: <a href="http://www.adobe.com/devnet/AIR/articles/signing_AIR_applications_print.html" target="_blank">Digitally signing Adobe AIR applications</a>.</p>
<p><strong>Destination</strong> <br />
Choose the folder destination and a name for your application.</p>
<p><strong>Include files</strong> <br />
Automatically Flash selects some files that are needed to run the application. If you are using other files in your app (like a caurina tween for example) you must include these files as part of the app.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-10.jpg" alt=""/></div>
<h2>Step 17: Scripting Window Move</h2>
<p>In this part we&#8217;ll use the &quot;NativeWindow&quot; class and the function &quot;startMove()&quot;, to allow our application to move across the whole stage. Go to the actions layer and add the following code. Then test it:</p>
<pre name="code" class="javascript">stage.addEventListener(MouseEvent.MOUSE_DOWN, moveWin);

  function moveWin(e:MouseEvent):void
  {
  stage.nativeWindow.startMove();
  }</pre>
<h2>Step 18: Close and Minimize Buttons</h2>
<p>Now our application can move over the whole stage, but if you want to close or minimize, you can&#8217;t. Go and design two buttons: minimize (btMinimize instance name) and close (btClose instance name) such as the next picture, but this time you must use the main movie clip (twitterApp). Finally, add the following code:</p>
<pre name="code" class="javascript">//Minimize button
  twitterApp.btMinimize.addEventListener(MouseEvent.CLICK, btMinimize_CLICK);
  function btMinimize_CLICK(e:MouseEvent):void
  {
stage.nativeWindow.minimize();
}

  //Maximize button
  twitterApp.btClose.addEventListener(MouseEvent.CLICK, btClose_CLICK);
  function btClose_CLICK(e:MouseEvent):void
  {
  stage.nativeWindow.close();
  }</pre>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-11.jpg" alt=""/></div>
<h2>Step 19: Always in Front Feature</h2>
<p>This feature is very simple. Just add a button below the Follow Me button, so it creates a new layer inside the  main movieclip &quot;twitterApp&quot;. Write &quot;btAlwaysfront&quot; as an instance name:</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-12.jpg" alt=""/></div>
<p>Once you&#8217;ve created this button, go inside and create another frame, each one with a stop action. The objective is to have two states for the button. Frame one <strong>deactivated</strong> and the second frame <strong>activated</strong>. This feature uses the <strong>alwaysInFront</strong> method from the nativeWindow class. After this we must add the actions to the btAlwaysfront button, so go to actions frame and paste the following code:</p>
<pre name="code" class="javascript">//Activate window always front
  stage.nativeWindow.alwaysInFront=false;
  twitterApp.btAlwaysfront.addEventListener(MouseEvent.CLICK, btAlwaysfront_CLICK);
  function btAlwaysfront_CLICK(e:MouseEvent):void
  {
if ( stage.nativeWindow.alwaysInFront!=true){
twitterApp.btAlwaysfront.gotoAndStop(2);
stage.nativeWindow.alwaysInFront=true;
}else{
twitterApp.btAlwaysfront.gotoAndStop(1);
stage.nativeWindow.alwaysInFront=false;
} 

}</pre>
<h2>Step 20: The Complete Code</h2>
<pre name="code" class="javascript">//Twitter rss url
  var twitterURL:String = &quot;http://twitter.com/statuses/user_timeline/16211488.rss&quot;;
  var twitterXML:URLRequest = new URLRequest(twitterURL);
  var myLoader:URLLoader = new URLLoader(twitterXML);
  myLoader.addEventListener(&quot;complete&quot;, xmlLoaded);

  function xmlLoaded(evtObj:Event) {
  var twitter:XML = new XML(myLoader.data);
  var TwitterTitle:String = twitter.child(0).description;
  var UserUrl:String = twitter.child(0).link; 

  var myUpdates:String = &quot;&quot;; 

  //The loop 

  for each (var nodo:XML in twitter..item) {
  myUpdates += &quot;&lt;a href='&quot;+nodo.link+&quot;'&gt;&lt;font color='#a4917c'&gt;&quot;+nodo.title+&quot;&lt;/font&gt;&lt;/a&gt;&lt;br&gt;&quot;+&quot;&lt;font color='#a4bc34'&gt;&quot;+nodo.pubDate +&quot;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;&quot;;
  } 

  //THE TITLE APP &gt; &quot;Twitter updates from Darío Gutiérrez / _dariux.&quot;
  twitterApp.titleApp.text = TwitterTitle; 

  //Display the valor of myUpdates into the  textfield
  twitterApp.myUpdates.htmlText = myUpdates; 

  //Actions for Follow Me button
  twitterApp.btFollowme.addEventListener(MouseEvent.CLICK, btFollowme_CLICK);

  function btFollowme_CLICK(e:MouseEvent):void{
  var targetURL:URLRequest = new URLRequest(UserUrl);
  navigateToURL(targetURL);
  } 

  }

  /******************************************************
  Listeners and functions for scroll buttons
  ******************************************************/
  twitterApp.btUp.addEventListener(MouseEvent.CLICK, scrollUp);
  twitterApp.btDown.addEventListener(MouseEvent.CLICK, scrollDown);

  function scrollUp(Event:MouseEvent):void {
  twitterApp.myUpdates.scrollV -=5;
  }

  function scrollDown(Event:MouseEvent):void {
  twitterApp.myUpdates.scrollV +=5;
  } 

/******************************************************
  AIR Zone
  ******************************************************/
  //Window move
  stage.addEventListener(MouseEvent.MOUSE_DOWN, moveWin);

  function moveWin(e:MouseEvent):void
  {
  stage.nativeWindow.startMove();
  } 

  //Minimize button
  twitterApp.btMinimize.addEventListener(MouseEvent.CLICK, btMinimize_CLICK);
  function btMinimize_CLICK(e:MouseEvent):void
  {
  stage.nativeWindow.minimize();
  }

  //Maximize button
  twitterApp.btClose.addEventListener(MouseEvent.CLICK, btClose_CLICK);
  function btClose_CLICK(e:MouseEvent):void
  {
  stage.nativeWindow.close();
  } 

  //Activate window always front
  stage.nativeWindow.alwaysInFront=false;
  twitterApp.btAlwaysfront.addEventListener(MouseEvent.CLICK, btAlwaysfront_CLICK);
  function btAlwaysfront_CLICK(e:MouseEvent):void
  {
if ( stage.nativeWindow.alwaysInFront!=true){
twitterApp.btAlwaysfront.gotoAndStop(2);
stage.nativeWindow.alwaysInFront=true;
}else{
twitterApp.btAlwaysfront.gotoAndStop(1);
stage.nativeWindow.alwaysInFront=false;
} 

}</pre>
<h2>Step 21: Creating the AIR File</h2>
<p>To publish your .air file in <strong>flash CS4</strong> go to File  &gt; AIR Settings menu and click on the &quot;Publish AIR file button&quot;.</p>
<p>For <strong>flash CS3</strong> go to  Commands &gt; AIR &#8211; Create AIR File.</p>
<p>Then you&#8217;ll see a new window (the Digital Signature). Choose a certificate and type your password. It takes some time to create the .air file, but when finisedh you&#8217;ll see another window with the following text &quot;AIR file has been created&quot;. The .air file is created in the same work directory as your .fla file.</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/-13.jpg" alt=""/></div>
<h2>Step 22: Final details</h2>
<p>As you can see, my app has a drop shadow. If you want a mac windows style just select the main movie clip &quot;twitterApp&quot; and apply:</p>
<div class="tutorial_image"><img src="http://flashtuts.s3.amazonaws.com/063_AIRTwitterReader/final-preview.jpg" /></div>
<h2>Conclusion</h2>
<p>So there we have our AIR application! It&#8217;s a little application, but I hope it helps you as a reference to developing your own. With this technology we can develop awesome applications, mashable with APIs like Twitter, Gmaps and Flickr. There are many other features not covered in this tutorial, plenty of scope for a future tutorial or quick guide! Thanks for reading.</p>
]]></content:encoded>
			<wfw:commentRss>http://active.tutsplus.com/tutorials/air/create-your-own-adobe-air-application-with-flash/feed/</wfw:commentRss>
		<slash:comments>55</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.250 seconds -->
