Ultrashock Tutorials > Flash MX > Creating professional Flash components in seven easy steps  
 
by Aral Balkan, BitsAndPixels.co.uk
 Download PDF file of this tutorial 
Download Source Files 
 
Creating professional Flash components in seven easy steps - Step 2
 
 Introduction: What Makes a Professional Flash Component? 
 Step 1: Creating the component 
 Step 2: Building the Custom UI 
 Step 3: Adding Live Preview 
 Step 4: Creating Reference Panel Documentation 
 Step 5: Adding Code Hints 
 Step 6: Implementing Syntax Highlighting 
 Step 7: Packaging it up 

Flash MX Most Wanted Components

Aral Balkan is
co-author of
 Flash MX 
 Most Wanted 
 Components 

 Check it out 
 at Amazon! 

Step 2: Building the Custom UI

All but the simplest components can benefit from a Custom UI. In our case, the Very Simple Button component is so simple that we could, in reality, get away with not having a Custom UI. Since this tutorial is about the process of creating professional components, however, we're going to plough ahead and create a simple Custom UI. Open up very_simple_custom_ui.fla and very_simple_button_2.fla in Flash and follow along.

  1. First off, let's take a look at very_simple_button_2.fla. You'll notice that it looks very similar to the previous version of the file.
  2. Open up the Library (F11; Ctrl-L)


  3. Right-Click (Ctrl-Click) on the Very Simple Button component. From the context-sensitive menu, select Component Definition. You should see a panel similar to the one below.


  4. As you can see, I've added a Custom UI (very_simple_custom_ui.swf). Exit out of the Component Definition panel.
  5. On the Stage, click on the Very Simple Button component and take a look at the Property Inspector.


  6. Instead of showing you a list of the component's parameters like before, there should be a button there labeled: "Launch Component Parameters Panel". Click this button. Depending on the default size of your Component Parameters panel, you will either see the panel below:


  7. Or, this one:


  8. If you see the previous panel, resize it until the input controls become visible. I wish it was possible to open up the Component Parameters panel at the correct size but, alas, we'll need to wait for the next version of the Flash authoring tool for that! This method of displaying a message for the user to resize the panel is currently the best way we have to alert the user if the Component Parameters panel is too small for the Custom UI.
  9. Play around with the new Custom UI to get familiar with it. Try changing the label, font and font size and run the movie to see the changes.
  10. All right, so how did we make this? Well, you already know how we told our component to use a Custom UI, we simple entered the name of our Custom UI SWF in the Component Definition panel (see Step 3, above.) But what does the FLA for our Custom UI look like? Well, let's take a look. If you haven't done so already, open up very_simple_custom_ui.fla in Flash.
  11. First off, take a look at how the timeline is structured. There are four main frames, labeled preload, checkSize, main and expand. Let's go through each of these in turn since they constitute the major tasks that we must undertake when creating a Custom UI.


  12. Click on the preload frame on the actions layer. You should see following script:
    // don't scale
    Stage.scaleMode = "noscale";
    Stage.showMenu = false;
    Stage.align = "LT";
    
    // resize the background clip
    
    // frames
    _global.frames = {
            preload: 1,
            checkSize: 10,
            main: 20,
            expand: 30
    }
    
    // set global property to stop yellow focus rectangles
    _focusRect = false;
    
    // wait for the exchange object to become available
    _root.onEnterFrame = function() {
            if (typeof _root.xch != "undefined") {
                    delete _root.onEnterFrame; // delete listener
                    gotoAndPlay(frames["checkSize"]);
            }
    }
    
    stop();
        
  13. What we do in the preload frame is set the movie so that it does not scale (since we don't want it to scale when the developer resizes the Component Parameters panel) and to appear flush with the top-left of the Component Parameters panel. We also hide the focus rectangle (the ugly yellow rectangle that displays by default around movie clips and text fields when users use the Tab key.) Next, we set up an enterFrame listener to wait for the Exchange Object to be initiated. This is a workaround that's necessary due to another failing in the current version of the Flash authoring environment.

    The Exchange Object (which resides on the _root timeline and is called xch) is how we communicate between the Flash authoring environment and our Custom UI. When it is first initialized, it contains the component's default parameters (if any). As you will see when we look at the main frame in a second, the first thing we do is store these defaults so we can display them in our Custom UI. Then, we update the parameters in the xch object whenever the user updates an input control on our Custom UI. This, in a nutshell, is how a Custom UI works.

    Once the Exchange Object has been initialized, we remove the enterFrame listener (since it has now served its purpose) and move on to the checkSize frame.
  14. Click on the checkSize frame on the actions layer. You should see following script:
    /*
    Check the size of the stage and diplay message 
    if we can't display the full panel */
    COMPONENT_WIDTH = 400; COMPONENT_HEIGHT = 250; ENABLED_COLOR = 0xD4D0C8; DISABLED_COLOR = 0x808080; function onResize() { // set the size of the background color clip to fit bg_mc._width = Stage.width; bg_mc._height = Stage.height; // check if the component parameters panel is the correct size if ( Stage.height < COMPONENT_HEIGHT ||
                 Stage.width < COMPONENT_WIDTH ) { // too small, can't display full ui,
    // ask user to expand the panel
    // hide the layout boxes hideBoxes(); // set the bg to the correct color bg_mc.setColor(DISABLED_COLOR); // show the expand clip if (frames.expand != _currentframe) { gotoAndStop(frames.expand); } // eye candy - line divider line_mc._width = Stage.width; // position expand clip at center of stage expand_mc._x = Stage.width/2 - (expand_mc._width/2); expand_mc._y = Stage.height/2 - (expand_mc._height/2); } else { // ok, we can display the full ui // set the bg to the correct color bg_mc.setColor(ENABLED_COLOR); if (frames.main != _currentframe) { gotoAndStop(frames.main); } } } Stage.addListener(this); onResize(); // do it for the first time stop();
  15. The script on the checkSize frame is again necessary because of a shortcoming of the Flash MX authoring environment. Basically, the Component Parameters panel doesn't open up at the correct size to display the Custom UI. We thus need to constantly keep checking to know whether the Stage is large enough to display the Custom UI (this happens in the frame labeledexpand.). If it isn't, we display an icon alerting the user that they need to resize the panel. Once the panel is large enough to display the Custom UI, we move the playhead over to the frame labeledmain, where we actually display the Custom UI.

    You can easily take this FLA as a template and replace only the input components and logic in the main frame (and perhaps customize the "expand the panel" message) to create your own Custom UIs.
  16. All right, finally we're at the main frame. This is where we display the Custom UI. Click on the main frame on the actions layer. You should see following script:

    stop();
    
    // initializes the tab order
    function initTabOrder() {
            for (var i = 0; i < tabOrder.length; i++) {
                    tabOrder[i].tabIndex = i+1; // start tab order at one
            }
    }
    
    /*
    interface logic
    */
    
    // setup the tab order for interface elements
    tabOrder = [
            label_txt,
            font_cb,
            fontsize_slider,
            changeHandler_txt
    ];
    
    // get the font list for the label font selector
    var theFontList_array = TextField.getFontList();
    theFontList_array.sort();
    font_cb.setDataProvider(theFontList_array);
    
    /*
    get the current component parameters from the exchange object
    */
    label_txt.text = _root.xch.textLabel;
    font_cb.setEditable(true);
    font_cb.setValue(_root.xch.textFont);
    fontSize_slider.setValue(_root.xch.textSize);
    changeHandler_txt.text = _root.xch.changeHandler;
    
    /*
    update component parameters on the exchange 
    object when our input controls change */
    // label textfield label_txt.onChanged = function() { _root.xch.textLabel = this.text; } // font combo box fontOnChange = function( the_cb ) { _root.xch.textFont = the_cb.getValue(); } // font size slider fontSliderOnChange = function ( the_slider ) { trace (typeof the_slider.getValue()); _root.xch.textSize = the_slider.getValue(); } // change handler textfield changeHandler_txt.onChanged = function() { _root.xch.changeHandler = this.text; } // change handler for font name combo box font_cb.setChangeHandler("fontOnChange"); // change hander for font size slider fontSize_slider.setChangeHandler("fontSliderOnChange"); /* end of interface logic */ // set up the tab order initTabOrder()
  17. Take a look at the section in between the comments /* interface logic */ and /* end of interface logic */. This is the area that you can customize with your own code if you're going to use this FLA as a template. The first thing we do in this section is set up the tab order for our input controls. Setting up tab order allows the user to tab through the controls in a predictable fashion which, in turn makes for better usability (and accessibility) and is a must-have for professional components. To customize this for your own Custom UIs, substitute the instance names of your input controls in place of the ones currently in the tabOrder array.

    After having set up tab order, we move on to initializing our components. We load in the names of all installed fonts into the Label font combo box (drop down menu). Next, we look at the defaults passed to us in the Exchange Object (xch) and initialize our components with these defaults. All that's left is to set up handlers so that we can update the Exchange Object. We go through each of our input controls in turn and create change handlers for them. Finally, we call our initTabOrder method to set up the correct tab order.

Well, we've come quite far. We're about a third of the way there but we've still got quite a bit to think about. For one thing, did you notice how the Very Simple Button component on the Stage doesn't really reflect how it will appear when the movie is run? When you stretch it in the authoring environment, it scales. Nothing happens when you change the font or font size or the label text until you actually run the movie. Wouldn't it be great if a button instance on Stage in the authoring environment looked the same as it does when the movie is run? Wouldn't it be peachy if we could get instant feedback when we change the label or the font size? Well we can!

The feature that allows us to do this is called Live Preview and it requires the creation of yet another SWF (a Live Preview SWF.) In most instances, your Live Preview SWF will contain either a slightly modified version of the component (or may even contain the component itself.) Let's get cracking so you can see what I'm talking about.

 
©2003 Ultrashock.com - All rights reserved