Wednesday, January 11, 2006

Flash - ActionScript - Movie Clip Buttons

Movie Clip Buttons offer more controls over older style button symbols. Older style buttons did not have a timelines. They can only have scripts attached to their instances in the form of button event handlers. Movie Clip Buttons also allow the flexibility for adding custom states. Following steps shows how to create a Movie Clip Button:

1) Create a new Movie symbol, name it as button, and make sure the Export for ActionScript and Export in first frame options are selected.

2) Create 3 layers. Rename layers to Button Text, Button Image, and Label respectively.

3) Go to Label Layer, frame 1, change the frame label to _up. Go to frame 10, insert new keyframe, change the frame label to _over. Go to frame 20, insert new keyframe, change the frame label to _down. Go to frame 30, insert new frame.

4) Go to Button Image Layer, frame 1, draw an image for the button normal state (_up). Go to frame 10, insert blank keyframe, draw an image for the button mouse over state (_over). Go to frame 20, insert blank keyframe, draw an image for the button pressed state (_down). Go to frame 30, insert new frame.

5) Goto Button Text Layer, frame 1, add Text to the stage. Change the text to Button. Align Text properly towards to the button. Change the Text instance name to Caption. Go to frame 30, insert new frame. Below is the result:


There are 10 frames between each state. But the number of frames between each state can be as low as 1. Adding more frames is just to enable the Frame Labels to be more visible (readable). To purpose to label frames to _up, _over, and _down is to enable Flash to automatically go to the correct frame for the correct button state (Flash will response to the correct state automatically if this 3 labels exists).

Following code shows how to attach Movie Clip Button to the main timeline, or to other movie clip:
// Attach movie, button is the Symbol Name
attachMovie("button", "SampleButton", 1);

// Set button location
SampleButton._x = 10;
SampleButton._y = 10;

// Button text. Caption is the name given 
// to the Text object in the 
SampleButton.Caption.text = "Click Here";

// Stop the button timeline from playing. 
SampleButton.stop();

// Below handler is important. Flash will only
// make the movie clip to be button after at least
// one button event handlers has been defined
SampleButton.onPress = function() {
 // do something here after button pressed
}

Monday, January 09, 2006

C# - Resources – Binary Typed Resources

A Text-Based Typed Resources (.resx xml file) can be compiled into Binary Typed Resources with the following command:
 resgen [resource filename.resx]

 resgen BinaryResourcesForm.resx
The above command will produce a Binary Typed Resources file with extension .resources. The application can load and enumerate the Binary Typed Resources with ResourceReader object from the System.Resources namespace:
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Resources;
using System.Collections;

namespace BinaryResourcesApplication {
 public class BinaryResourcesForm: Form {

  // Constructor
  public BinaryResourcesForm() {
   this.SuspendLayout();

   // Load the resources from the resource file 
   // BinaryResources.resources assuming this file 
   // located at the same folder as the application 
   // executable
   using (ResourceReader reader = 
      new ResourceReader(@"BinaryResources.resources")) {

    // Enumerate with a Dictionary object
    foreach (DictionaryEntry entry in reader) {
     string temp = string.Format("
      Name: {0}, // Resource Name (name attribute)
      Value: {1}, // Resoutce Value (value attribute)
      Type: {2}", // Resource Type (type attribute)
      entry.Key, 
      entry.Value,
      entry.Value.GetType());
     MessageBox.Show(temp);
    }
   }

   this.ResumeLayout(false);
  }

  public static void Main() {
   Application.Run(new BinaryResourcesForm());
  }
 }
}
The code above is similar to the Text-Based Typed Resources application, and there is no random access provided by the ResourceReader class. So the application has to loop through all the resources to find the matching entry. The Binary Typed Resources file (.resources file) can be embedded into the application assembly like other resources:
 csc [source file name.cs] /resource:[resource file name]

 csc BinaryResourcesApplication.cs /resource:BinaryResources.resources
The above code will embed the resources into the assembly as Nested Resources. Nested Resources are resources grouped into a named container:

Above example generated by running ildasm:
 ildasm BinaryResourcesApplication.exe
The example shows there are 2 resources embedded into the assembly:
…
.mresource public BinaryResources.resources
{
  // Offset: 0x00000000 Length: 0x00002683
}
.mresource public ufo.gif
{
  // Offset: 0x00002688 Length: 0x00000A01
}
…
The first entry, BinaryResoures.resources is a Named Container for the Binary Typed Resources. Following code shows how to retrieve the resources embedded into this Named Container:
using System;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Resources;
using System.Collections;
using System.Reflection;

namespace BinaryResourcesApplication {
 public class BinaryResourcesForm: Form {

  private Assembly assembly;

  // Constructor
  public BinaryResourcesForm() {
   this.assembly = this.GetType().Assembly;
    
   this.SuspendLayout();
     
   // Load stream from the Named Container (binary resources)
   Stream  stream = 
      this.assembly.GetManifestResourceStream("BinaryResources.resources");
    
   // Pass the stream object to the ResourceReader Constructor
   using (ResourceReader reader = new ResourceReader(stream)) {
     
    // Enumerate the resources container with a Dictionary object 
    foreach (DictionaryEntry entry in reader) {
       
     // Matching entry for Form Caption
     if (entry.Key.ToString() == "FormCaption") {
      this.Text = (string) entry.Value;
     }
    }
   }
        
   // Close Stream object
   stream.Close();
     
   this.ResumeLayout(false);
  }

  public static void Main() {
   Application.Run(new BinaryResourcesForm());
  }
 }
}