An xml based, windows "Start" style, menu system

Building a Flash based dynamic hierarchical menu system according to external XML data

 

Introduction

A couple of days ago I finished coding the xml_menu
smart clip which I packaged and submitted, as a Flash extension, to Macromedia.
This tutorial is meant to give some idea, to anyone interested, of how such
a menu system can be built using Flash's ActionScript. Full code of the smart
clip is available when you download the xml_menu Flash extension from
the Macromedia
site
; this tutorial will only present the portions of code that constitute
the heart of the smart clip. The following paragraphs give you some idea of
what xml_menu does. The rest of the sections in this page explain how
it is done (don't expect anything close to a 'step by step newbie guide though).

The xml_menu smart clip creates a hierarchical
menu system (windows style) based on an external XML file that can be accessed
locally or through the Internet. The URL path to the XML file containing the
menu's specification is the only parameter that you need to pass to the smart
clip's instance via its "clip parameters" panel. The smart clip provides
it's own clip parameters mini UI (User Interface) for easy entry of the URL
path to the XML file.

The menu's positioning, appearance and behavior are highly customizable via
property values specified within the xml file (as parameters of the root node
tag). Menu items can be linked to other web pages or to internal actionscript
functions (placed at the root of the movie or movie clip that contains the smart
clip instance). Whether a menu item links to a web page (a URL) or an internal
actionscript function depends on the value of the calltype parameter
of the item's respective XML node.



The xml_menu in action

The basic features of the xml_menu smart clip are:

  • High customizability. Most of the characteristics of the xml_menu
    are customizable. Check the "Menu Parameters" section for a complete
    list.
  • Auto Scrolling. The menu automatically scrolls vertically and horizontally
    when the mouse gets close to its bounds. Thus, if menu items are outside the
    viewing area they are brought in and become accessible to the user.
  • Smart y-axis menu expansion. The menu expands towards the side of
    its bounding box with the most space on the y axis. This ensures better management
    of the available viewing area.
  • Smart x-axis menu expansion. This is actually an option. If this
    option is on, the menu only expands towards the right if there is enough space
    for one more level, otherwise it expands towards the left. If the option is
    off the menu will always expand to the right and the items that expand off
    the viewable area can be reached via the menu's auto scrolling feature.
  • Auto Bounds Detection. The xml_menu smart clip can automatically
    detect the dimensions of the movie clip that contains it and behave accordingly.
  • Supports both URLs and Actions. The menu items can access both URLs
    (an unlimited number of them) and internal Flash movie actions (an unlimited
    number of them).
  • XML reload capability. If the connection to the XML file, for some
    reason, fails during loading the clip gives you the option of re-attempting
    to load the XML file without having to reload the whole page containing the
    movie that uses the xml_menu smart clip instance.
  • Menu navigation current path visual cue. The current path of menu
    expansion is cued in the display by having the arrows of expanded nodes (only
    nodes that have children have arrows) turn to an alternate color (in the picture
    above they turn to red, but this is a customizable option).
  • HTML menu items. The text content of the menu items is actually HTML,
    allowing for font face, font color, font style and font size customization.
    Font style (bold and italic) are customizable per item, the rest are customizable
    for the whole of the menu.

 

The concept

The XML data is brought in and parsed with a myXMLobject.load()
type of call. After that it remains in memory as a standard W3C DOM tree
that can be easily accessed via DOM API calls.

Every time the user rolls over a menu element, the
button within the "el" clip detects it and among other things (like
lighting up to show that it is activated) it calls the walkTree() function
that resides at the root of the smart clip. This function is recursive and it
basically walks the tree until it finds a tree node by the name of its 'name'
passed argument. When it does, it sets the 'found' root var to the name
of the found node and sets the 'node_level' clip root var to the number
that corresponds to the depth of the found node. It can do that because it always
starts from the root of the tree (and with level == 0) and counts levels every
time it goes deeper in the structure. Other existing menu item clips know whether
they should keep displaying or remove themselves because they are constantly
monitoring this 'node_level' value (along with which the active parent node
clip is).

Here is the full code of the walkTree() function
that constitutes the most important piece of code in the smart clip. walkTree()
walks the sibling nodes of the current node and if a sibling has children, it
calls itself in order to do the same with the next level of the tree.

////////////////////////////////////////////////////



function walkTree(start, name, level)

{

  var sib = start.firstChild;



  while (sib)

  {

    if (sib.attributes.name == name)

    {

      found = sib;

      

      node_level = level;



      return;

    }

    else if (sib.hasChildNodes())

      walkTree(sib, name, level + 1);



    sib = sib.nextSibling;      

  }

}



////////////////////////////////////////////////////

 

Smart Clip Design and Coding

When coding a smart clip the most important thing
to remember is that all references to other clips have to be relative. Specifically
no _root or _level type of paths should be used. _parent
or nested _parent references (e.g. _parent._parent_parent) should
be used instead along with the this reference which is the best way to
access the current clip.

The reason we need the smart clip to use relative
addressing is because we don't know where the user will place its instance;
at the _root of a movie or within another movie clip.


What the smart
clip's fla looks like in the flash development environment. Note the already
installed xml_menu extension that appears as another common libraries element.

 

The xml_menu smart clip uses the following basic layout:

  1. Just one frame in its root timeline
  2. Variable declarations and basic functions are packed in the actions of this
    single frame.
  3. A controller clip with no graphics content at all is used as the placeholder
    of all the actionscript code that needs to be looped (i.e. repeated in each
    frame). This code basically attaches menu item clip instances according to
    variable values at the root of the smart clip.
  4. A clip named "el" for "element" (as in "menu
    element") is in the smart clip's assets, along with its own assets. This
    clip contains other clips that are needed in order to display the way it is
    supposed to and it is dynamically attached at the root of our smart clip whenever
    we need a new menu element to be displayed.
  5. One of the layers of this clip holds a clip that in turn holds a button.
    This button's rollOver and rollOut events are used to detect
    the user's browsing within the menu area.
  6. The clip instance, within the "el" clip, that holds the button
    also holds the rest of the important code of the smart clip. This code basically
    checks to see whether this menu element clip instance should keep existing
    or remove itself. It does this by monitoring the current 'node_level'
    value at the root of the clip (the 'node_level' var basically holds
    the menu depth level at which the user currently is)

 

Keeping the GUI cueing

The user should be continually and intuitively informed
by the GUI's visual display cues of the menu's state. The menu's basic taxonomy,
as visually exemplified by levels of stacked selectable buttons, accomplishes
this to a degree. However, with complex menu systems it needs to be complemented
by a system that will, as intuitively as possible, inform the user of the current
path of navigation in a fully expanded and complex menu state. What this means
is that it should be very easy to determine, at any moment, to which parent
node another node belongs. The design decision to have a child menu level begin
vertically at it's parent's y coordinate is not enough. We need something faster;
we need the arrow of each active parent menu clip to change color! This is accomplished
with the regressRed() function that resides at the root of the "el"
movie clip.

What the regressRed() function does is light
up the active arrow clip of the current "el" instance and then
travel back the current menu navigation path, effectively calling itself in
other "el" instances it finds along this path. The result is
a "snake path" of menu elements with lighted "active" arrows
that is very natural for the user to follow with his/her eyes. I named this
function "regressRed()" because initially the active arrow
was a standard color of red. However, later on I turned this color into another
of the numerous parameters that the xml_menu smart clip receives (you
can see the complete list of parameters in the documentation of the xml_menu
extension
) and therefore this part of the function name is not part of its
functional description any more, just part of its history. Here is the simple
yet elegant code:

function regressRed(val)

{

  if (!leaf)

    showredarrow = val;



  if (parent_node != null)

    _parent[parent_node].regressRed(val);

}


val may be 0 or 1 for "turn off"
and "turn on" respectively. The "Turn on" snaky regression
is triggered on rollOver of the button within the menu element's "el"
clip instance, the "turn off" is triggered on rollOut.

 

Conclusion

Well, those were the most important (and pretty)
pieces of code in the xml_menu smart clip. However, to make the smart
clip really work as expected, a lot more code is needed. You can view this code
when you download and install the xml_menu extension; however, it is
complicated (although I have added some explanatory comments), mundane and a
bit ad hoc at places. Keep in mind that there are more than one ways to build
a menu system like this and mine is just one of them. In retrospect, it is not
even the best that I can think of. However, it does work well.

 

Contact

Fotios is a lone programmer devoted to freedom of
speech, ideas and code. He currently exists alone in the Scottish wasteland
and lives off freelance projects, that he takes up now and then, and part time
bouncing for local pubs and clubs. His dream is to one day become a full time
systems programmer for a major company and part time bouncer for a topless or
all-nude joint in New York City.

 

Live Flashy and prosper!

Post new comment

The content of this field is kept private and will not be shown publicly.

Share

  submit to reddit