Generating a Menu
The GenerateMenu function follows these steps:
- Set up some variables to be used in the function
call.
- var curr_node;
- var curr_item;
- var curr_menu ...
- Create an empty movieclip for the menu to live in
within the passed container argument with the name
given by the name argument at the depth given by the
depth argument. Assign this clip to one of the
variables created for future reference.
- var curr_menu =
container.createEmptyMovieClip(name, depth);
- For each node in the passed node_xml, create a
menu item movieclip by attaching an instance of
menuitem from the library.
- for (var i=0; i<node_xml.childNodes.length; i++)
{
- Position each menu item correctly so each
following item is placed below the previous and set
each to trackAsMenu (this allows for dragOver events
to work as well as rollOver events).
- curr_item._x = x;
- curr_item._y = y + i*curr_item._height;
- curr_item.trackAsMenu = true;
- Save the attributes of each XML node (name, action
and variables) to the item created for that node so
that they may be referenced when needed, the name
value being placed in the textfield in the attached
menu item clip.
- curr_node = node_xml.childNodes[i];
- curr_item.action = curr_node.attributes.action;
- curr_item.variables =
curr_node.attributes.variables;
- curr_item.name.text = curr_node.attributes.name;
- Assign rollOver actions to each node, opening a
submenu if a menu node and closing a submenu if an
item node. When opening a menu, re-use GenerateMenu
and position the new menu to the left of the current
menu. The node for this menu is the current node
which, when GenerateMenu is called for it, will make
the new submenu based on all the nodes within this
one. In closing a menu, any submenu_mc in the current
menu is simply removed.
- if (node_xml.childNodes[i].nodeName == "menu"){
- curr_item.node_xml = curr_node;
- curr_item.onRollOver = curr_item.onDragOver =
function(){
- var x = this._x + this._width - 5;
- var y = this._y + 5;
- GenerateMenu(curr_menu, "submenu_mc", x, y,
1000, this.node_xml);
- };
- }else{ // node is an item node
- curr_item.arrow._visible = false;
- curr_item.onRollOver = curr_item.onDragOver =
function(){
- curr_menu.submenu_mc.removeMovieClip();
- };
- }
Notice how here, too, that the arrow movieclip in the
attached menuitem is set to have 0 visibility for
non-submenu opening menus. The arrow serves as a
visual indicator that the item opens a submenu. By
having it in the menuitem movieclip, its assumed that
all items start as menu-opening items. For those that
are not, it is simply hidden.
- Finally, assign a release action for each item
(menu and otherwise) which calls the required action
and closes all submenus.
- curr_item.onRelease = function(){
- Actions[this.action](this.variables);
- CloseSubmenus();
- };
And... ACTION!
Notice how the actions are executed. You have some sort
of Actions object with a reference to the action of the
node with the variables passed in to it (as its being
called as a function).
- Actions[this.action](this.variables);
The Actions object is, in fact, a custom object. This
is the object to handle your actions, obviously. It
contains functions with names that are similar to that
which would be passed in to the action attribute of an
XML node. The variables value is then passed in along
with that. Consider the gotoURL action from previous
examples. You would end up with a call such as.
- Actions["gotoURL"]("http://www.google.com");
This calls the gotoURL function in the Actions object
passing http://www.google.com along as an argument. You
of course would need to make an Actions object and
define what gotoURL is before being able to use it.
Here's an example that will open the passed url in a new
window.
- Actions = Object();
- Actions.gotoURL = function(urlVar){
- getURL(urlVar, "_blank");
- };
For any action you wish to be able to use, you would
create a function in the Actions object in this manner.
Whatever functions you have there can then be used in
the XML definition to specify what is to happen when a
menu item is pressed.
In the final menu example, a textfield is placed at
the bottom of the screen. An action in the Actions
object is then used to change that text. The function
for that is as follows where message_txt is the name of
that textfield.
- Actions.message = function(msg){
- message_txt.text = msg;
- };
New Menu Please
There's one more action that I want to include,
and thats an action that will load a new menu XML file
into the XML object used to handle the menu.
- Actions.newMenu = function(menuxml){
- menu_xml.load(menuxml);
- };
When loaded, any XML that was within the menu_xml
object will be replaced and the onLoad event of that
object will be called. Remember what's in the onLoad
event? That's right, script used to generate the main
menu. Whenever you load a new XML file into that object
and re-call that main menu generating script, any
existing menu is replaced and the new menu is created in
its place. This means a simple load command is all that
is needed to completely change your menu. If you didn't
already notice, the last menu in the posted example does
this (titled load menu).