logo
468x60-2-495


  • Home
  • Privacy Policy
  • About
search
Dec 31, 2010 Posted on Dec 31, 2010 in Flash Video Training | 1 comment

The Elastic Trick -performance and tutorial


Trick- Using an elastic you can find the spectator’s card in a flash! Tutorial- Watch & learn!

Dec 31, 2010 Posted on Dec 31, 2010 in Hints and Tips | 2 comments

A Nostalgic Rummage Through the History of Flash

New Year’s Eve is a time for reflection. A time when the nostalgic amongst us can whip out the photo album and revel in how things used to be. With that in mind, let’s use this opportunity to put silly hats on, dive into the archives and take a look at Flash; from its conception, through to its more familiar adulthood.

Note: Documentation from version 1 to version 9 alpha – a.k.a. CS3

If you ever think Flash is difficult to use, you should try drawing with a joystick on an Apple II before the concept of undo was invented. That will test your patience.

-Jonathan Gay, Father of Flash.


How it All Began

The story as described by Jonathan Gay, the Creator of Flash.

Jonathan Gay grew up playing with LEGO blocks when there were no LEGO men or whales or complicated accessory packs – just rectangular blocks and a few wheels. LEGO taught him the basics of engineering design. Even better, they helped him to express his early passion for building things…

About that time, he got an Apple II computer. As he began to program, he quickly discovered that with computer software you can design something that will work and respond to you. His first game was a Space Invaders clone in Apple II Basic.

After dabbling with games, he returned to building graphics editors. He added PostScript style drawing to a Macintosh product called SuperPaint II while still in college.

A company called Go was building an operating system. So in January of 1993, Jonathan convinced Charlie Jackson to invest some money and the two of them started FutureWave Software to dominate the market for graphics software on pen computers (computers whose screens could be written on using an electronic stylus).

He imagined drawing with a pen on a computer screen would be a fantastic improvement. So Jonathan and Charlie set out to build SmartSketch, software that would make drawing on the computer easier than drawing on paper. In the meantime, AT&T bought Go. In January 1994, just as they were about to ship their product, AT&T pulled the plug on Go and left them without a market. They did actually make a few sales of SmartSketch.

The failure of Go and pen computing was a big setback for the two of them. The only opportunity they saw was to take their software and make it run on Windows and the Macintosh. Jonathan and Charlie did it, but now they were competing against Illustrator and FreeHand.

SmartSketch would never replace high-end paint or illustration programs, but it was an appealing tool for professional artists and illustrators, who could use it with other programs.

Jonathan and Charlie were at SIGGRAPH In 1995, and got lots of feedback from people that they should turn SmartSketch into an animation product. They were starting to hear about the Internet and the Web, and it seemed possible that the Internet would become popular enough that people would want to send graphics and animation over it. So they began to add animation to SmartSketch..

They renamed the program CelAnimator, “CelAnimator is based on FutureWave Software’s award-winning SmartSketch drawing technology. It will allow users, for the first time, to create vector-based drawings and buttons and then animate them. Both the drawings and the animations can be placed on HTML Web pages..”

Source: Press Release http://www.highbeam.com/doc/1G1-18238250.html

FutureWave Software renames CelAnimator to FutureSplash Animator; new name reflects broader market and wide variety of Internet browser support.

Source: Press Release http://www.highbeam.com/doc/1G1-18238250.html

At the time, the only way to extend a Web browser to play back animation was through Java. So Jonathan and his friend wrote a simple animation player that used Java and was horribly slow. They stubbornly kept at it though, and in the fall, Netscape came out with their plug-in API. Finally, they had a way to extend the Web browser with decent performance (this was the ancestor of Macromedia Flash Player).

Their big success came in August of 1996. Microsoft was working on MSN and wanted to create the most TV-like experience on the Internet. They became big fans of FutureSplash and adopted the technology. Their other high-profile client was Disney Online. They were using FutureSplash to build animation and the user interface for the Disney Daily Blast. Disney was also working with Macromedia Shockwave.

Source: Macromedia info http://en.wikipedia.org/wiki/Macromedia

In November of 1996, Macromedia had heard enough about them through their relationship with Disney and approached them about working together. At the time, Jonathan and Charlie had been running FutureWave for four years with a total investment of $500,000, and the idea of having a larger company’s resources to help them get FutureSplash established seemed like a good one.

In December 1996, they sold FutureWave Software to Macromedia, and FutureSplash Animator became Macromedia Flash 1.0: a contraction of "Future" and "Splash".

Macromedia originated in the 1992 merger of Authorware Inc. (makers of Authorware) and MacroMind-Paracomp (makers of Macromind Director). Director, an interactive multimedia-authoring tool widely used to make CD-ROMs and information kiosks which lives on today, served as Macromedia’s flagship product until the mid-1990s. As the CD-ROM market began to decline and the World Wide Web gained in popularity, Macromedia created Shockwave, a Director-viewer plug-in for Web browsers, but decided it also needed to expand its market by branching out into web-native media tools.

Macromedia developed all versions of Flash from v1 to v8, although after version 5 they temporarily stopped using straightforward numbering: the sixth version was called Flash MX and the seventh was Flash MX 2004.

In June 6, 2005 Macromedia announced the unveiling of the Macromedia Flash Platform “for delivering the most effective experiences for rich content, applications, and communications across browsers, operating systems, and devices of all kinds. The Flash Platform provides the solutions that make great digital experiences possible. It is a proven technology that companies and institutions such as America Online, SAP, Wharton, and Yahoo! have adopted for their diverse needs.”

Source: http://www.adobe.com/macromedia/proom/pr/2005/unveiling_flashplatform.html

On April 18 2005, Adobe acquired Macromedia in an all-stock transaction, for approximately $3.4 billion.

Source: http://www.adobe.com/aboutadobe/invrelations/adobeandmacromedia.html

Adobe was founded in December 1982 by John Warnock and Charles Geschke, who established the company after leaving Xerox PARC in order to develop and sell the PostScript page description language. In 1985, Apple Computer licensed PostScript for use in its LaserWriter printers, which helped spark the desktop publishing revolution. The company name Adobe comes from Adobe Creek in Los Altos, California, which ran behind the house of one of the company’s founders. Adobe acquired its former competitor, Macromedia, in December 2005, which added newer software products and platforms such as Coldfusion, Dreamweaver, Flash and Flex to its product portfolio.

Source: http://en.wikipedia.org/wiki/Adobe_Systems

Macromedia Flash become Adobe Flash from the CS3 Edition (V9, which was released in 2007) onwards.

Adobe celebrated the tenth anniversary of Flash by launching a microsite.

Source: http://www.adobe.com/designcenter/dialogbox/flash_anniversary/

Source: 10th Flash anniversary by Nectarine (animation) http://flash10.nectarine.com.au

Click to enlarge

A quick tour of Flash’s Genealogy Tree!


Source: http://en.wikipedia.org/wiki/Adobe_Flash


Zoom In: Flash

Release Year Description
FutureSplash Animator 1996 initial version of Flash with basic editing tools and a timeline
Macromedia Flash 1 1996 a Macromedia re-branded version of the FutureSplash Animator
Macromedia Flash 2 1997 Released with Flash Player 2, new features included: the object library
Macromedia Flash 3 1998 Released with Flash Player 3, new features included: the movieclip element, JavaScript plug-in integration, transparency and an external stand alone player
Macromedia Flash 4 1999 Released with Flash Player 4, new features included: internal variables, an input field, advanced ActionScript, and streaming MP3
Macromedia Flash 5 2000 Released with Flash Player 5, new features included: ActionScript 1.0 (based on ECMAScript, making it very similar to JavaScript in syntax), XML support, Smartclips (the precursor to components in Flash), HTML text formatting added for dynamic text
Macromedia Flash MX(6) 2002 Released with Flash Player 6, new features included: a video codec (Sorenson Spark), Unicode, v1 UI Components, compression, ActionScript vector drawing API
Macromedia Flash MX 2004(7) 2003 Released with Flash Player 7, new features included: Actionscript 2.0 (which enabled an object-oriented programming model for Flash, although it lacked the Script assist function of other versions, meaning Actionscript could only be typed out manually), behaviors, extensibility layer (JSAPI), alias text support, timeline effects. Macromedia Flash MX Professional 2004 included all Flash MX 2004 features, plus: Screens (forms for non-linear state-based development and slides for organizing content in a linear slide format like PowerPoint), web services integration, video import wizard, Media Playback components (which encapsulate a complete MP3 and/or FLV player in a component that may be placed in an SWF), Data components (DataSet, XMLConnector, WebServicesConnector, XUpdateResolver, etc.) and data binding APIs, the Project Panel, v2 UI components, and Transition class libraries.
Macromedia Flash 8 2005 Macromedia Flash Basic 8, a less feature-rich version of the Flash authoring tool targeted at new users who only want to do basic drawing, animation and interactivity. Released with Flash Player 8, this version of the product has limited support for video and advanced graphical and animation effects. Macromedia Flash Professional 8 added features focused on expressiveness, quality, video, and mobile authoring. New features included Filters and blend modes, easing control for animation, enhanced stroke properties (caps and joins), object-based drawing mode, run-time bitmap caching, FlashType advanced anti-aliasing for text, On2 VP6 advanced video codec, support for alpha transparency in video, a stand-alone encoder and advanced video importer, cue point support in FLV files, an advanced video playback component, and an interactive mobile device emulator.

Source: Wikipedia http://en.wikipedia.org/wiki/ActionScript


Zoom In: ActionScript

  • Flash Player 2: The first version with scripting support. Actions included gotoAndPlay, gotoAndStop, nextFrame and nextScene for timeline control.
  • Flash Player 3: Expanded basic scripting support with the ability to load external SWFs (loadMovie).
  • Flash Player 4: First player with a full scripting implementation (called Actions). The scripting was a flash based syntax and contained support for loops, conditionals, variables and other basic language constructs.
  • Flash Player 5: Included the first version of ActionScript. Used prototype-based programming based on ECMAScript, and allowed full procedural programming and object-oriented programming.
  • Flash Player 6: Added an event handling model, accessibility controls and support for switch. The first version with support for the AMF and RTMP protocols which allowed for on demand audio/video streaming.
  • Flash Player 7: Additions include CSS styling for text and support for ActionScript 2.0, a programming language based on the ECMAScript 4 Netscape Proposal with class-based inheritance. However, ActionScript 2.0 can cross compile to ActionScript 1.0 byte-code, so that it can run in Flash Player 6.
  • Flash Player 8: Further extended ActionScript 1/ActionScript 2 by adding new class libraries with APIs for controlling bitmap data at run-time, file uploads and live filters for blur and dropshadow.
  • Flash Player 9 (initially called 8.5): Added ActionScript 3.0 with the advent of a new virtual machine, called AVM2 (ActionScript Virtual Machine 2), which coexists with the previous AVM1 needed to support legacy content. Performance increases were a major objective for this release of the player including a new JIT compiler. Support for binary sockets, E4X XML parsing, TR1 = LIXO full-screen mode and Regular Expressions were added. This is the first release of the player to be titled Adobe Flash Player.
  • Flash Player 10 (initially called Astro): Added basic 3D manipulation, such as rotating on the X, Y, and Z axis, and a 3D drawing API. Ability to create custom filters using Adobe Pixel Bender. Several visual processing tasks are now offloaded to the GPU which gives a noticeable decrease to rendering time for each frame, resulting in higher frame rates, especially with H.264 video. There is a new sound API which allows for custom creation of audio in flash, something that has never been possible before.Furthermore, Flash Player 10 supports Peer to Peer (P2P) communication with Real Time Media Flow Protocol (RTMFP).
  • Flash Player 10.1: Particularly notable for being able to be run on Android mobile devices, while maintaining all the features of the regular Flash Player.

Source: Wikipedia http://en.wikipedia.org/wiki/ActionScript


Zoom In: Flash Lite

Adobe Flash Lite is a lightweight version of Adobe Flash Player, a software application published by Adobe Systems.

  • Flash Lite 1.0: Flash Lite is the Flash technology specifically developed for mobile phones and consumer electronics devices. Supports Flash 4 ActionScript.
  • Flash Lite 1.1: Flash 4 ActionScript support and additional device APIs added.
  • Flash Lite 2.0 and 2.1: Added support for Flash 7 ActionScript 2.0 and some additional fscommand2 API.
  • Flash Lite 3: Added support for Flash 8 ActionScript 2.0 and also FLV video playback.
  • Flash Lite 4: Added support for Flash 10 ActionScript 3.0 as a browser plugin and also hardware graphics acceleration.

Flash Showcase: Packaging

Macromedia Flash 1

Macromedia Flash 2

Macromedia Flash 3

Macromedia Flash 4

Macromedia Flash 5

Macromedia Flash MX

Macromedia Flash MX2004

Macromedia Flash 8 Basic

Macromedia Flash 8 Professional


Flash Showcase: Logos

FutureWave FutureSplash

From Macromedia Flash 1 to Macromedia Flash 5

Macromedia Flash MX & Macromedia Flash MX2004

Macromedia Flash 8


Flash Showcase: Splashes

Futurewave Future Splash / Macromedia Flash 1

Macromedia Flash 2

Macromedia Flash 3

Macromedia Flash 4

Macromedia Flash 5

Macromedia Flash MX

Macromedia Flash MX 2004 Basic

Macromedia Flash 8 Basic

Macromedia Flash 8 Professional

Adobe Flash 9 Professional ActionScript 3 Public Alpha


Flash Showcase: User Interface

Futurewave Future Splash / Macronedia Flash 1

Macromedia Flash 2

Macromedia Flash 3

Macromedia Flash 4

Macromedia Flash 5

Macromedia Flash MX

Macromedia Flash MX 2004

Macromedia Flash 8

Adobe Flash 9 Public Alpha


Flash Showcase: About Box and Full UI

Futurewave Future Splash / Macronedia Flash 1

Macromedia Flash 2

Click to enlarge

Macromedia Flash 3

Click to enlarge

Macromedia Flash 4

Click to enlarge

Macromedia Flash 5

Click to enlarge

Macromedia Flash MX

Click to enlarge

Macromedia Flash MX 2004

Click to enlarge

Macromedia Flash 8

Click to enlarge

Adobe Flash 9 Public Alpha

Click to enlarge

Flash Showcase: Icons

Icons used by Flash, from version 1 to version 8

Macromedia Flash 2 / Macromedia Flash 3

Macromedia Flash 4 / Macromedia Flash 5

Macromedia Flash MX

Macromedia Flash MX2004

Macromedia Flash 8


Flash Showcase: Flash Player

Futurewave Future Splash Player / Macronedia Flash Player 1

Macromedia Flash Player 2

Macromedia Flash Player 3

Macromedia Flash Player 4

Macromedia Flash Player 5

Macromedia Flash Player 6

Macromedia Flash Player 7

Macromedia Flash Player 8

Adobe Flash Player 9


Flash Showcase: Get Flash Player Icons


And Voilà!

Thank you for reading. I hope you find this information useful and please leave any interesting Flash tidbits you know of in the comments!

Complete List of Resources:

  • http://www.adobe.com/macromedia/events/john_gay/
  • http://www.highbeam.com/doc/1G1-17103165.html
  • http://www.flashmagazine.com/news/detail/the_flash_history/ (ScreenShots)
  • http://www.highbeam.com/doc/1G1-18238250.html
  • http://www.highbeam.com/doc/1G1-18572981.html
  • http://en.wikipedia.org/wiki/Adobe_Flash
  • http://en.wikipedia.org/wiki/Macromedia
  • http://www.adobe.com/macromedia/proom/pr/2005/unveiling_flashplatform.html
  • http://www.adobe.com/newsletters/edge/july2005/
  • http://www.adobe.com/aboutadobe/invrelations/adobeandmacromedia.html
  • http://en.wikipedia.org/wiki/Adobe_Systems
  • http://www.adobe.com/stories/
  • http://www.adobe.com/products/flash/special/flashanniversary/microsite/
  • http://flash10.nectarine.com.au/
  • http://en.wikipedia.org/wiki/Adobe_Flash
  • http://en.wikipedia.org/wiki/Adobe_Flash_Lite
  • Flash Screenshots made by Yassine Bouhlel from trial versions with Adobe Fireworks



View full post on Activetuts+

Dec 31, 2010 Posted on Dec 31, 2010 in Flash Video Training | 7 comments

How to manually back up your MySQL databases from PHPMyAdmin


www.developphp.com There is nothing more precious than information on the internet. So why leave things to chance regarding your database data? You may have a database full of members, or you render out all of your pages using a Custom Content Management System, which usually stores page data in a MySQL database. In this quick video tutorial Adam shows you how to go into your PHPMyAdmin MySQL database interface and back up or save your sensative database information. There are a few ways that you could lose the data in your database, so creating backup insert files manually is an easy way for a webmaster to safeguard his or her data. First step in keeping your database secure is not allowing users to input harmful strings. Learn of strings that may harm your database and cancel them out in your form processing. But I am assuming your scripts are secure and that you would like to backup your database just in case anything may happen out of the ordinary. You can easily replace any lost data in a few minutes using this manual methid with PHPMyAdmin. Databases get created on your server either through your cpanel or if you are on GoDaddy or a host that has a custom control panel. Once made you have acces to PHPMyAdmin which is for interacting with your database from a not too technical online interface. So not only is it handy but it teaches you code to write scripts that can interact with your database at runtime. HOT TIP: I have learned a lot of PHP-MySQL syntax from using …

Dec 31, 2010 Posted on Dec 31, 2010 in Hints and Tips | 10 comments

Understanding the PureMVC Open Source Framework

Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This tutorial was first published in May, 2009.

Now and again you may be asked to work on a project which requires a lot of coding and/or collaboration with colleagues. It’s safe to say that frameworks are often the best choice regarding structure, semantics and productivity.

Understanding a framework can take a lot of time, but once you’re happy with your knowledge, you can literally code at the speed of thought. PureMVC is a great framework for AS3; some may say it’s a bit difficult to get your head around, but you’ll be happy you did.

As you can see from the demo, what we’re working towards is pretty simple, but it’s enough to give you an understanding of how PureMVC works.


Before we Start…

Before we begin I’d like to make sure the following bases are covered. This is a tutorial for intermediate to advanced Actionscripters, but don’t be intimidated if you’re neither, there’s no time like the present to start learning!

  1. This example is built using Flex Builder. You can go to Adobe’s web site and download yourself a copy (60 day free trial!). However, it’ll happily work in an IDE of your choice, whether it be FlashDevelop, FDT, or good ol’ TextMate.
  2. Like I’ve said, this tutorial is for intermediate to advanced Actionscripters, so I’m going to skip the mundane parts such as setting up your project in your chosen IDE, etc…
  3. It’s worth noting that next time you go to do your business, it’s advisable to first print off a copy of PureMVC’s best practices. It’s fairly heavy, but you’ll be glad you read it.

Step 1: Set Up

It would be wise to grab yourself a copy of the project .zip file. Within it, you will see the basic set up for this tutorial. Fire up your IDE (mine is Flex Builder) and create a new project. The next thing you’ll need to do is set up the Flex compiler to use the "src" folder for the source path, the "debug" folder for the debug bin and the "deploy" folder for the release bin. Simple.

Secondly, I’ve included two additional libraries within the "src" folder: Greensock’s TweenLite ("src/gs") and PureMVC ("src/assets/swc"). You’ll notice that I’ve used a .swc for the PureMVC library rather than the source folder, this is because I prefer using .swc files. Make sure that both these libraries are set to compile when you debug and eventually deploy. Below is a screenshot of the target layout for the project. Although you’re more than welcome to import the project and go through it file by file, I’m going to tell you how to write each file so you end up with a project similar to the example.


Step 2: Fundamentals

The concept of PureMVC may make the best of us shy away, but once you’ve got your head around the bare fundamentals, you’ll soon be flying your way around it. PureMVC’s structure means that notifications are used to run certain commands whether they be within models, views or controllers. These notifications consist of the name and an optional body. The body parameter allows you to send data from the view (such as which button was clicked on) to a controller that can then pass it to model which then returns the relative data.

This notion of notifications means that PureMVC has a very definite structure to how the source files are set up:

  • Proxies (model):
    A proxy is simply a model. A model, to those who may not know, is a class that handles all data transactions such as loading XML data, storing it and retrieving it. Unlike mediators or commands, proxies never listen to or handle notifications; they only ever dispatch them. This means that in order for a command or a mediator to get a hold of some data, the data will have to either be passed back to the called via a notification’s body or by retrieving the instance of the proxy from the facade. Proxies store their data within public classes called VO (value objects). They are just simple classes that have public variables where we can keep our data for retrieving and updating via our proxies.
  • Mediators and their views (view):
    A mediator is a class that acts on behalf of a view. Within your application you may have several views and all these views will be extending a DisplayObject class (otherwise they wouldn’t be views). A mediator will be the class that adds your view to your base (the "viewComponent"; it’s the first argument that’s passed to a mediator) and it will also handle all incoming and outgoing notifications relating to that view. This means that the mediator is in charge of notifying your application if the user has triggered an event in the view (such as by clicking a button) and will also be in charge of passing data from a proxy to the view in order to update it. A mediator listens and handles notifications itself and is able to register new mediators into the facade when they’re needed rather than loading them all at once.
  • Commands (controller):
    A command is simply a controller. Although it doesn’t listen to notifications itself, it does have notifications piped to it from the facade. This means that a command has to run a conditional statement to allow it to determine which notification it’s received and what to do next. As well as receiving notifications, commands are allowed to send them out too. They are also able to register proxies, mediators and more commands.

Hopefully that should have given you a simple understanding of how PureMVC is set out. For a visual representation of how notifications can "fly" around your application, check out PureMVC’s conceptual diagram:

You’ll be forgiven if you think that’s all very daunting, but once you sit down and plan out what your application is going to look like, you’ll soon understand what we’re going for:

  1. Our base class will fire up the facade
  2. The facade will then call the start up command
  3. The start up command will register our proxy and application mediator
  4. The proxy will then reference its value object and wait for further notifications
  5. The application mediator will register the progress mediator
  6. The progress mediator will create the progress view and then send a notification to load the data
  7. The facade will receive this notification and pass it to the data command
  8. The data command will then filter the notification and tell the proxy to load the data
  9. The proxy will notify the progress view that it’s loading the data (it will be shown), the progress (it will be updated) and when it’s finished (it will be hidden); the mediator will handle all of this
  10. The proxy will then send a notification for the application mediator to handle
  11. The application mediator will register the urls view where we’ll create buttons for the user to click
  12. The urls view mediator will pass the data from the proxy to the urls view and add the urls view to the stage
  13. The user will click on a button, this will then be handled by the mediator and a notification will be sent to the proxy
  14. The proxy will then again load the data, always relaying the state to the progress view
  15. The proxy will then again send a notification for the application mediator to handle
  16. The application mediator will then tell the urls view mediator to hide the urls view and then register the images view
  17. The images view mediator will create the images view from the proxy’s data

That may sound complex, but it’s just a case of braking down your application’s function into small bit-size chunks.


Step 3: Everything Starts With the Facade

Whenever you work with PureMVC, you must understand that coding always starts with the facade. The facade is a layer that links the PureMVC framework, your MVC code and your base Actionscript file; in this case mine’s called "App.as". At runtime, App.as will do it’s business, whether it be setting up the scaling of the stage, the frame rate and whatnot; and when it’s ready, it’ll call upon the facade to start up the application.

Let’s create our base Actionscript file. Using your favourite IDE create a new file, name it "App.as" within "src" and be sure that it extends the Sprite class like so:

		package
		{
			import flash.display.Sprite;

			public class App extends Sprite
			{
				public function App()
				{

				}
			}
		}
	

Step 4: Setting Up the Base

Now that we’ve created our base class, feel free to add stuff such as setting the width, height, background colours and so on. It’s also handy to import any assets you may need, such as fonts or images. Once you’re happy with your base class, we can then move on to creating the facade. Below is a preview of my base class:

		package
		{
			import flash.display.GradientType;
			import flash.display.Sprite;
			import flash.geom.Matrix;
			import flash.text.Font;

			[SWF( width='600', height='400', frameRate='30', backgroundColor='#000000' )]

			public class App extends Sprite
			{
				[Embed( systemFont='Arial', fontName='Arial', mimeType='application/x-font' )]
				private var arialFont:Class;

				public function App()
				{
					init();
				}

				private function init():void
				{
					var mat:Matrix = new Matrix();
					var bg:Sprite = new Sprite();

					mat.createGradientBox( stage.stageWidth, stage.stageHeight, Math.PI * .5 );

					bg.graphics.beginGradientFill( GradientType.LINEAR, [ 0x333333, 0x000000 ], [ 1, 1 ], [ 0, 255 ], mat );
					bg.graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight );
					bg.graphics.endFill();

					addChild( bg );

					Font.registerFont( arialFont );
				}
			}
		}
	

Step 5: Setting Up the Facade

In this step we delve straight into the world of PureMVC. Like I said in Step 2, the facade is an important layer which holds your application together. Create a new class called "ApplicationFacade.as" within "src/com/flashtuts", make sure it extends Facade and implements IFacade. Note that our facade doesn’t have a constructor as it’s extending the Facade class. Within our facade we’re going to have 3 functions with a 4th optional one. Additionally, we’re going to have 2 public constants. Below is what we’ll aim to get our facade class looking like:

		package com.flashtuts
		{
			import com.flashtuts.controller.*;
			import com.flashtuts.model.*;
			import com.flashtuts.view.*;
			import com.flashtuts.view.component.ImagesView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IFacade;
			import org.puremvc.as3.patterns.facade.Facade;
			import org.puremvc.as3.patterns.observer.Notification;

			public class ApplicationFacade extends Facade implements IFacade
			{
				public static const NAME:String							= 'ApplicationFacade';

				public static const STARTUP:String						= NAME + 'StartUp';

				public static function getInstance():ApplicationFacade
				{
					return (instance ? instance : new ApplicationFacade()) as ApplicationFacade;
				}

				override protected function initializeController():void
				{
					super.initializeController();

					registerCommand( STARTUP, StartupCommand );

					registerCommand( URLsView.DATA_GET, DataCommand );
					registerCommand( ImagesView.DATA_GET, DataCommand );
				}

				public function startup(stage:Object):void
				{
					sendNotification( STARTUP, 	stage );
				}

				override public function sendNotification(notificationName:String, body:Object=null, type:String=null):void
				{
					trace( 'Sent ' + notificationName );

					notifyObservers( new Notification( notificationName, body, type ) );
				}
			}
		}
	

Within PureMVC, events or "notifications" are used to route data and trigger functions to be carried out within our views or controllers. Therefore since our facade is going to send a notification to a command telling it to start up the application, we create a unique constant that will be used by the facade to send the command and the start up function listening to the command:

		public static const NAME:String							= 'ApplicationFacade';

		public static const STARTUP:String						= NAME + 'StartUp';
	

Although you don’t need to have a constant called NAME, it’s a good idea to always create it in classes that have notification constants within them as to keep these notifications unique and less susceptible to human error (such as spelling mistakes).

Next we come to the first of our required functions, "getInstance()". This is the first and foremost function of the facade and allows our base class to retrieve an instance of the facade, then fire the start up command (we’ll get to that):

		public static function getInstance():ApplicationFacade
		{
			return (instance ? instance : new ApplicationFacade()) as ApplicationFacade;
		}
	

Now we come to the function which controls the routing of notifications to our controllers, or as PureMVC calls them, commands:

		override protected function initializeController():void
		{
			super.initializeController();

			registerCommand( STARTUP, StartupCommand );

			registerCommand( URLsView.DATA_GET, DataCommand );
			registerCommand( ImagesView.DATA_GET, DataCommand );
		}
	

It’s pretty important to keep "registerCommand( STARTUP, StartupCommand );" as without this, the application wouldn’t start. All it basically means is that the facade will pass the notification called "STARTUP" to a command called "StartupCommand". As you can see, I have two more. They both point to another controller called "DataCommand" and both notifications are requests to get data.

We now get to our last required function without our facade, "startup()". All this simply does is fire a notification which is routed to "StartupCommand" via the "registerCommand" handlers:

		public function startup(stage:Object):void
		{
			sendNotification( STARTUP, 	stage );
		}
	

Finally, last but by no means least, we have our final function. This is an optional function that I like to add when I’m working with PureMVC as it allows me to see what events are being fired and in what order. The function simply overwrites the "sendNotification()" function which you use within PureMVC to send notifications. As well as notifying the application’s observers, it traces the events for you to see:

		override public function sendNotification(notificationName:String, body:Object=null, type:String=null):void
		{
			trace( 'Sent ' + notificationName );

			notifyObservers( new Notification( notificationName, body, type ) );
		}
	

So that’s our facade. Before we’re finished, we need to apply one more line to our base class. This line will simply get an instance of our facade and then run the start up command:

		ApplicationFacade.getInstance().startup( this );
	

Make sure you put this file at the end of whatever your base class is doing. For example, I’ve put it under all the stuff that sets the background gradient for my application:

		package
		{
			import com.flashtuts.ApplicationFacade;

			import flash.display.GradientType;
			import flash.display.Sprite;
			import flash.geom.Matrix;
			import flash.text.Font;

			[SWF( width='600', height='400', frameRate='30', backgroundColor='#000000' )]

			public class App extends Sprite
			{
				[Embed( systemFont='Arial', fontName='Arial', mimeType='application/x-font' )]
				private var arialFont:Class;

				public function App()
				{
					init();
				}

				private function init():void
				{
					var mat:Matrix = new Matrix();
					var bg:Sprite = new Sprite();

					mat.createGradientBox( stage.stageWidth, stage.stageHeight, Math.PI * .5 );

					bg.graphics.beginGradientFill( GradientType.LINEAR, [ 0x333333, 0x000000 ], [ 1, 1 ], [ 0, 255 ], mat );
					bg.graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight );
					bg.graphics.endFill();

					addChild( bg );

					Font.registerFont( arialFont );

					ApplicationFacade.getInstance().startup( this );
				}
			}
		}
	

Now we’re ready to get our hands dirty.


Step 6: The Start Up Command

As discussed within Step 4, the facade handles all notification routing to our commands (the controllers). The first command we have to create is the "StartupCommand". So create a new file called "StartupCommand.as" within "src/com/flashtuts/controller". Make sure that it extends SimpleCommand and implements ICommand. Just like our facade, our commands won’t have constructors, instead override a public function from the SimpleCommand class called "execute()":

		package com.flashtuts.controller
		{
			import com.flashtuts.model.DataProxy;
			import com.flashtuts.view.ApplicationMediator;

			import org.puremvc.as3.interfaces.ICommand;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.command.SimpleCommand;

			public class StartupCommand extends SimpleCommand implements ICommand
			{
				override public function execute(notification:INotification):void
				{
					facade.registerProxy( new DataProxy() );

					facade.registerMediator( new ApplicationMediator( notification.getBody() as App ) );
				}
			}
		}
	

You’ll notice that within our "execute()" function, there’s one argument called "notification". We don’t need to use that as this stage, but this will become something that we do use within our other commands. As this command is used to start up our application, the first thing it does it register a proxy (a model):

		facade.registerProxy( new DataProxy() );
	

and then our mediator:

		facade.registerMediator( new ApplicationMediator( notification.getBody() as App ) );
	

So now we have our start up command ready. What we’ll do now is create our proxy and then get on to our ApplicationMediator.


Step 7: Creating a Proxy

Now that we have our "StartupCommand" registering our proxy, we need to make sure that the proxy exists. So create a new file called "DataProxy.as" within "src/com/flashtuts/model", and make sure it extends Proxy and implements IProxy. To start off with we’re just going to have two functions within our proxy: the constructor and a "get" function to retrieve the VO (value object):

		package com.flashtuts.model
		{
			import com.flashtuts.model.vo.DataVO;

			import org.puremvc.as3.interfaces.IProxy;
			import org.puremvc.as3.patterns.proxy.Proxy;

			public class DataProxy extends Proxy implements IProxy
			{
				public static const NAME:String							= 'DataProxy';

				public function DataProxy()
				{
					super( NAME, new DataVO() );
				}

				public function get vo():DataVO
				{
					return data as DataVO;
				}
			}
		}
	

As you can see, the first function within our proxy is our constructor where we "super()" two variables: the proxy’s name (set by the NAME constant) and the VO. We need to pass the name of the proxy as this will allow us to retrieve the facade’s instance of it rather than creating a new instance and losing our VO’s data:

		public static const NAME:String							= 'DataProxy';

		public function DataProxy()
		{
			super( NAME, new DataVO() );
		}
	

The second function is a simple get function that returns our VO. This allows the proxies, commands and mediators to easily access the VO via the proxy:

		public function get vo():DataVO
		{
			return data as DataVO;
		}
	

Before we finish with our proxy, we need to create our VO, so create a new class called "DataVO.as" within "src/com/flashtuts/model/vo". Then we’re going to add three public variables: "dataURL:String", "urlsArray:Array" and "urlsDataArray:Array". We’re going to set the "dataURL" to point to our XML file in "src/assets/xml" called "data.xml" and for the other two we’re just going to set them as empty arrays:

		package com.flashtuts.model.vo
		{
			public class DataVO
			{
				public var dataURL:String								= 'assets/xml/data.xml';
				public var urlsArray:Array								= [ ];
				public var urlsDataArray:Array							= [ ];
			}
		}
	

These are the contents of the XML file:

		<?xml version="1.0" encoding="UTF-8"?>
		<urls>
			<url>http://api.flickr.com/services/rest/?method=flickr.photos.search&amp;tags=london&amp;api_key=YOURAPIKEY</url>
			<url>http://api.flickr.com/services/rest/?method=flickr.photos.search&amp;tags=paris&amp;api_key=YOURAPIKEY</url>
			<url>http://api.flickr.com/services/rest/?method=flickr.photos.search&amp;tags=new%20york&amp;api_key=YOURAPIKEY</url>
		</urls>
	

Note: You’ll see that I’ve removed my API key. You can easily apply for one by going to Flickr’s API documentation site.

Now that we’ve got our proxy and VO in place, we’ll need to set up our mediators and views.


Step 8: Creating the ApplicationMediator

The "ApplicationMediator" is the layer that will sit between our "StartupCommand" and your view mediators. As your application gets bigger and bigger, it will no longer make sense to register all your mediators at once (for example, at start up). Therefore, by having a parent mediator (the ApplicationMediator) you can have that listen to the notifications being sent around your application and register mediators when they are needed. Since mediators act on behalf of the views, sometimes the data required for a view may not have been loaded yet, therefore it seems silly to register the mediator and create the view without being able to pass it any data.

To begin with, create a new file called "ApplicationMediator.as" within "src/com/flashtuts/view" and make sure it extends Mediator and implements IMediator. Below is what you should be aiming your "ApplicationMediator" to look like:

		package com.flashtuts.view
		{
			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ApplicationMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ApplicationMediator';

				public function ApplicationMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent );
				}
			}
		}
	

As you can see, the mediator starts with our old friend the "NAME" constant and its constructor. Back when we registered the mediator in Step 6, we passed an instance of the stage, our base class ("App.as") as the first argument. Within our constructor we super the NAME and the first argument, the "viewComponent" as it’s the viewComponent that’s going to allow our mediators to add their views to the stage, our base class.

Now is a good time to start talking about our views. Within my example I have three: a progress view, a url selection view and an images view. For each view we have a mediator. Since the first thing we want to do is load the data from our XML file, it seems fitting to create our progress view, then the mediator and then register the mediator with our "ApplicationMediator".

By extending the class Mediator, it allows us to override a handy function called "onRegister()". This function is called when the facade registers a mediator, so that seems the best place to get our "ApplicationMediator" to register the mediator for our progress view:

		override public function onRegister():void
		{
			facade.registerMediator( new ProgressViewMediator( viewComponent ) );
		}
	

As you can see, it’s the same style that we used within the "StartupCommand" and we’re passing the "viewComponent" to the mediator so it’s able to add the progress view to the stage. Your application mediator should look like this:

		package com.flashtuts.view
		{
			import com.flashtuts.view.component.ProgressView;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ApplicationMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ApplicationMediator';

				public function ApplicationMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent );
				}

				override public function onRegister():void
				{
					facade.registerMediator( new ProgressViewMediator( viewComponent ) );
				}
			}
		}
	

Step 9: Creating Our Progress Mediator and View

Now that we’ve set our "ApplicationMediator" to register our "ProgressViewMediator", we first of all start by creating a "ProgressView.as" class within "src/com/flashtuts/view/components". This is a class that simply extends the DisplayObject, in this case Sprite. I won’t go through the code for the view as it’s pretty standard for any Actionscripter but I will talk about the interaction between the view and its mediator below:

		package com.flashtuts.view.component
		{
			import flash.display.Sprite;
			import flash.text.TextField;
			import flash.text.TextFieldAutoSize;
			import flash.text.TextFormat;

			import gs.TweenLite;

			public class ProgressView extends Sprite
			{
				public static const NAME:String							= 'ProgressView';

				public static const SHOW:String							= NAME + 'Show';
				public static const HIDE:String							= NAME + 'Hide';
				public static const UPDATE:String						= NAME + 'Update';

				private var textField:TextField;

				public function ProgressView()
				{
					init();
				}

				private function init():void
				{
					var textFormat:TextFormat = new TextFormat();

					textFormat.color = 0xFFFFFF;
					textFormat.font = 'Arial';

					textField = new TextField();

					textField.autoSize = TextFieldAutoSize.CENTER;
					textField.defaultTextFormat = textFormat;
					textField.embedFonts = true;
					textField.text = 'Please wait...';
					textField.x = 300 - ( textField.width / 2 );
					textField.y = 200 - ( textField.height / 2 );

					addChild( textField );
				}

				public function show():void
				{
					textField.text = 'Please wait...';

					TweenLite.to( this, .5, { autoAlpha: 1 } );
				}

				public function hide():void
				{
					TweenLite.to( this, .5, { autoAlpha: 0 } );
				}

				public function update(percent:Number):void
				{
					textField.text = 'Loaded ' + percent + '%';
				}
			}
		}
	

As the mediator does ‘all the talking’ for the view, it’s important the view and the mediator can pass information to one another. The mediator can pass information to the view as the mediator will have an instance of the view declared within it, but for the view to pass information to the mediator (such as a user clicking on a button) we rely on events (not to be mixed up with notifications). We simply get our view to dispatch an event and get our mediator to listen to that event. The mediator can therefore handle the event from the view, digest the information and run something accordingly. We declared the name of these events by using public constants, so our view has three events: SHOW, HIDE and UPDATE (much like our facade).

Note: the placing of event names can be placed within the facade ("ApplicationFacade.as" file) or within the relative views. I find it easier and cleaner to keep them within the views, but it’s up to you which way you think works better for you.

As you can tell, I’ve created a text field that will be used to display the percentage of the data loaded through our application.

We can now move on to the mediator, so create a new file called "ProgressViewMediator.as" in "src/com/flashtuts/view" and be sure that it extends Mediator and implements IMediator. It’ll follow the same style as our "ApplicationMediator" and therefore have a constructor that has one argument (the "viewComponent"), a public constant called NAME and our friend the overridden "onRegister()". Below is what your mediator should look like:

		package com.flashtuts.view
		{
			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ProgressViewMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ProgressViewMediator';

				public function ProgressViewMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent );
				}

				override public function onRegister():void
				{

				}
			}
		}
	

The first thing we need to add to our view as a reference into our mediator:

		package com.flashtuts.view
		{
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ProgressViewMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ProgressViewMediator';

				private var progressView:ProgressView;
				...
	

and now we get the mediator to add our view to the "viewComponent" so we have:

		package com.flashtuts.view
		{
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ProgressViewMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ProgressViewMediator';

				private var progressView:ProgressView;

				public function ProgressViewMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent );
				}

				override public function onRegister():void
				{
					progressView = new ProgressView();

					viewComponent.addChild( progressView );
				}
			}
		}
	

Now that we’ve got the bare-bones of our mediator, we need to look at what our view is going to do. Well, as you can probably tell from the constants, our view is going to tell the user how much has been loaded so far, therefore it has the public constants SHOW, HIDE and UPDATE. Since these are going to be something that our view will react to (as you can tell by the "show()", "hide()" and "update()" functions within our view), we need our mediator to handle these notifications and run these functions accordingly.

We’ll add two new functions to our mediator: "listNotificationInterests()" and "handleNotification()". The first function returns an array of all the notifications this mediator is interested in (this is why it’s so important to stick these notifications in public constants so they’re easy to reference). The latter actually does something with them. This mediator is only interested in SHOW, HIDE and UPDATE so that’s what we add to the first function and handle in the second:

		package com.flashtuts.view
		{
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ProgressViewMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ProgressViewMediator';

				private var progressView:ProgressView;

				public function ProgressViewMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent );
				}

				override public function onRegister():void
				{
					progressView = new ProgressView();

					viewComponent.addChild( progressView );

					sendNotification( URLsView.DATA_GET );
				}

				override public function listNotificationInterests():Array
				{
					return [
						ProgressView.SHOW,
						ProgressView.HIDE,
						ProgressView.UPDATE
					];
				}

				override public function handleNotification(notification:INotification):void
				{
					var name:String = notification.getName();
					var body:Object = notification.getBody();

					switch ( name )
					{
						case ProgressView.SHOW:
						progressView.show();

						break;

						case ProgressView.HIDE:
						progressView.hide();

						break;

						case ProgressView.UPDATE:
						progressView.update( body.percent );

						break;
					}
				}
			}
		}
	

You can simply see that our "handleNotification()" takes the argument of an INotification, a class that contains the name and body of a notification. We use a "switch" statement to determine which notification is to be handled and run the functions accordingly. Simple.

Congratulations! You’ve reached the first milestone! Haven’t we come far? Test your file and you should see the following:


Milestone

So far we’ve created our facade, added a command, proxy and application mediator, then created a view and added it to our application using the view’s facade.


Step 10: Creating Our URLs View

Now we want to load some data. Before we do this, let’s create the view that will be used to display this data. As we’re loading three Flickr API feeds, I see it fitting that in our next view we create three buttons which allow the user to click, at which point our application will return the images from the corresponding feed. Let’s then create a new file called "URLsView.as’" in "src/com/flashtuts/view/component" and just like our "ProgressView", this will extend the Sprite class:

		package com.flashtuts.view.component
		{
			import flash.display.Sprite;
			import flash.events.DataEvent;
			import flash.events.MouseEvent;
			import flash.text.TextField;
			import flash.text.TextFieldAutoSize;
			import flash.text.TextFormat;

			import gs.TweenLite;

			public class URLsView extends Sprite
			{
				public static const NAME:String							= 'URLsView';

				public static const DATA_GET:String						= NAME + 'DataGet';
				public static const DATA_READY:String					= NAME + 'DataReady';
				public static const SHOW:String							= NAME + 'Show';
				public static const HIDE:String							= NAME + 'Hide';
				public static const CLICKED:String						= NAME + 'Clicked';

				public function init(urls:Array):void
				{
					var i:Number = 0;
					var textFormat:TextFormat = new TextFormat();
					var textContainer:Sprite;
					var textField:TextField;

					textFormat.color = 0xFFFFFF;
					textFormat.font = 'Arial';

					for each ( var url:String in urls )
					{
						textContainer = new Sprite();

						textContainer.addEventListener( MouseEvent.CLICK, handleContainerClick );

						textContainer.buttonMode = true;
						textContainer.graphics.lineStyle( 1, 0xFFFFFF );
						textContainer.graphics.beginFill( 0x333333 );
						textContainer.graphics.drawRoundRect( 0, 0, 150, 30, 5, 5 );
						textContainer.graphics.endFill();
						textContainer.mouseChildren = false;
						textContainer.y = i * 40;

						textField = new TextField();

						textField.autoSize = TextFieldAutoSize.CENTER;
						textField.defaultTextFormat = textFormat;
						textField.embedFonts = true;
						textField.text = 'Select URL ' + ( ++i );
						textField.x = 75 - ( textField.width / 2 );
						textField.y = 15 - ( textField.height / 2 );

						textContainer.addChild( textField );

						addChild( textContainer );
					}

					alpha = 0;
					x = 300 - ( width / 2 );
					y = 200 - ( height / 2 );
				}

				public function show():void
				{
					TweenLite.to( this, .5, { autoAlpha: 1 } );
				}

				public function hide():void
				{
					TweenLite.to( this, .5, { autoAlpha: 0 } );
				}

				private function handleContainerClick(e:MouseEvent):void
				{
					var index:Number = getChildIndex( e.target as Sprite );

					dispatchEvent( new DataEvent( CLICKED, true, false, index.toString() ) );
				}
			}
		}
	

I’m not going to walk you through this view class, as with all the view classes. They’re basic AS3 classes and you should be familiar with them. However, as you can see I’ve left the constructor out as we only want to build the buttons when the data has been loaded by our "DataProxy". Also, take note of the public constants at the top of the class, mainly DATA_GET and DATA_READY. These are events that will be fired off in order to signal that the data needs to be loaded, then that the data has loaded and is ready for the view.

We now come to our view’s mediator, so create a file called "URLsViewMediator.as" within "src/com/flashtuts/view" and make sure it extends Mediator and implements IMediator. This is just like all mediators within our application. As with our "ProgressViewMediator" this one has a constructor where it supers its NAME and the "viewComponent" and also has the overridden "onRegister" function. Again, just like "ProgressViewMediator", we declare a new instance of our view:

		package com.flashtuts.view
		{
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class URLsViewMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'URLsViewMediator';

				private var urlsView:URLsView;

				public function URLsViewMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent);
				}

				override public function onRegister():void
				{
					urlsView = new URLsView();
				}
			}
		}
	

We now need to think about what our view is going to do. Well, it’s going to allow the user to click on a button within it and dispatch an event (that’s what the function "handleContainerClick()" within the view does). We need to tell our mediator to give our view a listener for that event and handle it accordingly:

		package com.flashtuts.view
		{
			import com.flashtuts.view.component.URLsView;

			import flash.events.DataEvent;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class URLsViewMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'URLsViewMediator';

				private var urlsView:URLsView;

				public function URLsViewMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent);
				}

				override public function onRegister():void
				{
					urlsView = new URLsView();

					urlsView.addEventListener( URLsView.CLICKED, handleURLsViewClicked );
				}

				private function handleURLsViewClicked(e:DataEvent):void
				{

				}
			}
		}
	

Now we need to think about when this mediator will come into use. Remember earlier I said that there’s no point running a mediator before it’s needed? Well this mediator isn’t going to be run before we need it, so we’re assuming that when it’s first registered, the data will be ready for the view to build the buttons, so we update our "onRegister()" function to send the data to the view, show the view and add it to the stage. Since our data is stored within our "DataProxy" VO, we’ll need to add another function which allows us to access the facade’s instance of the proxy and retrieve data from the VO:

		override public function onRegister():void
		{
			urlsView = new URLsView();

			urlsView.addEventListener( URLsView.CLICKED, handleURLsViewClicked );

			urlsView.init( proxy.vo.urlsArray );

			urlsView.show();

			viewComponent.addChild( urlsView );
		}

		private function get proxy():DataProxy
		{
			return facade.retrieveProxy( DataProxy.NAME ) as DataProxy;
		}

Finally, as this mediator will be created when the data’s ready, we need to tell our "ProgressView" that we no longer want it to be visible, so we fire a notification called "ProgressView.HIDE" which will be picked up by the "ProgressViewMediator" and will tell "ProgressView" to hide itself:

		override public function onRegister():void
		{
			urlsView = new URLsView();

			urlsView.addEventListener( URLsView.CLICKED, handleURLsViewClicked );

			urlsView.init( proxy.vo.urlsArray );

			urlsView.show();

			viewComponent.addChild( urlsView );

			sendNotification( ProgressView.HIDE );
		}
	

Once again, before we can continue, we need to think about which notifications this mediator will need to listen to. Since we’re going to make this a usable application, there’s no point in not letting the user go back and pick another Flickr feed url, so it makes sense to allow this view to be shown again. This is where the public const SHOW comes in to play (you’ll notice that I have a naming convention when it comes to all my notifications, this is a good thing and will speed up your development). Just like with our "ProgressViewMediator", we add "listNotificationInterests()" and "handleNotification()" functions to our class:

		package com.flashtuts.view
		{
			import com.flashtuts.model.DataProxy;
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import flash.events.DataEvent;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class URLsViewMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'URLsViewMediator';

				private var urlsView:URLsView;

				public function URLsViewMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent);
				}

				override public function onRegister():void
				{
					urlsView = new URLsView();

					urlsView.addEventListener( URLsView.CLICKED, handleURLsViewClicked );

					urlsView.init( proxy.vo.urlsArray );

					urlsView.show();

					viewComponent.addChild( urlsView );

					sendNotification( ProgressView.HIDE );
				}

				override public function listNotificationInterests():Array
				{
					return [
						URLsView.SHOW
					];
				}

				override public function handleNotification(notification:INotification):void
				{
					var name:String = notification.getName();
					var body:Object = notification.getBody();

					switch ( name )
					{
						case URLsView.SHOW:
						urlsView.show();

						break;
					}
				}

				private function handleURLsViewClicked(e:DataEvent):void
				{
					urlsView.hide();

					sendNotification( URLsView.CLICKED, { index: e.data } );
				}

				private function get proxy():DataProxy
				{
					return facade.retrieveProxy( DataProxy.NAME ) as DataProxy;
				}
			}
		}
	

You’ll notice that I’ve added some stuff to the "handleContainerClick()" function. All this function does is simply pass the index of the button pressed (like 0, 1, 2…) with the event name "URLsView.CLICKED". We will handle this event shortly as this is the event we’ll use to load the Flickr feed the user has picked.

Now that our view is ready for our data, we can proceed to the proxy and load some XML. Whoop whoop!


Step 11: Loading Data

As I mentioned above, our "ProgressViewMediator" fires off a notification called "URLsView.DATA_GET". In order for our proxy to receive this notification, we need it to go via our facade and then a command that will then call the proxy’s function. First then, we need to register the command within our facade, so open up "ApplicationFacade.as" and add the "registerCommand" function to the "initializeController()" function like so:

		package com.flashtuts
		{
			import com.flashtuts.controller.*;
			import com.flashtuts.model.*;
			import com.flashtuts.view.*;
			import com.flashtuts.view.component.ImagesView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IFacade;
			import org.puremvc.as3.patterns.facade.Facade;
			import org.puremvc.as3.patterns.observer.Notification;

			public class ApplicationFacade extends Facade implements IFacade
			{
				public static const NAME:String							= 'ApplicationFacade';

				public static const STARTUP:String						= NAME + 'StartUp';

				public static function getInstance():ApplicationFacade
				{
					return (instance ? instance : new ApplicationFacade()) as ApplicationFacade;
				}

				override protected function initializeController():void
				{
					super.initializeController();

					registerCommand( STARTUP, StartupCommand );

					registerCommand( URLsView.DATA_GET, DataCommand );
				}

				public function startup(stage:Object):void
				{
					sendNotification( STARTUP, 	stage );
				}

				override public function sendNotification(notificationName:String, body:Object=null, type:String=null):void
				{
					trace( 'Sent ' + notificationName );

					notifyObservers( new Notification( notificationName, body, type ) );
				}
			}
		}
	

You’ll see that we’re telling our facade to pass this notification to a command called "DataCommand", this is the name of the controller we’re going to make to handle this notification and run the proxy. Next, create a file called "DataCommand.as" in "src/com/flashtuts/controller" and it’ll need to extend SimpleCommand and implement ICommand. Our class won’t need a constructor as we’re interested in the "execute()" function (just like the "StartupCommand"):

		package com.flashtuts.controller
		{
			import org.puremvc.as3.interfaces.ICommand;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.command.SimpleCommand;

			public class DataCommand extends SimpleCommand implements ICommand
			{
				override public function execute(notification:INotification):void
				{

				}
			}
		}
	

If you have a sharp eye, you’ll notice that we’re facing our friend the INotification class. Just as with a mediator, this class gives us the name and body of a notification, so we handle it in the same way – with a switch:

		package com.flashtuts.controller
		{
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.ICommand;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.command.SimpleCommand;

			public class DataCommand extends SimpleCommand implements ICommand
			{
				override public function execute(notification:INotification):void
				{
					var name:String = notification.getName();
					var body:Object = notification.getBody();

					switch ( name )
					{
						case URLsView.DATA_GET:

						break;
					}
				}
			}
		}
	

Since we want that notification to tell the proxy to load some data, we need to get the facade’s instance of the proxy and get it to fire a function. We use the same method we used within our mediator and create a get function:

		package com.flashtuts.controller
		{
			import com.flashtuts.model.DataProxy;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.ICommand;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.command.SimpleCommand;

			public class DataCommand extends SimpleCommand implements ICommand
			{
				override public function execute(notification:INotification):void
				{
					var name:String = notification.getName();
					var body:Object = notification.getBody();

					switch ( name )
					{
						case URLsView.DATA_GET:
						proxy.urlsDataGet();

						break;
					}
				}

				private function get proxy():DataProxy
				{
					return facade.retrieveProxy( DataProxy.NAME ) as DataProxy;
				}
			}
		}
	

Finally, you’ll see that we’re calling a function within our proxy called "urlsDataGet()". This will load our data, so we’d better create it. Open up "DataProxy.as" and create a function called "urlsDataGet()" which will load the data, like so:

		package com.flashtuts.model
		{
			import com.flashtuts.model.vo.DataVO;
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import flash.display.LoaderInfo;
			import flash.events.Event;
			import flash.events.ProgressEvent;
			import flash.net.URLLoader;
			import flash.net.URLRequest;
			import flash.utils.Dictionary;

			import org.puremvc.as3.interfaces.IProxy;
			import org.puremvc.as3.patterns.proxy.Proxy;

			public class DataProxy extends Proxy implements IProxy
			{
				public static const NAME:String							= 'DataProxy';

				private var indexDic:Dictionary = new Dictionary();

				public function DataProxy()
				{
					super( NAME, new DataVO() );
				}

				public function urlsDataGet():void
				{
					var request:URLRequest = new URLRequest();
					var loader:URLLoader = new URLLoader();

					sendNotification( ProgressView.SHOW );

					request.url = vo.dataURL;

					loader.addEventListener( ProgressEvent.PROGRESS, handleProgress );
					loader.addEventListener( Event.COMPLETE, handleURLsDataGetComplete );

					loader.load( request );
				}

				private function handleURLsDataGetComplete(e:Event):void
				{
					var data:XML = new XML( e.target.data );

					for each ( var url:XML in data..url )
					{
						vo.urlsArray.push( url.toString() );
						vo.urlsDataArray.push( '' );
					}

					sendNotification( URLsView.DATA_READY );
				}

				private function handleProgress(e:ProgressEvent):void
				{
					sendNotification( ProgressView.UPDATE, { percent: Math.round( ( e.bytesLoaded / e.bytesTotal ) * 100 ) } );
				}

				public function get vo():DataVO
				{
					return data as DataVO;
				}
			}
		}
	

You’ll notice that we’re making use of our VO here by again creating a get function so that we can use and add data to it. You should be familiar with loading XML data so I won’t walk through the functions; you should be able to see what they do. You may be wondering why I’m running through a loop of the urls from the XML data and populating an array with an empty string, you’ll find out later…

The main things I will mention are the "handleProgress()" and "handleURLsDataGetComplete()" functions. They both send notifications to the application, the first sends a percentage of the data load to our progress view (remember I said a notification is made up of a name and body?) and the latter sends a notification to the application stating that our first bit of data has finished loading.

Finally, because we only want our "URLsViewMediator" and "URLsView" to be registered when the data is ready, we need to amend the application mediator to register the mediator when that event is sent:

		package com.flashtuts.view
		{
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ApplicationMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ApplicationMediator';

				public function ApplicationMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent );
				}

				override public function onRegister():void
				{
					facade.registerMediator( new ProgressViewMediator( viewComponent ) );
				}

				override public function listNotificationInterests():Array
				{
					return [
						URLsView.DATA_READY
					];
				}

				override public function handleNotification(notification:INotification):void
				{
					var name:String = notification.getName();
					var body:Object = notification.getBody();

					switch ( name )
					{
						case URLsView.DATA_READY:
						facade.registerMediator( new URLsViewMediator( viewComponent ) );

						break;
					}
				}
			}
		}
	

That code shouldn’t be too unfamiliar, but as you can see we’re setting which notifications we want it to listen to and then handling them. In this case registering the "URLsViewMediator" which runs its "onRegister()" function and builds the view.

We’re at the next mile stone! Now we should see that our application will load the XML data and then pass this data to our "URLsViewMediator" which will in turn tell the "URLsView" to create some buttons ready for the user to click:


Milestone

Give yourself a pat on the back as you’ve achieved a lot! By now you should be familiar with how notifications play a big part in the application and how the whole structure is brought together by the facade. The next bit will be a breeze…


Step 12: Handling a User Event

As I explained earlier, a view will dispatch a user event, such as mouse move or in this case mouse click. This event will then be picked up by its mediator which then decides what to do. Since we’ve set up the function "handleContainerClick()" within "URLsViewMediator" to send an index of the button, we now need to handle that event and load the subsequent data. First we’ll need to build our final view and mediator.

Here’s the view:

		package com.flashtuts.view.component
		{
			import flash.display.Loader;
			import flash.display.Sprite;
			import flash.events.Event;
			import flash.events.MouseEvent;
			import flash.net.URLRequest;
			import flash.text.TextField;
			import flash.text.TextFieldAutoSize;
			import flash.text.TextFormat;

			import gs.TweenLite;

			public class ImagesView extends Sprite
			{
				public static const NAME:String							= 'ImagesView';

				public static const DATA_GET:String						= NAME + 'DataGet';
				public static const DATA_READY:String					= NAME + 'DataReady';
				public static const SHOW:String							= NAME + 'Show';
				public static const HIDE:String							= NAME + 'Hide';
				public static const GO_BACK_CLICKED:String				= NAME + 'GoBackClicked';

				public function init(images:XML):void
				{
					var maxImages:Number = 15;
					var perRow:Number = 5;
					var xRowCount:Number = 0;
					var yRowCount:Number = 0;
					var element:XML;
					var request:URLRequest;
					var loader:Loader;

					for ( var i:Number = 0; i < maxImages; i++ )
					{
						element = images..photo[ i ];

						request = new URLRequest();

						request.url = 'http://farm' + element.@farm + '.static.flickr.com/' + element.@server + '/' + element.@id + '_' +element.@secret + '_t.jpg';

						loader = new Loader();	

						if ( xRowCount == perRow )
						{
							xRowCount = 0;
							yRowCount++;
						}

						loader.contentLoaderInfo.addEventListener( Event.COMPLETE, handleLoaderComplete );

						loader.alpha = 1;
						loader.x = xRowCount * 120;
						loader.y = yRowCount * 120;

						loader.load( request );

						xRowCount++;

						addChild( loader );
					}

					addBackButton();

					alpha = 0;
				}

				private function handleLoaderComplete(e:Event):void
				{
					TweenLite.from( e.target.content, .5, { autoAlpha: 0 } );
				}

				private function addBackButton():void
				{
					var textFormat:TextFormat = new TextFormat();
					var textContainer:Sprite = new Sprite();
					var textField:TextField = new TextField();

					textFormat.color = 0xFFFFFF;
					textFormat.font = 'Arial';

					textContainer.addEventListener( MouseEvent.CLICK, handleContainerClick );

					textContainer.buttonMode = true;
					textContainer.graphics.lineStyle( 1, 0xFFFFFF );
					textContainer.graphics.beginFill( 0x333333 );
					textContainer.graphics.drawRoundRect( 0, 0, 150, 30, 5, 5 );
					textContainer.graphics.endFill();
					textContainer.mouseChildren = false;
					textContainer.x = 430;
					textContainer.y = 350;

					textField.autoSize = TextFieldAutoSize.CENTER;
					textField.defaultTextFormat = textFormat;
					textField.embedFonts = true;
					textField.text = 'Go back';
					textField.x = 75 - ( textField.width / 2 );
					textField.y = 15 - ( textField.height / 2 );

					textContainer.addChild( textField );

					addChild( textContainer );
				}

				private function handleContainerClick(e:MouseEvent=null):void
				{
					if ( numChildren > 0 )
					{
						for ( var i:Number = 0; i < numChildren; i++ )
						{
							removeChildAt( i );
						}

						handleContainerClick();
					}
					else
					{
						dispatchEvent( new Event( GO_BACK_CLICKED, true ) );
					}
				}

				public function show():void
				{
					TweenLite.to( this, .5, { autoAlpha: 1 } );
				}

				public function hide():void
				{
					TweenLite.to( this, .5, { autoAlpha: 0 } );
				}
			}
		}
	

All this view does is take the XML data loaded in from the Flickr API, build a grid of images and a back button. Here’s the mediator:

		package com.flashtuts.view
		{
			import com.flashtuts.model.DataProxy;
			import com.flashtuts.view.component.ImagesView;
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import flash.events.Event;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ImagesViewMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ImagesViewMediator';

				private var imagesView:ImagesView;

				public function ImagesViewMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent );
				}

				override public function onRegister():void
				{
					imagesView = new ImagesView();

					imagesView.addEventListener( ImagesView.GO_BACK_CLICKED, handleImagesViewGoBackClicked );

					viewComponent.addChild( imagesView );
				}

				override public function listNotificationInterests():Array
				{
					return [
						ImagesView.DATA_READY
					];
				}

				override public function handleNotification(notification:INotification):void
				{
					var name:String = notification.getName();
					var body:Object = notification.getBody();

					switch ( name )
					{
						case ImagesView.DATA_READY:
						imagesView.init( proxy.vo.urlsDataArray[ body.index ] );

						imagesView.show();

						sendNotification( ProgressView.HIDE );

						break;
					}
				}

				private function handleImagesViewGoBackClicked(e:Event):void
				{
					imagesView.hide();

					sendNotification( URLsView.SHOW );
				}

				private function get proxy():DataProxy
				{
					return facade.retrieveProxy( DataProxy.NAME ) as DataProxy;
				}
			}
		}
	

Again, none of this should be new to you as we’re simply creating an instance of our view, adding it to the stage, adding listeners to our view (and their handlers) and then setting out the notifications its going to listen to and how it will handle them.

In order to to handle this notification, we update the application mediator one last time and set it to listen to the "URLsView.CLICKED" notification:

		package com.flashtuts.view
		{
			import com.flashtuts.view.component.ImagesView;
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IMediator;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.mediator.Mediator;

			public class ApplicationMediator extends Mediator implements IMediator
			{
				public static const NAME:String							= 'ApplicationMediator';

				public function ApplicationMediator(viewComponent:Object=null)
				{
					super( NAME, viewComponent );
				}

				override public function onRegister():void
				{
					facade.registerMediator( new ProgressViewMediator( viewComponent ) );
				}

				override public function listNotificationInterests():Array
				{
					return [
						URLsView.DATA_READY,
						URLsView.CLICKED
					];
				}

				override public function handleNotification(notification:INotification):void
				{
					var name:String = notification.getName();
					var body:Object = notification.getBody();

					switch ( name )
					{
						case URLsView.DATA_READY:
						facade.registerMediator( new URLsViewMediator( viewComponent ) );

						break;

						case URLsView.CLICKED:
						if ( !facade.hasMediator( ImagesViewMediator.NAME ) )
						{
							facade.registerMediator( new ImagesViewMediator( viewComponent ) );
						}

						sendNotification( ImagesView.DATA_GET, body );				

						break;
					}
				}
			}
		}
	

One thing to note about the handling of this event: the first thing the code does is check if the mediator has been registered. If not, it registers and everyone gets on with it. The reason for this, as opposed to re-registering it is that we’re going to create a back button for the user to be able to go back and pick another Flickr feed. Since we only need to show and hide the buttons that allow the user to choose, there’s no need to rebuild them. However, since the user will then potentially choose another Flickr feed, we need to rebuild our images. To save duplicating our code, we only build images when the "ImagesViewMediator" has received the event "ImagesView.DATA_READY".

Since our application sends "ImagesView.DATA_GET" whenever the user selects a Flickr API, we need to adjust "ApplicationFacade", "DataCommand" and "DataProxy" to a) handle the event and b) load the data and send an event back.

We first edit "ApplicationFacade" adding a "registerCommand()" to the "initializeController()" function:

		package com.flashtuts
		{
			import com.flashtuts.controller.*;
			import com.flashtuts.model.*;
			import com.flashtuts.view.*;
			import com.flashtuts.view.component.ImagesView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.IFacade;
			import org.puremvc.as3.patterns.facade.Facade;
			import org.puremvc.as3.patterns.observer.Notification;

			public class ApplicationFacade extends Facade implements IFacade
			{
				public static const NAME:String							= 'ApplicationFacade';

				public static const STARTUP:String						= NAME + 'StartUp';

				public static function getInstance():ApplicationFacade
				{
					return (instance ? instance : new ApplicationFacade()) as ApplicationFacade;
				}

				override protected function initializeController():void
				{
					super.initializeController();

					registerCommand( STARTUP, StartupCommand );

					registerCommand( URLsView.DATA_GET, DataCommand );
					registerCommand( ImagesView.DATA_GET, DataCommand );
				}

				public function startup(stage:Object):void
				{
					sendNotification( STARTUP, 	stage );
				}

				override public function sendNotification(notificationName:String, body:Object=null, type:String=null):void
				{
					trace( 'Sent ' + notificationName );

					notifyObservers( new Notification( notificationName, body, type ) );
				}
			}
		}
	

We then tell the "DataCommand" how to handle it (through the proxy):

		package com.flashtuts.controller
		{
			import com.flashtuts.model.DataProxy;
			import com.flashtuts.view.component.ImagesView;
			import com.flashtuts.view.component.URLsView;

			import org.puremvc.as3.interfaces.ICommand;
			import org.puremvc.as3.interfaces.INotification;
			import org.puremvc.as3.patterns.command.SimpleCommand;

			public class DataCommand extends SimpleCommand implements ICommand
			{
				override public function execute(notification:INotification):void
				{
					var name:String = notification.getName();
					var body:Object = notification.getBody();

					switch ( name )
					{
						case URLsView.DATA_GET:
						proxy.urlsDataGet();

						break;

						case ImagesView.DATA_GET:
						proxy.imagesDataGet( body.index );

						break;
					}
				}

				private function get proxy():DataProxy
				{
					return facade.retrieveProxy( DataProxy.NAME ) as DataProxy;
				}
			}
		}
	

Finally we edit the "DataProxy":

		package com.flashtuts.model
		{
			import com.flashtuts.model.vo.DataVO;
			import com.flashtuts.view.component.ImagesView;
			import com.flashtuts.view.component.ProgressView;
			import com.flashtuts.view.component.URLsView;

			import flash.display.LoaderInfo;
			import flash.events.Event;
			import flash.events.ProgressEvent;
			import flash.net.URLLoader;
			import flash.net.URLRequest;
			import flash.utils.Dictionary;

			import org.puremvc.as3.interfaces.IProxy;
			import org.puremvc.as3.patterns.proxy.Proxy;

			public class DataProxy extends Proxy implements IProxy
			{
				public static const NAME:String							= 'DataProxy';

				private var indexDic:Dictionary = new Dictionary();

				public function DataProxy()
				{
					super( NAME, new DataVO() );
				}

				public function urlsDataGet():void
				{
					var request:URLRequest = new URLRequest();
					var loader:URLLoader = new URLLoader();

					sendNotification( ProgressView.SHOW );

					request.url = vo.dataURL;

					loader.addEventListener( ProgressEvent.PROGRESS, handleProgress );
					loader.addEventListener( Event.COMPLETE, handleURLsDataGetComplete );

					loader.load( request );
				}

				private function handleURLsDataGetComplete(e:Event):void
				{
					var data:XML = new XML( e.target.data );

					for each ( var url:XML in data..url )
					{
						vo.urlsArray.push( url.toString() );
						vo.urlsDataArray.push( '' );
					}

					sendNotification( URLsView.DATA_READY );
				}

				public function imagesDataGet(index:Number):void
				{
					var request:URLRequest = new URLRequest();
					var loader:URLLoader = new URLLoader();

					sendNotification( ProgressView.SHOW );

					if ( vo.urlsDataArray[ index ] == '' )
					{
						request.url = vo.urlsArray[ index ];

						indexDic[ loader ] = index;

						loader.addEventListener( ProgressEvent.PROGRESS, handleProgress );
						loader.addEventListener( Event.COMPLETE, handleImagesDataGetComplete );

						loader.load( request );
					}
					else
					{
						handleImagesDataGetFinished( index );
					}
				}

				private function handleImagesDataGetComplete(e:Event):void
				{
					var data:XML = new XML( e.target.data );

					vo.urlsDataArray[ indexDic[ e.target ] ] = data;

					handleImagesDataGetFinished( indexDic[ e.target ] );
				}

				private function handleImagesDataGetFinished(index:Number):void
				{
					sendNotification( ImagesView.DATA_READY, { index: index } );
				}

				private function handleProgress(e:ProgressEvent):void
				{
					sendNotification( ProgressView.UPDATE, { percent: Math.round( ( e.bytesLoaded / e.bytesTotal ) * 100 ) } );
				}

				public function get vo():DataVO
				{
					return data as DataVO;
				}
			}
		}
	

You’ll notice I’ve performed a bit of Actionscript wizardry in the "imagesDataGet()" function. Again, it’s just loading some XML, nothing special about that, but it’ll only load unique data once. This is the beauty of having VOs and using indexes when buttons are pressed. Essentially what happens is that if the user presses button 2 (the 3rd one), it’ll check to see if that index has any data bound to it (as the loop when the urls were first loaded created an array with empty strings). If it has, there’s no need to load the data again, otherwise the data’s loaded and using the beauty of Dictionaries, we’re able to put it into the array.

Finally, this proxy then pushes the notification "ImagesView.DATA_READY" back to our application and to our view where some magic will happen..


You’ve done it!

There’s your first PureMVC application! You should know have an understanding of how PureMVC works and, most valuably, a skeleton so when it comes to developing more applications you can take this code, rework it or just use it as reference.


Footnote

PureMVC is a great tool and I use it on many projects, but there are some key differences between using it with Actionscript 3.0 and MXML. When you use MXML, you add the views using XML, like so:

		<?xml version="1.0" encoding="utf-8"?>
		<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%" backgroundColor="#000000" backgroundAlpha=".6"
			creationComplete="ApplicationFacade.getInstance().startup( NAME, this )"
			xmlns:component="com.application.view.component.*">

			<mx:Script>
				<![CDATA[

					import com.application.ApplicationFacade;

					public static const NAME:String						= 'Showcase';

					public static const STACK_PROGRESS:Number			= 0;
					public static const STACK_MAIN:Number				= 1;

				]]>
			</mx:Script>

			<mx:Style source="Showcase.css" />

			<mx:ViewStack id="stack" width="980" height="750" horizontalCenter="0" verticalCenter="0" creationPolicy="all">
				<component:ProgressView id="progress" />
				<component:ShowcaseMainView id="main" />

			</mx:ViewStack>

		</mx:Application>
	

Flex automatically creates those views rather than allowing your to defer their creation. Therefore, when you’re ready to dive into more PureMVC, they’ve created a little application that tells you how you can use deferred instantiation.

I hope you enjoyed following this tutorial, feel free to leave any questions or feedback in the comments!



View full post on Activetuts+

Dec 31, 2010 Posted on Dec 31, 2010 in Flash Video Training | 17 comments

Flash MX Basics


www.websiteguruservices.com Learn a few basics in Flash MX

Page 1 of 2112345...1020...»Last »
search search search search search
Find an Article
Categories
  • Flash Video Training
  • Hints and Tips
  • Recommended
Please Support Our Sponsors
Recent Posts
  • Tuts+ Community Meetup in New York!
  • HTML5 Canvas Optimization: A Practical Example
  • Recreate the Cover Flow Effect Using Flash and AS3
  • Drawing Activetuts+ to a Close
  • Intro to Dart: Creating a Marquee
Tag Cloud
2011 ActionScript Active Activetuts+ Adobe animation Basic Basix Best Build Button Character Code Create Creating Critique Custom design Effect Effects Files Flash from Game Guide HTML5 Introduction Macromedia Motion Muzzle part Player Premium Professional Quick Silverlight Simple Text Tool Tutorial Tuts+ Using Video website Workshop
About Our Site:

Hey there and welcome to "Flash Video Training Source", a resource for anybody interested in learning more about Adobe's great tool. We feature educational videos, which will help you master Adobe Flash and help you get to know all of its features. We at "Flash Video Training Source" believe that video training and video... more

Why don't you follow us on Twitter and get the latest video tutorials twitted to your account. Just click on the floating twitter bar to your right!

Go Back In Time
December 2010
M T W T F S S
« Nov   Jan »
 12345
6789101112
13141516171819
20212223242526
2728293031  
Pretty Blank Box
top

Blogroll

  • Development Blog
  • Documentation
  • Plugins
  • Suggest Ideas
  • Support Forum
  • Themes
  • WordPress Planet

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

Archives

  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
Powered by WordPress  |  Designed by Elegant Themes  |  Lightning Fast Hosting by Site 5 Hosting