Flex开发简单工作流程设计工具

在线预览地址

  http://rj.8634.com/xiaoshandong/workflowdesigner/workflowdesigner.html

源代码下载

  https://files.cnblogs.com/files/ffmpeg/WorkFlowDesigner.zip

截图

 

源代码

WorkFlowDesigner.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="onAppComplete();" fontSize="12" height="100%" width="100%">
      <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import wf.*;
            import mx.formatters.DateFormatter;
            import mx.events.ItemClickEvent;
            
            import mx.events.DataGridEvent;
            import mx.events.IndexChangedEvent;
            import mx.events.CloseEvent;


              import mx.core.UIComponent;
             private var myDrawBoard:DrawBoard=new DrawBoard;
            private var fr:FileReference= new FileReference();
            private var iniXml:XML=null;
                
               private function onAppComplete():void {
                   CreateContainer();
                   tn_prop.removeAllChildren();
                   fr.addEventListener(Event.COMPLETE,onFileComplete);
              }
               private function CreateContainer():void {
                   myDrawBoard.x=0;
                   myDrawBoard.y=0;
                   myDrawBoard.percentWidth=100;
                   myDrawBoard.percentHeight=100;
                  myCanvas.addChild(myDrawBoard);
                  myDrawBoard.addEventListener(DrawBoard.STATUSCHANGED,onstatuschanged);
                  myDrawBoard.addEventListener(ElementEvent.ELEMENT_SELECT_CHANGED,onelementselectchanged);
                   iniXml=
                    <WorkFlow>
                      <Route ID="13" Name="" FromElementID="5" ToElementID="2"/>
                      <Route ID="12" Name="" FromElementID="10" ToElementID="5"/>
                      <Route ID="11" Name="" FromElementID="1" ToElementID="10"/>
                      <BeginNode ID="1" Name="" x="247" y="87" Radio="20"/>
                      <EndNode ID="2" Name="" x="247" y="335" Radio="20"/>
                      <WorkNode ID="5" Name="审批" NodeType="审批" x="197" y="224" Width="100" Height="30"/>
                      <WorkNode ID="10" Name="审批" NodeType="审批" x="197" y="156" Width="100" Height="30"/>
                    </WorkFlow>
                if(iniXml != null){
                       myDrawBoard.ParseFromXml(iniXml);                       
                }                
                myDrawBoard.AddUndo();
               }
               
              private function onstatuschanged(event:Event):void {
                  tx_Status.text= myDrawBoard.Status;
              }
              private function onelementselectchanged(event:ElementEvent):void {
                  if (event.srcElement is Element) {
                      if (event.srcElement.Selected==true) {
                          tn_prop.removeAllChildren();
                          if (event.srcElement is WorkNode) {
                              tn_prop.addChild(tab_worknode_prop);
                              tn_prop.tabChildren=false;
                              showWorkNodeProperty(event.srcElement as WorkNode)
                          }
                          if (event.srcElement is BeginNode) {
                              tn_prop.addChild(tab_beginnode_prop);
                              tn_prop.tabIndex=0;
                              showBeginNodeProperty(event.srcElement as BeginNode)
                          }
                          if (event.srcElement is EndNode) {
                              tn_prop.addChild(tab_endnode_prop);
                              tn_prop.tabIndex=0;
                              showEndNodeProperty(event.srcElement as EndNode)
                          }
                          if (event.srcElement is Route) {
                              tn_prop.addChild(tab_route_prop);
                              tn_prop.tabIndex=0;
                              showRouteProperty(event.srcElement as Route)
                          }
                      }
                      tx_Eement.text=event.srcElement.className;
                      tx_Status.text= myDrawBoard.Status;
                  }
              }
              
              private function showWorkNodeProperty(iElement:WorkNode):void{
                  tx_WorkNode_ID.text =iElement.ID.toString();
                  tx_WorkNode_Name.text =iElement.Name;
                  cb_WorkNode_Type.text =iElement.NodeType;
                  tx_WorkNode_Left.text =iElement.x.toString();
                  tx_WorkNode_Top.text =iElement.y.toString();
                  tx_WorkNode_Width.text =iElement.width.toString();
                  tx_WorkNode_Height.text =iElement.height.toString();
              }

              private function showBeginNodeProperty(iElement:BeginNode):void{
                  tx_BeginNode_ID.text =iElement.ID.toString();
                  tx_BeginNode_Left.text =iElement.x.toString();
                  tx_BeginNode_Top.text =iElement.y.toString();
              }
              private function showEndNodeProperty(iElement:EndNode):void{
                  tx_EndNode_ID.text =iElement.ID.toString();
                  tx_EndNode_Left.text =iElement.x.toString();
                  tx_EndNode_Top.text =iElement.y.toString();
              }
              private function showRouteProperty(iElement:Route):void{
                  tx_Route_ID.text =iElement.ID.toString();
                  tx_Route_Name.text =iElement.Name;
                  tx_Route_Left.text =iElement.fromX.toString();
                  tx_Route_Top.text =iElement.fromY.toString();
                  tx_Route_Right.text =iElement.toX.toString();
                  tx_Route_Bottom.text =iElement.toY.toString();
              }
            private function DeleteElement():void {
                var i:int=0;
                for (i=0;i<myDrawBoard.getChildren().length;i++) {
                    if ((myDrawBoard.getChildAt(i) as Element).Selected==true) {
                        myDrawBoard.DeleteElement(myDrawBoard.getChildAt(i) as Element);
                    }
                }
            }
            private function SaveFile():void {
                var fr:FileReference= new FileReference();
                var xml:XML=new XML(myDrawBoard.BuildXml().toString());
                var dt:Date = new Date();
                var filename:String;
                
                var dateFormatter:DateFormatter=new DateFormatter();
                dateFormatter.formatString="YYYY-MM-DD JJ-NN-SS";//2009-01-21 12-01-04
                filename="workflow_"+dateFormatter.format(dt)+".xml";
                fr.save(xml,filename);
            }
            private function OpenFile():void {
                var fileRefList:FileReferenceList = new FileReferenceList();
                var allFilter:FileFilter = new FileFilter("xml (*.xml)", "*.xml");                
                if (fr.browse(new Array(allFilter))) {
                    fr.addEventListener(Event.SELECT,onFileSelect);
                }
            }
            private function onFileComplete(event: Event):void {
                var xml:XML=new XML(fr.data.toString());
                this.myDrawBoard.Clear();
                this.myDrawBoard.ParseFromXml(xml);
                this.myDrawBoard.AddUndo();
            }
            private function onFileSelect(event: Event):void {
                fr.load();
            }
            private function onChange(event: IndexChangedEvent):void {
                if (event.newIndex==1) {
                    tx_XML.text=myDrawBoard.BuildXml().toString();
                }
            }
            private function ontabIndexChange(event: Event):void {
                Alert.show(event.toString());
            }
            private function onNameChange(event: flash.events.Event):void {
                myDrawBoard.selectedElement.Name=(event.currentTarget as TextInput).text;
                myDrawBoard.selectedElement.Draw();
                myDrawBoard.AddUndo();
            }
            private function onLeftChange(event: flash.events.Event):void {
                myDrawBoard.selectedElement.x=int((event.currentTarget as TextInput).text);
                myDrawBoard.selectedElement.Draw();
                myDrawBoard.AddUndo();
            }
            private function onTopChange(event: flash.events.Event):void {
                myDrawBoard.selectedElement.y=int((event.currentTarget as TextInput).text);
                myDrawBoard.selectedElement.Draw();
                myDrawBoard.AddUndo();
            }
            private function onWidthChange(event: flash.events.Event):void {
                myDrawBoard.selectedElement.width=int((event.currentTarget as TextInput).text);
                myDrawBoard.selectedElement.Draw();
                myDrawBoard.AddUndo();
            }
            private function onHeightChange(event: flash.events.Event):void {
                myDrawBoard.selectedElement.height=int((event.currentTarget as TextInput).text);
                myDrawBoard.selectedElement.Draw();
                myDrawBoard.AddUndo();
            }
            private function onNodeTypeChange(event: flash.events.Event):void {
                (myDrawBoard.selectedElement as WorkNode).NodeType=(event.currentTarget as ComboBox).text;
                if (myDrawBoard.selectedElement.Name=="") {
                    myDrawBoard.selectedElement.Name=(event.currentTarget as ComboBox).text;
                    tx_WorkNode_Name.text=myDrawBoard.selectedElement.Name;
                }
                myDrawBoard.selectedElement.Draw();
                myDrawBoard.AddUndo();
            }
            public function ontoolbarclick(event:ItemClickEvent) : void {
                switch(event.item.cmd) {
                    case "openfile":
                    {
                        OpenFile();
                        break;
                    }
                    case "savefile":
                    {
                        SaveFile();
                        break;
                    }
                    case "delete":
                    {
                        DeleteElement();
                        break;
                    }
                    case "select":
                    {
                        myDrawBoard.Status="";
                        break;
                    }
                    case "beginnode":
                    {
                        myDrawBoard.Status="beginnode";
                        break;
                    }
                    case "endnode":
                    {
                        myDrawBoard.Status="endnode";
                        break;
                    }
                    case "worknode":
                    {
                        myDrawBoard.Status="worknode";
                        break;
                    }
                    case "route":
                    {
                        myDrawBoard.Status="routebegin";
                        break;
                    }
                    case "undo":
                    {
                        myDrawBoard.Undo();
                        break;
                    }
                    case "redo":
                    {
                        myDrawBoard.Redo();
                        break;
                    }
                    case "clear":
                    {
                        Alert.show("您确认要清空图形吗?","提示",Alert.YES | Alert.NO,null,onClearCloseHandler);
                        break;
                    }
                }
            }
            private function onClearCloseHandler(event:CloseEvent):void {
                if (event.detail==Alert.YES) {
                    myDrawBoard.Clear();
                    myDrawBoard.AddUndo();
                }
            }
        ]]>
    </mx:Script>
    <mx:Array id="ToolButton">
        <mx:Object label="打开" icon="@Embed('img/open.gif')" cmd="openfile"/>
        <mx:Object label="保存XML文件" icon="@Embed('img/save.gif')" cmd="savefile"/>
        <mx:Object label="清空" icon="@Embed('img/clear.gif')" cmd="clear"/>
        <mx:Object label="删除" icon="@Embed('img/del.gif')" cmd="delete"/>
        <mx:Object label="撤销" icon="@Embed('img/undo.gif')" cmd="undo"/>
        <!--<mx:Object label="重做" icon="@Embed('img/redo.gif')" cmd="redo"/>-->
        <mx:Object width="10"/>
        <mx:Object label="选择" icon="@Embed('img/select.png')" cmd="select"/>
        <mx:Object label="开始环节" icon="@Embed('img/beginnode.gif')" cmd="beginnode"/>
        <mx:Object label="结束环节" icon="@Embed('img/endnode.gif')" cmd="endnode"/>
        <mx:Object label="业务环节" icon="@Embed('img/worknode.gif')" cmd="worknode"/>
        <mx:Object label="路由线" icon="@Embed('img/route.png')" cmd="route"/>
    </mx:Array>
    <mx:ButtonBar x="0" y="10" id="tb_Main" height="30" dataProvider="{ToolButton}" itemClick="ontoolbarclick(event)"/>
    <mx:HDividedBox left="0" top="50" bottom="30" right="0">
        <mx:TabNavigator change="onChange(event);" width="90%" height="100%" id="tn_designer" selectedIndex="0" creationPolicy="all" tabIndexChange="ontabIndexChange(event);">
            <mx:Canvas label="设计器" width="100%" height="100%" id="myCanvas"/>
            <mx:Canvas label="XML" width="100%" height="100%">
                <mx:TextArea x="0" y="0" width="100%" height="100%" id="tx_XML"/>
            </mx:Canvas>
        </mx:TabNavigator>
        <mx:TabNavigator width="200" height="100%" id="tn_prop" selectedIndex="2" creationPolicy="all">
            <mx:Canvas id="tab_worknode_prop" label="业务环节" width="100%" height="100%">
                <mx:Label x="10" y="10" text="编号:"/>
                <mx:TextInput y="8" right="10" left="71" id="tx_WorkNode_ID" enabled="false"/>
                <mx:Label x="10" y="42" text="名称:"/>
                <mx:Label x="10" y="75" text="业务类型:"/>
                <mx:Label x="10" y="113" text="位置"/>
                <mx:Label x="71" y="115" text="左:"/>
                <mx:Label x="71" y="143" text="上:"/>
                <mx:TextInput y="113" right="10" left="108" id="tx_WorkNode_Left" change="onLeftChange(event);"/>
                <mx:Label x="71" y="173" text="宽:"/>
                <mx:TextInput y="171" right="10" left="108" id="tx_WorkNode_Width" change="onWidthChange(event);"/>
                <mx:Label x="71" y="203" text="高:"/>
                <mx:TextInput y="201" right="10" left="108" id="tx_WorkNode_Height" change="onHeightChange(event);"/>
                <mx:TextInput y="141" right="10" left="108" id="tx_WorkNode_Top" change="onTopChange(event);"/>
                <mx:TextInput y="40" right="10" left="71" id="tx_WorkNode_Name" change="onNameChange(event)"/>
                <mx:ComboBox y="72" right="10" left="71" id="cb_WorkNode_Type" change="onNodeTypeChange(event)">
                    <mx:dataProvider>
                        <mx:Array>
                            <mx:Object label="审批" data="审批"/>
                            <!--<mx:Object label="查勘" data="查勘"/>
                            <mx:Object label="审批" data="审批"/>
                            <mx:Object label="收费" data="收费"/>
                            <mx:Object label="配表" data="配表"/>
                            <mx:Object label="装接" data="装接"/>
                            <mx:Object label="归档" data="归档"/>-->
                        </mx:Array>
                    </mx:dataProvider>
                </mx:ComboBox>
                <mx:HRule y="103" right="10" left="10"/>
            </mx:Canvas>
            <mx:Canvas id="tab_endnode_prop" label="结束环节" width="100%" height="100%">
                <mx:Label x="10" y="10" text="编号:"/>
                <mx:TextInput y="8" right="10" left="71" id="tx_EndNode_ID" enabled="false"/>
                <mx:Label x="10" y="48" text="位置"/>
                <mx:Label x="71" y="50" text="左:"/>
                <mx:Label x="71" y="78" text="上:"/>
                <mx:TextInput y="48" right="10" left="108" id="tx_EndNode_Left" change="onLeftChange(event);"/>
                <mx:TextInput y="76" right="10" left="108" id="tx_EndNode_Top" change="onTopChange(event);"/>
                <mx:HRule y="38" right="10" left="10"/>
            </mx:Canvas>
            <mx:Canvas id="tab_beginnode_prop" label="开始环节" width="100%" height="100%">
                <mx:Label x="10" y="10" text="编号:"/>
                <mx:TextInput y="8" right="10" left="71" id="tx_BeginNode_ID" enabled="false"/>
                <mx:Label x="10" y="48" text="位置"/>
                <mx:Label x="71" y="50" text="左:"/>
                <mx:Label x="71" y="78" text="上:"/>
                <mx:TextInput y="48" right="10" left="108" id="tx_BeginNode_Left" change="onLeftChange(event);"/>
                <mx:TextInput y="76" right="10" left="108" id="tx_BeginNode_Top" change="onTopChange(event);"/>
                <mx:HRule y="38" right="10" left="10"/>
            </mx:Canvas>
            <mx:Canvas id="tab_route_prop" label="路由" width="100%" height="100%">
                <mx:Label x="10" y="10" text="编号:"/>
                <mx:TextInput y="8" right="10" left="71" id="tx_Route_ID" enabled="false"/>
                <mx:Label x="10" y="42" text="名称:"/>
                <mx:Label x="10" y="149" text="位置"/>
                <mx:Label x="71" y="151" text="左:"/>
                <mx:Label x="71" y="179" text="上:"/>
                <mx:TextInput y="149" right="10" left="108" id="tx_Route_Left" enabled="false"/>
                <mx:Label x="71" y="209" text="右:"/>
                <mx:TextInput y="207" right="10" left="108" id="tx_Route_Right" enabled="false"/>
                <mx:Label x="71" y="239" text="下:"/>
                <mx:TextInput y="237" right="10" left="108" id="tx_Route_Bottom" enabled="false"/>
                <mx:TextInput y="177" right="10" left="108" id="tx_Route_Top" enabled="false"/>
                <mx:TextInput y="40" right="10" left="71" id="tx_Route_Name" change="onNameChange(event)"/>
                <mx:Label x="12" y="70" text="表达式:"/>
                <mx:HRule y="134" right="10" left="10"/>
                <mx:TextArea y="69" right="10" left="71" height="57" id="tx_Route_Expression"/>
            </mx:Canvas>
        </mx:TabNavigator>
    </mx:HDividedBox>
    <mx:ControlBar width="100%" height="30" bottom="0" left="0">
        <mx:Text width="128" id="tx_Status" visible="false"/>
        <mx:TextInput id="tx_Eement" visible="false"/>
    </mx:ControlBar>
</mx:Application>

BeginNode.as

package wf
{
    public class BeginNode extends Node
    {
        public var radio:int=20;
        
        public function BeginNode(iDrawBoard:DrawBoard,iXML:XML=null)
        {
            super(iDrawBoard,iXML);
            Lable.text="开始";
            Lable.x=-14;
            Lable.y=-9;
              Lable.width=30;
              Lable.height=20;
        }
        
        override public function Draw(): void{    
              this.graphics.clear();
            this.SetLineColor();
            this.graphics.beginFill(0x00FF00,1); 
            this.graphics.moveTo(x,y);
              this.graphics.drawCircle(0,0,radio);
              this.graphics.endFill();
              
              this.myDrawBoard.ReDrawRelationElement(this);    
        }

        override public function BuildXml(): XML{
            var xml:XML=new XML("<BeginNode/>");
            xml.@ID=this.ID;
            xml.@Name=this.Name;
            xml.@x=this.x;
            xml.@y=this.y;
            xml.@Radio=this.radio;
            return xml;
        }
        override public function ParseFromXml(iXML:XML): int{
            this.ID=iXML.@ID;
            this.Name=iXML.@Name;
            this.x=iXML.@x;
            this.y=iXML.@y;
            this.radio=iXML.@Radio;
            this.Draw();
            return 0;
        }
        
    }
}

DrawBoard.as

package wf
{
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.system.ApplicationDomain;
    
    import mx.containers.Canvas;
    //[Event(name="myStatusChanged", type="flash.events.Event")]
    public class DrawBoard extends Canvas
    {
        private var _status:String="";
        private var tmpElement:Element;
        public static  const STATUSCHANGED:String="myStatusChanged";
        public static  const SELECT_CHANGED:String="SelectChanged";
        public var selectedElement:Element;
        public var fromElement:Element;
        public var toElement:Element;
        public var maxID:int=0;
        public var undoXML:XML=new XML("<UndoList><WorkFlow/></UndoList>");
        public var redoXML:XML=new XML("<RedoList/>");
        public function DrawBoard()
        {
            super();
            this.setStyle("backgroundColor","0xFFFFFF");
            this.addEventListener(MouseEvent.CLICK,onClick);
            this.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
            this.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
            this.addEventListener(KeyboardEvent.KEY_UP,onKeyUp,true);
        }
        public function get Status(): String{
            return _status;
        }
        
        public function set Status(value: String): void{
            this._status = value;
            var e:Event =new Event(STATUSCHANGED);
            dispatchEvent(e);
        }
        public function AddUndo() :void {
            undoXML.appendChild(new XML(this.BuildXml().toXMLString()));
        }
        public function Undo() :void {
            var workflows:XMLList= undoXML..WorkFlow;
            if (workflows.length()>1) {
                var index:int=workflows.length()-2;
                var xml:XML=new XML(workflows[index+1].toString());
                redoXML.appendChild(xml);
                delete workflows[index+1];
                this.ParseFromXml(workflows[index]);
            }
        }
        public function Redo() :void {
            var workflows:XMLList= redoXML..WorkFlow;
            if (workflows.length()>0) {
                var index:int=workflows.length()-1;
                var xml:XML=new XML(workflows[index].toString());
                undoXML.appendChild(xml);
                this.ParseFromXml(workflows[index]);
                delete redoXML.WorkFlow[index];
            }
        }

        private function onClick(event: MouseEvent):void {
            var newElement:Element;   
            if (this.Status=="worknode"){
               newElement = new WorkNode(this);                 
             }else if (this.Status=="beginnode"){
               newElement = new BeginNode(this);                  
            }else if (this.Status=="endnode"){
               newElement = new EndNode(this);                 
            }
            if (newElement!=null) {
                newElement.x=mouseX;
                newElement.y=mouseY;
                if (this.selectedElement!=null) {
                    this.selectedElement.Selected=false;
                }
                newElement.Selected=true;
                this.AddUndo();
            }
            this.Status="";
        }

        private function onMouseUp(event: MouseEvent):void{
            if (this.Status=="routebegin"){
                var nodeCheck:Boolean;
                nodeCheck=((this.fromElement is WorkNode) && (this.toElement is WorkNode));//业务环节-业务环节
                nodeCheck=nodeCheck || ((this.fromElement is BeginNode) && (this.toElement is WorkNode));//开始环节-业务环节
                nodeCheck=nodeCheck || ((this.fromElement is WorkNode) && (this.toElement is EndNode));//业务环节-结束环节
                
                nodeCheck=nodeCheck && tmpElement is Route;
                if (nodeCheck==true) {
                    var myroute:Route=tmpElement as Route;
                    myroute.fromElement=this.fromElement;
                    myroute.toElement=this.toElement;
                    myroute.Name="测试线";
                    myroute.Draw();
                    AddUndo();
                  }
                  else
                  {
                      if (tmpElement!=null) { 
                          this.removeChild(tmpElement);
                      }
                  }
                tmpElement=null;
                this.fromElement=null;
                this.toElement=null;
                this.Status="";
            }
        }
        private function onMouseMove(event: MouseEvent):void{
            if (this.Status=="routebegin"){
                var myroute:Route;
                if (this.fromElement is Element) {
                    if (tmpElement is Route) {
                          myroute=tmpElement as Route;
                      }else{
                       myroute=new Route(this);                  
                       this.setChildIndex(myroute,0);
                       myroute.fromElement=this.fromElement;
                       tmpElement=myroute;
                      }
                   myroute.toX=mouseX;
                   myroute.toY=mouseY;
                   myroute.Draw();
                  }
            }
        }
        
        public function UnSelectedAllElement():void{
            for each (var myelement:Element in this.getChildren()) {
                if (myelement.Selected) {
                    myelement.Selected=false;
                }
            }
        }
        
        public function DeleteElement(iElement:Element):void{
            this.removeChild(iElement);
            AddUndo();
        }
        
        public function ReDrawRelationElement(iElement:Element):void{
            if ((iElement is WorkNode) || (iElement is BeginNode) || (iElement is EndNode)) {
                for each (var myelement:Element in this.getChildren()) {
                    if (myelement is Route) {
                        var myroute:Route=myelement as Route;
                        if ((myroute.fromElement==iElement)||(myroute.toElement==iElement)) {
                            myroute.Draw();
                        }
                    }
                }
            }
        }
        private function onKeyUp(event:KeyboardEvent):void {
            //Alert.show( event.keyCode.toString());
            if (event.keyCode==46){//Delete
                this.DeleteElement(this.selectedElement);
            }
            else if ((event.keyCode==90) && event.ctrlKey){//Ctrl+Z Undo
                this.Undo();
            }
            else if ((event.keyCode==89) && event.ctrlKey){//Ctrl+Y Redo
                this.Redo();
            }
        }
        public function BuildXml(): XML{
            var xml:XML=new XML("<WorkFlow/>");
            for each (var myelement:Element in this.getChildren()) {
                xml.appendChild(myelement.BuildXml());
            }
            return xml;
        }
        public function ParseFromXml(iXML:XML): void{
            this.Clear();
            var newElementClass : Class
            var myelement:Element;
             var domain : ApplicationDomain = ApplicationDomain.currentDomain;
             var elementName:String="";
             //先解析Node,再解析Route
            var elements:XMLList=iXML..BeginNode+iXML..EndNode+iXML..WorkNode+iXML..Route;
            for each (var elementXml:XML in elements) {
                elementName="wf."+elementXml.name();//动态创建类的名称需要加包名
                if(domain.hasDefinition(elementName))
                {
                    //动态创建类
                    newElementClass = domain.getDefinition(elementName) as Class;
                    myelement = new newElementClass(this,elementXml);
                    //动态调用方法
                    var fnc_draw:Function=myelement["Draw"];
                    fnc_draw.call(myelement);
                }
            }
        }
        public function GetNewElementID():int{
            return maxID+1;
        }
        public function Clear():void{
            this.removeAllChildren();
        }
        public function GetElementFromID(iID:int):Element{
            for each (var myelement:Element in this.getChildren()) {
                if (myelement.ID==iID) {
                    return myelement;
                }
            }
            return null;
        }
    }
}

Element.as

package wf
{
    import mx.core.UIComponent;
    public class Element extends UIComponent
    {
        public var myDrawBoard:DrawBoard;
        public static  const LINE_SELECT_COLOR:int=0x0000FF; 
        public static  const LINE_UNSELECT_COLOR:int=0x000000; 
        private var _selected:Boolean;
        private var _id:int=0;
        protected var _name:String="";
        public function Element(iDrawBoard:DrawBoard,iXML:XML=null)
        {
            super();
            this.myDrawBoard=iDrawBoard;
            iDrawBoard.addChild(this);
            iDrawBoard.setChildIndex(this,iDrawBoard.getChildren().length-1);
            if (iXML==null) {
                ID=iDrawBoard.GetNewElementID();
            }else{
                ParseFromXml(iXML);
            }
            if (ID>iDrawBoard.maxID) {
                iDrawBoard.maxID=ID;
            }
            this.focusEnabled=true;
            this.useHandCursor=true;
            this.buttonMode=true;
            this.mouseChildren=false;
            //this.cursorManager.setCursor
        }
        public function get ID(): int{
            return _id;
        }
        
        public function set ID(value: int): void{
            this._id = value;
        }

        public function get Name(): String{
            return _name;
        }
        
        public function set Name(value: String): void{
            this._name = value;
        }

        public function get Selected(): Boolean{
            return _selected;
        }
        
        public function set Selected(value: Boolean): void{
            if (_selected!=value) {
                this._selected = value;
                if (value==false) {
                    myDrawBoard.selectedElement=null;
                } else {
                    this.setFocus();
                    myDrawBoard.selectedElement=this;
                }
                Draw();
                var evt:ElementEvent=new ElementEvent(ElementEvent.ELEMENT_SELECT_CHANGED);
                evt.srcElement=this;
                myDrawBoard.dispatchEvent(evt);
            }
        }
        
        public function SetLineColor():void{
            if (Selected==true) {
                this.graphics.lineStyle(2,LINE_SELECT_COLOR);
            } else {
                this.graphics.lineStyle(1,LINE_UNSELECT_COLOR);
            }
        }
        public function Draw(): void{}
        public function BuildXml(): XML{return null;}        
        public function ParseFromXml(iXML:XML): int{return 0;}        
        
    }
}

ElementEvent.as

package wf
{
    import flash.events.Event;

    public class ElementEvent extends Event
    {
        public var srcElement:Element;
        public static  const ELEMENT_SELECT_CHANGED:String="ElementSelectChanged";
        public function ElementEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
        {
            super(type, bubbles, cancelable);
        }
        
    }
}

EndNode.as

package wf
{
    public class EndNode extends Node
    {
        public var radio:int=20;
        public function EndNode(iDrawBoard:DrawBoard,iXML:XML=null)
        {
            super(iDrawBoard,iXML);
            Lable.text="结束";
            Lable.x=-14;
            Lable.y=-9;
              Lable.width=30;
              Lable.height=20;
        }
        
        override public function Draw(): void{    
              this.graphics.clear();
            this.SetLineColor();

            this.graphics.beginFill(0xFF0000,1); 
            this.graphics.moveTo(x,y);
              this.graphics.drawCircle(0,0,radio);
              this.graphics.endFill();
              
              this.myDrawBoard.ReDrawRelationElement(this);
        }

        override public function BuildXml(): XML{
            var xml:XML=new XML("<EndNode/>");
            xml.@ID=this.ID;
            xml.@Name=this.Name;
            xml.@x=this.x;
            xml.@y=this.y;
            xml.@Radio=this.radio;
            return xml;
        }        
        override public function ParseFromXml(iXML:XML): int{
            this.ID=iXML.@ID;
            this.Name=iXML.@Name;
            this.x=iXML.@x;
            this.y=iXML.@y;
            this.radio=iXML.@Radio;
            this.Draw();
            return 0;
        }            
        
    }
}

Node.as

package wf
{
    import flash.events.MouseEvent;
    import mx.controls.Alert;
    import mx.controls.Text;

    public class Node extends Element
    {
        protected var Lable:mx.controls.Text=new Text();
        
        public function Node(iDrawBoard:DrawBoard,iXML:XML=null)
        {
            super(iDrawBoard,iXML);
            this.addChild(Lable);
            Lable.setStyle("textAlign","center");            
              this.addEventListener(MouseEvent.CLICK,onclick);
             this.addEventListener(MouseEvent.MOUSE_DOWN,onmousedown);
             this.addEventListener(MouseEvent.MOUSE_UP,onmouseup);            
        }
        
        private function onclick(event: MouseEvent):void{
            if (myDrawBoard.Status=="") {
                myDrawBoard.UnSelectedAllElement();
                this.Selected=true;
            }
        }
        private function onmousedown(event: MouseEvent):void{
            if (myDrawBoard.Status=="") {
                this.startDrag();
            }else if (myDrawBoard.Status=="routebegin") {
                 myDrawBoard.fromElement=this;
            } 
        }
        private function onmouseup(event: MouseEvent):void{
            if (myDrawBoard.Status=="") {
                this.stopDrag();
                myDrawBoard.AddUndo();
            }else if (myDrawBoard.Status =="routebegin") {
                 myDrawBoard.toElement=this;
            } 
        }
    }
}

Route.as

package wf
{
    import flash.events.MouseEvent;
    import flash.text.*;
    
    import mx.controls.Label;
    public class Route extends Element
    {
        public var fromElement:Element;
        public var toElement:Element;
        public var fromX:int;
        public var fromY:int;
        public var toX:int;
        public var toY:int;
        private var lable:Label=new  Label();
        public function Route(iDrawBoard:DrawBoard,iXML:XML=null)
        {
            super(iDrawBoard,iXML);
            lable.width=0;
            lable.height=0;
            this.addChild(lable);
            //RouteName="测试线";
              this.addEventListener(MouseEvent.CLICK,onclick);
        }

        
        override public function set Name(value: String): void{
            _name = value;
            lable.text=value;
            lable.validateNow();//立即计算文本的尺寸
            //自动根据文本设置尺寸
            lable.width=lable.textWidth+5;
            lable.height=lable.textHeight+2;
            Draw();
        }
        
        override public function Draw():void{
              this.graphics.clear();
            this.SetLineColor();
              if (fromElement is Element) {
                  fromX=fromElement.x+fromElement.width/2;
                  fromY=fromElement.y+fromElement.height/2;
                this.graphics.moveTo(fromX,fromY);
              } else {
                  throw new Error("Route中非法的fromElement")
              }
            if (toElement is Element) {
                toX=toElement.x;
                toY=toElement.y;
            }

            if (toElement is WorkNode) {
                //计算终点
                var minDistance:int;                 
                var distance1:int=Math.sqrt(Math.pow(fromX-toElement.x,2)+Math.pow(fromY-(toElement.y+toElement.height/2),2)); //var distance2:int=Math.sqrt(Math.pow(fromX-(toElement.x+toElement.width),2)+Math.pow(fromY-(toElement.y+toElement.height/2),2)); //var distance3:int=Math.sqrt(Math.pow(fromX-(toElement.x+toElement.width/2),2)+Math.pow(fromY-toElement.y,2));//var distance4:int=Math.sqrt(Math.pow(fromX-(toElement.x+toElement.width/2),2)+Math.pow(fromY-(toElement.y+toElement.height),2));////取最小距离
                minDistance= Math.min(distance1,distance2,distance3,distance4);
                if (minDistance==distance1) {
                    toX=toElement.x;
                    toY=toElement.y+toElement.height/2;
                }
                if (minDistance==distance2) {
                    toX=(toElement.x+toElement.width);
                    toY=(toElement.y+toElement.height/2);
                }
                if (minDistance==distance3) {
                    toX=(toElement.x+toElement.width/2);
                    toY=toElement.y;
                }
                if (minDistance==distance4) {
                    toX=(toElement.x+toElement.width/2);
                    toY=(toElement.y+toElement.height);
                }
            }
            if (toElement is EndNode) {
                var distance:int=Math.sqrt(Math.pow((toX-fromX),2)+Math.pow((toY-fromY),2));
                var rate:Number=1-(toElement as EndNode).radio/distance;
                toX=fromX+(toX-fromX)*rate;
                toY=fromY+(toY-fromY)*rate;
            }
            
            this.graphics.lineTo(toX,toY);
            //箭头
            this.graphics.beginFill(0x000000,1);
              var slopy:Number;
              var cosy:Number;
              var siny:Number;
              var Par:Number=6;
              slopy = Math.atan2((fromY - toY),(fromX - toX));
              cosy = Math.cos(slopy);
              siny = Math.sin(slopy);
            this.graphics.moveTo(toX,toY);
              this.graphics.lineTo(toX + int( Par * cosy - ( Par / 2.0 * siny ) ), toY + int( Par * siny + ( Par / 2.0 * cosy ) ) );
              this.graphics.lineTo(toX + int( Par * cosy + Par / 2.0 * siny ),toY - int( Par / 2.0 * cosy - Par * siny ) );
              this.graphics.lineTo(toX,toY);              
            //this.graphics.drawCircle(toX,toY,3);//圆 
            this.graphics.endFill();
            lable.x=(fromX+toX)/2;
            lable.y=(fromY+toY)/2;
            //Lable.width=100;
            //Lable.height=50;
              this.myDrawBoard.ReDrawRelationElement(this);
        }
        private function onclick(event: MouseEvent):void{
            if (myDrawBoard.Status=="") {
                myDrawBoard.UnSelectedAllElement();
                this.Selected=true;
            }
        }
        override public function BuildXml(): XML{
            var xml:XML=new XML("<Route/>");
            xml.@ID=this.ID;
            xml.@Name=this.Name;
            xml.@FromElementID=this.fromElement.ID;
            xml.@ToElementID=this.toElement.ID;
            return xml;
        }        
        override public function ParseFromXml(iXML:XML): int{
            this.fromElement=this.myDrawBoard.GetElementFromID(iXML.@FromElementID);
            this.toElement=this.myDrawBoard.GetElementFromID(iXML.@ToElementID);
            this.ID=iXML.@ID;
            this.Name=iXML.@Name;
            myDrawBoard.setChildIndex(this,0);
            this.Draw();
            return 0;
        }            
        
    }
}

WorkNode.as

package wf
{

    public class WorkNode extends Node
    {
        private var _nodetype:String="";
        public function WorkNode(iDrawBoard:DrawBoard,iXML:XML=null)
        {
            super(iDrawBoard,iXML);
            this.width=100;
            this.height=30;            
        }

        public function get NodeType(): String{
            return _nodetype;
        }
        
        public function set NodeType(value: String): void{
            this._nodetype = value;
        }
        
        override public function set Name(value: String): void{
            this._name = value;
            Lable.text=value;
        }
        
        override public function Draw(): void{    
              this.graphics.clear();
            this.SetLineColor();
            
              Lable.width=width;
              Lable.height=height;
        
            this.graphics.beginFill(0xFFFFFF,1); 
            this.graphics.moveTo(x,y);
              this.graphics.drawRect(0,0,width,height);
          
              this.graphics.endFill();
            this.myDrawBoard.ReDrawRelationElement(this);            
        }
        override public function BuildXml(): XML{
            var xml:XML=new XML("<WorkNode/>");
            xml.@ID=this.ID;
            xml.@Name=this.Name;
            xml.@NodeType=this.NodeType;
            xml.@x=this.x;
            xml.@y=this.y;
            xml.@Width=this.width;
            xml.@Height=this.height;
            return xml;
        }        
        override public function ParseFromXml(iXML:XML): int{
            this.ID=iXML.@ID;
            this.Name=iXML.@Name;
            this.x=iXML.@x;
            this.y=iXML.@y;
            this.NodeType=iXML.@NodeType;
            this.width=iXML.@Width;
            this.height=iXML.@Height;
            this.Draw();
            return 0;
        }            
        
    }
}

 

posted @ 2015-03-31 19:18  小山东  阅读(731)  评论(0编辑  收藏  举报