I mentioned earlier that I would explain how to embed fonts in the swf file. This is icing on the cake for this article, and I want to make it clear that I am only going to cover one method of font embedding. There are at least a couple more, but I don't to make this an article on font embedding (I may be saving that one for later, I suppose!).

In the flash authoring tool, you will notice in the library panel an obscure little triangle:


When you click this triangle shaped button, you will get the following menu (Note, you can also get this same menu just by right-clicking the library itself on an empty space):


Choose New Font... from the menu. When you do, you will get a font symbol added to the library. Now we just need to make sure that this font symbol has the font we want, and that it's set for export for actionscript. Right-click the symbol and choose Properties, and you will get this dialog box. Let's embed the Arial font, and export it for actionscript:


Click OK. Flash will next give you the familiar dialog box that says the class cannot be found, and so it will make one for you, etc, etc! Click OK again. That's all there is to it! Now the font will be embedded in the swf file. Bear in mind that this increases your file size a bit (no, I don't have any figures for you, so you can conduct your own experiment to determine how much). Now let's consider what embedding a font does for us. If the end user doesn't have the font on their system, we can be sure that they will still see the font anyway. Also, embedded fonts can do some things and be transformed in ways that non-embedded fonts can't. For example, one of these things is rotation. Now that the font is embedded, let's return to the fla file. Delete all the code on frame 1 again, and paste in the following. This time we will set the embedFonts property to true for each of the buttons:
menu.x = menu.y = 50;
addChild(menu);
menu.heading = btn;

var btn2:MenuButton = new MenuButton();
btn2.label = "This is the first item!";
btn2.fontColor = 0xFFFFFF; //white
btn2.width = 250;
btn2.height = 40;
btn2.fontSize = 18;
btn2.backgroundColor = 0x00FF00; //green
btn2.embedFonts = true;

menu.addItem(btn2);

var btn3:MenuButton = new MenuButton();
btn3.label = "This is the second item!";
//btn3.fontName = "Times New Roman";
btn3.fontColor = 0xFFFFFF; //white
btn3.width = 250;
btn3.height = 40;
btn3.fontSize = 20;
btn3.backgroundColor = 0x0000FF; //blue
btn3.embedFonts = true;

menu.addItem(btn3);

var btn4:MenuButton = new MenuButton();
btn4.label = "This is the third item!";
btn4.fontColor = 0xFFFFFF; //white
btn4.width = 250;
btn4.height = 40;
btn4.fontSize = 18;
btn4.backgroundColor = 0x999999; //gray
btn4.embedFonts = true;

menu.addItem(btn4);

btn4.addEventListener(MouseEvent.CLICK, btn4Click);
function btn4Click(event:MouseEvent):void {
    btn4.label = "You clicked me!!";
    btn4.backgroundColor = 0x000000; //black
}

Notice the line at the end of each code block that sets the embedFonts property to true for that button. I commented out the line that set the fontName to "Times New Roman" for the second button, since we didn't embed that font. If you set embedFonts to true, but then you don't embed the font, the text won't show up (try running this both ways, with this line commented and then with it uncommented, and you will see the text disappear for the second button in the panel).

When you run the file, it won't look any different than it did before, but if someone didn't have Arial on their system, they would still see your font. However, let's now proceed to give our menu a little bit of a "tilt" (add this line to the end of the above code):
menu.rotation += 10;

Here's the resulting swf from the above code:

Okay, yeah, I know, maybe it's a bit silly, but it does demonstrate that with an embedded font you can do transformations like this that you can't do with device fonts. If you tried rotating this menu without setting embedFonts to true (or without having the fonts actually embedded, of course), all the text will disappear.

Extra bonus tip on font embedding: We've all had a few hair-pulling experiences with Flash, I suppose: those late night sessions where something isn't working right, and it drives us to Google to search out what the problem is (and costs up to several hours!). One of mine was when I was embedding a font, and using it for some scrolling text. Some of the text had to be bold. The bold text just would not show up, no matter what I did. I Googled my dilemma, trying to think of the right search terms. Anyway, it turned out that if you want to use bold fonts, you have to embed the same font again with bold selected. That would mean two symbols in the library for Arial (in this case), both set for export and one having Regular selected and the other having Bold selected. I just thought I'd pass that along, since it took me so long to find it. Maybe someone will benefit.

Using the DropMenu class with other content
You might have noticed that you can use the DropMenu class by sending it instances of the MenuButton class. And yet, the DropMenu class doesn't depend on the MenuButton class. Notice that DropMenu's addItem() method, and the set heading() method, both expect to receive a Sprite object. Since the MenuButton class extends Sprite, instances of MenuButton certainly qualify. But so does anything that's a member of any class that extends Sprite, even MovieClip symbols or instances of classes that extend MovieClip.

So to round out this article, I am going to demonstrate a DropMenu menu that uses a MenuButton instance for the heading, but uses some other (hand crafted) MovieClip instances for the dropdown items. We can actually make anything at all be an item in the DropMenu, as long as it's got Sprite in its ancestry somewhere! Which is pretty versatile indeed, since Sprite is a container! I am including this demo file in the ZIP also, which you can download at the end of this page, below. I threw this together pretty quickly using some small image files and some text copied and pasted from Wikipedia. So please, just consider it a really quick demo of the possibilities, and not any kind of attempt at a finished piece. I didn't even put in click listeners or turn on buttonMode, but I could do all of that if I had a good reason to. Hopefully this will just help spark your own imagination.

In conclusion, I'd like to say that of all the articles I've done so far, this one seems to have sparked my own imagination the most. Some of the things that the menu could do surprised me, especially considering how easy the classes were to make. A lot of ideas come to mind, such as making more classes that also extend Sprite but that do other specialized things, instances of which can be sent to the menu instead of MenuButton instances. Plus the idea that you can mix them and match them however you like. It also ought to be obvious that you can easily make more instances of the menu, and so build a full menu bar if you want. Since the DropMenu is itself a Sprite, you could also have menus within menus. That is, use addItem() to add other DropMenu instances to a DropMenu! Another (related) enhancement might be a Submenu class where the menus open to the side of the header instead. Yet another enhancement might be some kind of scrollbar in the dropdown panel, to make menus that are too long for the display. You could also work in some kind of 3-D content somehow. Have I sparked any ideas yet?

As always, consider this as a springboard, the tip of the iceberg. I hope I've helped you realize that creating custom classes is one of the most creative and healthy addictions you can have! It's just plain fun!

See you next time, happy coding. Thanks for your comments, and send me a link to your stuff!

Mr. Jody Hall
Feb 18, 2010