Flash Catalyst: Mockup to Masterpiece, Part II

Tweet

In part one of this article we started building a small Rich Internet Application that would display music charts using data from a YQL query. We started with Adobe Illustrator to mock up the user interface for our app, then transferred the Illustrator file into Flash Catalyst to begin converting the design into an interactive piece.

In part two, we will continue adding interactivity in Catalyst, and then move into Flash Builder to finish it up. For fun, there’s a quiz at the end!

Creating Buttons From The Artwork

Each of the tabs on the left of our application will now be converted into a button component. We’ll do this by selecting both the text and background graphic for the first tab, and using the Heads Up Display (HUD) to convert it into a button. Repeat this process for the other two tab graphics.

Selecting the Popular Artists arrow

Converting the art to a Button component

Button components have four states:

  • Up, as a normal state for the button
  • Over, when the mouse is hovering over the button
  • Down, for when the button is being clicked
  • Disabled, for when the button may not be pressed

Buttons for each of these states appear within the HUD whenever one of your buttons has been selected. We can edit each of the states’ graphics individually by clicking on them.

Up, over, down, and disabled states

Double-click on the button with the blue arrow graphic to select it, and copy the button. Use the breadcrumb at the top of the Design area to switch out of the button, and then double-click one of the other two buttons. Go to the Over state, delete the graphic that’s there, then paste the blue arrow in its place. To align it precisely, look at the Properties panel and set the X and Y values to 0. You should now find that the arrow is positioned perfectly.

Something missing? The text in that state will most likely have disappeared, because the blue arrow will have been placed into a new layer above the text. To make it reappear, simply go to the Layers panel and grab and drag the text layer and drop it above the new graphic layer. This text will also need a change of font color.

Currently, Catalyst’s ability to edit graphics is quite limited. We’re able to modify this label’s size and opacity, but to change other attributes like color or font, we need to return to Illustrator. To do that, right click on the text object and choose Edit in Adobe Illustrator CS4.. You can do this either in the design area, or within the Layers palette.

Edit in Adobe Illustrator CS4

This will launch the artwork in Illustrator – only the text will be editable‚ and the remaining content will be disabled. You’ll also see a bold yellow message above the Illustrator artboard, telling you to save and close the window when you’re finished.

In Illustrator, change the font colour to white and save. Illustrator will prompt you to save with FXG options‚ FXG is the new language that Catalyst uses to exchange graphics between itself and Adobe design tools like Illustrator and Photoshop. Accept the defaults and close the file in Illustrator, and then switch back to Catalyst. There’ll be a dialog asking you whether you want to accept the Illustrator changes. Accept them, and you’ll see the text with its new colour.

Repeat that process for the button’s Down state. You’ll need to copy a grey background from one of the other two buttons to use for the Up and Disabled states in the Popular Artists button as it had the blue arrow graphic when we created it. You’ll also need to change the colour of the font for this button in Illustrator to black for the Up and Disabled states‚ so let’s do that now.

Adding States to the Repeated Item

Back in part one, we created a Data List component for the list of tracks. The repeated item in the Data List features some interactivity that may not be apparent until testing‚ you can do this by choosing File > Run Project. In your browser, you’ll see the application appear in a new tab or window. You should notice that when you roll over or click on an item, the items reveal a subtle light blue background: we’re going to adjust the background colour to be a bit brighter.

Double-click on the repeated item component to open it, and you’ll see the three states that represent different interactions‚ normal, hovered, and selected. Managing the appearance of the way the item changes across states is relatively easy; we simply edit the appearance of the object in each state, much as we did for buttons.

First, we’ll modify the colour of the background in the Hovered state. Right click on the background image and choose Edit in Adobe Illustrator CS4.. Change the fill colour of the graphic to a shade to your liking. Save the changes in Illustrator and switch back to Catalyst, accepting the change it asks for. You’ll see that the background colour of the Hovered state has been updated. We can do the same for the Selected state.

The music chart up/down arrow needs states too; we’ll show an up or down arrow to show how the track has changed chart position lately. Since none of the pre-set component types in Catalyst will be able to help us with this task, we’ll need to convert the arrow into a custom component. Select the arrow and select Custom/Generic Component from the Convert Artwork list. Then, choose Duplicate State from the top left of the screen‚ it’s a small button just below the Pages/State list. At the top right of Catalyst is a toolbar: clicking the last one, Transform, will let you rotate the arrow to point down. Double-clicking on the name of a state will allow you to rename it. Here, I’ve named the states trackUp and trackDown, respectively.

Editing the arrow

Adding States To The Application

The list will look a little empty until the user has selected a music chart to display. We’re going to set the application to start with the list hidden, only displaying it once the data has been fetched from Yahoo. We’re going to use two application states to achieve this effect.

Duplicate the current state and rename it to defaultState, then name the second one chartState. Select the Data List in defaultState and delete it: you’ll see that the list is still in the second state when you switch between the two.

Our two states: defaultState and chartState

When a user presses one of the chart buttons on the left, we’d like to show the chartState. To make this happen, we’ll choose one of the buttons in the first state and select the plus button to the right of Custom Interactions in the HUD. Choose On Click from the list. From On Click Interactions choose Play transition to state and choose chartState from the list. For the user, clicking on the button will make the list appear. Later, we’ll add code to that button in Flash Builder to call a Yahoo YQL query to fetch the data to display in the list.

Adding a new custom interaction

On click, the button will make a transition to chartState

Repeat the process for each of the buttons. With the interactions added you should see that each object has a Fade transition effect added to the Timeline below the design view. The switch between states’ actions can be animated with that Fade effect. Sliding the effect in the Timeline to control it is quite intuitive: simply grab it and move it. You’re now ready to test the interactions. Choose File > Run Project to run the application again, and click on the buttons to see the change between states. Adjust the interaction changes in the Timeline to taste.

We’re going to add one more state to the application to serve as a detail view for the repeated items: this will use the artwork from the detailed view we created all the way back in part one. The additional panel will behave like a pop up to display other releases for a selected artist.

Start by duplicating chartState – call the new state artistDetailState. The design has a pop over panel to display the new information. We’re going to dim the current content for this state as the detail panel appears. Do this by selecting all the items in the state except the background graphic, and set their opacity to 40 in the properties panel.

If you look carefully at the Layers palette you’ll see a layer called Overlay. This contains all the objects that will be shown in the detail state. When we do this, we’ll make the repeated item a button. Go back to chartState and enter the Data List component by double-clicking on it, then open the repeated item by double-clicking again, and select its background. Convert the background into a button using the HUD and set its On Click event to play to artistDetailState. The Fade effect in the Timeline will do a really nice job of transitioning the opacity later on if you choose to use it. The detail view has repeated data in its design. Later, we’ll convert this to a component in Flash Builder. For now, delete the text, leaving the title text as is.

Oops‚ I’ve just realised we forgot to provide a way of closing the panel in the artwork! This is a great excuse to show you how to create a new button from scratch in Catalyst.

To do it, draw a circle with the Ellipse tool found in the toolbar at the top right of Catalyst‚ it looks like a circle itself. Add a letter X with the Text tool to the center of the circle and select the two, converting them to a button from the HUD‚ feel free to edit the button to have other graphics in the other states if required. Add an On Click interaction to the new button and set it to switch back to chartState to close the panel.

With all of the interactions the way we want them, we’re almost ready to complete the project in Flash Builder! This is a great time to double-check that you’ve saved your work.

Coding Data Services In Flash Builder

While we’ve been working on our project, Catalyst has been building a number of MXML files that Flash Builder can compile to Flash. It’s possible to view that code right here in Catalyst by switching from Design to Code view‚ do this by using the pull-down menu at the top right in Catalyst. Save the Catalyst project and then launch Flash Builder.

In Flash Builder, you can create a project from an FXP file by selecting File > Import Flex Project (FXP). Using the navigator on the left, locate the project’s root file at src > (default package) > Main.mxml. You’ll see that there is a fx:Script block at the top of the code that contains functions for each of the three buttons that you created in Flash Catalyst. Also, note the s:transitions tag pair, which contains any transition effects you may have added via the Timeline in Catalyst. Below that the states are defined in the s:states tag pair. Finally, you should see buttons and other visual elements, all of which have been assigned instance names that we can access from ActionScript.

We’re going to be calling a Yahoo service called YQL to fill our application with data. It’s a language that you can use to query data from web services. You will need to have a developer account with Yahoo to build and test with YQL: more details can be found at the Yahoo developers’ site. YQL queries are simply URLs with your query attached as a string at the end. You can choose to have the results returned as either XML or JSON using an additional variable at the end of the URL to indicate the return type‚ &format=xml or &format=json, respectively.

The Flex HTTPService component is used to call a remote HTTP service. We need to add one HTTPService for each YQL call, and both these tags need to be nested in a pair of fx:Declarations tags.

Below is an example of a HTTPService call to a YQL service to retrieve the most popular music tracks. The URL value of the tag is the YQL query. The tag’s result attribute indicates what function to use once the query result is received. Flash Builder will prompt to create the outline of a function for you if you add that attribute, which is what we’ve chosen to do here. The resultFormat attribute is used to indicate how the result’s data will be typed. To provide feedback to the user, we’ve also used the showBusyCursor attribute to change the cursor while the data is being fetched.

<s:HTTPService id="trackPopularService"    
 url="http://query.yahooapis.com/v1/public/yql?  
 q=select%20*%20from%20music.track.popular"  
 result="releasePopularService_resultHandler(event)"  
 resultFormat="xml" showBusyCursor="true"/>

These services will be called by clicking on one of the buttons that we created in Flash Catalyst. There’s a click handler function for each button already in the fx:Script block at the top of the code. These click handlers were created in order of button creation by Catalyst – you may need to run the application later to double check that the names match the positions. Here’s an example of one of these button click handlers: we’ve added a second line to it to call the URL of the HTTPService discussed above.

protected function Button_click():void   
 {  
   currentState='chartState';  
   trackPopularService.send();  
 }

The function that will be called once the result has been received has a ResultEvent parameter, which in turn has a result property. This is where we’ll find the XML data that we need to populate the Data List. Flex data components have a dataProvider property that typically has an ArrayCollection assigned as its value. This is a wrapper class that exposes an array as a collection, but essentially is an array of objects that has additional methods and properties. We’ve already defined a variable typed as ArrayCollection called chartData in the script block and made that bindable so that any component using that variable as a dataProvider will update if the ArrayCollection changes. Here’s that variable:

[Bindable] private var chartData:ArrayCollection = new ArrayCollection();

The function for the result of the first HTTPService call is listed below. You’ll notice that we reset the chartData ArrayCollection by re-initializing it. We then create an XML variable out of the event’s result property, then loop over the XML to parse it. With each iteration of the loop we create an object called dataObj and add properties to it which are equal to specific values in the XML. The last thing that we do in the loop is use the ArrayCollection‘s addItem method to add dataObj to it.

protected function releasePopularService_resultHandler(event:ResultEvent):void   
 {  
   chartData = new ArrayCollection();  
   var resultsXML:XML = XML(event.result);  
   var tracksXMLList:XMLList = resultsXML.child("results").children();  
   var len:Number = tracksXMLList.length();  
   for ( var i:Number = 0;i<len;i++) {  
     var dataObj:Object = new Object();  
     dataObj.track = tracksXMLList[i].attribute("title");  
     dataObj.artist = tracksXMLList[i].child("Artist").attribute("name");  
     dataObj.artistID = tracksXMLList[i].child("Artist").attribute("id");  
     dataObj.chartNow = tracksXMLList[i].child("ItemInfo").child("ChartPosition").attribute("this");  
     dataObj.chartPrevious = tracksXMLList[i].child("ItemInfo").child("ChartPosition").attribute("last");  
     chartData.addItem(dataObj);  
   }  
}

Binding Data In Flash Builder

The Data List we created in Catalyst is used as the skin for a Flex List component. That’s located in the code below the three buttons, which you’ll see in the following example. Catalyst has manually added values to populate the list by nesting an ArrayCollection. You’ll see that the dataProvider attribute is there, but has an empty string value. We’re going to delete that ArrayCollection and bind the dataProvider attribute to our chartData ArrayCollection. Below, you’ll notice I’ve used a pair of curly brackets, this will repopulate the list if the value of chartData changes.

<s:List x="200" y="89" skinClass="components.DataList1" id="list1" includeIn="artistDetailState,chartState" alpha.artistDetailState="0.4" dataProvider="{chartData}"/>

The repeated item that we built in Catalyst is now a component in the Flex project. It’s stored in a file, RepeatedItem1.mxml, which can be found in the components folder of the project. Open it and you’ll see RichText components that we’ll need to populate with data from the List’s dataProvider. You should see that the text attribute of each of the RichText components is already bound to a property of an object called data‚ this is the collective name given to the values passed by the List component the current row as it loops over the dataProvider. We need to update the text attribute of each of these RichText tags to equal the data we’ve received.

The example code below is one of the RichText components from RepeatedItem1.mxml. Look at the text attribute of this tag and you’ll see that its value is bound using curly brackets‚ this means it will update to the current value assigned, which in this case is data.chartNow. The chartNow value is in the chartData ArrayCollection that we populated with the function detailed above. It’s one of the properties of the dataObj object that we built and populated while we looped over the XML data received from the YQL service call. Check the other RichText tags and you’ll see that we’ve also updated ours to equal other properties in the data from the ArrayCollection.

<s:RichText width="38" height="54"    
 textAlign="center" fontFamily="Helvetica"    
 fontSize="30" lineHeight="120%" color="0xffffff"    
 whiteSpaceCollapse="preserve" kerning="on"    
 ai:knockout="0" d:userLabel="5" text="{data.chartNow}"    
 x="14" id="richtext1" y="18"></s:RichText>

We’ve added a function to the fx:Script block of RepeatedItem1.mxml to change the display of the chart arrow to either up, down or hidden based on music chart movement. It’s using the chartNow and chartPrevious values from the same data we used to populate the RichText tags. The function is controlling the chart arrow component, which in this case will have a name like customcomponent11. That function is called each time we render a row by using the opening tag’s render event. You’ll find that in the first line of code in RepeatedItem1.mxml in our sample version. The function is detailed below:

private function chartPosIndicator():void {    
 if (data.chartPrevious == "0" ) {    
   customcomponent11.visible = false;    
   richtext2.text = "new";          
 } else if ( Number(data.chartNow) < Number(data.chartPrevious) ) {    
   customcomponent11.currentState = 'trackUp';    
 } else if ( data.chartNow == data.chartPrevious ) {    
   customcomponent11.visible = false;    
   richtext2.text = "";    
 } else if ( Number(data.chartNow) > Number(data.chartPrevious) ) {    
   customcomponent11.currentState = 'trackDown';    
 }    
}

The other function in RepeatedItem1.mxml calls a public method in the parent file, Main.mxml, passing the artistID and artist values for the current row.

protected function Button_click():void    
{    
 mx.core.FlexGlobals.topLevelApplication.showArtistReleases(data.artistID,data.artist);    
}

This function in turn assigns the values received to local variables already created, calls the send method of the last HTTPService, and changes the state of the application to artistDetailState.

    
public function showArtistReleases(selectedArtistID:Number,selectedArtistName:String):void {    
 artistID = selectedArtistID;    
 artistName = selectedArtistName;    
 releaseArtistService.send();    
 currentState='artistDetailState';    
}    

The fourth HTTPService call uses a parameter to retrieve releases for a specific artist. We need to use the data from the row that the user clicks on to make that work, which is why we’re using the two functions listed above. The first calls the second from within RepeatedItem1.mxml, passing the artistID needed as a parameter for the HTTPService call. Within the second function, we’re assigning that artistID to a local variable that we’re using within the url attribute of the last HTTPService call. Below is that URL, and if you look towards the end of the value you’ll see {artistID}, which is a binding to the variable.

url="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20music.release.artist%20where%20id%3D%22{artistID}%22"

The result handler function for that service call is similar to the other result functions. Instead of the chartData ArrayCollection, we’re populating another ArrayCollection called otherReleasesArtist. This is used to populate a DataGrid component that we’ve added to the details panel we build as part of this article. The panel can be found in the components directory as CustomComponent2.mxml. We’ve added an ArrayCollection to this component and used it as the dataProvider for the DataGrid, setting the ArrayCollection as public so that we can change its value from Main.mxml – this is set in the last line of the result handler listed below. We’re also setting the title of the panel to the artistName variable passed when RepeatedItem1.mxml was clicked.

    
protected function releaseArtistService_resultHandler(event:ResultEvent):void    
{    
 otherReleasesArtist = new ArrayCollection();    
 var resultsXML:XML = XML(event.result);    
 var tracksXMLList:XMLList = resultsXML.child("results").children();    
 var len:Number = tracksXMLList.length();      
 for ( var i:Number = 0;i<len;i++) {    
   var dataObj:Object = new Object();    
   dataObj.releaseTitle = tracksXMLList[i].attribute("title");    
   dataObj.releaseYear = tracksXMLList[i].attribute("releaseYear");;    
   otherReleasesArtist.addItem(dataObj);    
 }    
 customcomponent21.artistName = artistName;    
 customcomponent21.otherReleasesData = otherReleasesArtist;                  
}

And that should be it! Save your work, and test your application by pressing the Run button at the top of Flash Builder. If all went well, chart data should start flowing into the completed application.

You can view my completed app here, and if you’re interested in viewing the complete source of my project, you can download my Flash Builder project here.

The app is running!

Designers and Developers, Together at Last

Through both parts of this article we have demonstrated how to design a Flash application interface using Illustrator, and then convert the resulting Illustrator file into interactive Flash content using Flash Catalyst. Designers can now easily translate their design skills into interactive user interfaces and add functionality using Flash Builder. So, congratulations – you’ve just created a Flash masterpiece!

Why not test your knowledge of this article with our quiz?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

No Reader comments