Showcase and discover digital art at yex

Follow Design Stacks

Subscribe to our free newsletter to get all our latest tutorials and articles delivered directly to your inbox!

Skinning with Code

Skinning with Code

In general, if you want more control over your skinning, you must use code. In some cases, this method also offers skinning options not available in the previously studied methods. Some methods are quite simple, while others can be quite involved.

Use the Prototype Method

The prototype method is the easiest coding method. This method involves writing code that redefines the default value of skin properties.

Take the Button component, for example. If you wanted to set the four main values for skin properties ( falseUpSkin, falseDownSkin, falseOverSkin, falseDisabledSkin) you would do the following (the finished result can be found in the Prototype folder of the downloadable sample code):

  1. Create a movie clip symbol for each state in your library.
  2. Be sure the Linkage identifier is set for each state; usually its best to follow some standard naming convention. For this example, I use the BlueButtonUpSkin, BlueButtonDownSkin, BlueButtonOverSkin, and BlueButtonDisabledSkin identifiers (see Figure 2).

    The completed Linkage Properties dialog box for the BlueButtonUpSkin identifier

    Figure 2. The completed Linkage Properties dialog box for the BlueButtonUpSkin identifier

    Notice that I didn’t set the symbol to export in the first frame. If you don’t mind exporting all your symbols on the first frame, then you can leave the Export in first frame checkbox selected and skip to step 7.

  3. Create a new movie clip symbol called FirstFrameExporter. The symbol doesn’t need to have a linkage identifier. In the new movie clip symbol we will create two frames.
  4. On the first frame you will have a stop() function call.
  5. Place the four symbols you created in step 2 on the second frame (see Figure 3).

    The completed FirstFrameExporter symbol

    Figure 3. The completed FirstFrameExporter symbol

  6. Place a copy of that new symbol on the Stage. Notice it will end up being just an empty item with the registration point visible. It’s usually easiest to place that symbol at the registration point 0,0.
  7. Finally, you need to place the code that will set the values of the properties equal to the Linkage IDs. The easiest way is to open the FLA file, go to the main Timeline, and enter the following code:

    mx.controls.Button.prototype.falseUpSkin = "BlueButtonUpSkin";
    mx.controls.Button.prototype.falseDownSkin = "BlueButtonDownSkin";
    mx.controls.Button.prototype.falseOverSkin = "BlueButtonOverSkin";
    mx.controls.Button.prototype.falseDisabledSkin = "BlueButtonDisabledSkin";
  8. Place a Button component on the Stage.
  9. Select Control > Test Movie to view the result.

This method is the simplest method for skinning components through code. It has the benefit of enabling you to redefine the skin property values of all instances of a component in one place. With the previous example, all Buttons added to our project will use those new default values rather than the default values the component was originally set to.

This method also has the advantage of enabling you to set skin property values for subcomponents of a component. A good example of this use is the ComboBox component, which uses a ListBox component. If you set the skin property values for a ListBox using this method, the ComboBox ListBox will automatically use the new value.

However, this method has one downside, which may not affect you—the ability to skin a component on an instance basis. Many times this is not needed, but there are times when you want to set the skin property values of a component specifically for that instance. In that case, you can use one of the other methods that require code.

Pass in the Values with initObject

Another approach similar to the using the prototype method is passing in the new skin property values to the initObject object when attaching a component through code, rather than setting them through the prototype method. To achieve this method, you can follow these steps:

  1. Open the FLA file you created in the previous example.
  2. Remove the code you placed on the main timeline and delete the instance of the Button component from the Stage. Make sure you don’t delete the instance in the Library as we will need that to attach the component through code.
  3. On the main timeline, create an initObject object with the properties and values of the skin properties and pass the object to the createClassObject() calls, using the following code:

    var initObj:Object = new Object();
    initObj.falseUpSkin = "BlueButtonSkin";
    initObj.falseDownSkin = "BlueDownSkin";
    initObj.falseOverSkin = "BlueOverSkin";
    initObj.falseDisabledSkin = "BlueDisabledSkin";
    createClassObject(mx.controls.Button,"myButton",1,initObj);
  4. Select Control > Test Movie to view the result.

This method offers several benefits. For example, it enables you to specify the values on a per component instance basis. Although some applications can live with a single skin per component, often you run into situations where you need that extra level of control.

This method does have some drawbacks though. The most obvious is the requirement to specify this information for each and every instance of a component. It can sometimes get tedious to do this for each component you plan to use. Another requirement is having to attach the component through code. I almost always attach my components through code, but for times when you want to place a component on the Stage, this method won’t work.

Overall, I prefer to use a mixture of the method described in this section and the prototype method in my applications. It’s a personal preference, but I’ve found that using the prototype method I can define global settings, and the per instance method enables me to override those values for the times in my application where the component will not use the values set using the prototype method.

Subclassing a Component Class

The last method that I want to discuss is subclassing a component class to define the skin property values. This approach enables you to create a subclass of the component that doesn’t do anything but define new skin property values.

Follow these steps:

  1. Create a new FLA file and save it.
  2. Open the file StandardComponents.fla located in the C:Program FilesMacromediaFlash MX 2004enConfigurationComponentFLA (Windows) or Hard Drive/Users/ <username>/Library/Application Support/Macromedia/Flash MX 2004/ <language>/Configuration/ComponentFLA (OS X) directory.
  3. Open the libraries of both FLA files.
  4. Create a new folder in the library in the blank FLA called Flash UI Components 2.
  5. Locate the Button component base symbol (Main Button component symbol) in the file StandardComponents.fla and drag it to the library folder you created in step 4. The symbol is located in Flash UI Components 2 of the library. Your Library panel now should look similar to Figure 4.

    Completed copying of Button component-related symbols

    Figure 4. Completed copying of Button component-related symbols

  6. Create another folder in the Library panel called My Components.
  7. Create a duplicate of the main Button component symbol in the new folder.
  8. Specify an identifier and a class for the duplicated symbol. For this example, I used com.rewindlife.controls.MyButton for both and cleared the Export in first frame check box (see Figure 5).

    Completed Duplicate Symbol dialog box

    Figure 5. Completed Duplicate Symbol dialog box

  9. Create a folder called Skins in the My Components library folder.
  10. Create four skins for the different states of the Button and include the linkage identifier as you did in steps 1 and 2 of the prototype method. Alternatively, you could also copy the symbols from the library of the prototype method example to this one.

    The library should now look like Figure 6.

    Added Skins and MyButton symbol

    Figure 6. Added Skins and MyButton symbol

  11. Double click the MyButton symbol and locate the second frame of the assets layer. Drag the four new skins and place them on the second frame to ensure they are exported properly when Flash is ready to compile your new skinned component (see Figure 7).

    The MyButton symbol with the skins

    Figure 7. The MyButton symbol with the skins

    Now you have completed all the work you need to do before writing any code. The last step is to write your component class which will be a subclass of the Button class.

  12. Create a new folder to place your class in the proper package (in this example, the package is com.rewindlife.controls, so you will create com/rewindlife/controls folder structure) and create a new ActionScript file called MyButton.as and save it in that folder (see Figure 8).

The Folder structure with new class file

  • Figure 8. The Folder structure with new class file

    In the MyButton.as file include the following code:

    //It is good practice to include this information
    //and in some instances it is required
    import mx.controls.Button

    class com.rewindlife.controls.MyButton extends Button
    {
    //these values are required for every components,
    //we set the symbolName equal to the symbol identifier
    //of our components
    //
    //We set the symbol ownder equal to the fully qualified
    //class name.
    //
    //We can copy these values from the original Button class
    //as a starting point, the Class file can be found here:
    //C:Program FilesMacromediaFlash MX 2004en
    // First RunClassesmxcontrols
    //
    static var symbolName:String = "com.rewindlife.controls.MyButton";
    static var symbolOwner = com.rewindlife.controls.MyButton;
    //Here we define the SkinIDs, again we can easily open the
    //Button class and copy/paste the current values as a good
    //starting point
    var falseUpSkin:String = "BlueButtonUpSkin";
    var falseDownSkin:String = "BlueButtonDownSkin";
    var falseOverSkin:String = "BlueButtonOverSkin"
    var falseDisabledSkin:String = "BlueButtonDisabledSkin";
    }
  1. Place the MyComponent component symbol on the main Stage and select Control > Test Movie to view the result.

As you have seen, this method is the most involved of the coding methods to set up. It might not seem worth it at first, but it definitely has several benefits. For example, it enables you to create different buttons and easily re-use a button without having to redefine the skin property values each time (as you would have to do with the initObject method).

I like to use this method when I am working on a project with multiple interfaces, and those interfaces will share certain common skin property definitions. With this method I can create a Button and re-use it through all the projects without having to rewrite anything. If I ever want to change the skin property values for that component later on, I can edit that single class file and re-export all my interfaces with the updated values. This is also the only coding method that enables me to use components that are skinned through code without any code (that is, once this method is set up).

When working in teams, developers may at times set up such components for designers to give designers access to the component. You can also package your new component as a SWC file with this method, if you want. In larger teams this can prove to be a very valuable benefit.

Comments

Skinning with Code

Skinning with Code

In general, if you want more control over your skinning, you must use code. In some cases, this method also offers skinning options not available in the previously studied methods. Some methods are quite simple, while others can be quite involved.

Using the Prototype Method

The prototype method is the easiest coding method. It involves writing code that redefines the default value of skin properties.

Take the Button component, for example. If you wanted to set the four main values for skin properties (falseUpSkin, falseDownSkin, falseOverSkin, and falseDisabledSkin), you would do the following—the finished result can be found in the Prototype folder of the downloadable sample code:

  1. Create a movie clip symbol for each state in your library.

    Be sure the linkage identifier is set for each state. Usually it’s best to follow some standard naming convention. For this example, I use the BlueButtonUpSkin, BlueButtonDownSkin, BlueButtonOverSkin, and BlueButtonDisabledSkin identifiers (see Figure 2).

    Completed Linkage Properties dialog box for the BlueButtonUpSkin identifier

    Figure 2. Completed Linkage Properties dialog box for the BlueButtonUpSkin identifier

    Note that I didn’t set the symbol to export in the first frame. If you don’t mind exporting all your symbols on the first frame, you can leave the Export in First Frame option selected and skip to Step 5.

  2. Create a new movie clip symbol and name it FirstFrameExporter. The symbol doesn’t need to have a linkage identifier. In the new movie clip symbol you will create two frames.
  3. On the first frame you will need a stop() function call. Place the four symbols you created in Step 1 on the second frame (see Figure 3).

    Completed FirstFrameExporter symbol

    Figure 3. Completed FirstFrameExporter symbol

  4. Place a copy of that new symbol on the Stage. Notice that it ends up being just an empty item with the registration point visible. It’s usually easiest to place that symbol at the registration point 0,0.
  5. Place the code that will set the values of the properties equal to the linkage identifiers. The easiest way is to open the FLA file, go to the main Timeline, and enter the following code:
    mx.controls.Button.prototype.falseUpSkin = "BlueButtonUpSkin";
    mx.controls.Button.prototype.falseDownSkin = "BlueButtonDownSkin";
    mx.controls.Button.prototype.falseOverSkin = "BlueButtonOverSkin";
    mx.controls.Button.prototype.falseDisabledSkin
    = "BlueButtonDisabledSkin";
  6. Place a Button component on the Stage.
  7. Select Control > Test Movie to view the result.

This method is the simplest method for skinning components through code. It has the benefit of enabling you to redefine the skin property values of all instances of a component in one place. With the previous example, all Button components you add to your project will use those new default values rather than the default values to which the component was originally set.

This method also has the advantage of enabling you to set skin property values for subcomponents of a component. A good example of this use is the ComboBox component, which uses a ListBox component. If you set the skin property values for a ListBox component using this method, the ComboBox ListBox component within the ListBox component will automatically use the new value.

However, this method has one downside, which may not affect you—the inability to skin a component on an instance basis. Many times this is not needed, but there are times when you want to set the skin property values of a component specifically for that instance. In that case, you can use one of the other methods that require code.

Passing in the Values with initObject

Another approach similar to the prototype method is passing in the new skin property values to the initObject object when attaching a component through code, rather than setting them through the prototype method. To achieve this method, you can follow these steps:

  1. Open the FLA file you created in the previous example.
  2. Remove the code you placed on the main Timeline and delete the instance of the Button component from the Stage. Make sure you don’t delete the instance in the library—you will need that to attach the component through code.
  3. On the main Timeline, create an initObject object with the properties and values of the skin properties and pass the object to the createClassObject() calls, using the following code:
    var initObj:Object = new Object();
    initObj.falseUpSkin = "BlueButtonSkin";
    initObj.falseDownSkin = "BlueDownSkin";
    initObj.falseOverSkin = "BlueOverSkin";
    initObj.falseDisabledSkin = "BlueDisabledSkin";
    createClassObject(mx.controls.Button,"myButton",1,initObj);
  4. Select Control > Test Movie to view the result.

This method offers several benefits. For example, it enables you to specify the values on a per-component instance basis. Although some applications can live with a single skin per component, you will often run into situations where you need that extra level of control.

This method does have some drawbacks, however. The most obvious one is the requirement to specify this information for each and every instance of a component. It can get tedious sometimes to do this for each component you plan to use. Another requirement is having to attach the component through code. I almost always attach my components through code but if you usually don’t, and you place a component on the Stage instead, this method won’t work.

Overall, I prefer to use a mixture of this initObject method and the prototype method in my applications. I use the prototype method to specify the overall default values of components within an application and the initObject method to override those defaults on a case-by-case basis where needed.

Subclassing a Component Class

The last method I want to describe is subclassing a component class to define the skin property values. This approach enables you to create a subclass of the component that doesn’t do anything but define new skin property values.

Follow these steps:

  1. Create a new FLA file and save it.
  2. Open the file StandardComponents.fla located here:

    • (Windows) C:Program FilesMacromediaFlash 8<language>ConfigurationComponentFLA
    • (Macintosh) Hard Drive/Users/<username>/Library/Application Support/Macromedia/Flash 8/<language>/Configuration/ComponentFLA
  3. Open the libraries of both FLA files.
  4. Create a new folder in the library in the blank FLA called Flash UI Components 2.
  5. Locate the Button component base symbol (Main Button component symbol) in the file StandardComponents.fla and drag it to the library folder you created in Step 4. The symbol is located in Flash UI Components 2 of the library. Your Library panel now should look similar to Figure 4.

    Copying the Button component-related symbols to the Library panel

    Figure 4. Copying the Button component-related symbols to the Library panel

  6. Create another folder in the Library panel called My Components.
  7. Create a duplicate of the main Button component symbol in the new folder.
  8. Specify an identifier and a class for the duplicated symbol. For this example, I used com.rewindlife.controls.MyButton for both and cleared the Export in First Frame check box (see Figure 5).

    Completed Duplicate Symbol dialog box

    Figure 5. Completed Duplicate Symbol dialog box

  9. Create a folder called Skins in the My Components library folder.
  10. Create four skins for the different states of the Button and include the linkage identifier as you did in Steps 1 and 2 of the prototype method. Alternatively, you could copy the symbols from the library of the prototype method example to this one. The library should now look like Figure 6.

    Added Skins and MyButton symbol

    Figure 6. Added Skins and MyButton symbol

  11. Double-click the MyButton symbol and locate the second frame of the assets layer. Drag the four new skins and place them on the second frame to ensure they are exported properly when Flash is ready to compile your new skinned component (see Figure 7).

    MyButton symbol with the skins

    Figure 7. MyButton symbol with the skins

    Now you have completed all the work you need to do before writing any code. The last step is to write your component class, which will be a subclass of the Button class.

  12. Create a new folder to place your class in the proper package (in this example, the package is com.rewindlife.controls, so you create the com/rewindlife/controls folder structure), create a new ActionScript file called MyButton.as, and save it in that folder (see Figure 8).

    Folder structure with the new class file

    Figure 8. Folder structure with the new class file

  13. Include the following code in the MyButton.as file:

    //It is good practice to include this information
    //and in some instances it is required
    import mx.controls.Button

    class com.rewindlife.controls.MyButton extends Button
    {
    //These values are required for all components;
    //set the symbolName equal to the symbol identifier
    //of your components.
    //
    //Set the symbol ownder equal to the fully qualified
    //class name.
    //
    //You can copy these values from the original Button class
    //as a starting point; the Class file can be found here:
    //C:Program FilesMacromediaFlash 8<language>
    // First RunClassesmxcontrols (Windows)
    //Hard Drive/Applications/Flash 8/First Run/Classes/mx/controls (Mac)

    static var symbolName:String = "com.rewindlife.controls.MyButton";

    static var symbolOwner = com.rewindlife.controls.MyButton;
    //Here you define the SkinIDs. Again you can easily open the
    //Button class and copy and paste the current values as a good
    //starting point
    var falseUpSkin:String = "BlueButtonUpSkin";
    var falseDownSkin:String = "BlueButtonDownSkin";
    var falseOverSkin:String = "BlueButtonOverSkin"
    var falseDisabledSkin:String = "BlueButtonDisabledSkin";
    }
  14. Place the MyComponent component symbol on the main Stage and select Control > Test Movie to view the result.

As you have seen, this method is the most involved of the coding methods to set up. It might not seem worth it at first but it definitely has several benefits. For example, it enables you to create different buttons and easily reuse a button without having to redefine the skin property values each time, as you must do with the initObject method.

I like to use this method when I am working on a project that has multiple interfaces, and those interfaces share certain common skin property definitions. With this method I can create a Button and reuse it throughout my projects without having to rewrite anything. If I ever want to change the skin property values for that component later on, I can edit that single class file and re-export all my interfaces with the updated values. This is also the only coding method that enables me to use components that are skinned through code without any code—that is, once I set it up.

More Advanced Skinning

So far you have used a graphical symbol in the library to represent a specific skin. This approach is the simplest and provides a straightforward approach. However, you should at least know of another option that enables you to write code to render a skin rather than a static graphical image. Keep in mind that a skin is only a movie clip, and a movie clip can do a lot more than be a static graphic. So anything you can do in a movie clip can actually become a skin. For example, if you want to use the Drawing API to draw your skins rather than use static library symbols, you can do so. In the default theme (Halo) that is provided with Flash, Macromedia does exactly that: It makes extensive use of the Drawing API to render a skin rather than static graphics in the library.

So what are the benefits to this approach? The biggest benefit of using code to render a skin is the ability to have more control over how a skin resizes. Usually when you create custom skins for your own use, you know the target size and thus can easy build them. Macromedia, however, wanted to build skins that would scale well and render beautifully regardless of the size of the component.

Comments