Archive for January, 2008

ActionScript 2 Accordion Menu

This is an ActionScript 2 version of the ActionScript 3 Accordion Menu.

This version is far far less feature complete than the ActionScript 3 version. This version was a “proof” of concept if you like of how I would approach making an Accordion Menu, which I then used as conceptual direction when making the ActionScript 3 version.

Nevertheless, it is an XML Accordion, but does not support function calls from the XML file. It is also not class based, and instead relies on two fairly simple sections of timeline actionScript to generate its functionality. The two .fla files have good comments and directions on what to edit to make changes to the ActionScript.

If there is demand, I can finish this menu to the level of the ActionScript 3 version.

View Example
Here is an example of the menu; http://www.noponies.com/dev/as2_accordion/

Source Files
Here are the source files; ActionScript 2 Accordion Menu Source

Dependencies
The menu uses Tweener. Its an old file, that I have not update to tweenLite.

ActionScript 3 Liquid Layout Manager

Simple class that repositions objects passed to it when a stage resize event occurs.

Class is designed to simplify creating flexible or liquid layouts in Flash CS3. For a project I had I needed to create a flexible layout, so rather than creating a set of functions etc that resized the various objects I wrote this class.

It is simple and probably not as optimised as it could be, but does support the features I needed it to well.

Class positions elements using proportions of the stage, rather than specific values. I felt it was simpler to specify a value of 100 for absolute bottom or right, or 50 for middle etc.

Read Class documentation for usage directions.

Class Features

  • Ability to set a min Stage size at which point the layout manager will not reposition objects
  • Layouts are proportionally based
  • Use either clip reg point or clip natural center for positioning
  • Public method for accommodating changes in content dimensions

View Example
Here is an example; http://www.noponies.com/dev/as3_stage_manager (Resize the browser window to see it work, click pink square!)

Source Files
Here are the source files; AS3 Stage Manager Source Files, v1.2

Dependencies
Flash CS3

Class ActionScript

/*******************************************************************************
STAGE LAYOUT MANAGER CLASS
********************************************************************************

Simple class that repositions objects passed to it when a stage resize event occurs.

Sample useage:

StageManager(target:InteractiveObject, xpos:int, ypos:int, displaceX:int, displaceY:int, useClipRegPoint:Boolean )
var stageTest:StageManager = new StageManager(Black, 30, 100, 0, 90, true)

Instance Vars - Via constructor
target:Instance of an interactive object you want to position
xpos:  X Postion on the stage as a PERCENTAGE of the stage where you want your object to sit - 0=hard left, 100 = full right etc.
ypos:  Y Position on the stage as a PERCENTAGE of the stage Height where you want your object to sit - 0 = Top, 100  = full bottom
displaceX: An offset value, as a PERCENTAGE of your clips Width. For instance, if you want your clip to sit at right of stage, minus its width, then this would be 100
displaceY: An offset value, as a PERCENTAGE of your clips Height. For instance, if you want your clip to sit at bottom of stage, minus its width, then this would be 100
useClipRegPoint:Boolean. TRUE means clip is positioned off its reg point, FALSE means its natural center (height/width) is used.

Static Vars - Set via Class
useMinStageSize: Boolean, for using the min size parameters. Use this if you want to stop responding to RESIZE events at a certain stage size
XminSize: Integer, set if using useMinStageSize
YminSize: Integer, set if using useMinStageSize

Pass a value of 0 to both displacement vars if you want your clip to have no displacement. If no displacement is provided, then the clip is placed at centered on the
desired xpos and ypos values. You can pass displacement values greater that 100%. Clips are positioned using a subtraction. So, if wanted a clip to sit off say the bottom of the

use
stage, then you would pass it a displacement Y value of 120 etc.

Example Middle Stage Position
var stageTest2:StageManager = new StageManager(Pink, 50, 50, 0,0, true)

Example Bottom Middle Minus Clip Height Position
var stageTest:StageManager = new StageManager(Black, 50, 100, 0, 100, false)

Version 1.2; 04 March, 2008. Updated to take into account pensamente (off actionScript.orgs forums) suggestions.
Some adjustments to script for performance.
Addition of new variable for basing instance position off either regpoint or clips natural center.
Added in a fix from user Freddy

**************************************************************************************
Made in 2008 by noponies
http://www.blog.noponies.com

Terms of use
http://www.blog.noponies.com/terms-and-conditions

**************************************************************************************/


package {

import flash.display.*;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;

public class StageManager extends Sprite {
private var managedObject:InteractiveObject;
private var xAxis:int;
private var yAxis:int;
private var offSetX:int;
private var offSetY:int;
//set minimum size at which point elements stop being repositioned. This is a global setting!
private static  var XminSize:int = 400;
private static  var YminSize:int = 400;
private static  var useMinStageSize:Boolean = false;
private var yAmount:int;
private var xAmount:int;
private var useClipRegPoint:Boolean;


//constructor function
public function StageManager(target:InteractiveObject, xpos:int, ypos:int, displaceX:int, displaceY:int, useClipRegPoint:Boolean ) {
managedObject = target;
xAxis = xpos;
yAxis = ypos;
offSetX = displaceX;
offSetY = displaceY;
this.useClipRegPoint = useClipRegPoint;
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);//add listener for adding to stage, then we can access its properties
}
//set initial positions of clips
//if we are basing our clips pos off either its reg point or its natural center point derived by finding center of clip from width/height
//Here we calc stage dimensions as a %, if we are using an offset, it will be included here
//also this is a public function, call this function if your clip changes dimensions
public function setUpLayOut():void {
if (useClipRegPoint) {
yAmount = offSetY!=0 ? (managedObject.height*.01)*offSetY : 0;
xAmount = offSetX!=0 ? (managedObject.width*.01)*offSetX : 0;
setLayout();
} else {
yAmount = offSetY!=0 ? (managedObject.height*.01)*offSetY : managedObject.height*.5;
xAmount = offSetX!=0 ? (managedObject.width*.01)*offSetX : managedObject.width*.5;
setLayout();
}
}
//function reflows the cip if a resize event occurs
private function setLayout():void {
if (useMinStageSize) {
if (stage.stageWidth >= XminSize) {
managedObject.x = (stage.stageWidth * .01) * xAxis - xAmount;
}
if (stage.stageHeight >= YminSize) {
managedObject.y = (stage.stageHeight * .01) * yAxis - yAmount;
}
return;
}
//set the position of our objects
managedObject.x = (stage.stageWidth*.01)*xAxis - xAmount;
managedObject.y = (stage.stageHeight*.01)*yAxis - yAmount;
}
//resize listener
private function resizeListener(e:Event):void {
setLayout();
}
//added to stage handler
private function addedToStageHandler(e:Event):void {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.RESIZE, resizeListener);
//call set up layout function
setUpLayOut();
}
}
}
}

ActionScript 3 Sliding Images XML Gallery

This file is a ActionScript 3 demo of a sliding images gallery, as used on my work site, http://www.thereformation.co.nz.

Basically images are loaded sequentially from an XML file into a Sprite, which is dynamically masked and then tweened. The gallery has support for text descriptions (via a support class) and also creates a dynamic image number navigation system which updates itself based off how many images you happen to load in.

This is a class based file, which relies on two helper support classes. One of which simply provides an array of images from an XML file. The other, the “TextNavigation” class provides a mechanism for dispatching events to the text navigation section of the gallery. Updating its status, so that it matches the currently displayed image. There is also an optional text descriptions class which will pull in descriptions from an XML file and display these along with the images.

Gallery Features

  • Vertical or Horizontal Sliding
  • External XML Images
  • next, previous, play, pause public methods
  • Event Based Architecture
  • Dynamic tweened mask, so that it supports different image sizes
  • Either Manual or Automatic Image Progression
  • Optional Text Navigation - supports embedded fonts
  • Optional Text Comments - supports embedded fonts

Updates
July 08, 2008: A new rewrite of the class moving it to a more modular structure. I’ve decided to make this a donator file, after spending a solid day rewriting it. Download includes, source, example and documentation.

Updated 15 July, with a new method for autotweening text comments

View Example
Here is an example of the file; http://www.noponies.com/dev/as3_slideimages/

Source Files
Donator Only File

Dependencies
Files use TweenLite, available from here; http://www.tweenlite.com

Holiday Reading

A bit of light holiday reading for me while up at Rarawa Beach on the North Islands East Coast. Can’t beat a dose of Essential ActionScript 3!

Holiday Reading

Simple ActionScript 2 XML Gallery

Sample Flash file for a very basic bare bones XML gallery with a scrolling thumbnails track, and simple load progress handling. This example is really meant as a basis to build something more elegant and interesting on. In that sense, it provides a skeleton for a site, and it is up to you, as a user of the file to skin it.

This file started life as a comparison to an ActionScript 3 implementation of the same idea. The ActionScript 3 version is more elegant and is slightly more flexible.

Gallery Features;

  • Horizontal or Vertical Scrolling Thumbs track
  • External XML Images
  • Load Progress Handling
  • Ability to load in different XML files

The source file contains two files, one file has a horizontal image scrolling track, while the other has a vertical images scrolling track.

View Example
Example can be viewed here;  http://www.noponies.com/dev/as2_simple_gallery/ (Note, no progress loading implemented)

Source Files
Here are the source files; ActionScript 2 Simple Gallery Files

Dependencies
File uses TweenLite, for image fading in and out.
Flash 8 or Flash CS3

ActionScript 2 Sliding Images Gallery

This file is a demo of a sliding images gallery, as used on my work site, http://www.thereformation.co.nz.

Basically images are loaded sequentially from an XML file into a movieClip, which is dynamically masked and then tweened. The gallery has support for text descriptions and also creates a dynamic image numbers navigation system which updates itself based off how many images you happen to load in. All text is CSS styled.

Contained in the .zip file are a Flash CS3 and Flash 8 source file, XML files, sample images, the tweenFilterLite class and the font used in the project.

Updates
09 June, 2008. File now supports multiple XML files

View Example
View an example of the project here; http://noponies.com/dev/slideimages/ (no preloader, 36k file size)

Source Files
Grab source files here; Sliding Images Gallery Source

Dependencies
TweenFilterLite http://www.tweenlite.com
Flash CS3 or Flash 8

ActionScript Source

/************************************************************************
NOTES

This file works with fixed image sizes! I attaches the image holding MC "imageHouse" from the
library along with the navigation text MC, "navHolders". Text links are added to this MC by
attaching the "SampleLinks" mc. These MCs are attached like so, so that the navHolders MC can
be tweened easily, if need be.

The main images are simply a movieClip with a mask. The images are loaded in into the background of
the "imageHouse" clip, which is then tweened to create the sliding image movement. The mask is created
via actionScript and bases its dimensions off the size of the first bit of loaded large image content.

The large images have text fields, drawn in from the XML file. Simple remove references to this, if you
do not want text descriptions.

The text is CSS styled.

The font used is Minion. Included in file.

There is no formal preloader for each large image. But the progress handler exists, its just not hooked into
in the script.

I requires the http://www.tweenLite.com AS2 TweenFilterLite class files.

by noponies, 2008
http://www.blog.noponies.com

************************************************************************
DONATE
************************************************************************
Consider donating to pay for the hosting and development time of this file.
https://www.paypal.com

************************************************************************/

//init global variables and properties
Stage.scaleMode = "noscale";
import gs.TweenFilterLite;
import gs.TweenLite;
stop();
/************************************************************************
LOAD STYLE SHEET FOR DESCRIPTIONS TEXT
************************************************************************/

var styleObj:TextField.StyleSheet = new TextField.StyleSheet();
styleObj.onLoad = function(success:Boolean) {
  if (success) {
    //nada
  }
};
styleObj.load("styles.css");
/************************************************************************
LOAD XML
************************************************************************/

var slide:XML = new XML();
slide.ignoreWhite = true;
var urls:Array = new Array();
var captions:Array = new Array();
var imageName:Array = new Array();
//not used
var p:Number = 0;
//positional Array Index tracker
slide.onLoad = function() {
  urls = []
  captions = []
     imageName = []
  xmlNode = this.firstChild;
  var photos:Array = this.firstChild.childNodes;
  for (i=0; i<photos.length; i++) {
    urls[i] = xmlNode.childNodes[i].childNodes[0].firstChild.nodeValue;
    imageName[i] = xmlNode.childNodes[i].childNodes[1].lastChild.nodeValue;
    captions[i] = xmlNode.childNodes[i].childNodes[2].firstChild.nodeValue;
  }
  p = 0;
  loadLarge();
  //load the large images
};
slide.load("slideimages.xml");
//attach the main content holder MC
//delete this attachMovie if you want to have a MC sitting on the stage, manually added. Just make sure it has
//the instance name "imageHolder_mc"
this.attachMovie("imageHouse", "imageHolder_mc", this.getNextHighestDepth(), {_x:7, _y:163});
//attach the nav holder movieClip, remove this if you don't want nav text...
this.attachMovie("navHolders", "navHolder_mc", this.getNextHighestDepth(), {_x:7, _y:120});
//Slider vars
var offset:Number = imageHolder_mc._y;
//pos of image holder movieClip
var imageNavPunctuation:String = ",";
//imageNavPunctuationuation string, for dynacmically attached image numbering
var butNavCounter:Number = 0;
//used by the next image button...
var pos:Number = 0;
//vertical increment value, based off each images height
var navPos:Number = 0;
//start pos of image navigation links
/************************************************************************
LOAD LARGE IMAGES
************************************************************************/

function loadLarge() {
  var container:MovieClip = imageHolder_mc.attachMovie("ImageHolder", "ImageHolder"+([p]), imageHolder_mc.getNextHighestDepth(), {_x:0, _y:pos});
  //images
  var navContainer:MovieClip = navHolder_mc.attachMovie("sampleLinks", "sampleLinks"+p, navHolder_mc.getNextHighestDepth(), {_x:navPos, _y:0});
  //image nav text
  var Clip:MovieClipLoader = new MovieClipLoader();
  var mclListener:Object = new Object();
  var target_mc = container;
  //indicate loading in of work samples and attach mask of the content
  if (p == 0) {
    //create a mask for the image content, based off position of imageHolder_mc
    container._parent._parent.createEmptyMovieClip("imageMask_mc", 400);
    //_root timeline
    imageMask_mc.beginFill(0xFF0000, 0);
    imageMask_mc.moveTo(imageHolder_mc._x, imageHolder_mc._y);
    imageMask_mc.lineTo(imageHolder_mc._x+imageHolder_mc._width, imageHolder_mc._y);
    imageMask_mc.lineTo(imageHolder_mc._x+imageHolder_mc._width, imageHolder_mc._y+imageHolder_mc._height);
    imageMask_mc.lineTo(imageHolder_mc._x, imageHolder_mc._y+imageHolder_mc._height);
    imageMask_mc.lineTo(imageHolder_mc._x, imageHolder_mc._y);
    imageMask_mc.endFill();
    imageHolder_mc.setMask(imageMask_mc);
  }
  mclListener.onLoadProgress = function(target_mc:MovieClip, bytesLoaded:Number, bytesTotal:Number):Void  {
     load_txts.text = "Loaded "+ bytesLoaded + " bytes of " + bytesTotal +" of image number "+(p+1);
  };
  mclListener.onLoadInit = function(target_mc:MovieClip) {
    //indicate how many images to load
    details_txts.text = "Fetched "+(p+1)+" of "+(urls.length)+" Images";
    //handle the numbering of mc's, this function removes the final comma  
    if (p == urls.length-1) {
      imageNavPunctuation = "";
    }
    //text details in imageHolder
    container.imageDetails_txt.styleSheet = styleObj;
    //css style
    container.imageDetails_txt.htmlText = captions[p];
    //add text description
    //set up the nav text
    navContainer.nav_txt.text = p+1+imageNavPunctuation;
    //add 1 to remove leading 0 from array index
    navContainer.nav_txt.autoSize = "left";
    //autosize the samples text
    /************************************************************************
    NAVIGATION BUTTONS
    ************************************************************************/

    navContainer.onRollOver = function() {
      TweenLite.to(this, .2, {_alpha:50});
    };
    navContainer.onRollOut = function() {
      TweenLite.to(this, 1, {_alpha:100});
    };
    //handle a click on the navigation text
    navContainer.onRelease = function() {
      //here we check to see what numbered button a user has pressed
      //we take one off the parseInt result because we added a 1 earlier, when we set up the button nav..
      targetLoc = (parseInt(this.nav_txt.text))-1;
      //convert the text clicked on into an integer, -1. This gives
      //us a number to use in the below equation for calculating how far to slide the images to.
      TweenLite.to(imageHolder_mc, 1, {_y:-(container._height*targetLoc)+offset, ease:Strong.easeOut});
    };
    /************************************************************************
    IMAGES
    ************************************************************************/

    target_mc.onRollOver = function() {
      TweenFilterLite.to(target_mc, .4, {type:"Color", saturation:0, ease:None.easeOut});
    };
    target_mc.onRollOut = function() {
      TweenFilterLite.to(target_mc, 1, {type:"Color", saturation:1, ease:None.easeOut});
    };
    //increment counter variable
    p++;
    //function checking section, are we done loading?
    if (p<urls.length) {
      pos = pos+container._height;
      //increment image height.
      navPos = navPos+navContainer._width-8;
      //space the nav text, this spacing allows for this text to contain more than one digit
      //recursive call to same function, runs only as many times as there are images
      loadLarge();
    }
    if (p == urls.length) {
      details_txts.text = "";
      load_txts.text = ""
      //clear loading message
      slideImages_btn._visible = true;
      //turn on nav button
      loadNewGallery_btn._visible = true;
    }
  };
  Clip.addListener(mclListener);
  Clip.loadClip(urls[p], container.sample);
}
/************************************************************************
SLIDE IMAGE BUTTON
************************************************************************/

slideImages_btn._visible = false;
//turn it off to all is loaded
slideImages_btn.onRelease = function() {
  butNavCounter++//increment the counter variable, we set this to be 0 initially, which is the first image, so we add 1 to the start, to get
  //to the next image with the first click
  TweenLite.to(imageHolder_mc, 1, {_y:-(imageHolder_mc.getInstanceAtDepth(1)._height*butNavCounter)+offset, ease:Strong.easeOut});
  //reset the counter var to create a loop. Note that we are setting it to -1, so that when this function runs again, butNavCounter becomes 0, which
  //is the first image
  if(butNavCounter== urls.length-1){
  butNavCounter = -1 
  //butNavCounter = urls.length-1 //for making the image stop at the last one
  //this.enabled =false //turn off the button if you stop the slides, good UI practice!
  }
};
/****************************************************************************
REMOVE ALL CONTENT METHOD
****************************************************************************/

//Use to clear old images if you are going to add in a new set of images
function removeSlides():Void {
  for (var i in imageHolder_mc) {
    if (typeof (imageHolder_mc[i]) == "movieclip") {
      removeMovieClip(imageHolder_mc.getInstanceAtDepth(imageHolder_mc[i].getDepth()));
    }
    ImageHolder._height = 0;
    imageHolder_mc._y = offset;
    p = 0;
    pos = 0;
  }
}

function clearTextNav():Void {
  for (var i in navHolder_mc) {
    if (typeof (navHolder_mc[i]) == "movieclip") {
      removeMovieClip(navHolder_mc.getInstanceAtDepth(navHolder_mc[i].getDepth()));
    }
    butNavCounter = 0;
    navPos = 0;
  }
}
/****************************************************************************
ADD IN NEW GALLERY
****************************************************************************/


loadNewGallery_btn._visible = false;
loadNewGallery_btn.onRelease = function() {
  removeSlides()
  clearTextNav()
  slide.load("slideimagesa.xml");
};

ActionScript 3 XML Accordion Menu

This menu system was written as a means to display images or other content in a condensed manner.

Class based ActionScript 3 Accordion Menu, with either a rollOver/RollOff activation scheme for a onRelease activation scheme. Menu is built using a custom event dispatch scheme to keep each menu item synchronised with the changing states of the menu. The menu grabs a reference to the Stage via the ADDED_TO_STAGE event, which is uses as its base for setting up the communication between menu elements.

Menu Functionality

    Support for Images and Swfs as content.Swfs can contain their own interactivity.Either Click or MouseOver menu to activate it.XML Driven.XML can contain function calls with parameters, or URLs or nothing.Menu Highlighting is an option.Either the whole menu item, or just the menu bar can be used to trigger menu movement.Menu supports content of differing sizes. Menu will auto size the menu bar width, but is content height agnostic.Support for placement.Support for spacing between menu items and menu bar item height.Menu Bar has a test element, pulled in from the XML file.Column support. But you will have to add that change yourself.Menu uses either tweenLite or tweener for menu movement.Custom Event Dispatch class for sending events to particular menu instances. Eg, for telling one menu to slide open after all have loaded.Class has a reset method, should you need to reset the menu

If you are going to get the menu to trigger events it is generally it is better to only use the bar, so as to not interfere with your other nested actions.

Menu is a class file, which relies on be passed three values in its constructor,  (loader content, title text, menu action), all of which are values that are pulled in from the XML file.

Included in the download are two folders, one  accordianAS3_rel contains the onRelease version of the class. The other, accordianAS3_roll contains the RollOver version of the class. In each folder are each classes respective Flash CS3 document, its associated Document Class file, an XML file, an XML parsing class, the tweenLite Class and images and swfs.

Updates10th Feb, 2008: Added custom event dispatch class to both examples.

View ExamplesActionScript 3 XML Accordion Menu: On Release VersionActionScript 3 XML Accordion Menu: On RollOver Version

Source FilesHere are the source files; ActionScript 3 XML Accordion Menu V2

DependenciesClass uses the tweenLite tweening class for menu movement, highlighting etc; http://www.tweenlite.com

Class ActionScript

/*******************************************************************************
SIMPLE XML ACCORDION MENU
********************************************************************************
This menu system was written as a means to display images in a condensed manner.

Simple XML based accordion menu. Menu acts as a content space minimiser, with content hidden behind menu bar items. Content
slides into view when the menu item is clicked on.

Menu supports parsing function calls from the XML file, along with parameter support for these functions. This is useful for perhaps
calling a function on the parent timeline of the menu. Menu also supports a standard URL call from the XML, but this runs with on the first click of
the menu item, so it is perhaps better to use SWFs to achieve this kind of functionality. You can of course have no action supplied.

Menu supports both images and swfs. Loaded swfs can contain their own interactivity and can call parent functions.

Menu supports using either the whole menu or just the menu bar as the mechansim for sliding the menu up and down. Generally it is better to only use
the bar if you want to include interactivity in the menu items.

Positioning menu: Provide it with start values in the class below, then it positions itself based off the barHeight and menuPadding variables. To
create a column, or otherwise change menu item positions, set either the menuPosX or menuPosY values, like so, accordionMenu.menuPosX = newValue

Menu supports custom events, so that individual menu instances can be targetted. Doing so relies on the MenuEvent class, which allows for the passing
of one parameter (ID) which is an integer. This param is checked against the ID var of each menu, if they match, then the menu acts on the event. If you
want to be able to send other params to the menus, edit the MenuEvent Class. Each menu obtains an ID that matches its instantiation order, starting from 0, whic
is the first menu.

Dispatch events to individual menu items like so;
//dispatch a new event telling the 3 menu item to open
dispatchEvent(new MenuEvent(MenuEvent.MENU_EVENT,3));


********************************************************************************
SAMPLE USEAGE
********************************************************************************
//load the menu content - (loader content, title text, menu action)
var newMenu:accordionMenu = new accordionMenu(loader.content, menuXML.menuitem.names.text()[p], menuXML.menuitem.action.text()[p]);

********************************************************************************
NOTES
********************************************************************************
Use either Tweener or TweenLite to animate the menus. Currently menu is using TweenLite, but should you want to
use Tweener, then comment out TweenLite references, and uncomment Tweener References.

TweenLite from here;http://blog.greensock.com/tweenliteas3
Tweener from here;http://code.google.com/p/tweener/

Made in 2007 by noponies
http://www.blog.noponies.com

Terms of use
http://www.blog.noponies.com/terms-and-conditions

********************************************************************************/

package {
import flash.display.*;
import flash.display.Stage;
import flash.events.*;
//import caurina.transitions.Tweener;//using Tweener to tween the y property
import gs.TweenLite;//using TweenLite to tween the y property
import flash.text.*;
import flash.net.*;


public class accordionMenuRoll extends Sprite {
/*******************************************************************************/
/*USER DEFINABLE MENU VARIABLES
/*******************************************************************************/

private var barHeight:int = 14;//height of menu bar
private var menuPadding:int = 6;//space between menuitems
public static  var menuPosY:int = 20 //start y position of first menu item, this is a static var, that increments with each menu item, adjust for column layouts..
public static  var menuPosX:int = 100//start x value of first menu item
private var speed:Number = .5;//menu transition speed - in seconds
private var useWholeMenu:Boolean = false;//use the whole menu or just the black bar to trigger menu shuffles, default is true, use the whole menu
private var menuColour:int = 0x000000; //menu bars colour
private var useHighLighting:Boolean = true//change colours of bar on rollOver?
private var menuHighlightColour:int = 0x00FFFF//menu rollover colour
/*******************************************************************************/
/*REQUIRED VARS
/*******************************************************************************/

private var startY:int;//a value indicating the starting y position of each menu item
public static  var SHUFFLEPOS:String = "shufflepos";//set up for custom event dispatch
public static  var RESETPOS:String = "resetpos";//set up for custom event dispatch
public static  var RESETALL:String = "resetall";//Reset all menu items
private var menuBar:Sprite;//the menu bar
private var contentHolder:Sprite;//sprite to hold loaded content
private var menuTxt:TextField;//menu bars text
private var menuFormat:TextFormat;//text formating for menu bar text
private var masker:Shape;//mask the shape of the menus content
private var activated:Boolean=false;//var to track if the menu is expanded.
public static var counter:int = 0//counter var, used to give a menu an ID
private var id:int//id var
// below vars passed in via arguments to constructor
private var loadedContent:*;//content of loader - varies
private var titleText:String;
private var action:String;//temp var for passing each menu an action



public function accordionMenuRoll(loadedContent, titleText, menuAction) {
//var passed via constructor, links back to XML action node, contains URL or action
action = menuAction;
//generic setup
menuPosY+=(barHeight+menuPadding)//positioning of menu, vertically = barheight + menu padding
buttonMode = true;
useHandCursor = true;
mouseChildren = true;

//Give each menu an ID
this.id = counter++

//add content
contentHolder = new Sprite();
contentHolder.y = -loadedContent.height;//set a negative height so content is hidden behind menu bar
contentHolder.addChild(loadedContent);
addChild(contentHolder);

//mask
masker = new Shape();
masker.graphics.beginFill(0xFFFFFF);
masker.graphics.drawRect(0, barHeight, loadedContent.width, loadedContent.height);
masker.graphics.endFill();
addChild(masker);
loadedContent.mask = masker;//mask the loaded content

//visible bar sprite
menuBar = new Sprite();
menuBar.graphics.beginFill(menuColour);
menuBar.graphics.drawRect(0, 0, loadedContent.width, barHeight);//height, width of menu bar
menuBar.graphics.endFill();
addChild(menuBar);//add in the black menu bar

//text field formatting
menuFormat = new TextFormat();
menuFormat.font = new standard07_65().fontName;//class name of font in parent library
menuFormat.size = 8;
menuFormat.color = 0xFFFFFF;

//text field constructing
menuTxt = new TextField();
menuTxt.type = TextFieldType.DYNAMIC;
menuTxt.autoSize = TextFieldAutoSize.LEFT;
menuTxt.embedFonts = true;
menuTxt.x = 8;
menuTxt.y = 0;
menuTxt.mouseEnabled = false;
menuTxt.htmlText = titleText;
menuTxt.setTextFormat(menuFormat);
addChild(menuTxt);//add the menus title text
//position the menu using provide vars
this.x = menuPosX
this.y = menuPosY


//event listeners
//check to see if we are gonna use the whole menu or just the black bar
if (useWholeMenu) {
addEventListener(MouseEvent.CLICK, mouseClickHandler);
} else {
menuBar.addEventListener(MouseEvent.CLICK, mouseClickHandler);
}

addEventListener(MouseEvent.ROLL_OUT, rollOutHandler); //use rollovers in order to treat each instance as a whole and so we only fire one event.
addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);//comment out this listener to make the menus stay open even if rolled out.
addEventListener(MouseEvent.ROLL_OVER, mouseOverHandler);

//stage added event listener
addEventListener(Event.ADDED_TO_STAGE, addedHandler);//use stage as listener for custom events

}
//added to stage handler
private function addedHandler(event:Event):void {
stage.addEventListener(accordionMenuRoll.SHUFFLEPOS, shuffleHandler);
stage.addEventListener(accordionMenuRoll.RESETPOS, resetHandler);
stage.addEventListener(accordionMenuRoll.RESETALL, resetMenus);
//custom event listener
stage.addEventListener(MenuEvent.MENU_EVENT,CustomMenuEventHandler);
startY = event.target.y;//find out our start ypos
}
//click
private function mouseClickHandler(event:MouseEvent):void {
/*check to see if we have a function call or URL in the XML file. We also check to see if that function
contains parameters. The checking is based off testing to see if the first characters in our action
variable equal http, which if they do, we assume is a URL, rather than a function call*/

if (this.action =="") {
//catch empty string
} else if (this.action.indexOf("http", 0)!==0) {
//call a function, support for parameters in XML calls
var params:Array = this.action.split(",");
if (params.length&gt;1) {
parent[params[0]](params.slice(1,params.length));
} else {
parent[params[0]]();
}

} else {//open the url
var ur:URLRequest = new URLRequest(this.action);
navigateToURL(ur, "_blank");
}

dispatchEvent(new Event(accordionMenuRoll.RESETPOS,true));
TweenLite.to(this.contentHolder, speed, {y:barHeight});
//Tweener.addTween(this.contentHolder,{y:barHeight, time:speed});
dispatchEvent(new Event(accordionMenuRoll.SHUFFLEPOS,true));
this.activated = true;

}


/*mouse move handler, used to trigger a variable that enables smoother dowards movement through the menus
basically this creates a 'active zone', which triggers a switch of the activated variable. If we are inside this zone, we keep it true. This
helps with downwards mouse movement across the menus.*/

private function mouseMoveHandler(event:MouseEvent):void {
if (stage.mouseY&lt;=this.y+2 || stage.mouseY&gt;=this.y+(this.menuBar.height+this.masker.height)-2 || stage.mouseX&lt;=this.x+20 || stage.mouseX&gt;=this.x+this.width-20) {
this.activated = false
}
}

//rollout
private function rollOutHandler(event:MouseEvent):void {
if(useHighLighting){
TweenLite.to(this.menuBar, speed, {tint:menuColour});
//Tweener.addTween(this.menuBar,{_color:menuColour, time:speed});

}
if (!this.activated) {
dispatchEvent(new Event(accordionMenuRoll.RESETPOS,true));
TweenLite.to(this.contentHolder, speed, {y:-this.contentHolder.height});
//Tweener.addTween(this.contentHolder,{y:-this.contentHolder.height, time:speed});
this.activated = false;
}
}

//rollover
private function mouseOverHandler(event:MouseEvent):void {
if(useHighLighting){
TweenLite.to(this.menuBar, .1, {tint:menuHighlightColour});
//Tweener.addTween(this.menuBar,{_color:menuHighlightColour, time:.4});
}
dispatchEvent(new Event(accordionMenuRoll.RESETPOS,true));
TweenLite.to(this.contentHolder, speed, {y:barHeight});
//Tweener.addTween(this.contentHolder,{y:barHeight, time:speed});
dispatchEvent(new Event(accordionMenuRoll.SHUFFLEPOS,true));
this.activated = true;
}

//reset position of clips listener handler
private function resetHandler(event:Event):void {
TweenLite.to(this, speed, {y:startY});
//Tweener.addTween(this,{y:startY, time:speed });
this.activated = false;//reset this var to indicate that menus are closed. Stops an issue where a menu can be activated, ie opened, but then a user
//can click on a different menu, resulting in the original menus activated state not getting reset.
}

//custom menu event handler, send an event to a particular menu, in this instance, telling it to expand
private function CustomMenuEventHandler(event:MenuEvent):void {
if (event.menuId == this.id) {
dispatchEvent(new Event(accordionMenuRoll.RESETPOS,true));
TweenLite.to(this.contentHolder, speed, {y:barHeight});
dispatchEvent(new Event(accordionMenuRoll.SHUFFLEPOS,true));
this.activated = true;
}
}

//shuffle the clips positions, dependent on their x pos and y pos in relation to the currently active menu
//using xpos gives us column support
private function shuffleHandler(event:Event):void {
if (this!==event.target) {
//slide the bars back up
TweenLite.to(this.contentHolder, speed, {y:-this.contentHolder.height});
//Tweener.addTween(this.contentHolder,{y:-this.contentHolder.height, time:speed});

}
if ((this.y&gt;event.target.y) &amp;&amp; (this.x == event.target.x)) {
//slide the bars back up
TweenLite.to(this, speed, {y:startY+event.target.contentHolder.height});
//Tweener.addTween(this,{y:startY+event.target.contentHolder.height, time:speed});
}
}
//reset menu method
public function resetMenus(event:Event):void{
dispatchEvent(new Event(accordionMenuRoll.RESETPOS,true));
dispatchEvent(new Event(accordionMenuRoll.SHUFFLEPOS,true));

}

//kill listeners, call if needed
public function killListeners(event:Event):void{
removeEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
removeEventListener(MouseEvent.ROLL_OVER, mouseOverHandler);
removeEventListener(Event.ADDED_TO_STAGE, addedHandler);
stage.removeEventListener(accordionMenuRoll.SHUFFLEPOS, shuffleHandler);
stage.removeEventListener(accordionMenuRoll.RESETPOS, resetHandler);
stage.removeEventListener(accordionMenuRoll.RESETALL, resetMenus);
stage.removeEventListener(MenuEvent.MENU_EVENT,CustomMenuEventHandler);

}

}
}