Home / Tutorials / Components / Archive - Creating a Flash MX Component (Nov 2002) /

Flash Tutorials

Archive - Creating a Flash MX Component (Nov 2002) - Creating a Flash MX Component (Nov 2002)

Posted by : Librarian on Oct 28, 2008

 

5.0/5

Creating a Flash MX Component

This tutorial has been excerpted from the book "Flash for Interactive Simulation", by Jonathan Kaye and David Castillo, to be published by Delmar Thomson Learning, November 2002.

Flash MX Components introduce a powerful new tool for the Flash developer, expanding the application of Flash 5 SmartClips. This (long) tutorial walks you through the creation of a simple isosceles triangle component. It will teach you how to:

1. Apply new ActionScript instructions, such as #initclip and registerClass, to create a simple component with a custom icon, as well as using new methods such as addProperty to insulate your code better, and _targetInstanceName,

2. Touch on the mechanism that allows component inheritance,

3. Make an enhanced (custom UI) property inspector (Step 11), and

4. Make a Live Preview movie (Step 12)

While it may be possible to complete these tutorials using the Normal mode of the Actions panel, we highly recommend that you use the Expert mode for entering actions.

What is a Component?

Functions have parameters that customize the actions performed within it. Similarly, movie clips can be 'parameterized' to customize the animation, by defining variables (or 'properties') within them and setting those values from outside the clip before or during the execution of the animation, such as the minimum and maximum values for a dial. Therefore, a movie clip can be thought of as a parameterized animation.

Flash 5 introduced SmartClips as an easy way to create parameterized animations. Flash MX Components are the next generation of SmartClips. SmartClips enabled the creation of animations in a straightforward way that promoted sharing, reuse, and workflow efficiency. The limitation of SmartClips, however, was that they didn't fit programmatically into ActionScript's object-oriented framework. The main contribution of Flash MX Components is to integrate the SmartClip concept into the framework.

In addition to the ability with SmartClips to define a custom user interface ("property inspector") for the parameters, Components introduce Live Preview, an optional mechanism created by the Component developer that lets the user see in the authoring environment what a component will look like when it is active in the presentation.

To demonstrate how to create a custom component, we are going to build a simple isosceles triangle component that has the following properties: base, height, tint color, and a boolean flag indicating whether or not to apply the tint color. It will also have methods to get and set these properties, as well as area. After we show how to make the component and a custom icon, we will show how to create a custom User Interface, and then how to make a Live Preview movie.

Overview

A Component starts with a movie clip. We are first going to define the visuals for the triangle within a movie clip, and then write the ActionScript within the movie clip for the triangle class, properties, and methods. We then link the movie clip with the class definition. When the Component is placed in a movie, the class constructor is invoked. The triangle is very simple, so we do not need complex visuals or animation. The triangle has a base, a height, and a tint color property, a boolean flag (property) indicating whether or not to apply the tint, as well as a set of methods for reading and setting those values. The methods access the properties and manipulate the visuals.

Step 1. Create the triangle movie clip

The first step is to create the prototype triangle that we will scale and stretch according to the set base and height. Start by creating a new movie clip, naming it "Triangle Component". Inside that clip, draw an isosceles triangle any way you know how. Next, set the width and height of the triangle using the Property panel to be 10 pixels by 10 pixels.

Select the triangle, open the Align panel, select "To Stage", and align the triangle to the center (horizontally) and bottom (vertically). We align it to the bottom center so that when we place the component on the stage, we know that the base will remain in position when we scale the base and height. Your screen should look as follows:

Step 2. Define the triangle class

Now we will create the triangle class. Within the movie clip, add a new layer and label it "definitions". Open the Actions panel for the first keyframe and enter the following:

#initclip
function TriangleClass () {
this.cobj = new Color(this);
this.update();
}

// Allow TriangleClass to inherit MovieClip propertiesTriangleClass.prototype = new MovieClip();

// Update draws the triangle at the current base and height values.
TriangleClass.prototype.update = function () {
if (this.applyTint) {
this.cobj.setRGB(this.tcolor);
}
this._xscale = 10 * this.tbase;
this._yscale = 10 * this.theight;
}

// Connect the class with the linkage ID for this movie clip
Object.registerClass("FTriangle", TriangleClass);
#endinitclip

You have just defined the component class! Let's take a closer look at the instructions you used to get this far. #initclip and #endinitclip

Flash MX has two new statements ('pragmas'), #initclip and #endinitclip, that are used in defining components. When you make a component, you define a constructor for the class, define all the methods, and then register (connect) the class with the movie clip.

The #initclip and #endinitclip pragmas are used to mark a block of code for a component definition and registration. The code within the pragmas gets executed only one time during the playback of the whole movie, regardless of how many instances of the component you are using in the movie. The code within the pragmas is executed before any code in the timeline of the movie clip. This allows you to refer to class methods immediately when the clip is placed, overcoming a limitation of Flash 5 that required one to wait one keyframe before defined methods became available.

Note: The pragmas #initclip/#endinitclip are really only useful for defining components. At first glance, they may have seemed like they should work to evaluate a block of code on any timeline, but they do not.

Advanced #initclip

The mischievous among you may be wondering what would happen if you put something other than a method, constructor, or registerClass within the #initclip pragmas. The answer is that it will be evaluated at the _root level, with "this" referring to _root as well.

That means that you can refer to the component only through method definitions, so you have to avoid the temptation to use a statement such as "this.myProp = 5;" to try to set a property of the component outside of the constructor or a component method. You need to bring that statement into the constructor or into a method. That goes as well for defining event handlers, such as onEnterFrame or onPress.

If you want to define these event handlers for your component, they should be done as

myComponentClass.prototype.onEnterFrame = function () {...}

or from within a constructor or method:

function myComponentClass () { ... this.onEnterFrame = function () { ... } ... }

While the approaches are functionally equivalent, the former is more efficient if you want it to apply to the whole class because it defines the method once for the class, whereas the latter defines the method for each instance of myComponentClass.

The TriangleClass Constructor

function TriangleClass () 

This defines the constructor for the triangle component. When Flash creates the component, it will call this constructor and execute its actions. The properties (tbase and theight) are automatically set by default already (we will see how, later).

Setting Up Inheritance of Movie Clip Properties and Methods

TriangleClass.prototype = new MovieClip();

When you issue the instruction to connect the class definition to a movie clip, Flash reassigns the type of the movie clip to the type (class) we define. However, we still want the movie clip to behave like a movie clip, so we have to set up our new class to inherit the methods and properties of movie clips. Therefore, the statement above sets up the inheritance so that we can use any method and property of a movie clip with our component.

It is imperative that this statement follows immediately after the constructor and before any methods have been defined for the class.

Triangle Update Routine

TriangleClass.prototype.update = function ()

This method draws the triangle at the current base and height values. It first checks to see if we are supposed to apply the tint to the triangle, and, if so, it applies the tint. The property "applyTint" is a true or false value that tells us whether or not to apply the tint. However, once a tint has been applied, it cannot be removed, only tinted to something else. This is a limitation of our programming strategy, which has been kept as simple as possible for didactic purposes.

In this example, we multiply by 10 rather than 100 because we originally set the triangle to a width and height of 10.

Registering the Class with the Movie Clip

Object.registerClass("FTriangle", TriangleClass);

This is the critical instruction that links the class (TriangleClass) with the movie clip identified with the Linkage ID "FTriangle". In Step 6, we will label the component with this Linkage ID.

Step 3. Defining the Read and Write Methods for the Triangle Properties

It is time to define other methods we need for this component, namely those that set and access the base, height, and tint color values. As well, we will add a method to compute the area of the triangle. For the set routines, once we change the value to the value passed in, we redraw the triangle. For the get routines, we simply return the property value. Add the following methods within the same #initclip/#endinitclip block, any place after the MovieClip inheritance statement:

TriangleClass.prototype.setBase = function (b) {
  this.tbase = b;
  this.update();
}

TriangleClass.prototype.getBase = function () {
  return (this.tbase);
}

TriangleClass.prototype.setHeight = function (h) {
  this.theight = h;
  this.update();
}

TriangleClass.prototype.getHeight = function () {
  return (this.theight);
}

TriangleClass.prototype.setTintColor = function (c) {
  this.tcolor = c;
  this.update();
}

TriangleClass.prototype.turnOnTint = function () {
  this.applyTint = true;
  this.update();
}

TriangleClass.prototype.getArea = function () {
  return (0.5 * this.tbase * this.theight);
}
Step 4. Defining the Triangle Component Properties

It is now time to define officially the component parameters in the Component Definition window. Open the Library panel and find the Triangle Component movie clip you made (it shouldn't be hard, because it should be the only symbol in the Library). Open the Component Definition window by right-clicking (Windows) or Ctrl-clicking (Mac) on the movie clip and choosing "Component Definitionary".

In this window, you enter the parameters for your component. The plus and minus at the top are used to add properties or remove properties, respectively. By default, properties are added of type Default, with a value of defaultValue. These come out as Strings. Flash MX allows you to make properties of the following types: Default, Array, Object, List, String, Number, Boolean, Font Name, and Color. There are four columns in this topmost box. The first column, Name, is the text you would like to be shown in the component property inspector. The name may contain spaces, alphanumeric characters, and punctuation. You would enter a descriptive title for the parameter in this space.

The second column, Variable, is the name of the property name you use in your component scripts. This cannot have spaces or punctuation marks, except for the underline character (which may not be the first character). Having both Name and Variable allows you to use a short property name in your script, but to present a more descriptive phrase to help the component user understand what each value represents.

Note: If you specify a Variable but no Name, Flash puts the name of the variable in the property inspector. If you specify a Name but no Variable, you use that Name in your script to refer to the property.

The third column, Value, is the default starting value for the property. The final column is the type of the parameter, selected by choosing from the drop-down list. For our triangle component, add the following properties:

**Name****Variable****Value****Type**
Base Lengthtbase10Number
Heighttheight10Number
Tint Colortcolor0Color
Apply Tint?applyTintfalseBoolean

Since we do not yet have a custom User Interface or a Live Preview movie for the component, leave the next two lines, Custom UI and Live Preview, blank. If you want to enter a text description for to help users understand the function of your component, press the Set button on the opposite side (right) of the Description box. In the Description window that appears, select "Description Is Plain Text" and enter the description in the area provided. The other option is to create a formatted description in the Reference panel ("Description is a Reference Panel Item"). See the Flash documentation or Flash MX Developer Site for information on creating a reference panel description for the component.

Choose an icon for the component to accompany its name by pressing and holding the icon located directly beneath the Description label. In the next step, we will show you how to define a custom icon.

Beneath this area are two options: whether or not to lock parameters in instances (meaning that a user can or cannot add parameters when the component has been put on the stage), and whether or not to display the component in the Components panel. Note: If you check the "Display in Components panel", the component will not automatically be added to the Components Panel. We will talk about how to do this when we discuss deploying the component. Choose OK to continue.

Step 5. Setting a Custom Icon

Flash MX allows you to define a custom icon to represent the component in the Library, Movie Explorer, and Components panel, or you may choose one of the default icons from beneath the Description label in the Component Definition window.

In an image-editing program such as Photoshop or Fireworks, create a 24 by 20 pixel image (we recommend GIF or PNG with transparency, but it can be JPEG, too) to represent the component. Import the graphic into the Library directly (File > Import to Library). Flash links the custom icon you created with the component if you name the graphic in the Library with the same name as the component, and you place the graphic in a folder within the Library called FCustomIcons (create the folder, if you have not already).

When you close and re-open the Library, you will see your custom icon alongside the component name.

Step 6. Setting the Symbol Properties

If you have not done so already, close the movie clip and return to the main Scene. The movie clip you have created exists in the Library. You are now going to setup the Linkage ID by right-clicking (Windows) or Ctrl-clicking (Mac) on the triangle component in the Library, and choosing "Properties".

If your screen looks like only the top portion of this, press the Advanced button, located at the bottom beneath the Edit button. In the space marked Identifier (under Linkage), enter the Linkage ID we made up for the triangle component: FTriangle, for "Flash Triangle". Under the check box options, check Export for ActionScript and leave the others blank. This tells Flash to package the component by default with any movie that uses the component. Because you did not check "Export in first frame," Flash will load the component just before it is used in your movie. If you check Export in First Frame, Flash will preload the component in the first frame of that movie. The reason we typically do not preload the component in the first frame is for movie loading considerations on the Web. The component would be loaded before your preloader begins, defeating the purpose of the preloader. The two other options refer to creating components that can be shared at runtime. You can learn more about this feature by consulting the documentation.

Step 7. Trying Out the Triangle

You are now ready to test out your new component. Open the Library panel and drag an instance of the Triangle Component onto the stage. If you test the movie at this point (Control > Test Movie), you will see a triangle with a base and height of 10. Exit the test and we will see how we can set the properties to different values.

You can examine and change the component's properties through the Properties window, by right-clicking (Windows) or Ctrl-clicking (Mac) on the symbol (on the stage), and choosing Properties. You may change the values by clicking on the Value cell and typing in (or selecting, for Color) the new value. When you have set them to your preferences, test the movie and you will see the triangle displayed at the set size and tint (if you chose to set applyTint to true).

Step 8. Testing the Component Install within the Component Panel

Before you install the component, we recommend that you place the component movie clip into a new Library folder with the name of your component, as well as any other symbol you use within the component. When a person takes your component out of the Component Panel and into a movie, Flash copies the component into the Library. If you organize your component symbols in a folder, they will all be transferred in that folder and it will be easier for the user to know which symbols belong to the component.

You probably are eager to see and test your component in the official Component Panel, rather than just pulling it out of the Library. The best installation method is to use the Extension Manager, but for now all you need to do is to place your fla file in a special location (see table on the right) and Flash will install your component into the panel on startup.

Here are some things to check if you do not see your component in the Component Panel (accessible by selecting Windows > Components). The Component Panel comes up with the set of Flash UI Components by default. Next to the title is a drop-down list. Click on that, and see if the filename in which you saved the trangle appears there. If so, choose it and your component should be displayed in the box, with the icon you chose. If the file is there but your component is not, you probably forgot to check the box "Display in Component Panel" on the Component Definition window (Step 4). If the filename is not in the drop down list, you did not place the file in the correct folder. If you find that you need to change the code, replace the file in the special data storage area.

If you still cannot find the file, use the operating system's search function to locate it.

Step 9. Insulating your Implementation with Object.addProperty

We designed the triangle component with good programming practice in mind, namely, defining access methods such as setBase, getBase, etc. for the outside world to use in order to access internal variables tbase, etc. In that way, if we changed how we store the base internally, we would just have to fix getBase and setBase, for example, and we would not break developer's code that used the component. However, Flash does not have a way of enforcing public and internal (private) class areas, such as other object-oriented languages like C++. Unfortunately, that means rogue developers can go in and access and manipulate properties that you really never intended for them to see.

The new addProperty method allows you to define a property that, when accessed, calls a function to compute a value, instead of storing the value in a real variable. For example, we can define a property called "base" that uses setBase and getBase to do its setting and reading, respectively. When we tell the outside world to use "base", "height", and other of these properties, we know that they are really calling the functions we have defined and not using the internal variables. Therefore, if we change the internal implementation, we only have to update the access functions and code built with the component will behave properly.

Here is the code to add within the #initclip/#endinitclip block (after getBase and setBase have been defined):

TriangleClass.prototype.addProperty("base", TriangleClass.prototype.getBase, TriangleClass.prototype.setBase); 

The addProperty method takes three arguments: the name (in double quotes) of the new property, the method to use in order to access the 'value' of the property, and the method to use to store a new value. The get function must return the value, and the set function must accept one argument, which is the new value. The functions can do whatever computation is necessary to produce the property value. An example of this is the "area" property:

TriangleClass.prototype.addProperty("area", TriangleClass.prototype.getArea, null); 

As you can see from the code, we do not explicitly store the triangle's area, rather, we compute when requested to do so. From the user's perspective, it does not matter because we compute it when the user requests that property. For area of a triangle, there is no way to set its value explicitly, so we pass in null.

For completeness, we also define a "height" property (not to be confused with the _height property of the movie clip, which is the y axis extent of the component)

TriangleClass.prototype.addProperty("height", TriangleClass.prototype.getHeight, TriangleClass.prototype.setHeight);

Suppose a developer creates an instance of your triangle component called "tri0". We tell the developer about the public properties, namely area, base, and height. Now we do not have to worry about potential problems caused by implementation changes in the future.

Advanced: Robin Debreuil pointed out (thank you!) that one catch with this way of defining properties is that it will not work if you override the get or set methods for a sub-class, because the method will remain set from TriangleClass. To be the safest possible, if you believe your class may be sub-classed and the methods overridden, use the following as an example:

TriangleClass.prototype.addProperty("height", function () { return this.getHeight(); }, function (v) { this.setHeight(v); } );
Step 10. Programmatically Introducing a Triangle into a Movie

The most straightforward way to instantiate a triangle component is to drag it onto the stage from the Component Panel or, if you already have an instance on the stage, from the Library. However, you may want to dynamically create triangles through the course of the movie, and you would prefer not to have to create all the possible instances in the beginning. This is easily accomplished using either the attachMovie or duplicateMovieClip methods.

You simply specify the Linkage ID and Flash takes care of the rest, for example: attachMovie("FTriangle", "tri0", 10); The first argument is the Linkage ID, the second is the name of the new component on the current timeline, and the third is the depth (order). This statement pulls out the triangle component "FTriangle" from the Library, names the clip "tri0", places it on the stage at coordinates _x = 0, _y = 0, and sets its stacking order depth to 10, and calls the TriangleClass constructor. Clips placed on higher-value depths appear on top of clips placed on lower depths.

Before you rush off to try this out, we have to solve the problem of how to get component parameter values into the component at the time the constructor is called. If we did something like this: attachMovie("FTriangle", "tri0", 10);tri0.tbase = 5; We would be too late for the tbase variable to be used in the constructor. In our case, it would not make a difference, but in most cases it could have an impact. Flash MX does not leave you hanging. There is an optional final parameter (an Object) to attachMovie and duplicateMovieClip, which you can use as in the following example:

attachMovie("FTriangle", "tri0", 10, { tbase : 5, theight : 10, tcolor : 0x000000, applyTint : false } );

This code creates an Object (using { }) and populates it with tbase, theight, tcolor, and applyTint properties. Flash copies all the properties from that Object into the component instantiation it is creating, before invoking the component constructor. In that way, the properties are available to the constructor at the right time.

Done for Now!

If you've followed the tutorial so far, you will have a functioning triangle component.

There's obviously a lot more you can do with components than space permits us to describe here, including component inheritance (like the Flash UI Components), skinning, etc. The best place to look for more detail is to examine the source code that comes with the UI Components, which you will conveniently find in the data storage area indicated in Step 8.

The next steps are:

  • Creating a Custom User Interface
  • Creating a Live Preview Movie

Before going on to create a custom User Interface and a Live Preview, we want to present a new Flash MX feature, _targetInstanceName, that allows your components to modify stage elements onto which the component is dropped. We also will talk briefly about component inheritance.

_targetInstanceName: Creating Components that Change the Behavior of Other Stage Elements

We have taught you how to create a self-contained component, but one of the most exciting features introduced with Flash MX Components is the ability to create a component that modifies the behavior of some other stage element onto which it is dropped. For those of you who are familiar with Director, you will already know these as 'behaviors.

With this feature, you can drag the component onto some other stage element (e.g., a movie clip or text field) and have the component alter that stage element's properties. For example, the scroll bar component that Macromedia provides places and sizes itself to any text field onto which it is dropped, and automatically provides scroll bar functionality to that text field. The _targetInstanceName property tells the component the name (String) of the stage element onto which it has been dropped. To access the target object's properties or methods, you use the following syntax from within a component method: this._parent[this._targetInstanceName]. For example, to retrieve the width of the target object, you would write:

this._parent[this._targetInstanceName]._width

To make this property available, you include it in the list of your component parameters (see Figure above). You also get a special surprise: your component will 'snap' into place. When you drop your component over another stage element, your component will align itself with the upper left-hand corner of the target stage element. This is also a convenient visual check that the component has been connected with a target object. Alternatively, you can type in the name of the target object into the property inspector. If the component is not dropped onto a stage element, the _targetInstanceName property is set to the default value you give it when you add the property to the component's property list.

Setting Up Inheritance for Components

Now that you can sub-class movie clips easily with Components and tie them to user-defined classes, you can create hierarchies of animations that share foundational elements.

The essential idea is that you make your foundational class inherit from MovieClip, as we have done with triangles, and then sub-classes inherit from the foundational class (or other sub-classes). Because you must define the foundational class first, you must use an order number in the foundational class definition: #initclip 0

In your sub-classes, you use order numbers greater than the order number of parent classes, such as #initclip 1. This ensures that the foundational element class is defined before the sub-class. To establish the inheritance, in place of inheriting from MovieClip, you would use a statement such as: MySubClass.prototype = new FoundationClass(); Now your sub-class (MySubClass) will have all the properties and methods of the foundation (FoundationClass).

Macromedia's Flash User Interface Components, which include elements such as a list box, a combo box, a push button, and several more, are great examples of using component hierarchies. Each element has unique properties and methods to implement particular behavior, but they all share fundamental style properties and methods such as enabled/disabled states, sizing, and fonts. Designers can modify the global style sheet (GlobalStyleFormat) and all the components that draw from global elements will change. You can create your own composite component by inheriting from any of these classes, too.

When you create the movie clip for the sub-class, you can either place the parent component within the clip or bring the parent component in programmatically via attachMovie or duplicateMovieClip.

Step 11. Creating a Custom UI for a Flash MX Component

So far, we saw how to create a custom Flash MX Component for an isosceles triangle. In this tutorial, we expand on that discussion to show how to create a custom user interface.

A custom user interface is special Flash movie that you would make to allow those using your component to enter property values in a more convenient way than the default component property panel, as illustrated below:

Motivation

Being over the major hurdles as far as component creation is concerned, you bask in the glow from excited faces of your designers and developers eager to exploit the magic of your triangle component. One group whose faces are surprisingly not glowing is the Quality Assurance people, who now tell you that you have made it so easy to produce isosceles triangles for Flash movies that people are using them improperly. In fact, they tell you that if the base and height are out of a certain proportion, the triangle is no longer user friendly.

The head of Quality Assurance tells you that you must incorporate a 'user-friendly' metric into your component to warn developers when triangles are becoming dangerously unfriendly. To help, she gives you the industry-accepted, friendliness-to-user quotient for isosceles triangles: fuqu = (base * 4.211) / height; The ideal fuqu is 4.211, and the more it departs (either higher or lower) from this value, the more unfriendly the triangle becomes. Creating triangles with fuqu's below 2.211 or above 6.211 is even grounds for dismissal at your company.

Your altruistic side decides you need to alert users of your component before they make a fatal mistake. You will create a custom UI for the triangle component that alerts the user if the triangle violates corporate policy, based on the base and height they enter. This will not help programmers who script the component dynamically, but they are likely beyond hope already.

Creating the Custom UI

To create the custom UI, you create a new Flash presentation. The swf file will run either within the regular property inspector (dimensions are approximately 406 x 72 pixels) or within the component property panel (used when you need a larger area than what would fit in the property inspector).

You will need to create a means in this movie to retrieve the property values the component user will set, namely tbase, theight, tcolor, and applyTint. To build the fuqu index, you will include an indicator of the fuqu, with a warning when it departs from the ideal setting, and an alert when it violates the fuqu grossly.

The key element you need in your custom UI is a movie clip instance that Flash creates for you called "xch". You pass values to your component by having the custom UI write values to properties of xch, such as xch.tbase = 20;.

The custom UI should allow the user to enter new values. In our case, the interface will also show the fuqu warning, as necessary. When the movie with the triangle component is tested or published, Flash copies the properties and values on xch to the component so that it is ready to initialize itself with the values that the user entered.

Take the following steps to create a custom UI:

  1. Create a new movie and change its dimensions to 406 x 72.

  2. Create Static Text for "base", "height", "Red", "Green", "Blue", "fuqu =", "Rating:", and "0-255", and place them as in the illustration.

  3. Now, define the text fields we use to retrieve our tbase and theight property values. Create a base and a height text field (type: Input Text), place them above the corresponding Static Text field, and set the instance names to 'bs' and 'ht', respectively.

  4. Next, define input text fields we use to retrieve the tint color. Create three more Input Text fields, naming them 'rc', 'gc', and 'bc', (for red color, green color, and blue color), and place them above the corresponding Static Text field. The user will enter an integer between 0 and 255 to represent the amount of that particular color. Numbers below 0 will be set to 0, and numbers above 255 will be set to 255.

  5. So that the user can preview the color, we make a tile that shows the current tint setting. Use the drawing tool to create a square. Convert that square into a movie clip, and name the instance 'tintSq'.

  6. We can use a pre-defined Flash component, FCheckBox, to set whether or not the user wants to apply the tint color. Open the Components Panel and drag out a Check Box into its place on the stage. In the Properties window, set the text to "Apply Tint?" and its default value to false. Under the property Change Handler, enter tintApply. Name the instance apTint.

  7. Now we create the indicators to help the user make friendly triangles. To make the user aware of the fuqu value for the new triangle, create a Dynamic Text field, name it "fuquTF", and place it alongside the "fuqu =" static text.

  8. Next, create the fuqu rating indicator, which tells the user if the fuqu is PERFECT (4.211), ACCEPTABLE (between 2.211 and 6.211, but not 4.211), or FAIL. Create a new movie clip called "fuqu text" with three frames. In frame 1, place Static Text "PERFECT", in frame 2, place Static Text "ACCEPTABLE", and in frame 3, place Static Text "FAIL!". Make sure that these texts are left-aligned with respect to one another. In frame 1 of a new layer (label it "actions"), open the Actions editor for the keyframe and enter the instruction "stop();". Finally, close this movie clip and name the instance 'fuquEval'.

Ready or Not, Here we Code

  1. The final step is to write the code for the custom UI. In a new layer, enter the following into frame 1:

    fscommand("allowscale", "false");
    
    // Set the default property values. When the custom UI is activated,// this mechanism sets up our fields based on the current properties. 
    _root.onEnterFrame = function () {
    // Initialize the base and height text fields
    bs.text = xch.tbase;
    ht.text = xch.theight;
    // isolate the red, green, and blue fields of the color
    rc.text = (xch.tcolor & 0xFF0000) >> 16;
    gc.text = (xch.tcolor & 0x00FF00) >> 8;
    bc.text = xch.tcolor & 0x0000FF;
    aptint.setValue(xch.applyTint);
    compute_fuqu(xch.tbase, xch.theight);
    // Initialize the tint tile and color text fields
    tsc = new Color(tintSq);
    setTintSq(ParseInt(rc.text), ParseInt(gc.text), ParseInt(bc.text));
    // this initialization mechanism only needs to run once, so delete it
    delete _root.onEnterFrame;
    } 
    
    // Given a base and height value, compute the fuqu and set the
    // fuqu indicator based on the computed value
    function compute_fuqu (b, h) {
    var fuqu;
    
    if (isNaN(b))
    b = 0;
    if (isNaN(h))
    h = 0;
    
    fuqu = b/h * 4.211;
    
    if (fuqu == 4.211) {
    fuquEval.gotoAndStop(1);
    } else if (fuqu >= 2.211 && fuqu <= 6.211) {
    fuquEval.gotoAndStop(2);
    } else {
    fuquEval.gotoAndStop(3);
    }
    // Set the text field that shows the fuqu
    fuquTF.text = Math.round(fuqu * 1000) / 1000;
    }
    
    // Given a red, green, and blue color value (0-255), create a composite
    // color value, set the tint tile, and return the composite color value.
    function setTintSq(r, g, b) {
    var col = r << 16 | g << 8 | b;
    tsc.setRGB(col);
    return col;
    }
    
    // When the base and height text fields change, recompute the fuqu
    // and set the appropriate property in xch
    bs.onChanged = function () {
    xch.tbase = this.text;
    compute_fuqu(ParseFloat(this.text), ParseFloat(xch.theight));
    }
    ht.onChanged = function () {
    xch.theight = this.text;
    compute_fuqu(ParseFloat(xch.tbase), ParseFloat(this.text));
    }
    
    // Given an integer c, clamp it to values between 0 and 255 
    function boundColor (c) {
    if (isNaN(c))
    return 0;
    if (c < 0) {
    c = 0;
    } else if (c > 255) {
    c = 255;
    }
    return c;
    }
    
    // When the color text fields change, change the tint color
    // and set the appropriate property in xch
    rc.onChanged = function () {
    xch.tcolor = setTintSq(boundColor(this.text), ParseInt(gc.text), ParseInt(bc.text));
    }
    gc.onChanged = function () {
    xch.tcolor = setTintSq(ParseInt(rc.text), boundColor(this.text), ParseInt(bc.text));
    }
    bc.onChanged = function () {
    xch.tcolor = setTintSq(ParseInt(rc.text), ParseInt(bc.text), boundColor(this.text));
    }
    
    // The check box (c) calls this function when the user checks or unchecks
    // the box. Set the applyTint property of xch appropriately.
    function tintApply (c) {
    xch.applyTint = c.getValue();
    }
    

Just About Done!

  1. Save the movie to your hard drive, then test it (Control > Test Movie). This will create the swf in the same location you saved the file.

  2. The last step is to integrate the custom UI with the triangle movie. Go back to your triangle movie, open the Library, and select the Triangle Component. Open the Component Definition window, and to the right of "Custom UI", press the Set button.

  3. Next to Type, select "Custom UI with .swf file embedded in .fla file". The other option, "Custom UI in external .swf file" allows you to keep the custom UI outside of the triangle, which is good for testing rather than deployment. With this setting, you not only have to enter the absolute path to the file, which means that if you use the component on a different platform this has to be adjusted, but also you must distribute both files.

  4. Next to Display, select "Display in Property Inspector."

  5. Under "Custom UI .swf file", press Browse to locate the swf file, or Update if you have done this already and want to reload your Custom UI.

  6. Finally, press OK and when you select the triangle on the stage and the Properties window is open, you will see your custom UI.

That should take care of it! When you edit a component's properties, you should see the custom UI displayed and working.

The last step is to make a Live Preview movie for the triangle.

Step 12. Creating a Live Preview Movie for a Flash MX Component

In this last step, we will explain how to create a Live Preview movie, which allows a component user to see in the authoring environment what the component will look like when the movie is published. While the designer changes parameters, those changes are propagated to a customizable swf running in the authoring environment, and we make that swf look like the component and obey the set parameters.

This is a great feature that will make it easier to place components and design your movies better.

Motivation

It would help a great deal if your component users could see approximately what the triangle will look like on the stage while they are setting the triangle properties. This will help them design more efficiently because they will not have to waste time in the cycle of adjusting values, testing the movie, adjusting values, testing the movie, etc.

Flash MX introduces the Live Preview feature, which does exactly that. Essentially, you create a separate swf (like the custom UI), and you tell Flash to use that swf to display your component when it is placed on the stage (during authoring). You would typically make the swf to appear exactly like the component, based on the property values.

The triangle on the stage is a Live Preview movie we made.

Overview

With a custom user interface (UI), you set values within the xch object to transfer to the component. With Live Preview, you read values from the xch object. Like making a custom UI, you do not have to create the xch object for your Live Preview movie, as Flash does this automatically for you. Whenever the user has made a change to a component property, Flash invokes a function you define in the Live Preview called onUpdate. In that way, you are told when it may be necessary to update the preview you are displaying.

The Live Preview movie is designed for previewing basic characteristics of the component, such as color and size, rather than previewing animation, since the movie runs only at one (1) frame per second. This is designed not to hurt the performance of the authoring environment.

Let's now make a live preview movie for the triangle component. Before we begin, however, we need to consider how the Live Preview will be different from the actual component. In many circumstances, they will not be different, and it is perfectly acceptable to use and control an instance of your component within a Live Preview movie. In our situation, when we are using the real component, turning on the tint cannot be reversed. In the design phase, however, we may want to see what the triangle is like tinted and non-tinted. Therefore, we cannot use the same tinting code we did for the real component. Instead, we make two triangles, one for non-tinted viewing and one for tinted viewing. When the designer wants to see tinting, we apply the tinting, display the tinted triangle, and hide the non-tinted triangle. When the designer wants not to see the tinting, we hide the tinted view and display the non-tinted triangle.

The Process

Follow these steps to create the Live Preview movie.

  1. Create a new movie (file). Set the dimensions of the movie clip to be the same size as the triangle component movie clip, which are 10 by 10 pixels.

  2. Label the layer "plain triangle" and place a triangle that is aligned to the bottom center of the stage, exactly like in the triangle component (10 x 10 pixels). Convert this into a movie clip called "triangle graphic", and name the instantiation "tc". This triangle will be our non-tinted triangle.

  3. Create a new layer above "plain triangle" layer, call it "tinted triangle", then copy tc onto this layer as well. Rename the instance "tctint".

  4. Make a new layer and call it "actions". We are going to put our onUpdate function, which will read the property values and scale the triangle appropriately. Depending on whether or not to show the tinting, onUpdate will show and hide the appropriate triangle movie clips. Place the following code in the first keyframe:

    // Routine called whenever component properties have been changed.
    // Redraw the triangle based upon the new values. If the tint s/b applied,
    // use the tctint triangle. If it should not be applied, use tc.
    function onUpdate(){
    var ac = _root.xch.applyTint, b = _root.xch.tbase, h = _root.xch.theight;
    
    tc._xscale = 10 * b;
    tc._yscale = 10 * h;
    tctint._xscale = tc._xscale;
    tctint._yscale = tc._yscale;
    
    if (ac) {
    tc_color.setRGB(_root.xch.tcolor);
    }
    
    tctint._visible = ac;
    tc._visible = !ac;
    }
    
    // We maintain two copies of the triangle, tc, for regular non-tinted previewing,
    // and tctint, for tinted previewing. By default, hide the tinted triangle.
    tctint._visible = false;
    // Make a Color for tint to apply.
    tc_color = new Color(tctint);
    
  5. It is a good idea at this point to see that you have the Live Preview setting turned on. Pull down the Control menu to verify at the bottom that "Enable Live Preview" is checked. If it is not, select it to turn it on.

  6. Save your movie, and then test it (Control > Test Movie). This will create the swf you will use for the real Triangle Component.

  7. Now we need to connect the Triangle Component to the Live Preview movie. Open the movie in which you have defined the Triangle Component, then open the Library. Select the Triangle Component and choose Component Definition by right-clicking (Windows) or Ctrl-clicking (Mac) on it.

  8. Find the line that reads "Live Preview" and press the "Set" button on the right side. Select the line "Live Preview with .swf file embedded in the file." This bundles the Live Preview swf with the component definition fla. Alternatively, you can choose to keep the Live Preview swf external, which may be good for testing. However, you not only have to enter the absolute path to the file, which means that if you use the component on a different platform this has to be adjusted, but also you must distribute both files.

  9. Select OK, and then OK on the Component Definition window, and you are done! When you return to the stage, you should see your Live Preview movie running in place of your component.

The End...Or the Beginning?

Components are an exciting new feature of Flash MX. We hope that this tutorial has given you the building blocks to realize your component dreams.

Good luck with your work!

Jonathan and David

no comment

Add comment

Please login to post comments.


SUPPORTERS