package com.visual {
    /* Flash widgets */
    import flash.display.Sprite;
    import flash.external.ExternalInterface;
    import flash.events.Event;

    /* OSMF widgets */
    import org.osmf.media.MediaPlayerSprite;
    import org.osmf.media.MediaPlayer;
    import org.osmf.media.URLResource;
    import org.osmf.elements.VideoElement;
    import org.osmf.media.MediaElement;
    import org.osmf.utils.OSMFSettings;
    import org.osmf.events.LoadEvent;
    import org.osmf.events.MediaElementEvent;
    import org.osmf.layout.LayoutMetadata;
    import org.osmf.layout.ScaleMode;
    import org.osmf.traits.DisplayObjectTrait;
    import org.osmf.traits.MediaTraitType;

    public class VisualVideo extends Sprite {
        // Create the container classes to displays media.
        OSMFSettings.enableStageVideo = false;
        private var image:VisualImage = new VisualImage();
        private var videoContainer:MediaPlayerSprite = null;
        private var video:MediaPlayer = null;
        private var layout:LayoutMetadata = new LayoutMetadata();
        private var loadFired:Boolean = false;
        private var videoEnded:Boolean = false;
        private var queuePlay:Boolean = false;
        private var attachedEvents:Boolean = false;
        public var pseudoStreamingOffset:Number = 0;

        // Logging
        private function trace(s:String):void {
            try {
                ExternalInterface.call("console.log", "FlashFallback", s);
            }catch(e:Error){}
        }

        // Callback for events
        public var callback:Function = function():void{};

        // Constructor method
        public function VisualVideo() {}
        private var inited:Boolean = false;
        private function init():void {
            if(inited) return;

            // Alignment
            layout.scaleMode = ScaleMode.LETTERBOX;
            layout.verticalAlign = 'middle';
            layout.horizontalAlign = 'center';
            // Add video stage
            videoContainer = new MediaPlayerSprite();
            this.addChild(videoContainer);
            // Size
            this.stage.addEventListener(Event.RESIZE, matchVideoSize);
            matchVideoSize();

            inited = true;
        }

        // PROPERTIES
        // Property: Source
        private var _source:String = null;
        public function set source(s:String):void {
            init();

            _source=s;
            //this really should be reset here, but we need to be able to overwrite with a property// this.pseudoStreamingOffset = 0;

            this.loadFired = false;
            this.videoEnded = false;
            var isPlaying:Boolean = (video && video.playing);
            var pseudoSource:String = '';
            if(this.pseudoStreamingOffset==0) {
                pseudoSource = _source;
            } else {
                pseudoSource = _source + (new RegExp("\\?").test(_source) ? '&' : '?') + 'start=' + this.pseudoStreamingOffset;
            }
            _duration = 0;

            // Load the stream and attach to playback
            var resource:URLResource = new URLResource(pseudoSource);
            video = videoContainer.mediaPlayer;
            video.autoPlay = isPlaying||queuePlay;
            video.bufferTime = (isLive ? 0.1 : 1);
            queuePlay = false;
            video.autoRewind = false;
            videoContainer.resource = new URLResource(pseudoSource);
            videoContainer.media.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, layout);

            // Smoothing with OSMF isn't supposed to be easy. We'll try two different things...
            // 1st case
            if (videoContainer.media is VideoElement) (videoContainer.media as VideoElement).smoothing = true;
            // 2nd case
            videoContainer.media.addEventListener(MediaElementEvent.TRAIT_ADD, function(event:MediaElementEvent):void {
              if(event.type == MediaElementEvent.TRAIT_ADD && event.traitType == MediaTraitType.DISPLAY_OBJECT) {
                var displayObject:Object = (videoContainer.media.getTrait(MediaTraitType.DISPLAY_OBJECT) as DisplayObjectTrait).displayObject;
                displayObject.smoothing = true;
              }
            });

            matchVideoSize();

            if(!this.attachedEvents) {
                this.video.addEventListener('durationChange', function():void{_duration=video.duration;});
                this.video.addEventListener('bytesLoadedChange', function():void{callback('progress');});
                this.video.addEventListener('complete', function():void{
                    videoEnded = true;
                    callback('ended');
                });
                this.video.addEventListener('volumeChange', function():void{callback('volumechange');});
                this.video.addEventListener('currentTimeChange', function():void{callback('timeupdate');});
                this.video.addEventListener('canPlayChange', function():void{
                    if(video.canPlay) {
                        callback('canplay');
                        if(queuePlay) {
                            playing = true;
                            queuePlay = false;
                        }
                    }
                });
                this.video.addEventListener('mediaPlayerStateChange', function():void{
                    if( !loadFired && (video.state=='playing'||video.state=='buffering'||video.state=='loading'||video.state=='ready')) {
                        callback('loadeddata');
                        callback('loadedmetadata');
                        loadFired = true;
                    }
                    if( video.state=='buffering'||video.state=='playbackError'||video.state=='loading' ) {
                        callback('stalled');
                    } else if( video.state=='playing' ) {
                        callback('play');
                        callback('playing');
                    } else if( video.state=='paused'||video.state=='ready' ) {
                        callback('pause');
                    }
                });
                this.attachedEvents = true;
            }
        }
        public function get source():String {
            return _source;
        }

        // Property: Poster
        private var _poster:String = null;
        public function set poster(p:String):void {
            init();

            if(_poster==p) return;
            this.addChildAt(image,0);
            image.source = p;
            _poster=p;
        }
        public function get poster():String {
            return _poster;
        }

        // Property: Playing
        public function set playing(p:Boolean):void {
            if(!this.video) return;
            try {
                if(p) {
                    if(this.videoEnded) this.currentTime = 0;
                    this.video.play();
                    callback('play');
                } else {
                    this.video.pause();
                }
            }catch(e:Error){
                queuePlay = p;
            }
        }
        public function get playing():Boolean {

            return this.video && this.video.playing;
        }

        // Property: Seeking
        public function get seeking():Boolean {
            return this.video && this.video.seeking;
        }

        // Property: Stalled
        public function get stalled():Boolean {
            return (this.video && (this.video.state=='buffering' || this.video.state=='loading' ||  this.video.state=='playbackError'));
        }

        // Property: Ended
        public function get ended():Boolean {
            return this.videoEnded;
        }

        // Property: Current time
        public function set currentTime(ct:Number):void {
            if(!this.video) return;
            if(ct<0||ct>duration) return;
            if(isLive) return;

            if(ct<this.pseudoStreamingOffset || ct>this.bufferTime) {
                _duration = duration - ct; // Guesstimate the duration of the new clip before changing the offset
                this.pseudoStreamingOffset = ct;
                trace('Pseudo streaming from ' + this.pseudoStreamingOffset);
                source = source; // switch source with new pseudo stream time
            } else {
                try {
                    this.video.seek(ct-this.pseudoStreamingOffset);
                }catch(e:Error){}
            }
        }
        public function get currentTime():Number {
            return (this.video ? this.pseudoStreamingOffset + this.video.currentTime : 0);
        }

        // Property: Duration
        private var _duration:Number = 0;
        public function get duration():Number {
            if(isLive) {
              return currentTime;
            } else {
              return (this.video ? this.pseudoStreamingOffset+_duration : 0);
            }
        }

        // Property: Buffer time
        public function get bufferTime():Number {
            if(!this.video) return 0;

            if(isLive) {
                return currentTime;
            } else {
                var bytesLoaded:int = (this.video ? this.video.bytesLoaded : 0);
                var bytesTotal:int = (this.video ? this.video.bytesTotal : 0);
                if(this.duration<=0 || bytesLoaded<=0 || bytesTotal<=0) {
                    return 0;
                } else {
                    return this.pseudoStreamingOffset+((bytesLoaded/bytesTotal)*_duration);
                }
            }
        }

        // Property: Volume
        public function set volume(v:Number):void {
            if(!this.video) return;
            this.video.volume = v;
        }
        public function get volume():Number {
            if(!this.video) return 1;
            return this.video.volume;
        }

        // Property: isLive
        public function get isLive():Boolean {
            return( /^rtmp:\/\//.test(_source.toLowerCase()) || /\.f4m$/.test(_source.toLowerCase()) );
        }

        private function matchVideoSize(e:Event=null):void {
            try {
                videoContainer.height = this.stage.stageHeight;
                videoContainer.width = this.stage.stageWidth;
                layout.height = this.stage.stageHeight;
                layout.width = this.stage.stageWidth;
            }catch(e:Error){}
       }
    }
}

package com.visual {
    /* Flash widgets */
    import flash.display.Sprite;
    import flash.external.ExternalInterface;
    import flash.events.Event;

    /* OSMF widgets */
    import org.osmf.media.MediaPlayerSprite;
    import org.osmf.media.MediaPlayer;
    import org.osmf.media.URLResource;
    import org.osmf.elements.VideoElement;
    import org.osmf.media.MediaElement;
    import org.osmf.utils.OSMFSettings;
    import org.osmf.events.LoadEvent;
    import org.osmf.events.MediaElementEvent;
    import org.osmf.layout.LayoutMetadata;
    import org.osmf.layout.ScaleMode;
    import org.osmf.traits.DisplayObjectTrait;
    import org.osmf.traits.MediaTraitType;

    public class VisualVideo extends Sprite {
        // Create the container classes to displays media.
        OSMFSettings.enableStageVideo = false;
        private var image:VisualImage = new VisualImage();
        private var videoContainer:MediaPlayerSprite = null;
        private var video:MediaPlayer = null;
        private var layout:LayoutMetadata = new LayoutMetadata();
        private var loadFired:Boolean = false;
        private var videoEnded:Boolean = false;
        private var queuePlay:Boolean = false;
        private var attachedEvents:Boolean = false;
        public var pseudoStreamingOffset:Number = 0;

        // Logging
        private function trace(s:String):void {
            try {
                ExternalInterface.call("console.log", "FlashFallback", s);
            }catch(e:Error){}
        }

        // Callback for events
        public var callback:Function = function():void{};

        // Constructor method
        public function VisualVideo() {}
        private var inited:Boolean = false;
        private function init():void {
            if(inited) return;

            // Alignment
            layout.scaleMode = ScaleMode.LETTERBOX;
            layout.verticalAlign = 'middle';
            layout.horizontalAlign = 'center';
            // Add video stage
            videoContainer = new MediaPlayerSprite();
            this.addChild(videoContainer);
            // Size
            this.stage.addEventListener(Event.RESIZE, matchVideoSize);
            matchVideoSize();

            inited = true;
        }

        // PROPERTIES
        // Property: Source
        private var _source:String = null;
        public function set source(s:String):void {
            init();

            _source=s;
            //this really should be reset here, but we need to be able to overwrite with a property// this.pseudoStreamingOffset = 0;

            this.loadFired = false;
            this.videoEnded = false;
            var isPlaying:Boolean = (video && video.playing);
            var pseudoSource:String = '';
            if(this.pseudoStreamingOffset==0) {
                pseudoSource = _source;
            } else {
                pseudoSource = _source + (new RegExp("\\?").test(_source) ? '&' : '?') + 'start=' + this.pseudoStreamingOffset;
            }
            _duration = 0;

            // Load the stream and attach to playback
            var resource:URLResource = new URLResource(pseudoSource);
            video = videoContainer.mediaPlayer;
            video.autoPlay = isPlaying||queuePlay;
            video.bufferTime = (isLive ? 0.1 : 1);
            queuePlay = false;
            video.autoRewind = false;
            videoContainer.resource = new URLResource(pseudoSource);
            videoContainer.media.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, layout);

            // Smoothing with OSMF isn't supposed to be easy. We'll try two different things...
            // 1st case
            if (videoContainer.media is VideoElement) (videoContainer.media as VideoElement).smoothing = true;
            // 2nd case
            videoContainer.media.addEventListener(MediaElementEvent.TRAIT_ADD, function(event:MediaElementEvent):void {
              if(event.type == MediaElementEvent.TRAIT_ADD && event.traitType == MediaTraitType.DISPLAY_OBJECT) {
                var displayObject:Object = (videoContainer.media.getTrait(MediaTraitType.DISPLAY_OBJECT) as DisplayObjectTrait).displayObject;
                displayObject.smoothing = true;
              }
            });

            matchVideoSize();

            if(!this.attachedEvents) {
                this.video.addEventListener('durationChange', function():void{_duration=video.duration;});
                this.video.addEventListener('bytesLoadedChange', function():void{callback('progress');});
                this.video.addEventListener('complete', function():void{
                    videoEnded = true;
                    callback('ended');
                });
                this.video.addEventListener('volumeChange', function():void{callback('volumechange');});
                this.video.addEventListener('currentTimeChange', function():void{callback('timeupdate');});
                this.video.addEventListener('canPlayChange', function():void{
                    if(video.canPlay) {
                        callback('canplay');
                        if(queuePlay) {
                            playing = true;
                            queuePlay = false;
                        }
                    }
                });
                this.video.addEventListener('mediaPlayerStateChange', function():void{
                    if( !loadFired && (video.state=='playing'||video.state=='buffering'||video.state=='loading'||video.state=='ready')) {
                        callback('loadeddata');
                        callback('loadedmetadata');
                        loadFired = true;
                    }
                    if( video.state=='buffering'||video.state=='playbackError'||video.state=='loading' ) {
                        callback('stalled');
                    } else if( video.state=='playing' ) {
                        callback('play');
                        callback('playing');
                        image.visible = false;
                    } else if( video.state=='paused'||video.state=='ready' ) {
                        callback('pause');
                    }
                });
                this.attachedEvents = true;
            }
        }
        public function get source():String {
            return _source;
        }

        // Property: Poster
        private var _poster:String = null;
        public function set poster(p:String):void {
            init();

            if(_poster==p) return;
            this.addChildAt(image,0);
            image.source = p;
            _poster=p;
        }
        public function get poster():String {
            return _poster;
        }

        // Property: Playing
        public function set playing(p:Boolean):void {
            if(!this.video) return;
            try {
                if(p) {
                    if(this.videoEnded) this.currentTime = 0;
                    this.video.play();
                    callback('play');
                } else {
                    this.video.pause();
                }
            }catch(e:Error){
                queuePlay = p;
            }
        }
        public function get playing():Boolean {

            return this.video && this.video.playing;
        }

        // Property: Seeking
        public function get seeking():Boolean {
            return this.video && this.video.seeking;
        }

        // Property: Stalled
        public function get stalled():Boolean {
            return (this.video && (this.video.state=='buffering' || this.video.state=='loading' ||  this.video.state=='playbackError'));
        }

        // Property: Ended
        public function get ended():Boolean {
            return this.videoEnded;
        }

        // Property: Current time
        public function set currentTime(ct:Number):void {
            if(!this.video) return;
            if(ct<0||ct>duration) return;
            if(isLive) return;

            if(ct<this.pseudoStreamingOffset || ct>this.bufferTime) {
                _duration = duration - ct; // Guesstimate the duration of the new clip before changing the offset
                this.pseudoStreamingOffset = ct;
                trace('Pseudo streaming from ' + this.pseudoStreamingOffset);
                source = source; // switch source with new pseudo stream time
            } else {
                try {
                    this.video.seek(ct-this.pseudoStreamingOffset);
                }catch(e:Error){}
            }
        }
        public function get currentTime():Number {
            return (this.video ? this.pseudoStreamingOffset + this.video.currentTime : 0);
        }

        // Property: Duration
        private var _duration:Number = 0;
        public function get duration():Number {
            if(isLive) {
              return currentTime;
            } else {
              return (this.video ? this.pseudoStreamingOffset+_duration : 0);
            }
        }

        // Property: Buffer time
        public function get bufferTime():Number {
            if(!this.video) return 0;

            if(isLive) {
                return currentTime;
            } else {
                var bytesLoaded:int = (this.video ? this.video.bytesLoaded : 0);
                var bytesTotal:int = (this.video ? this.video.bytesTotal : 0);
                if(this.duration<=0 || bytesLoaded<=0 || bytesTotal<=0) {
                    return 0;
                } else {
                    return this.pseudoStreamingOffset+((bytesLoaded/bytesTotal)*_duration);
                }
            }
        }

        // Property: Volume
        public function set volume(v:Number):void {
            if(!this.video) return;
            this.video.volume = v;
        }
        public function get volume():Number {
            if(!this.video) return 1;
            return this.video.volume;
        }

        // Property: isLive
        public function get isLive():Boolean {
            return( /^rtmp:\/\//.test(_source.toLowerCase()) || /\.f4m$/.test(_source.toLowerCase()) );
        }

        private function matchVideoSize(e:Event=null):void {
            try {
                videoContainer.height = this.stage.stageHeight;
                videoContainer.width = this.stage.stageWidth;
                layout.height = this.stage.stageHeight;
                layout.width = this.stage.stageWidth;
            }catch(e:Error){}
       }
    }
}

Hide thumbnail image when is playing

Hide thumbnail image when is playing


package Components
{
	[Bindable]
	public class Association
	{
		public var associatedNode:String;
		public var associatedLink:String;
		public var operatorIndex:int;

		public function Association(associatedNode:String,associatedLink:String,operatorIndex:int)
		{
			this.associatedLink = associatedLink;
			this.associatedNode = associatedNode;
			this.operatorIndex  = operatorIndex;
		}

	}
}

package Components
{
	[Bindable]
	public class Association
	{
		public var associatedNode:String;
		public var associatedLink:String;
		public var operatorIndex:int;
		public var order:int=0;

		public function Association(associatedNode:String,associatedLink:String,operatorIndex:int,order:int)
		{
			this.associatedLink = associatedLink;
			this.associatedNode = associatedNode;
			this.operatorIndex  = operatorIndex;
			this.order=order;
		}

	}
}

Order vairable added todecide order of association

SVN-Revision: 9306


//
// Flump - Copyright 2013 Flump Authors

package flump.display {

import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;

import flump.mold.LayerMold;
import flump.mold.MovieMold;

import react.Signal;

import starling.animation.IAnimatable;
import starling.display.DisplayObject;
import starling.display.Sprite;
import starling.events.Event;
import starling.utils.MatrixUtil;

/**
 * A movie created from flump-exported data. It has children corresponding to the layers in the
 * movie in Flash, in the same order and with the same names. It fills in those children
 * initially with the image or movie of the symbol on that exported layer. After the initial
 * population, it only applies the keyframe-based transformations to the child at the index
 * corresponding to the layer. This means it's safe to swap in other DisplayObjects at those
 * positions to have them animated in place of the initial child.
 *
 *
A Movie will not animate unless it's added to a Juggler (or its advanceTime() function
 * is otherwise called). When the movie is added to a juggler, it advances its playhead with the
 * frame ticks if isPlaying is true. It will automatically remove itself from its juggler when
 * removed from the stage.

 *
 * @see Library and LibraryLoader to create instances of Movie.
 */
public class Movie extends Sprite
    implements IAnimatable
{
    /** A label fired by all movies when entering their first frame. */
    public static const FIRST_FRAME :String = "flump.movie.FIRST_FRAME";

    /** A label fired by all movies when entering their last frame. */
    public static const LAST_FRAME :String = "flump.movie.LAST_FRAME";

    /** Fires the label string whenever it's passed in playing. */
    public const labelPassed :Signal = new Signal(String);

    /** @private */
    public function Movie (src :MovieMold, frameRate :Number, library :Library) {
        this.name = src.id;
        _labels = src.labels;
        _frameRate = frameRate;
        if (src.flipbook) {
            _layers = new Vector.<Layer>(1, true);
            _layers[0] = createLayer(this, src.layers[0], library, /*flipbook=*/true);
            _numFrames = src.layers[0].frames;
        } else {
            _layers = new Vector.<Layer>(src.layers.length, true);
            for (var ii :int = 0; ii < _layers.length; ii++) {
                _layers[ii] = createLayer(this, src.layers[ii], library, /*flipbook=*/false);
                _numFrames = Math.max(src.layers[ii].frames, _numFrames);
            }
        }
        _duration = _numFrames / _frameRate;
        updateFrame(0, 0);

        // When we're removed from the stage, remove ourselves from any juggler animating us.
        addEventListener(Event.REMOVED_FROM_STAGE, function (..._) :void {
            dispatchEventWith(Event.REMOVE_FROM_JUGGLER);
        });
    }

    /** @return the frame being displayed. */
    public function get frame () :int { return _frame; }

    /** @return the number of frames in the movie. */
    public function get numFrames () :int { return _numFrames; }

    /** @return true if the movie is currently playing. */
    public function get isPlaying () :Boolean { return _state == PLAYING; }

    /** @return true if the movie contains the given label. */
    public function hasLabel (label :String) :Boolean {
        return getFrameForLabel(label) >= 0;
    }

    /** @return the frame index for the given label, or -1 if the label doesn't exist. */
    public function getFrameForLabel (label :String) :int {
        for (var ii :int = 0; ii < _labels.length; ii++) {
            if (_labels[ii] != null && _labels[ii].indexOf(label) != -1) return ii;
        }
        return -1;
    }

    /** Plays the movie from its current frame. The movie will loop forever.  */
    public function loop () :Movie {
        _state = PLAYING;
        _stopFrame = NO_FRAME;
        return this;
    }

    /** Plays the movie from its current frame, stopping when it reaches its last frame. */
    public function playOnce () :Movie { return playTo(LAST_FRAME); }

    /**
     * Moves to the given String label or int frame. Doesn't alter playing status or stop frame.
     * If there are labels at the given position, they're fired as part of the goto, even if the
     * current frame is equal to the destination. Labels between the current frame and the
     * destination frame are not fired.
     *
     * @param position the int frame or String label to goto.
     *
     * @return this movie for chaining
     *
     * @throws Error if position isn't an int or String, or if it is a String and that String isn't
     * a label on this movie
     */
    public function goTo (position :Object) :Movie {
        const frame :int = extractFrame(position);
        updateFrame(frame, 0);
        return this;
    }

   /**
    * Plays the movie from its current frame. The movie will stop when it reaches the given label
    * or frame.
    *
    * @param position to int frame or String label to stop at
    *
    * @return this movie for chaining
    *
    * @throws Error if position isn't an int or String, or if it is a String and that String isn't
    * a label on this movie.
    */
    public function playTo (position :Object) :Movie {
       // won't play if we're already at the stop position
       return stopAt(position).play();
    }

    /**
     * Sets the stop frame for this Movie.
     *
     * @param position the int frame or String label to stop at.
     *
     * @return this movie for chaining
     *
     * @throws Error if position isn't an int or String, or if it is a String and that String isn't
     * a label on this movie.
     */
    public function stopAt (position :Object) :Movie {
        _stopFrame = extractFrame(position);
        return this;
    }

    /**
     * Sets the movie playing. It will automatically stop at its stopFrame, if one is set,
     * otherwise it will loop forever.
     *
     * @return this movie for chaining
     */
    public function play () :Movie {
        // set playing to true unless movie is at the stop frame
        _state = (_frame != _stopFrame ? PLAYING : STOPPED);
        return this;
    }

    /** Stops playback if it's currently active. Doesn't alter the current frame or stop frame. */
    public function stop () :Movie {
        _state = STOPPED;
        return this;
    }

    /** Stops playback of this movie, but not its children */
    public function playChildrenOnly () :Movie {
        _state = PLAYING_CHILDREN_ONLY;
        return this;
    }

    /** Advances the playhead by the give number of seconds. From IAnimatable. */
    public function advanceTime (dt :Number) :void {
        if (dt < 0) throw new Error("Invalid time [dt=" + dt + "]");
        if (_skipAdvanceTime) { _skipAdvanceTime = false; return; }
        if (_state == STOPPED) return;

        if (_state == PLAYING && _numFrames > 1) {
            _playTime += dt;
            var actualPlaytime :Number = _playTime;
            if (_playTime >= _duration) _playTime %= _duration;

            // If _playTime is very close to _duration, rounding error can cause us to
            // land on lastFrame + 1. Protect against that.
            var newFrame :int = int(_playTime * _frameRate);
            if (newFrame < 0) newFrame = 0;
            if (newFrame >= _numFrames) newFrame = _numFrames - 1;

            // If the update crosses or goes to the stopFrame:
            // go to the stopFrame, stop the movie, clear the stopFrame
            if (_stopFrame != NO_FRAME) {
                // how many frames remain to the stopframe?
                var framesRemaining :int =
                    (_frame <= _stopFrame ? _stopFrame - _frame : _numFrames - _frame + _stopFrame);
                var framesElapsed :int = int(actualPlaytime * _frameRate) - _frame;
                if (framesElapsed >= framesRemaining) {
                    _state = STOPPED;
                    newFrame = _stopFrame;
                }
            }
            updateFrame(newFrame, dt);
        }

        for each (var layer :Layer in _layers) {
            layer.advanceTime(dt);
        }
    }

    /**
     * @public
     *
     * Modified from starling.display.DisplayObjectContainer
     */
    public override function getBounds (targetSpace :DisplayObject, resultRect :Rectangle=null) :Rectangle {
        if (resultRect == null) {
            resultRect = new Rectangle();
        } else {
            resultRect.setEmpty();
        }

        // get bounds from layer contents
        for each (var layer :Layer in _layers) {
            layer.expandBounds(targetSpace, resultRect);
        }

        // if no contents exist, simply include this movie's position in the bounds
        if (resultRect.isEmpty()) {
            getTransformationMatrix(targetSpace, IDENTITY_MATRIX);
            MatrixUtil.transformCoords(IDENTITY_MATRIX, 0.0, 0.0, _s_helperPoint);
            resultRect.setTo(_s_helperPoint.x, _s_helperPoint.y, 0, 0);
        }

        return resultRect;
    }

    /**
     * @private
     *
     * Called when the Movie has been newly added to a layer.
     */
    internal function addedToLayer () :void {
        goTo(0);
        _skipAdvanceTime = true;
    }

    /** @private */
    protected function extractFrame (position :Object) :int {
        if (position is int) return int(position);
        if (!(position is String)) throw new Error("Movie position must be an int frame or String label");
        const label :String = String(position);
        var frame :int = getFrameForLabel(label);
        if (frame < 0) {
            throw new Error("No such label '" + label + "'");
        }
        return frame;
    }

    /**
     * @private
     *
     * @param dt the timeline's elapsed time since the last update. This should be 0
     * for updates that are the result of a "goTo" call.
     */
    protected function updateFrame (newFrame :int, dt :Number) :void {
        if (newFrame < 0 || newFrame >= _numFrames) {
            throw new Error("Invalid frame [frame=" + newFrame,
                " validRange=0-" + (_numFrames - 1) + "]");
        }

        if (_isUpdatingFrame) {
            _pendingFrame = newFrame;
            return;
        } else {
            _pendingFrame = NO_FRAME;
            _isUpdatingFrame = true;
        }

        const isGoTo :Boolean = (dt <= 0);
        const wrapped :Boolean = (dt >= _duration) || (newFrame < _frame);

        if (newFrame != _frame) {
            for each (var layer :Layer in _layers) {
                layer.drawFrame(newFrame);
            }
        }

        if (isGoTo) _playTime = newFrame / _frameRate;

        // Update the frame before firing frame label signals, so if firing changes the frame,
        // it sticks.
        const oldFrame :int = _frame;
        _frame = newFrame;

        // determine which labels to fire signals for
        var startFrame :int;
        var frameCount :int;
        if (isGoTo) {
            startFrame = newFrame;
            frameCount = 1;
        } else {
            startFrame = (oldFrame + 1 < _numFrames ? oldFrame + 1 : 0);
            frameCount = (_frame - oldFrame);
            if (wrapped) frameCount += _numFrames;
        }

        // Fire signals. Stop if pendingFrame is updated, which indicates that the client
        // has called goTo()
        var frameIdx :int = startFrame;
        for (var ii :int = 0; ii < frameCount; ++ii) {
            if (_pendingFrame != NO_FRAME) break;

            if (_labels[frameIdx] != null) {
                for each (var label :String in _labels[frameIdx]) {
                    labelPassed.emit(label);
                    if (_pendingFrame != NO_FRAME) break;
                }
            }

            // avoid modulo division by updating frameIdx each time through the loop
            if (++frameIdx == _numFrames) {
                frameIdx = 0;
            }
        }

        _isUpdatingFrame = false;
        // If we were interrupted by a goTo(), update to that frame now.
        if (_pendingFrame != NO_FRAME) {
            newFrame = _pendingFrame;
            updateFrame(newFrame, 0);
        }
    }

    protected function createLayer (movie :Movie, src :LayerMold, library :Library, flipbook :Boolean) :Layer {
        return new Layer(movie, src, library, flipbook);
    }

    /** @private */
    protected var _isUpdatingFrame :Boolean;
    /** @private */
    protected var _pendingFrame :int = NO_FRAME;
    /** @private */
    protected var _frame :int = NO_FRAME, _stopFrame :int = NO_FRAME;
    /** @private */
    protected var _state :int = PLAYING;
    /** @private */
    protected var _playTime :Number, _duration :Number;
    /** @private */
    protected var _layers :Vector.<Layer>;
    /** @private */
    protected var _numFrames :int;
    /** @private */
    protected var _frameRate :Number;
    /** @private */
    protected var _labels :Vector.<Vector.<String>>;
    /** @private */
    private var _skipAdvanceTime :Boolean = false;
    /** @private */
    internal var _playerData :MoviePlayerNode;
    /** @private */
    private static var _s_helperPoint :Point = new Point();

    private static const IDENTITY_MATRIX :Matrix = new Matrix();

    private static const NO_FRAME :int = -1;

    private static const STOPPED :int = 0;
    private static const PLAYING_CHILDREN_ONLY :int = 1;
    private static const PLAYING :int = 2;
}
}

//
// Flump - Copyright 2013 Flump Authors

package flump.display {

import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;

import flump.mold.LayerMold;
import flump.mold.MovieMold;

import react.Signal;

import starling.animation.IAnimatable;
import starling.display.DisplayObject;
import starling.display.Sprite;
import starling.events.Event;
import starling.utils.MatrixUtil;

/**
 * A movie created from flump-exported data. It has children corresponding to the layers in the
 * movie in Flash, in the same order and with the same names. It fills in those children
 * initially with the image or movie of the symbol on that exported layer. After the initial
 * population, it only applies the keyframe-based transformations to the child at the index
 * corresponding to the layer. This means it's safe to swap in other DisplayObjects at those
 * positions to have them animated in place of the initial child.
 *
 *
A Movie will not animate unless it's added to a Juggler (or its advanceTime() function
 * is otherwise called). When the movie is added to a juggler, it advances its playhead with the
 * frame ticks if isPlaying is true. It will automatically remove itself from its juggler when
 * removed from the stage.

 *
 * @see Library and LibraryLoader to create instances of Movie.
 */
public class Movie extends Sprite
    implements IAnimatable
{
    /** A label fired by all movies when entering their first frame. */
    public static const FIRST_FRAME :String = "flump.movie.FIRST_FRAME";

    /** A label fired by all movies when entering their last frame. */
    public static const LAST_FRAME :String = "flump.movie.LAST_FRAME";

    /** Fires the label string whenever it's passed in playing. */
    public const labelPassed :Signal = new Signal(String);

    /** @private */
    public function Movie (src :MovieMold, frameRate :Number, library :Library) {
        this.name = src.id;
        _labels = src.labels;
        _frameRate = frameRate;
        if (src.flipbook) {
            _layers = new Vector.<Layer>(1, true);
            _layers[0] = createLayer(this, src.layers[0], library, /*flipbook=*/true);
            _numFrames = src.layers[0].frames;
        } else {
            _layers = new Vector.<Layer>(src.layers.length, true);
            for (var ii :int = 0; ii < _layers.length; ii++) {
                _layers[ii] = createLayer(this, src.layers[ii], library, /*flipbook=*/false);
                _numFrames = Math.max(src.layers[ii].frames, _numFrames);
            }
        }
        _duration = _numFrames / _frameRate;
        updateFrame(0, 0);

        // When we're removed from the stage, remove ourselves from any juggler animating us.
        addEventListener(Event.REMOVED_FROM_STAGE, function (..._) :void {
            dispatchEventWith(Event.REMOVE_FROM_JUGGLER);
        });
    }

    /** @return the frame being displayed. */
    public function get frame () :int { return _frame; }

    /** @return the number of frames in the movie. */
    public function get numFrames () :int { return _numFrames; }

    /** @return true if the movie is currently playing. */
    public function get isPlaying () :Boolean { return _state == PLAYING; }

    /** @return true if the movie contains the given label. */
    public function hasLabel (label :String) :Boolean {
        return getFrameForLabel(label) >= 0;
    }

    /** @return the frame index for the given label, or -1 if the label doesn't exist. */
    public function getFrameForLabel (label :String) :int {
        for (var ii :int = 0; ii < _labels.length; ii++) {
            if (_labels[ii] != null && _labels[ii].indexOf(label) != -1) return ii;
        }
        return -1;
    }

    /** Plays the movie from its current frame. The movie will loop forever.  */
    public function loop () :Movie {
        _state = PLAYING;
        _stopFrame = NO_FRAME;
        return this;
    }

    /** Plays the movie from its current frame, stopping when it reaches its last frame. */
    public function playOnce () :Movie { return playTo(LAST_FRAME); }

    /**
     * Moves to the given String label or int frame. Doesn't alter playing status or stop frame.
     * If there are labels at the given position, they're fired as part of the goto, even if the
     * current frame is equal to the destination. Labels between the current frame and the
     * destination frame are not fired.
     *
     * @param position the int frame or String label to goto.
     *
     * @return this movie for chaining
     *
     * @throws Error if position isn't an int or String, or if it is a String and that String isn't
     * a label on this movie
     */
    public function goTo (position :Object) :Movie {
        const frame :int = extractFrame(position);
        updateFrame(frame, 0);
        return this;
    }

   /**
    * Plays the movie from its current frame. The movie will stop when it reaches the given label
    * or frame.
    *
    * @param position to int frame or String label to stop at
    *
    * @return this movie for chaining
    *
    * @throws Error if position isn't an int or String, or if it is a String and that String isn't
    * a label on this movie.
    */
    public function playTo (position :Object) :Movie {
       // won't play if we're already at the stop position
       return stopAt(position).play();
    }

    /**
     * Sets the stop frame for this Movie.
     *
     * @param position the int frame or String label to stop at.
     *
     * @return this movie for chaining
     *
     * @throws Error if position isn't an int or String, or if it is a String and that String isn't
     * a label on this movie.
     */
    public function stopAt (position :Object) :Movie {
        _stopFrame = extractFrame(position);
        return this;
    }

    /**
     * Sets the movie playing. It will automatically stop at its stopFrame, if one is set,
     * otherwise it will loop forever.
     *
     * @return this movie for chaining
     */
    public function play () :Movie {
        // set playing to true unless movie is at the stop frame
        _state = (_frame != _stopFrame ? PLAYING : STOPPED);
        return this;
    }

    /** Stops playback if it's currently active. Doesn't alter the current frame or stop frame. */
    public function stop () :Movie {
        _state = STOPPED;
        return this;
    }

    /** Stops playback of this movie, but not its children */
    public function playChildrenOnly () :Movie {
        _state = PLAYING_CHILDREN_ONLY;
        return this;
    }

    /** Advances the playhead by the give number of seconds. From IAnimatable. */
    public function advanceTime (dt :Number) :void {
        if (dt < 0) {
            throw new Error("Invalid time [dt=" + dt + "]");
        }

        if (_skipAdvanceTime) {
            _skipAdvanceTime = false;
            return;
        }

        if (_state == STOPPED) {
            return;
        }

        if (_state == PLAYING && _numFrames > 1) {
            _playTime += dt;
            var actualPlaytime :Number = _playTime;
            if (_playTime >= _duration) {
                _playTime %= _duration;
            }

            // If _playTime is very close to _duration, rounding error can cause us to
            // land on lastFrame + 1. Protect against that.
            var newFrame :int = int(_playTime * _frameRate);
            if (newFrame < 0) {
                newFrame = 0;
            } else if (newFrame >= _numFrames) {
                newFrame = _numFrames - 1;
            }

            // If the update crosses or goes to the stopFrame:
            // go to the stopFrame, stop the movie, clear the stopFrame
            if (_stopFrame != NO_FRAME) {
                // how many frames remain to the stopframe?
                var framesRemaining :int =
                    (_frame <= _stopFrame ? _stopFrame - _frame : _numFrames - _frame + _stopFrame);
                var framesElapsed :int = int(actualPlaytime * _frameRate) - _frame;
                if (framesElapsed >= framesRemaining) {
                    _state = STOPPED;
                    newFrame = _stopFrame;
                }
            }
            updateFrame(newFrame, dt);
        }

        for each (var layer :Layer in _layers) {
            layer.advanceTime(dt);
        }
    }

    /**
     * @public
     *
     * Modified from starling.display.DisplayObjectContainer
     */
    public override function getBounds (targetSpace :DisplayObject, resultRect :Rectangle=null) :Rectangle {
        if (resultRect == null) {
            resultRect = new Rectangle();
        } else {
            resultRect.setEmpty();
        }

        // get bounds from layer contents
        for each (var layer :Layer in _layers) {
            layer.expandBounds(targetSpace, resultRect);
        }

        // if no contents exist, simply include this movie's position in the bounds
        if (resultRect.isEmpty()) {
            getTransformationMatrix(targetSpace, IDENTITY_MATRIX);
            MatrixUtil.transformCoords(IDENTITY_MATRIX, 0.0, 0.0, HELPER_POINT);
            resultRect.setTo(HELPER_POINT.x, HELPER_POINT.y, 0, 0);
        }

        return resultRect;
    }

    /**
     * @private
     *
     * Called when the Movie has been newly added to a layer.
     */
    internal function addedToLayer () :void {
        goTo(0);
        _skipAdvanceTime = true;
    }

    /** @private */
    protected function extractFrame (position :Object) :int {
        if (position is int) return int(position);
        if (!(position is String)) throw new Error("Movie position must be an int frame or String label");
        const label :String = String(position);
        var frame :int = getFrameForLabel(label);
        if (frame < 0) {
            throw new Error("No such label '" + label + "'");
        }
        return frame;
    }

    /**
     * @private
     *
     * @param dt the timeline's elapsed time since the last update. This should be 0
     * for updates that are the result of a "goTo" call.
     */
    protected function updateFrame (newFrame :int, dt :Number) :void {
        if (newFrame < 0 || newFrame >= _numFrames) {
            throw new Error("Invalid frame [frame=" + newFrame + ", validRange=0-" + (_numFrames - 1) + "]");
        }

        if (_isUpdatingFrame) {
            _pendingFrame = newFrame;
            return;
        }

        _pendingFrame = NO_FRAME;
        _isUpdatingFrame = true;

        const isGoTo :Boolean = (dt <= 0);
        const wrapped :Boolean = (dt >= _duration) || (newFrame < _frame);

        if (newFrame != _frame) {
            for each (var layer :Layer in _layers) {
                layer.drawFrame(newFrame);
            }
        }

        if (isGoTo) {
            _playTime = newFrame / _frameRate;
        }

        // Update the frame before firing frame label signals, so if firing changes the frame,
        // it sticks.
        const oldFrame :int = _frame;
        _frame = newFrame;

        // determine which labels to fire signals for
        var startFrame :int;
        var frameCount :int;
        if (isGoTo) {
            startFrame = newFrame;
            frameCount = 1;
        } else {
            startFrame = (oldFrame + 1 < _numFrames ? oldFrame + 1 : 0);
            frameCount = (_frame - oldFrame);
            if (wrapped) {
                frameCount += _numFrames;
            }
        }

        // Fire signals. Stop if pendingFrame is updated, which indicates that the client
        // has called goTo()
        var frameIdx :int = startFrame;
        for (var ii :int = 0; ii < frameCount; ++ii) {
            if (_pendingFrame != NO_FRAME) break;

            if (_labels[frameIdx] != null) {
                for each (var label :String in _labels[frameIdx]) {
                    labelPassed.emit(label);
                    if (_pendingFrame != NO_FRAME) break;
                }
            }

            // avoid modulo division by updating frameIdx each time through the loop
            if (++frameIdx == _numFrames) {
                frameIdx = 0;
            }
        }

        _isUpdatingFrame = false;
        // If we were interrupted by a goTo(), update to that frame now.
        if (_pendingFrame != NO_FRAME) {
            newFrame = _pendingFrame;
            updateFrame(newFrame, 0);
        }
    }

    protected function createLayer (movie :Movie, src :LayerMold, library :Library, flipbook :Boolean) :Layer {
        return new Layer(movie, src, library, flipbook);
    }

    /** @private */
    protected var _isUpdatingFrame :Boolean;
    /** @private */
    protected var _pendingFrame :int = NO_FRAME;
    /** @private */
    protected var _frame :int = NO_FRAME, _stopFrame :int = NO_FRAME;
    /** @private */
    protected var _state :int = PLAYING;
    /** @private */
    protected var _playTime :Number = 0;
    /** @private */
    protected var _duration :Number;
    /** @private */
    protected var _layers :Vector.<Layer>;
    /** @private */
    protected var _numFrames :int;
    /** @private */
    protected var _frameRate :Number;
    /** @private */
    protected var _labels :Vector.<Vector.<String>>;
    /** @private */
    private var _skipAdvanceTime :Boolean = false;
    /** @private */
    internal var _playerData :MoviePlayerNode;

    private static const HELPER_POINT :Point = new Point();
    private static const IDENTITY_MATRIX :Matrix = new Matrix();

    private static const NO_FRAME :int = -1;

    private static const STOPPED :int = 0;
    private static const PLAYING_CHILDREN_ONLY :int = 1;
    private static const PLAYING :int = 2;
}
}

Fix a string concatenation and some minor cleanup


////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008-2013 Esri. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
package com.esri.builder.controllers
{

import com.esri.builder.controllers.supportClasses.processes.CleanUpProcess;
import com.esri.builder.controllers.supportClasses.processes.ProcessArbiter;
import com.esri.builder.controllers.supportClasses.processes.ProcessArbiterEvent;
import com.esri.builder.controllers.supportClasses.WellKnownDirectories;
import com.esri.builder.eventbus.AppEvent;
import com.esri.builder.model.WidgetType;
import com.esri.builder.model.WidgetTypeRegistryModel;
import com.esri.builder.views.BuilderAlert;

import flash.filesystem.File;

import mx.resources.ResourceManager;

public class RemoveCustomWidgetController
{
    private var removeWidgetArbiter:ProcessArbiter;

    private var widgetTypeToRemove:WidgetType;

    public function RemoveCustomWidgetController()
    {
        AppEvent.addListener(AppEvent.REMOVE_CUSTOM_WIDGET, removeCustomWidgetHandler);
    }

    private function removeCustomWidgetHandler(importCustomWidget:AppEvent):void
    {
        widgetTypeToRemove = importCustomWidget.data as WidgetType;
        removeWidget(widgetTypeToRemove);
    }

    private function removeWidget(widgetType:WidgetType):void
    {
        removeWidgetArbiter = new ProcessArbiter();
        removeWidgetArbiter.addEventListener(ProcessArbiterEvent.COMPLETE, importArbiter_completeHandler);
        removeWidgetArbiter.addEventListener(ProcessArbiterEvent.FAILURE, importArbiter_failureHandler);

        var customWidgetModule:File = WellKnownDirectories.getInstance().customModules.resolvePath(widgetTypeToRemove.name + "Module.swf");
        var customWidgetConfig:File = WellKnownDirectories.getInstance().customModules.resolvePath(widgetTypeToRemove.name + "Module.xml");
        var customWidgetFolder:File = WellKnownDirectories.getInstance().customFlexViewer.resolvePath("widgets/" + widgetType.name);

        removeWidgetArbiter.addProcess(new CleanUpProcess(customWidgetModule));
        removeWidgetArbiter.addProcess(new CleanUpProcess(customWidgetConfig));
        removeWidgetArbiter.addProcess(new CleanUpProcess(customWidgetFolder));

        removeWidgetArbiter.executeProcs();
    }

    protected function importArbiter_completeHandler(event:ProcessArbiterEvent):void
    {
        removeWidgetArbiter.removeEventListener(ProcessArbiterEvent.COMPLETE, importArbiter_completeHandler);
        removeWidgetArbiter.removeEventListener(ProcessArbiterEvent.FAILURE, importArbiter_failureHandler);

        WidgetTypeRegistryModel.getInstance().widgetTypeRegistry.removeWidgetType(widgetTypeToRemove);
        AppEvent.dispatch(AppEvent.REMOVE_CUSTOM_WIDGET_SUCCESS);
    }

    protected function importArbiter_failureHandler(event:ProcessArbiterEvent):void
    {
        removeWidgetArbiter.removeEventListener(ProcessArbiterEvent.COMPLETE, importArbiter_completeHandler);
        removeWidgetArbiter.removeEventListener(ProcessArbiterEvent.FAILURE, importArbiter_failureHandler);

        var removeCustomWidgetFailureMessage:String = ResourceManager.getInstance().getString("BuilderStrings",
                                                                                "removeCustomWidgetProcess.failure",
                                                                                [ event.message ]);
        var removeCustomWidgetFailureTitle:String = ResourceManager.getInstance().getString("BuilderStrings",
                                                                                "widgetManager.removeCustomWidget");
        BuilderAlert.show(removeCustomWidgetFailureMessage, removeCustomWidgetFailureTitle);

        AppEvent.dispatch(AppEvent.REMOVE_CUSTOM_WIDGET_FAILURE);
    }
}
}

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008-2013 Esri. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
package com.esri.builder.controllers
{

import com.esri.builder.controllers.supportClasses.WellKnownDirectories;
import com.esri.builder.controllers.supportClasses.processes.CleanUpProcess;
import com.esri.builder.controllers.supportClasses.processes.ProcessArbiter;
import com.esri.builder.controllers.supportClasses.processes.ProcessArbiterEvent;
import com.esri.builder.eventbus.AppEvent;
import com.esri.builder.model.WidgetType;
import com.esri.builder.model.WidgetTypeRegistryModel;
import com.esri.builder.views.BuilderAlert;

import flash.filesystem.File;

import mx.resources.ResourceManager;

public class RemoveCustomWidgetController
{
    private var removeWidgetArbiter:ProcessArbiter;

    private var widgetTypeToRemove:WidgetType;

    public function RemoveCustomWidgetController()
    {
        AppEvent.addListener(AppEvent.REMOVE_CUSTOM_WIDGET, removeCustomWidgetHandler);
    }

    private function removeCustomWidgetHandler(importCustomWidget:AppEvent):void
    {
        widgetTypeToRemove = importCustomWidget.data as WidgetType;
        removeWidget(widgetTypeToRemove);
    }

    private function removeWidget(widgetType:WidgetType):void
    {
        removeWidgetArbiter = new ProcessArbiter();
        removeWidgetArbiter.addEventListener(ProcessArbiterEvent.COMPLETE, importArbiter_completeHandler);
        removeWidgetArbiter.addEventListener(ProcessArbiterEvent.FAILURE, importArbiter_failureHandler);

        var customWidgetModule:File = WellKnownDirectories.getInstance().customModules.resolvePath(widgetTypeToRemove.name + "Module.swf");
        var customWidgetConfig:File = WellKnownDirectories.getInstance().customModules.resolvePath(widgetTypeToRemove.name + "Module.xml");
        var customWidgetFolder:File = WellKnownDirectories.getInstance().customFlexViewer.resolvePath("widgets/" + widgetType.name);

        removeWidgetArbiter.addProcess(new CleanUpProcess(customWidgetModule));
        removeWidgetArbiter.addProcess(new CleanUpProcess(customWidgetConfig));
        removeWidgetArbiter.addProcess(new CleanUpProcess(customWidgetFolder));

        removeWidgetArbiter.executeProcs();
    }

    protected function importArbiter_completeHandler(event:ProcessArbiterEvent):void
    {
        removeWidgetArbiter.removeEventListener(ProcessArbiterEvent.COMPLETE, importArbiter_completeHandler);
        removeWidgetArbiter.removeEventListener(ProcessArbiterEvent.FAILURE, importArbiter_failureHandler);

        WidgetTypeRegistryModel.getInstance().widgetTypeRegistry.removeWidgetType(widgetTypeToRemove);
        AppEvent.dispatch(AppEvent.REMOVE_CUSTOM_WIDGET_SUCCESS);
    }

    protected function importArbiter_failureHandler(event:ProcessArbiterEvent):void
    {
        removeWidgetArbiter.removeEventListener(ProcessArbiterEvent.COMPLETE, importArbiter_completeHandler);
        removeWidgetArbiter.removeEventListener(ProcessArbiterEvent.FAILURE, importArbiter_failureHandler);

        var removeCustomWidgetFailureMessage:String = ResourceManager.getInstance().getString("BuilderStrings",
                                                                                "removeCustomWidgetProcess.failure",
                                                                                [ event.message ]);
        var removeCustomWidgetFailureTitle:String = ResourceManager.getInstance().getString("BuilderStrings",
                                                                                "widgetManager.removeCustomWidget");
        BuilderAlert.show(removeCustomWidgetFailureMessage, removeCustomWidgetFailureTitle);

        AppEvent.dispatch(AppEvent.REMOVE_CUSTOM_WIDGET_FAILURE);
    }
}
}

Apply formatting.

Apply formatting.


// vim: tabstop=4 shiftwidth=4

// Copyright (c) 2010 , NetEase.com,Inc. All rights reserved.
//
// Author: Yang Bo (pop.atry@gmail.com)
//
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.

package com.netease.protobuf {
	import flash.utils.ByteArray
	public function stringToByteArray(s:String):ByteArray {
		const ba:ByteArray = new ByteArray
		for (var i:uint = 0; i < s.length; ++i) {
			ba.writeByte(s.charCodeAt(i))
		}
		return ba
	}
}

// vim: tabstop=4 shiftwidth=4

// Copyright (c) 2010 , NetEase.com,Inc. All rights reserved.
//
// Author: Yang Bo (pop.atry@gmail.com)
//
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.

package com.netease.protobuf {
	import flash.utils.ByteArray
	public function stringToByteArray(s:String):ByteArray {
		const ba:ByteArray = new ByteArray
		ba.length = s.length
		for (var i:uint = 0; i < s.length; ++i) {
			ba[i] = s.charCodeAt(i)
		}
		return ba
	}
}

初始化ByteArray时position为0


package server {
	import flash.events.EventDispatcher;
	import flash.events.NetStatusEvent;
	import flash.events.Event;
	import flash.net.Responder;

	public final class FMSBridge extends EventDispatcher {
		public var connection:FMSConnection;
		public var client:FMSClient;

		public function FMSBridge(rtmpAddress:String = null, ...rest) {
			connection = new FMSConnection();
			connection.client = client = new FMSClient();
			rtmpAddress && connect.apply(this, [rtmpAddress].concat(rest));
		}

		public function connect(rtmpAddress:String, ...rest):void {
			connection.connect.apply(this, [rtmpAddress].concat(rest));
		}

		public function dispose():void {
			connection.dispose();
		}

		public function close():void {
			connection.close();
		}

		public function registerUser(token:String, email:String, player:uint):void {
			connection.call('registerUser', null, token, email, player);
		}

		public function signinUser(token:String):void {
			connection.call('signinUser', null, token);
		}

		public function changePlayer(player:uint):void {
			connection.call('changePlayer', null, player);
		}

		public function startGame():void {
			connection.call('startGame', null);
		}

		public function updateScore(score:uint):void {
			connection.call('updateScore', null, score);
		}
	}
}

package server {
	import flash.events.EventDispatcher;
	import flash.events.NetStatusEvent;
	import flash.events.Event;
	import flash.net.Responder;

	public final class FMSBridge extends EventDispatcher {
		public var connection:FMSConnection;
		public var client:FMSClient;

		public function FMSBridge(rtmpAddress:String = null, ...rest) {
			connection = new FMSConnection();
			connection.client = client = new FMSClient();
			rtmpAddress && connect.apply(this, [rtmpAddress].concat(rest));
		}

		public function connect(rtmpAddress:String, ...rest):void {
			connection.connect.apply(this, [rtmpAddress].concat(rest));
		}

		public function dispose():void {
			connection.dispose();
			client.dispose();
		}

		public function close():void {
			connection.close();
		}

		public function registerUser(token:String, email:String, player:uint):void {
			connection.call('registerUser', null, token, email, player);
		}

		public function signinUser(token:String):void {
			connection.call('signinUser', null, token);
		}

		public function changePlayer(player:uint):void {
			connection.call('changePlayer', null, player);
		}

		public function startGame():void {
			connection.call('startGame', null);
		}

		public function updateScore(score:uint):void {
			connection.call('updateScore', null, score);
		}
	}
}

Update FMSBridge.as

Update FMSBridge.as


package krewfw.utils.as3 {

    /**
     * Flexible asynchronous tasker.
     *
     * Usage:
     *

     *     //--- Basic sequential task
     *     var async:KrewAsync = new KrewAsync({
     *         serial : [function_1, function_2, function_3],
     *         error  : _onErrorHandler,
     *         anyway : _onFinallyHandler
     *     });
     *     async.go();
     *
     *
     *     //--- Parallel task
     *     var async:KrewAsync = new KrewAsync({
     *         parallel: [function_1, function_2, function_3],
     *         error   : _onErrorHandler,
     *         anyway  : _onFinallyHandler
     *     });
     *     async.go();
     *
     *     * Throws error if both 'serial' and 'parallel' are specified.
     *
     *
     *     //--- Function receives KrewAsync instance,
     *     //    and you should call done() or fail().
     +
     *     var async:KrewAsync = new KrewAsync({
     *         serial: [
     *             function(async:KrewAsync):void {
     *                 if (TASK_IS_SUCCEEDED) {
     *                     async.done();
     *                 } else {
     *                     async.fail();
     *                 }
     *             }
     *         ]
     *     });
     *
     *
     *     //--- Sub task
     *     var async:KrewAsync = new KrewAsync({
     *         serial: [
     *             function_1,
     *             function_2,
     *             {parallel: [
     *                 function_3,
     *                 function_4,
     *                 {serial: [
     *                     function_5,
     *                     function_6
     *                 ]}
     *             ]},
     *             function_7
     *         ],
     *         error  : _onErrorHandler,
     *         anyway : _onFinallyHandler
     *     });
     *     async.go();
     *
     *     [Sequence]:
     *                   |3 ------>|
     *                   |         |
     *         1 -> 2 -> |4 ------>| -> 7 -> anyway
     *                   |         |
     *                   |5 -> 6 ->|
     *
     *

     *
     * @param asyncDef Object or Function or instance of KrewAsync. Example:
     *

     *     var async:KrewAsync = new KrewAsync(<asyncDef>);
     *
     *     <asyncDef> ::= {
     *         single  : function(async:KrewAsync):void {}  // KrewAsync uses internally
     *         // OR
     *         serial  : [<asyncDef>, ... ]
     *         // OR
     *         parallel: [<asyncDef>, ... ]
     *
     *         error   : function():void {},  // optional
     *         anyway  : function():void {}   // optional
     *     }
     *
     *     * If <asyncDef> == Function, then it is converted into:
     *         {single: Function}
     *
     *     * You can use class instances instead of asyncDef object:
     *
     *         public class MyKrewAsyncTask extends KrewAsync {
     *             public function MyKrewAsyncTask() {
     *                 super({
     *                     parallel: [method_1, method_2, method_3]
     *                 });
     *             }
     *         }
     *
     *         var async:KrewAsync = new KrewAsync({
     *             serial: [
     *                 function_1,
     *                 new MyKrewAsyncTask(),
     *                 function_2
     *             ]
     *         });
     *

     */
    //------------------------------------------------------------
    public class KrewAsync {

        private var _myTask:Function;
        private var _errorHandler:Function;
        private var _finallyHandler:Function;

        private var _serialTasks  :Vector.<KrewAsync>;
        private var _parallelTasks:Vector.<KrewAsync>;

        private var _serialTaskIndex:int = 0;
        private var _onComplete:Function = function():void {};

        public static const UNDEF   :int = 1;
        public static const RESOLVED:int = 2;
        public static const REJECTED:int = 3;

        private var _state:int = KrewAsync.UNDEF;

        //------------------------------------------------------------
        public function KrewAsync(asyncDef:*) {
            if (asyncDef is Function) {
                _initWithFunction(asyncDef);
                return;
            }
            if (asyncDef is KrewAsync) {
                _initWithKrewAsync(asyncDef);
            }
            if (asyncDef is Array) {
                _initWithArray(asyncDef);
                return;
            }
            if (asyncDef is Object) {
                _initWithObject(asyncDef);
                return;
            }
        }

        //------------------------------------------------------------
        // accessors
        //------------------------------------------------------------

        public function get myTask()        :Function { return _myTask; }
        public function get errorHandler()  :Function { return _errorHandler; }
        public function get finallyHandler():Function { return _finallyHandler; }

        public function get serialTasks()  :Vector.<KrewAsync> { return _serialTasks; }
        public function get parallelTasks():Vector.<KrewAsync> { return _parallelTasks; }

        public function get state():int { return _state; }

        //------------------------------------------------------------
        // public
        //------------------------------------------------------------

        public function go(onComplete:Function=null):void {
            if (onComplete != null) {
                _onComplete = onComplete;
            }

            if (_myTask != null) {
                _myTask(this);
                return;
            }

            if (_serialTasks != null) {
                _kickNextSerialTask();
                return;
            }

            if (_parallelTasks != null) {
                _kickParallelTasks();
                return;
            }
        }

        public function done():void {
            _state = KrewAsync.RESOLVED;
            _finalize();
        }

        public function fail():void {
            _state = KrewAsync.REJECTED;
            _finalize();
        }

        //------------------------------------------------------------
        // initializer
        //------------------------------------------------------------

        private function _initWithObject(asyncDef:Object):void {
            _validateInitObject(asyncDef);

            if (asyncDef.single   != null) { _myTask = asyncDef.single; }
            if (asyncDef.serial   != null) { _serialTasks   = _makeChildren(asyncDef.serial); }
            if (asyncDef.parallel != null) { _parallelTasks = _makeChildren(asyncDef.parallel); }

            if (asyncDef.error    != null) { _errorHandler   = asyncDef.error; }
            if (asyncDef.anyway   != null) { _finallyHandler = asyncDef.anyway; }
        }

        private function _validateInitObject(asyncDef:Object):void {
            var exclusiveDefCount:uint = 0;
            if (asyncDef.single   != null) { ++exclusiveDefCount; }
            if (asyncDef.serial   != null) { ++exclusiveDefCount; }
            if (asyncDef.parallel != null) { ++exclusiveDefCount; }

            if (exclusiveDefCount != 1) {
                throw new Error("[KrewAsync] Error: Invalid async task definition.");
            }
        }

        private function _makeChildren(asyncDefList:Array):Vector.<KrewAsync> {
            var children:Vector.<KrewAsync> = new Vector.<KrewAsync>;

            for each (var def:* in asyncDefList) {
                var async:KrewAsync = (def is KrewAsync) ? def : new KrewAsync(def);
                children.push(async);
            }
            return children;
        }

        private function _initWithFunction(asyncDef:Function):void {
            _initWithObject({
                single: asyncDef
            });
        }

        private function _initWithArray(asyncDef:Array):void {
            _initWithObject({
                serial: asyncDef
            });
        }

        private function _initWithKrewAsync(asyncDef:KrewAsync):void {
            _myTask         = asyncDef.myTask;
            _errorHandler   = asyncDef.errorHandler;
            _finallyHandler = asyncDef.finallyHandler;
            _serialTasks    = asyncDef.serialTasks;
            _parallelTasks  = asyncDef.parallelTasks;
        }

        //------------------------------------------------------------
        // task runner
        //------------------------------------------------------------

        private function _kickNextSerialTask():void {
            if (_serialTaskIndex >= _serialTasks.length) {
                done();
                return;
            }

            var nextTask:KrewAsync = _serialTasks[_serialTaskIndex];
            ++_serialTaskIndex;

            nextTask.go(function(async:KrewAsync):void {
                if (async.state == KrewAsync.RESOLVED) {
                    _kickNextSerialTask();
                } else {
                    _onReject();
                }
            });
        }

        private function _onReject():void {
            if (_errorHandler != null) {
                _errorHandler();
            }
            _finalize();
        }

        private function _finalize():void {
            if (_finallyHandler != null) {
                _finallyHandler();
            }
            _onComplete(this);
        }

        private function _kickParallelTasks():void {
            var doneCount:int = 0;

            for each (var task:KrewAsync in _parallelTasks) {
                task.go(function(async:KrewAsync):void {
                    if (async.state == KrewAsync.RESOLVED) {
                        ++doneCount;
                        if (doneCount == _parallelTasks.length) {
                            done();
                        }
                    } else {
                        _onReject();
                    }
                });
            }
        }

    }
}

package krewfw.utils.as3 {

    /**
     * Flexible asynchronous tasker.
     *
     * Usage:
     *

     *     //--- Basic sequential task
     *     var async:KrewAsync = new KrewAsync({
     *         serial : [function_1, function_2, function_3],
     *         error  : _onErrorHandler,
     *         anyway : _onFinallyHandler
     *     });
     *     async.go();
     *
     *
     *     //--- Parallel task
     *     var async:KrewAsync = new KrewAsync({
     *         parallel: [function_1, function_2, function_3],
     *         error   : _onErrorHandler,
     *         anyway  : _onFinallyHandler
     *     });
     *     async.go();
     *
     *     * Throws error if both 'serial' and 'parallel' are specified.
     *
     *
     *     //--- Function receives KrewAsync instance,
     *     //    and you should call done() or fail().
     +
     *     var async:KrewAsync = new KrewAsync({
     *         serial: [
     *             function(async:KrewAsync):void {
     *                 if (TASK_IS_SUCCEEDED) {
     *                     async.done();
     *                 } else {
     *                     async.fail();
     *                 }
     *             }
     *         ]
     *     });
     *
     *
     *     //--- Sub task
     *     var async:KrewAsync = new KrewAsync({
     *         serial: [
     *             function_1,
     *             function_2,
     *             {parallel: [
     *                 function_3,
     *                 function_4,
     *                 {serial: [
     *                     function_5,
     *                     function_6
     *                 ]}
     *             ]},
     *             function_7
     *         ],
     *         error  : _onErrorHandler,
     *         anyway : _onFinallyHandler
     *     });
     *     async.go();
     *
     *     [Sequence]:
     *                   |3 ------>|
     *                   |         |
     *         1 -> 2 -> |4 ------>| -> 7 -> anyway
     *                   |         |
     *                   |5 -> 6 ->|
     *
     *

     *
     * @param asyncDef Object or Function or instance of KrewAsync. Example:
     *

     *     var async:KrewAsync = new KrewAsync(<asyncDef>);
     *
     *     <asyncDef> ::= {
     *         single  : function(async:KrewAsync):void {}  // KrewAsync uses internally
     *         // OR
     *         serial  : [<asyncDef>, ... ]
     *         // OR
     *         parallel: [<asyncDef>, ... ]
     *
     *         error   : function():void {},  // optional
     *         anyway  : function():void {}   // optional
     *     }
     *
     *     * If <asyncDef> == Function, then it is converted into:
     *         {single: Function}
     *
     *     * You can use class instances instead of asyncDef object:
     *
     *         public class MyKrewAsyncTask extends KrewAsync {
     *             public function MyKrewAsyncTask() {
     *                 super({
     *                     parallel: [method_1, method_2, method_3]
     *                 });
     *             }
     *         }
     *
     *         var async:KrewAsync = new KrewAsync({
     *             serial: [
     *                 function_1,
     *                 new MyKrewAsyncTask(),
     *                 function_2
     *             ]
     *         });
     *

     */
    //------------------------------------------------------------
    public class KrewAsync {

        private var _myTask:Function;
        private var _errorHandler:Function;
        private var _finallyHandler:Function;

        private var _serialTasks  :Vector.<KrewAsync>;
        private var _parallelTasks:Vector.<KrewAsync>;

        private var _serialTaskIndex:int = 0;
        private var _onComplete:Function = function():void {};

        public static const UNDEF   :int = 1;
        public static const RESOLVED:int = 2;
        public static const REJECTED:int = 3;

        private var _state:int = KrewAsync.UNDEF;

        //------------------------------------------------------------
        public function KrewAsync(asyncDef:*) {
            if (asyncDef is Function) {
                _initWithFunction(asyncDef);
                return;
            }
            if (asyncDef is KrewAsync) {
                _initWithKrewAsync(asyncDef);
                return;
            }
            if (asyncDef is Array) {
                _initWithArray(asyncDef);
                return;
            }
            if (asyncDef is Object) {
                _initWithObject(asyncDef);
                return;
            }
        }

        //------------------------------------------------------------
        // accessors
        //------------------------------------------------------------

        public function get myTask()        :Function { return _myTask; }
        public function get errorHandler()  :Function { return _errorHandler; }
        public function get finallyHandler():Function { return _finallyHandler; }

        public function get serialTasks()  :Vector.<KrewAsync> { return _serialTasks; }
        public function get parallelTasks():Vector.<KrewAsync> { return _parallelTasks; }

        public function get state():int { return _state; }

        //------------------------------------------------------------
        // public
        //------------------------------------------------------------

        public function go(onComplete:Function=null):void {
            if (onComplete != null) {
                _onComplete = onComplete;
            }

            if (_myTask != null) {
                _myTask(this);
                return;
            }

            if (_serialTasks != null) {
                _kickNextSerialTask();
                return;
            }

            if (_parallelTasks != null) {
                _kickParallelTasks();
                return;
            }
        }

        public function done():void {
            _state = KrewAsync.RESOLVED;
            _finalize();
        }

        public function fail():void {
            _state = KrewAsync.REJECTED;
            _finalize();
        }

        //------------------------------------------------------------
        // initializer
        //------------------------------------------------------------

        private function _initWithObject(asyncDef:Object):void {
            _validateInitObject(asyncDef);

            if (asyncDef.single   != null) { _myTask = asyncDef.single; }
            if (asyncDef.serial   != null) { _serialTasks   = _makeChildren(asyncDef.serial); }
            if (asyncDef.parallel != null) { _parallelTasks = _makeChildren(asyncDef.parallel); }

            if (asyncDef.error    != null) { _errorHandler   = asyncDef.error; }
            if (asyncDef.anyway   != null) { _finallyHandler = asyncDef.anyway; }
        }

        private function _validateInitObject(asyncDef:Object):void {
            var exclusiveDefCount:uint = 0;
            if (asyncDef.single   != null) { ++exclusiveDefCount; }
            if (asyncDef.serial   != null) { ++exclusiveDefCount; }
            if (asyncDef.parallel != null) { ++exclusiveDefCount; }

            if (exclusiveDefCount != 1) {
                throw new Error("[KrewAsync] Error: Invalid async task definition.");
            }
        }

        private function _makeChildren(asyncDefList:Array):Vector.<KrewAsync> {
            var children:Vector.<KrewAsync> = new Vector.<KrewAsync>;

            for each (var def:* in asyncDefList) {
                var async:KrewAsync = (def is KrewAsync) ? def : new KrewAsync(def);
                children.push(async);
            }
            return children;
        }

        private function _initWithFunction(asyncDef:Function):void {
            _initWithObject({
                single: asyncDef
            });
        }

        private function _initWithArray(asyncDef:Array):void {
            _initWithObject({
                serial: asyncDef
            });
        }

        private function _initWithKrewAsync(asyncDef:KrewAsync):void {
            _myTask         = asyncDef.myTask;
            _errorHandler   = asyncDef.errorHandler;
            _finallyHandler = asyncDef.finallyHandler;
            _serialTasks    = asyncDef.serialTasks;
            _parallelTasks  = asyncDef.parallelTasks;
        }

        //------------------------------------------------------------
        // task runner
        //------------------------------------------------------------

        private function _kickNextSerialTask():void {
            if (_serialTaskIndex >= _serialTasks.length) {
                done();
                return;
            }

            var nextTask:KrewAsync = _serialTasks[_serialTaskIndex];
            ++_serialTaskIndex;

            nextTask.go(function(async:KrewAsync):void {
                if (async.state == KrewAsync.RESOLVED) {
                    _kickNextSerialTask();
                } else {
                    _onReject();
                }
            });
        }

        private function _onReject():void {
            if (_errorHandler != null) {
                _errorHandler();
            }
            _finalize();
        }

        private function _finalize():void {
            if (_finallyHandler != null) {
                _finallyHandler();
            }
            _onComplete(this);
        }

        private function _kickParallelTasks():void {
            var doneCount:int = 0;

            for each (var task:KrewAsync in _parallelTasks) {
                task.go(function(async:KrewAsync):void {
                    if (async.state == KrewAsync.RESOLVED) {
                        ++doneCount;
                        if (doneCount == _parallelTasks.length) {
                            done();
                        }
                    } else {
                        _onReject();
                    }
                });
            }
        }

    }
}

Modify KrewAsync a little

Modify KrewAsync a little


package org.openPyro.containers
{
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.getQualifiedClassName;

	import org.openPyro.core.ClassFactory;
	import org.openPyro.core.MeasurableControl;
	import org.openPyro.core.UIControl;
	import org.openPyro.layout.HLayout;
	import org.openPyro.layout.ILayout;
	import org.openPyro.managers.events.DragEvent;
	import org.openPyro.painters.GradientFillPainter;

	/**
	 *
	 */
	public class HDividedBox extends DividedBox
	{
		/**
		 * Constructor
		 */
		public function HDividedBox(){
			super();
			_styleName = "HDividedBox";
		}

		override public function initialize():void{
			super.layout = new HLayout();
			super.initialize()
		}

		override protected function get defaultDividerFactory():ClassFactory{
			var df:ClassFactory = new ClassFactory(UIControl);
			df.properties = {percentHeight:100, width:6, backgroundPainter:new GradientFillPainter([0x999999, 0x666666])}
			return df;
		}

		protected var leftUIC:MeasurableControl
		protected var rightUIC:MeasurableControl

		/**
		 * @inheritDoc
		 */
		override protected function getDividerDragRect():Rectangle{
			var point:Point = new Point(0,0);
			point = this.localToGlobal(point);

			return new Rectangle(point.x,point.y,this.width, 0)
		}

		override protected function onDividerDragDrop(event:DragEvent):void{
			/*
			If the divider moves left, delta is -ve, otherwise +ve
			*/
			var delta:Number = event.mouseXDelta

			for(var i:int=0; i<dividerPane.numChildren; i++){
				var child:DisplayObject = dividerPane.getChildAt(i)
				if(child == event.dragInitiator){
					leftUIC = MeasurableControl(contentPane.getChildAt(i));
					rightUIC = MeasurableControl(contentPane.getChildAt(i+1));
					break;
				}

			}

			/*
			Disable mouseEvents so that rollovers etc are
			not triggered if the mouse rolls over them
			*/
			leftUIC.cancelMouseEvents();
			rightUIC.cancelMouseEvents();

			var unallocatedWidth:Number = (this.width - this.explicitlyAllocatedWidth);
			var newUnallocatedWidth:Number = unallocatedWidth;

			if(isNaN(leftUIC.explicitWidth) && isNaN(rightUIC.explicitWidth)){

				/*
				* The change in dimensions can be compensated by recalculating the
				* two percents.
				*/
				var newLeftW:Number = leftUIC.width + delta;
				var newRightW:Number = rightUIC.width - delta;
				leftUIC.percentUnusedWidth = newLeftW*100/unallocatedWidth;
				rightUIC.percentUnusedWidth = newRightW*100/unallocatedWidth
			}

			else if(!isNaN(leftUIC.explicitWidth) && !isNaN(rightUIC.explicitWidth)){

				/*
				 * The dimension changes can be safely calculated
				 */
				leftUIC.width+=delta
				rightUIC.width-=delta;
			}

			else if(!isNaN(leftUIC.explicitWidth)) {

				/*
				 * Left child is explicitly sized , right is percent sized
				 */

				leftUIC.width+=delta;
				newUnallocatedWidth = unallocatedWidth-delta;
				for(var j:int=0; j<contentPane.numChildren; j++){
					var currChildL:MeasurableControl = contentPane.getChildAt(j) as MeasurableControl;
					if(dividers.indexOf(currChildL) != -1) continue;
					if(currChildL == leftUIC) continue;
					if(currChildL == rightUIC){
						var newW:Number = currChildL.width-delta;
						rightUIC.percentUnusedWidth = newW*100/newUnallocatedWidth
					}
					else if(!isNaN(currChildL.percentUnusedWidth)){
						currChildL.percentUnusedWidth = currChildL.percentUnusedWidth*unallocatedWidth/newUnallocatedWidth;

					}
				}
			}
			else{
				/*
				 * Right child is explicitly sized , left is percent sized
				 */
				rightUIC.width-=delta;
				newUnallocatedWidth = unallocatedWidth+delta;

				for(var k:int=0; k<contentPane.numChildren; k++){
					var currChild:MeasurableControl = contentPane.getChildAt(k) as MeasurableControl;
					if(dividers.indexOf(currChild) != -1) continue;
					if(currChild == rightUIC) continue;
					if(currChild == leftUIC){
						var newLW:Number = currChild.width+delta;
						leftUIC.percentUnusedWidth = newLW*100/newUnallocatedWidth
					}
					else if(!isNaN(currChild.percentUnusedWidth)){
						currChild.percentUnusedWidth = currChild.percentUnusedWidth*unallocatedWidth/newUnallocatedWidth;
					}
				}
			}

			leftUIC.enableMouseEvents()
			rightUIC.enableMouseEvents();

		}

		/**
		 * @inheritDoc
		 */
		override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			if(this.contentPane.numChildren < 2) return;
			for(var i:uint=1; i<this.contentPane.numChildren; i++){
				var child:DisplayObject = this.contentPane.getChildAt(i);
				dividerPane.getChildAt(i-1).x = child.x;
			}
		}

		override public function set layout(l:ILayout):void{
			throw new Error(getQualifiedClassName(this)+" cannot have layouts applied to it")
		}

	}
}

package org.openPyro.containers
{
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.getQualifiedClassName;

	import org.openPyro.core.ClassFactory;
	import org.openPyro.core.MeasurableControl;
	import org.openPyro.core.UIControl;
	import org.openPyro.layout.HLayout;
	import org.openPyro.layout.ILayout;
	import org.openPyro.managers.events.DragEvent;
	import org.openPyro.painters.GradientFillPainter;

	/**
	 *
	 */
	public class HDividedBox extends DividedBox
	{
		/**
		 * Constructor
		 */
		public function HDividedBox(){
			super();
			_styleName = "HDividedBox";
		}

		override public function initialize():void{
			super.layout = new HLayout();
			super.initialize()
		}

		override protected function get defaultDividerFactory():ClassFactory{
			var df:ClassFactory = new ClassFactory(UIControl);
			df.properties = {percentHeight:100, width:6, backgroundPainter:new GradientFillPainter([0x999999, 0x666666])}
			return df;
		}

		protected var leftUIC:MeasurableControl
		protected var rightUIC:MeasurableControl

		/**
		 * @inheritDoc
		 */
		override protected function getDividerDragRect():Rectangle{
			var point:Point = new Point(0,0);
			point = this.localToGlobal(point);

			return new Rectangle(point.x,point.y,this.width, 0)
		}

		override protected function onDividerDragDrop(event:DragEvent):void{
			/*
			If the divider moves left, delta is -ve, otherwise +ve
			*/
			var delta:Number = event.mouseXDelta

			for(var i:int=0; i<dividerPane.numChildren; i++){
				var child:DisplayObject = dividerPane.getChildAt(i)
				if(child == event.dragInitiator){
					leftUIC = MeasurableControl(contentPane.getChildAt(i));
					rightUIC = MeasurableControl(contentPane.getChildAt(i+1));
					break;
				}

			}

			/*
			Disable mouseEvents so that rollovers etc are
			not triggered if the mouse rolls over them
			*/
			leftUIC.cancelMouseEvents();
			rightUIC.cancelMouseEvents();

			var unallocatedWidth:Number = (this.width - this.explicitlyAllocatedWidth);
			var newUnallocatedWidth:Number = unallocatedWidth;

			if(isNaN(leftUIC.explicitWidth) && isNaN(rightUIC.explicitWidth)){

				/*
				* The change in dimensions can be compensated by recalculating the
				* two percents.
				*/
				var newLeftW:Number = leftUIC.width + delta;
				var newRightW:Number = rightUIC.width - delta;
				leftUIC.percentUnusedWidth = newLeftW*100/unallocatedWidth;
				rightUIC.percentUnusedWidth = newRightW*100/unallocatedWidth
			}

			else if(!isNaN(leftUIC.explicitWidth) && !isNaN(rightUIC.explicitWidth)){

				/*
				 * The dimension changes can be safely calculated
				 */
				leftUIC.width+=delta
				rightUIC.width-=delta;
			}

			else if(!isNaN(leftUIC.explicitWidth)) {

				/*
				 * Left child is explicitly sized , right is percent sized
				 */

				leftUIC.width+=delta;
				newUnallocatedWidth = unallocatedWidth-delta;
				for(var j:int=0; j<contentPane.numChildren; j++){
					var currChildL:MeasurableControl = contentPane.getChildAt(j) as MeasurableControl;
					if(dividers.indexOf(currChildL) != -1) continue;
					if(currChildL == leftUIC) continue;
					if(currChildL == rightUIC){
						var newW:Number = currChildL.width-delta;
						rightUIC.percentUnusedWidth = newW*100/newUnallocatedWidth
					}
					else if(!isNaN(currChildL.percentUnusedWidth)){
						currChildL.percentUnusedWidth = currChildL.percentUnusedWidth*unallocatedWidth/newUnallocatedWidth;

					}
				}
			}
			else{
				/*
				 * Right child is explicitly sized , left is percent sized
				 */
				rightUIC.width-=delta;
				newUnallocatedWidth = unallocatedWidth+delta;

				for(var k:int=0; k<contentPane.numChildren; k++){
					var currChild:MeasurableControl = contentPane.getChildAt(k) as MeasurableControl;
					if(dividers.indexOf(currChild) != -1) continue;
					if(currChild == rightUIC) continue;
					if(currChild == leftUIC){
						var newLW:Number = currChild.width+delta;
						leftUIC.percentUnusedWidth = newLW*100/newUnallocatedWidth
					}
					else if(!isNaN(currChild.percentUnusedWidth)){
						currChild.percentUnusedWidth = currChild.percentUnusedWidth*unallocatedWidth/newUnallocatedWidth;
					}
				}
			}

			leftUIC.enableMouseEvents()
			rightUIC.enableMouseEvents();
			forceUpdateDisplayList = true;
		}

		/**
		 * @inheritDoc
		 */
		override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			if(this.contentPane.numChildren < 2) return;
			for(var i:uint=1; i<this.contentPane.numChildren; i++){
				var child:DisplayObject = this.contentPane.getChildAt(i);
				dividerPane.getChildAt(i-1).x = child.x;
			}
		}

		override public function set layout(l:ILayout):void{
			throw new Error(getQualifiedClassName(this)+" cannot have layouts applied to it")
		}

	}
}

Fix to forceUpdateList on HDividedBox

Fix to forceUpdateList on HDividedBox


package {
  class A {
    var x = 1;
    var y = 2;
    var z = 3;
  }
  (function () {
    trace("--- Test 1 ---");
    var o : A = new A();
    var r0 = o.x;
    o.x = 2;
    var r1 = o.x;
    o.x = 3;
    var r2 = o.x;
    o.x = 4;
    var r3 = o.x;
    o.x = 5;
    var r4 = o.x;
    o.x = 6;
    var r5 = o.x;
    o.x = 7;
    var r6 = o.x;
    o.x = 8;
    var r7 = o.x;
    o.x = 9;
    var r8 = o.x;

    trace(r0);
    trace(r1);
    trace(r2);
    trace(r3);
    trace(r4);
    trace(r5);
    trace(r6);
    trace(r7);
    trace(r8);

  })();
}

package {
  class A {
    var x = 1;
    var y = 2;
    var z = 3;
  }
  (function () {
    trace("--- Test 1 ---");
    var o : A = new A();
    var r0 = o.x;
    o.x = 2;
    var r1 = o.x;
    o.x = 3;
    var r2 = o.x;
    o.x = 4;
    var r3 = o.x;
    o.x = 5;
    var r4 = o.x;
    o.x = 6;
    var r5 = o.x;
    o.x = 7;
    var r6 = o.x;
    o.x = 8;
    var r7 = o.x;
    o.x = 9;
    var r8 = o.x;

    trace(r0);
    trace(r1);
    trace(r2);
    trace(r3);
    trace(r4);
    trace(r5);
    trace(r6);
    trace(r7);
    trace(r8);

  })();

  (function () {
    trace("--- Test 2 ---");
    var o : A = new A();
    trace(o.x);
    o.x = 2;
    trace(o.x + o.x);
    o.x = 3;
    trace(o.x + o.x + o.x);
    o.x = 4;
    trace(o.x + o.x + o.x + o.x);
    o.x = 5;
    trace(o.x + o.x + o.x + o.x + o.x);
    o.x = 6;
    trace(o.x + o.x + o.x + o.x + o.x + o.x);
    o.x = 7;
    trace(o.x + o.x + o.x + o.x + o.x + o.x + o.x);
    o.x = 8;
    trace(o.x + o.x + o.x + o.x + o.x + o.x + o.x + o.x);
    o.x = 9;
    trace(o.x + o.x + o.x + o.x + o.x + o.x + o.x + o.x + o.x);
  })();
}

Add test case.

Add test case.