Hi! Welcome back to my never-ending series (hopefully) on making your own custom reusable Actionscript 3.0 classes. This time I'm going to share with you how to make a custom dropdown menu class. We'll also make an associated button class to represent the items that the dropdown menu is going to use. I'll share with you the planning and the thinking that goes into creating something like this, as we build it together starting with just the idea. If you are primarily a designer, or a visual person, that's okay, too. You will see that it helps to be able to draw and/or visualize the thing you are trying to make, even though you are doing it with strictly code.

Visualizing the finished menu beforehand
So we start with a drawing or a visualization of the object or objects we are going to make with code and classes. Right up front, if I draw a picture or a diagram of the overall thing I want to make (or if I even just have a mental picture), it helps me tremendously when I set out to write the code. This kind of planning is important, and you've no doubt heard that you should never just start cranking out code without doing some kind of planning. It's true. And along with the diagram or mental picture, you will also want to start determining what constitutes a class in your diagram, and then you can start listing what things you expect each class to do. Peoples' preferences vary, and I'm probably "old-school" in that I like to keep a scratch pad and pen next to the computer, and make an actual drawing. But if you'd rather draw using software, that's great too, and I'm actually making my illustrations for this tutorial using Flash.

For example, if I drew a diagram of the dropdown menu, it would probably look something like this:

You can see that the menu will have several parts. The "heading" will be a single button, and the "panel" (the part that goes up and down) will be a stack of buttons. Both the heading and the panel will use the same kind of button, and all of these buttons will be instances of the MenuButton class. You can see that MenuButton itself will be composed of other parts. An instance of the Shape class will serve for a background, and a dynamic textfield will be in the foreground. The next drawing illustrates the action of the dropdown menu, along with some helpful visualization of x and y coordinates that are going to be necessary for positioning. Also, the finished dropdown menu is going to need a masked area to serve as a view window through which the panel will "peek through" as it moves up and down:

This kind of drawing and planning (and thus, visualizing) is indispensable to your coding, so whatever you are making, you won't want to skip this step. But like I said, these images can also be mental, too. Just make sure you have some kind of concept of how your objects are going to be composed, and you'll be much better off when you write the code. Otherwise you will tend to have to revise things a lot, and as you change your mind about this and that, you will tend to forget what parts you left in or took out in the process.

In the above drawing, the dashed lines represent the panel opened, and the panel closed, and the (x, y) positioning that will need to be done can be fairly easily determined. Also the idea that we will need a masked area is shown, and we also get a good concept of the layering of the objects. The various parts will become properties in the finished class. Also at this point, it can be decided just what action will open and close the menu. So we decide that the menu will open when the mouse rolls over the heading, and the menu will close when the mouse rolls out of the whole thing. The menu will open and close by tweening, and we will employ some tweening classes for that. We will come back to this drawing later when we make the DropMenu class. For now, just realize that having these two drawings gives us an overall road map of where we need to go to make this dropdown menu a reality.

What will we require of MenuButton?
The other thing to do besides making drawings is to start asking questions and listing requirements. So let's start with the MenuButton class. The questions to start asking are many, but they all pertain to what is going to be expected from this class by outside code. What sorts of things do we need to send it, what sorts of things are we going to get back (if anything), what sorts of things can be customized from the outside controlling code? In fact, forget for a moment that this is going to be used in a dropdown menu, and consider it separately. If this were just a generic button (and it really is, after all), what do I want to be able to do to customize it?

When I start answering those questions for the MenuButton class, a bunch of things start occurring to me, especially looking at the first drawing and focusing on how the button itself will be composed. It occurs to me that the whole "button" ought to be a Sprite object, because it won't need a timeline, but it does need interactivity (mouse events), and it needs to contain other objects. There is a background shape, so I would like first of all to be able to control the color of it, and also the size (width and height, naturally). There is a foreground dynamic textbox, so it should go without saying that I need to be able to set the text (label). Along with that, I would also like to be able to control the font, the font size, and the font color. The textfield needs to be always centered horizontally and vertically, and autoSize from the center. And finally, just in case I might want to use a font other than a device font (like some obscure font I have that I like, but I know my end users are maybe not likely to have), I should be able to designate whether to use embedded fonts or not.

This is a pretty good list already:
  • Our class will extend Sprite, so it can contain the other objects
  • It will need (at least) these properties:
  • A label property so we can set the text (String)
  • A fontName property so we can set the font (String)
  • a fontSize property so we can set the font size (int)
  • a fontColor property so we can set the font color (uint, a hex number)
  • an embedFonts property so we can decide to embed fonts or not (Boolean)
  • a backgroundColor property so we can set the background color (uint, a hex number)
  • a width property so we can set the width of the button (Number)
  • a height property so we can set the height of the button (Number)
For those last two, since Sprites already have a width and height property, we will need to override those and substitute our own. Also, for all of these various properties, I would like the flexibility to be able to set all of the properties in the constructor if I want, but also be able to decide not to. I should be able to create a new instance of the class with no parameters passed, and get some kind of default button, with a hand cursor, and be able to further customize it by setting my eight properties separately if I want. In other words, you have to always be thinking about how this class will be used from outside of it, and make it as versatile, useful, and customizable as you possibly can.

What will we require of DropMenu?
Similarly, the DropMenu class has its own list of questions and requirements that need to be thought through. How are we going to set the heading for the menu? How are we going to add items to the panel? And how are we going to accomplish the motion of the panel? As I perceive it from the drawing, the class will need:
  • a heading property (to set the heading)
  • an addItem method (to add items to the dropdown panel from outside the class)
  • some way to tween the panel up and down
  • mouse event handlers added to the heading to make the panel go up and down
The DropMenu class should also allow me to make an instance of it without sending it any arguments to the constructor, for convenience, but if I want to, I should be able to send the constructor a Sprite instance to be used for the heading.

Programming for other programmers
In fact, it's helpful to pretend you are making your class for some other programmer to use who doesn't know anything about it. To keep the learning curve as short as possible, use descriptive and memorable property names and method names. Don't make required parameters unless you absolutely must. Make separate "setter" functions for all the parameters, so that they can optionally be set separately after the class is instantiated. Think about the built-in classes and just how you already use many of those. Realize that you use them and almost never get to see their insides, you just learn their API's from the documentation (an API, or "application programming interface," in the case of classes, is simply the list of public methods the class makes available, and what parameters those methods are expecting. Methods are simply functions that belong to a class, so the words method and function are usually interchangeable in this article). Some API's are easy to learn, and others require researching their documentation frequently. And that's how you should try to make your own classes: as much like the ones that come with Flash as possible, and as easy to learn as possible, especially without peeking inside of them.

This will make it a much easier for yourself also, when you have to come back to your own classes later. It might take longer to carefully craft a well thought out class, but in the long run you are putting some gems in your class library for later reuse, rather than a hacking something together quickly that gets the present job done, but doesn't have much in the way of future re-usability.

Having outlined those requirements for the whole project, and having figured out what we expect from the MenuButton and DropMenu classes, on the next page we will start coding the MenuButton class.