package com.exanimo.managers { import com.exanimo.events.StateManagerEvent; import flash.events.Event; import flash.events.EventDispatcher; import flash.external.ExternalInterface; [Event(name='stateSet', type='com.exanimo.events.StateManagerEvent')]; [Event(name='stateChange', type='com.exanimo.events.StateManagerEvent')]; [Event(name='stateRevisit', type='com.exanimo.events.StateManagerEvent')]; /** * * Adds state management (back button and deep-linking) to your flash app. * * @see http://exanimo.com/actionscript/statemanager/ * * @author Matthew Tretter (matthew@exanimo.com) * @version 2007.04.30 * */ public class StateManager { // An EventDispatcher that we can use. private static var _eventDispatcher:EventDispatcher; // The current stateChange event. private static var event:StateManagerEvent; // The default value of defaultStateID. private static const DEFAULT_STATE:String = 'defaultState'; // The ID of the default state. private static var _defaultStateID:String; // // Do some automatic setup. // StateManager._eventDispatcher = new EventDispatcher(); ExternalInterface.addCallback('dispatchStateChangeEvents', StateManager._dispatchEvent); // // accessors // /** * * Allow the user to get and set the id of the default state. * */ public static function set defaultStateID(defaultStateID:String):void { StateManager._defaultStateID = defaultStateID; ExternalInterface.call('eval', 'EXANIMO.managers.StateManager.defaultStateID="' + defaultStateID.split('"').join('\\"') + '"'); } public static function get defaultStateID():String { return StateManager._defaultStateID == null ? StateManager.DEFAULT_STATE : StateManager._defaultStateID; } // // public methods // /** * @copy flash.events.IEventDispatcher#addEventListener */ public static function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void { StateManager._eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference); } /** * @copy flash.events.IEventDispatcher#dispatchEvent */ private static function dispatchEvent(event:Event):Boolean { return StateManager._eventDispatcher.dispatchEvent(event); } /** * @copy flash.events.IEventDispatcher#hasEventListener */ public static function hasEventListener(type:String):Boolean { return StateManager._eventDispatcher.hasEventListener(type); } /** * * Initializes the StateManager. * */ public static function initialize():void { ExternalInterface.call('EXANIMO.managers.StateManager.initialize', true); } /** * @copy flash.events.IEventDispatcher#removeEventListener */ public static function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void { StateManager._eventDispatcher.addEventListener(type, listener, useCapture); } /** * * Log a state change. * * @param id the id of the state you want to load * */ public static function setState(id:String, ... rest:Array):void { var title:String = rest[0]; // If the state hasn't been set, set it. if (!StateManager.event) { ExternalInterface.call('EXANIMO.managers.StateManager.setState', id, title); StateManager._dispatchEvent(id, true); } // Otherwise, just set the title. else { ExternalInterface.call('EXANIMO.managers.StateManager.setTitle', title); } } /** * * Sets the title for the state. * * @param title * the string to show in your browser's title bar * */ public static function setTitle(title:String):void { ExternalInterface.call('EXANIMO.managers.StateManager.setTitle', title); } /** * @copy flash.events.IEventDispatcher#willTrigger */ public static function willTrigger(type:String):Boolean { return StateManager._eventDispatcher.willTrigger(type); } // // private methods // /** * * Dispatch a stateChange event. * * @param id * the id of the new state * @param manual * was the stateChange manual? manual changes are the result of * calls to setState. (automatic changes are the result of the * back/forward buttons or deep-linking.) */ private static function _dispatchEvent(id:String, ... rest:Array):void { var manual:Boolean = rest[0]; // Dispatch a stateChange event. StateManager.event = new StateManagerEvent(StateManagerEvent.STATE_CHANGE, false, false, id); StateManager.dispatchEvent(StateManager.event); var e:StateManagerEvent; if (manual) { e = new StateManagerEvent(StateManagerEvent.STATE_SET, false, false, id); StateManager.dispatchEvent(e); } else { e = new StateManagerEvent(StateManagerEvent.STATE_REVISIT, false, false, id); StateManager.dispatchEvent(e); } StateManager.event = null; } } }