Flex ObjectHandles 构建绘图程序!

模型

 

主画布组件:com/components/graph/GraphContainer.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" 
         creationComplete="init(event)"
         width="100%" height="100%">
    <fx:Script>
        <![CDATA[
            import com.components.model.ShapeModel;
            import com.roguedevelopment.objecthandles.Flex4ChildManager;
            import com.roguedevelopment.objecthandles.Flex4HandleFactory;
            import com.roguedevelopment.objecthandles.HandleClickedEvent;
            import com.roguedevelopment.objecthandles.ObjectChangedEvent;
            import com.roguedevelopment.objecthandles.ObjectHandles;
            import com.roguedevelopment.objecthandles.SelectionEvent;
            import com.components.shape.BaseShape;
            import com.components.shape.IShape;
            import com.components.shape.ShapeLoad;
            import com.components.shape.SimpleRect;
            
            import mx.controls.Alert;
            import mx.controls.Button;
            import mx.core.UIComponent;
            import mx.events.DragEvent;
            import mx.events.FlexEvent;
            import mx.managers.DragManager;
            [Bindable]
            public var objecthandles:ObjectHandles = null;
            
            override protected function initializationComplete() : void
            {                
                objecthandles = new ObjectHandles( mainGroup , null, new Flex4HandleFactory() , 
                    new Flex4ChildManager() );
                super.initializationComplete();
            }
            
            private function init(event:FlexEvent):void
            {
                this.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void{
                    if(event.target is IShape) {
                        if(objecthandles.selectionManager.currentlySelected.length > 1){
                            objecthandles.selectionManager.clearSelection();
                        }
                    }else{
                        objecthandles.selectionManager.clearSelection();
                    }
                    event.stopPropagation();
                });
            }
            
            protected function mainGroup_dragDropHandler(event:DragEvent):void
            {
                // TODO Auto-generated method stub
                
            }
            
            public function addShapeUI(shape:ShapeModel):void
            {
                var ishape:IShape = ShapeLoad.getShape(shape.shapeType);
                ishape.graph = this;
                ishape.model = shape;

                shape.ishape = ishape;
                if (shape.owner) {
                    var container:IShape = shape.owner.ishape
                    
                    if (container) {
//                        Alert.show(container.model.label);//alert Test
                        var oh:ObjectHandles = new ObjectHandles(container as Sprite, objecthandles.selectionManager, new Flex4HandleFactory(), new Flex4ChildManager());
                        oh.registerComponent(shape, ishape, []);

                        container.addShape(ishape);
                    } else {
                        Alert.show("null");
                    }
                } else {
                    
                    mainGroup.addElement(ishape);
                    
                    objecthandles.registerComponent(shape, ishape); //shapeModel Bindable #1069
                }
                
                if (shape.children && shape.children.length > 0) {
                    for (var i:int=0;i<shape.children.length;i++) {
                        var child:ShapeModel = shape.children[i];
                        addShapeUI(child);
                    }
                }

                ishape.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
//                    ishape.objectHandles.selectionManager.setSelected(shape);
                    event.stopPropagation(); //important
                });
                
                ishape.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void{
//                    ishape.objectHandles.selectionManager.setSelected(shape);
                    event.stopPropagation(); //important
                });

            }
            
            public function removeShapeUI(shape:ShapeModel):void
            {
                if (shape.owner) {
                    var container:IShape = shape.owner.ishape
                    container.removeChildByModel(shape);
                } else {
                    for (var i:int=0;i<mainGroup.numElements;i++) {
                        var ishape:IShape = mainGroup.getElementAt(i) as IShape;
                        
                        if (ishape.model == shape) {
                            objecthandles.unregisterComponent(ishape);
                            mainGroup.removeElement(ishape);
                        }
                    }
                }
            }
            
        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- 将非可视元素(例如服务、值对象)放在此处 -->
    </fx:Declarations>

    <s:Scroller width="100%" height="100%" >
        <s:Group width="100%" height="100%" id="mainGroup">
            
        </s:Group>
    </s:Scroller>
</s:Group>

GraphModel.as: com/components/model/

package com.components.model
{

    public class GraphModel
    {
        public function GraphModel()
        {
            
        }
    }
}

ShapeModel.as: 图形模型类,用于设置图形宽、高、坐标等参数

package com.components.model
{
    import com.roguedevelopment.objecthandles.IMoveable;
    import com.roguedevelopment.objecthandles.IResizeable;
    import com.components.shape.IShape;
    
    import flash.events.EventDispatcher;
    import flash.events.MouseEvent;
    
    import mx.messaging.AbstractConsumer;

    public class ShapeModel extends EventDispatcher implements IResizeable, IMoveable
    {
        [Bindable]
        private var _width:Number = 0;
        [Bindable]
        private var _height:Number = 0;
        [Bindable]
        private var _x:Number = 0;
        [Bindable]
        private var _y:Number = 0;
        [Bindable]
        private var _rotation:Number = 0;
        [Bindable]
        private var _label:String = '';
        [Bindable]
        private var _isLocked:Boolean = false;
        [Bindable]
        private var _color:uint = 0xffffff;
        [Bindable]
        private var _image:String;
        [Bindable]
        private var _ishape:IShape;
        [Bindable]
        private var _owner:ShapeModel = null;
        [Bindable]
        private var _children:Array;
        [Bindable]
        private var _shapeType:int = 0;
        
        public function ShapeModel()
        {

        }
        
        public function set width(value:Number):void
        {
            this._width = value;
        }
        
        [Bindable]
        public function get width():Number
        {
            return this._width;
        }
        
        public function set height(value:Number):void
        {
            this._height = value;
        }
        
        [Bindable]
        public function get height():Number
        {
            return this._height;
        }
        
        public function set x(value:Number):void
        {
            this._x = value;
        }
        
        [Bindable]
        public function get x():Number
        {
            return this._x;
        }
        
        public function set y(value:Number):void
        {
            this._y = value;
        }
        
        [Bindable]
        public function get y():Number
        {
            return this._y;
        }
        
        public function set rotation(value:Number):void
        {
            this._rotation = value;
        }
        
        [Bindable]
        public function get rotation():Number
        {
            return this._rotation;
        }
        
        public function set label(value:String):void
        {
            this._label = value;
        }
        
        [Bindable]
        public function get label():String
        {
            return this._label;
        }
        
        public function set isLocked(value:Boolean):void
        {
            this._isLocked = value;
        }
        
        [Bindable]
        public function get isLocked():Boolean
        {
            return this._isLocked;
        }
        
        //--------------------
        
        [Bindable]
        public function get ishape():IShape
        {
            return this._ishape;
        }
        
        public function set ishape(value:IShape):void
        {
            this._ishape = value;
        }
        
        public function set children(childs:Array):void
        {
            this._children = childs;
            
            if (childs && childs.length > 0) {
                var c:* = childs[0]; //检测是不是ShapeModel类型
                if (c is ShapeModel){
                    for each(var itm:ShapeModel in childs) {
                        itm.owner = this;
                    }
                }
            }
        }
        
        [Bindable]
        public function get children():Array
        {
            return this._children;
        }
        
        public function set owner(value:ShapeModel):void
        {
            this._owner = value;
        }
        
        [Bindable]
        public function get owner():ShapeModel
        {
            return this._owner;
        }
        
        //
        
        public function set color(value:uint):void
        {
            this._color = value;
        }
        
        [Bindable]
        public function get color():uint
        {
            return this._color;
        }
        
        public function set image(value:String):void
        {
            this._image = value;
        }
        
        [Bindable]
        public function get image():String
        {
            return this._image;
        }
        
        public function set shapeType(value:int):void
        {
            this._shapeType = value;
        }
        
        [Bindable]
        public function get shapeType():int {
            return this._shapeType;
        }
        
        public function setSelected(flag:Boolean):void {
            if (this._ishape) {
                if (flag) {
                    this._ishape.objectHandles.selectionManager.setSelected(this);
                } else {
                    this._ishape.objectHandles.selectionManager.removeFromSelected(this);
                }
            }
        }
    }
}

图形基组件: com/components/shape/BaseShape.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" 
         implements="com.components.shape.IShape"
         creationComplete="init(event)"
         width="{_model.width}" 
         height="{_model.height}"
         x="{_model.x}"
         y="{_model.y}"
         rotation="{_model.rotation}"
         
         >
    <fx:Declarations>
        <!-- 将非可视元素(例如服务、值对象)放在此处 -->
        <s:SolidColor id="backColor" color="0xdcdcdc" alpha="1" />
        <s:SolidColorStroke id="borderStroke" color="0x000000" weight="1" alpha="1" />
    </fx:Declarations>
    
    <fx:Script>
        <![CDATA[
            import com.components.graph.GraphContainer;
            import com.components.model.ShapeModel;
            import com.events.ShapeEvent;
            import com.roguedevelopment.objecthandles.Flex4ChildManager;
            import com.roguedevelopment.objecthandles.Flex4HandleFactory;
            import com.roguedevelopment.objecthandles.ObjectHandles;
            import com.utils.ShapeUtils;
            
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            
            [Bindable]private var _objectHandles:ObjectHandles ;
            [Bindable]private var _graph:GraphContainer;
            [Bindable]private var _model:ShapeModel;
            [Bindable]private var _showLabel:Boolean;
            [Bindable]private var _selected:Boolean;
            
            private var _state:int = 0;
            private var _rx:Number = 0;
            private var _ry:Number = 0;
            
            private function init(event:FlexEvent):void
            {
                var that:IShape = this;
                this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandle);
                this.addEventListener(MouseEvent.MOUSE_OUT, mousOutHandle);
                this.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandle);
                //this.addEventListener(MouseEvent.MOUSE_WHEEL, mouWheelHandle); //从没出现
                this.addEventListener(MouseEvent.ROLL_OUT, mouRolOutHandle);
                this.addEventListener(MouseEvent.ROLL_OVER, mouRolOverHandle);
                //this.addEventListener(MouseEvent.RELEASE_OUTSIDE, mouseOutsideHandle);//从没出现
            }
            
            private function mouseDownHandle(event:MouseEvent):void {
                
                _rx = this.mouseX;
                _ry = this.mouseY;
                this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandle);
                this.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandle);
                
            }
            
            //
            private function mousOutHandle(event:MouseEvent):void 
            {
                var cm:ShapeModel = this.model;
                if (cm) {
                    if (cm.x < 0) {
                        cm.x = 0;
                    }
                    
                    if (cm.y < 0) {
                        cm.y = 0
                    }
                }
                this.model.label = "MouseOut";

            }
            
            private function mouseOutsideHandle(event:MouseEvent):void
            {
                this.model.label = "Outside";
            }
            
            private function mouseOverHandle(event:MouseEvent):void
            {
                this.model.label = "MouseOver";
                ResizeContainer(this);
            }
            
            private function mouWheelHandle(event:MouseEvent):void
            {
                this.model.label = "MouseWheel";
            }
            
            private function mouRolOutHandle(event:MouseEvent):void
            {
                var cm:ShapeModel = this.model;
                if (cm) {
                    if (cm.x < 0) {
                        cm.x = 0;
                    }
                    
                    if (cm.y < 0) {
                        cm.y = 0
                    }
                }
                
                this.model.label = "RollOut";
                ResizeContainer(this);
                
                
            }
            
            private function mouRolOverHandle(event:MouseEvent):void
            {
                this.model.label = "MouseRollOver";
            }
            
            private function mouseMoveHandle(event:MouseEvent):void {
                if (_state != 6) {
                    _state = 6;
                    
                }
                this.model.label = "MouseMove";
                
                ResizeContainer(this, event);
            }
            
            private function mouseUpHandle(event:MouseEvent):void {
                if (_state != 7) {
                    _state = 7;
                }
                
                this.model.label = "UP";
                this.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandle);
                this.removeEventListener(MouseEvent.MOUSE_DOWN, mouseMoveHandle);
//                this.removeEventListener(MouseEvent.MOUSE_OUT, mousOutHandle);
//                this.removeEventListener(MouseEvent.ROLL_OUT, mouRolOutHandle);
//                this.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandle);
                var cm:ShapeModel = this.model;
                
                if (!cm || !cm.owner)
                    return;
                
                /*
                var xy:Object = ShapeUtils.getRealShapePosition(cm);
                
                var _pw:Number = cm.owner.width;
                var _ph:Number = cm.owner.height;
                var _px:Number = cm.owner.x;
                var _py:Number = cm.owner.y;
                
                if (cm.x<0) {
                    cm.owner.x = Number(xy.x);
                    cm.owner.width = _pw + (_px - Number(xy.x));    
                    cm.x = 0;
                }
                
                if (cm.y <0) {
                    cm.owner.y = Number(xy.y);
                    cm.owner.height = _ph + (_py - Number(xy.y));
                    cm.y = 0;
                }*/
            }
            
            private function ResizeContainer(shapeui:IShape, event:MouseEvent = null):void
            {
                var cm:ShapeModel = shapeui.model;
                if (cm && cm.owner) {
                    var _x:Number = cm.x;
                    var _y:Number = cm.y;
                    var _w:Number = cm.width;
                    var _h:Number = cm.height;
                    
                    var _pw:Number = cm.owner.width;
                    var _ph:Number = cm.owner.height;
                    var _px:Number = cm.owner.x;
                    var _py:Number = cm.owner.y;
                    
                    var xy:Object = ShapeUtils.getRealShapePosition(cm);
                    this.model.label = "Rs";
                    
                    /*
                    //Resize Right, Down
                    if ((_x+_w) > _pw) {
                        cm.owner.width = _x + _w;
                    }
                    
                    if ((_y + _h) > _ph) {
                        cm.owner.height = _y + _h;
                    }
                    
                    
                    
                    //Resize Left , UP
                    if (_x < 0) {
                        cm.owner.x = _px + (_x);
                        cm.owner.width = _pw + (-_x);
                    }
                    
                    if (_y < 0) {
                        cm.owner.y = _py + (_y);
                        cm.owner.height = _ph + (-_y);
                    }
                    
                    */
                    
                } else {
                    this.model.label = "Where";
                }
            }
            
            public function get objectHandles():ObjectHandles
            {
                if (!this._objectHandles) {
                    this._objectHandles = new ObjectHandles(this, null, new Flex4HandleFactory(), new Flex4ChildManager());
                }
                
                return this._objectHandles;
            }
            
            public function set graph(value:GraphContainer):void
            {
                this._graph = value;
                if (this._graph) {
                    this._objectHandles = this._graph.objecthandles;
                }
            }
            
            public function get graph():GraphContainer
            {
                return this._graph;
            }
            
            public function set model(value:ShapeModel):void
            {
                this._model = value;
            }
            
            [Bindable]
            public function get model():ShapeModel
            {
                return this._model;
            }
            
            public function set selected(value:Boolean):void
            {
                this._selected = value;
            }
            
            public function get selected():Boolean
            {
                return this._selected;
            }
            
            public function addShape(shapeui:IShape):void
            {
                ResizeContainer(shapeui);
            }
            
            public function removeChildByModel(shape:ShapeModel):void {
                
            }
            
            public function set showLabel(value:Boolean):void
            {
                this._showLabel = value;
            }
            
            public function get showLabel():Boolean
            {
                return this._showLabel;
            }
            
        ]]>
    </fx:Script>
    
</s:Group>

Shape图形接口: IShape.as

package com.components.shape
{
    import com.components.graph.GraphContainer;
    import com.components.model.ShapeModel;
    import com.roguedevelopment.objecthandles.ObjectHandles;
    
    import mx.core.IUIComponent;
    import mx.core.IVisualElement;
    import mx.core.IVisualElementContainer;

    public interface IShape extends IUIComponent, IVisualElement, IVisualElementContainer
    {
        function set graph(value:GraphContainer):void;
        function get graph():GraphContainer;
        function set model(value:ShapeModel):void;
        function get model():ShapeModel;
        function addShape(shapeui:IShape):void;
        function removeChildByModel(shape:ShapeModel):void;
        function set showLabel(value:Boolean):void;
        function get showLabel():Boolean;
        function get objectHandles():ObjectHandles;
        //
        function set selected(value:Boolean):void;
        function get selected():Boolean;
    }
}

图形ShapeModel与具体图形如SimpleRect.mxml[IShape]转换: ShapeLoad.as

package com.components.shape
{
    public class ShapeLoad
    {
        public function ShapeLoad()
        {
        }
        
        public static function getShape(stype:int):IShape
        {
            var shape:BaseShape;
            switch (stype) {
                case 0:
                    shape = new SimpleRect();
                    break;
                case 1:
                    shape = new SimpleEllipse();
                    break;
                default:
                    break;
            }
            
            return shape;
        }
    }
}

一个矩形图组件: com/components/shape/SimpleRect.mxml

<?xml version="1.0" encoding="utf-8"?>
<shape:BaseShape
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:shape="com.components.shape.*"
    width="{model.width}"
    height="{model.height}"
    x="{model.x}"
    y="{model.y}"
    rotation="{model.rotation}" >
    <fx:Script>
        <![CDATA[        
            import com.components.model.ShapeModel;
            
            import mx.controls.Alert;
            import mx.core.IVisualElement;
            import mx.core.UIComponent;
            import mx.events.FlexEvent;
            
            override public function addShape(shapeui:IShape):void
            {
                container.addElement(shapeui);
                super.addShape(shapeui);
            }
            
            override public function removeChildByModel(shape:ShapeModel):void
            {
                for (var i:int = 0; i<container.numElements;i++) {
                    var ishape:IShape = container.getElementAt(i) as IShape;
                    if (ishape && ishape.model == shape) {
                        objectHandles.unregisterComponent(ishape);
                        container.removeElement(ishape);
                    }
                }
            }
            
            override public function set showLabel(value:Boolean):void
            {
                super.showLabel = value;
            }
            
            [Bindable]
            override public function get showLabel():Boolean
            {
                return true;
            }
            
            
            protected function scrollDown_clickHandler(event:MouseEvent):void
            {
                // TODO Auto-generated method stub
                var itm:Object = event.target as DisplayObject;
                
                var tyName:String = itm.name;
                if (tyName && tyName.indexOf('Button') >= 0) {
                    event.stopPropagation();
                    objectHandles.selectionManager.clearSelection();
                }
                
            }
            
            protected function scrollUp_clickHandler(event:MouseEvent):void
            {
                 
            }
            
        ]]>
    </fx:Script>
    
    <s:Rect width="100%" height="100%" stroke="{borderStroke}" fill="{backColor}" />
    <s:Scroller width="100%" height="100%" mouseDown="scrollDown_clickHandler(event)" mouseUp="scrollUp_clickHandler(event)">
        <s:Group id="container" width="100%" height="100%" horizontalCenter="0" verticalCenter="0" />
    </s:Scroller>
    <s:Label text="{model.label}" horizontalCenter="0" verticalCenter="0" color="#000000" />
</shape:BaseShape>

使用方法Application: Flex4objectHandles.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" 
               width="100%" height="100%"
               xmlns:graph="com.components.graph.*"     
               creationComplete="init(event)" >
    <fx:Declarations>
        <!-- 将非可视元素(例如服务、值对象)放在此处 -->
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import com.components.model.ShapeModel;
            
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            
            private function init(event:FlexEvent):void
            {
                var shape:ShapeModel = new ShapeModel();
                shape.shapeType = 1;
                shape.width = 400;
                shape.height = 300;
                shape.x = 15;
                shape.y = 30;
                shape.label = "Test";
                shape.rotation = 0;
                
                var childs:Array = [];
                var child:ShapeModel = new ShapeModel();
                child.shapeType = 0;
                child.width = 100;
                child.height = 100;
                child.x = 60;
                child.y = 90;
                child.label = "child1";
                child.rotation = 0;
                childs.push(child);
                
                var _child:ShapeModel = new ShapeModel();
                _child.shapeType = 0;
                _child.width = 50;
                _child.height = 50;
                _child.x = 60;
                _child.y = 90;
                _child.label = "child1";
                _child.rotation = 0;
                child.children = [_child];
                
                child = new ShapeModel();
                child.shapeType = 1;
                child.width = 50;
                child.height = 50;
                child.x = 70;
                child.y = 10;
                child.label = "child2";
                child.rotation = 0;
                childs.push(child);
                
                shape.children = childs;
                
                graph.addShapeUI(shape);
            }
        ]]>
    </fx:Script>
    <s:SpriteVisualElement width="100%" height="100%" id="drawingLayer" />
    <s:Group width="100%" height="100%">
        <graph:GraphContainer id="graph" width="100%" height="100%"></graph:GraphContainer>
    </s:Group>
</s:Application>

资源源码下载

Flex4objectHandles.rar

 

posted @ 2014-07-15 17:57  Weiseditor  阅读(532)  评论(0编辑  收藏  举报