仿IBM-BPM Editor实现的WorkFlowEditor

在网上搜了一些例子,找了一大队资料,终于把workFlowEditor做得差不多了,这是一个类似IBM-BPM Editor的工作流编辑器,现还有一些功能没实现,现将部分代码贴在此,有需要的朋友可以交流,拍砖,哈哈。

上图:
[img]http://dl.iteye.com/upload/attachment/567690/1d83015d-ec06-34cc-b69a-71725bf4104c.jpg[/img]

节点间的连线重绘:
package com
{
import flash.geom.Point;

public class RefreshLine
{
/** 和节点相关的线条的数组 **/
public var lineList:Array = [];

public var width:Number;
public var height:Number;
public var lineFlag:LineLag;
public var line:Line;
public var node:Nodes;
private var isFromNode:Boolean=false;
private var num1:int=0; //开始节点,箭头右方向,连线数累加
private var num2:int=0; //开始节点,箭头左方向,连线数累加
private var num3:int=0; //开始节点,箭头上方向,连线数累加
private var num4:int=0; //开始节点,箭头下方向,连线数累加
private var numA:int=0; //结束节点,箭头右方向,连线数累加
private var numB:int=0; //结束节点,箭头左方向,连线数累加
private var numC:int=0; //结束节点,箭头上方向,连线数累加
private var numD:int=0; //结束节点,箭头下方向,连线数累加
private var startX:int;
private var startY:int;
private var endX:int;
private var endY:int;


public function RefreshLine(node:Nodes)
{
this.node=node;
lineList=node.lineList;
}

/**
* 重绘节点上的连线
* */
public function getAspectArr():void{
for(var j:int = 0; j < lineList.length; j++){
lineFlag = lineList[j];
line = lineFlag.line;

switch(line.aspect){
case 1:
if(line.fromNode==node)
num1++;
else
numA++;
break;
case 2:
if(line.fromNode==node)
num2++;
else
numB++;
break;
case 3:
if(line.fromNode==node)
num3++;
else
numC++;
break;
case 4:
if(line.fromNode==node)
num4++;
else
numD++;
break;
}
}
}

public function refreshLine():void{
var isHead:Boolean;
var startNO:int=0; //指向开始节点的连线的条数
var endNO:int=0; //指向结束节点的连线的条数

width=node.width;
height=node.height;
getAspectArr();

for(var i:int = 0; i < lineList.length; i++){
startX = node.x;
startY = node.y;
endX = node.x;
endY = node.y;
lineFlag = lineList[i];
line = lineFlag.line;
isHead = lineFlag.isHead;

if(line.fromNode==node){
isFromNode=true;
startNO++;
}else{
endNO++;
}

switch(node.type){
case Nodes.NODE:
case Nodes.EMAIL:
case Nodes.CLOCK:
case Nodes.ENDNODE:
circleNodePosition(startNO,endNO);
break;
case Nodes.RECT:
rectNodePosition(startNO,endNO);
break;
case Nodes.BRECT:
rectNodePosition(startNO,endNO);
break;
case Nodes.DIAMOND:
diamondNodePosition(startNO,endNO);
break;
}
/**
* 如果是连线箭头所指的,则重设线条开始位置
* 如果不是,则重设连线结束
**/
if(isHead)
line.startPoint = new Point(startX,startY);
else
line.endPoint = new Point(endX,endY);

line.drawLine(line.aspect);
}
num1=0;
num2=0;
num3=0;
num4=0;
numA=0;
numB=0;
numC=0;
numD=0;
}

private function circleNodePosition(startNO:int,endNO:int):void{
switch(line.aspect){
case 1:
//箭头向右
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.y<line.toNode.y){
startY+=Nodes.CIRCLE_RADIUS*2+1;
}else{
startY-=1;
}
startX+=width/2-Nodes.CIRCLE_RADIUS+Nodes.CIRCLE_RADIUS*2/(num1+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=13;
startY+=Nodes.CIRCLE_RADIUS*2/(num1+1)*(startNO);
break;
default:
startX+=width-15;
startY+=Nodes.CIRCLE_RADIUS*2/(num1+1)*(startNO);
break;
}
endX+=15;
endY+=Nodes.CIRCLE_RADIUS*2/(numA+1)*(endNO);
break;
case 2:
//箭头向左
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.y<line.toNode.y){
startY+=Nodes.CIRCLE_RADIUS*2+1;
}else{
startY-=1;
}
startX+=width/2-Nodes.CIRCLE_RADIUS+Nodes.CIRCLE_RADIUS*2/(num2+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=width-15;
startY+=Nodes.CIRCLE_RADIUS*2/(num2+1)*(startNO);
break;
default:
startX+=13;
startY+=Nodes.CIRCLE_RADIUS*2/(num2+1)*(startNO);
break;
}
endX+=width-13;
endY+=Nodes.CIRCLE_RADIUS*2/(numB+1)*(endNO);
break;
case 3:
//箭头向上
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.x<line.toNode.x){
startX+=width-15;
}else{
startX+=13;
}
startY+=Nodes.CIRCLE_RADIUS*2/(num3+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=width/2-Nodes.CIRCLE_RADIUS+Nodes.CIRCLE_RADIUS*2/(num3+1)*(startNO);
startY+=Nodes.CIRCLE_RADIUS*2+1;
break;
default:
startX+=width/2-Nodes.CIRCLE_RADIUS+Nodes.CIRCLE_RADIUS*2/(num3+1)*(startNO);
startY-=1;
break;
}
endX+=width/2-Nodes.CIRCLE_RADIUS+Nodes.CIRCLE_RADIUS*2/(numC+1)*(endNO);
endY+=Nodes.CIRCLE_RADIUS*2+3;
break;
case 4:
//箭头向下
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.x<line.toNode.x){
startX+=width-15;
}else{
startX+=13;
}
startY+=Nodes.CIRCLE_RADIUS*2/(num4+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=width/2-Nodes.CIRCLE_RADIUS+Nodes.CIRCLE_RADIUS*2/(num4+1)*(startNO);
startY-=1;
break;
default:
startX+=width/2-Nodes.CIRCLE_RADIUS+Nodes.CIRCLE_RADIUS*2/(num4+1)*(startNO);
startY+=Nodes.CIRCLE_RADIUS*2+1;
break;
}
endX+=width/2-Nodes.CIRCLE_RADIUS+Nodes.CIRCLE_RADIUS*2/(numD+1)*(endNO);
endY-=2;
break;
}
}

private function rectNodePosition(startNO:int,endNO:int):void{
switch(line.aspect){
case 1:
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.y<line.toNode.y){
startY+=height+2;
}else{
startY-=0;
}
startX+=width/(num1+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX-=0;
startY+=height/(num1+1)*(startNO);
break;
default:
startX+=width;
startY+=height/(num1+1)*(startNO);
break;
}
endX-=2;
endY+=height/(numA+1)*(endNO);
break;
case 2:
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.y<line.toNode.y){
startY+=height+2;
}else{
startY-=0;
}
startX+=width/(num2+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=width;
startY+=height/(num2+1)*(startNO);
break;
default:
startX-=0;
startY+=height/(num2+1)*(startNO);
break;
}
endX+=width+2;
endY+=height/(numB+1)*(endNO);
break;
case 3:
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.x<line.toNode.x){
startX+=width;
}else{
startX-=0;
}
startY+=height/(num3+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=width/(num3+1)*(startNO);
startY+=height+2;
break;
default:
startX+=width/(num3+1)*(startNO);
startY-=0;
break;
}
endX+=width/(numC+1)*(endNO);
endY+=height+3;
break;
case 4:
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.x<line.toNode.x){
startX+=width;
}else{
startX-=0;
}
startY+=height/(num4+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=width/(num4+1)*(startNO);
startY-=0;
break;
default:
startX+=width/(num4+1)*(startNO);
startY+=height+2;
break;
}
endX+=width/(numD+1)*(endNO);
endY-=1;
break;
}
}

private function diamondNodePosition(startNO:int,endNO:int):void{
switch(line.aspect){
case 1:
if((num1<=1 && line.fromNode==node) || (numA<=1 && line.toNode==node)){
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.y<line.toNode.y){
startY+=Nodes.DIAMOND_BORDER;
}else{
startY-=0;
}
startX+=width/2;
break;
case line.lineStyleArr[2]:
startX+=4;
startY+=Nodes.DIAMOND_BORDER/(num1+1)*(startNO);
break;
default:
startX+=Nodes.DIAMOND_BORDER+6;
startY+=Nodes.DIAMOND_BORDER/2;
break;
}
endX+=3;
endY+=Nodes.DIAMOND_BORDER/2;
}else{
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.y<line.toNode.y){
startY+=Nodes.DIAMOND_BORDER-13;
}else{
startY+=13;
}
startX+=width/(num1+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=(width-Nodes.DIAMOND_BORDER)/2+10;
startY+=Nodes.DIAMOND_BORDER/(num1+1)*(startNO);
break;
default:
startX+=Nodes.DIAMOND_BORDER-6;
startY+=Nodes.DIAMOND_BORDER/(num1+1)*(startNO);
break;
}
endY+=Nodes.DIAMOND_BORDER/(numA+1)*(endNO);

if((num1==3 && startNO==2) || (numA==3 && endNO==2)){
endX+=3;
}else{
endX+=15;
}
}
break;
case 2:
if((num2<=1 && line.fromNode==node) || (numB<=1 && line.toNode==node)){
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.y<line.toNode.y){
startY+=Nodes.DIAMOND_BORDER;
}else{
startY-=0;
}
startX+=width/2;
break;
case line.lineStyleArr[2]:
startX+=Nodes.DIAMOND_BORDER+6;
startY+=Nodes.DIAMOND_BORDER/(num2+1)*(startNO);
break;
default:
startX+=4;
startY+=Nodes.DIAMOND_BORDER/2;
break;
}
endX+=Nodes.DIAMOND_BORDER+6;
endY+=Nodes.DIAMOND_BORDER/2;
}else{
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.y<line.toNode.y){
startY+=Nodes.DIAMOND_BORDER-13;
}else{
startY+=13;
}
startX+=width/(num2+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=Nodes.DIAMOND_BORDER-6;
startY+=Nodes.DIAMOND_BORDER/(num2+1)*(startNO);
break;
default:
startX+=(width-Nodes.DIAMOND_BORDER)/2+13;
startY+=Nodes.DIAMOND_BORDER/(num2+1)*(startNO);
break;
}
endY+=Nodes.DIAMOND_BORDER/(numB+1)*(endNO);

if((num2==3 && startNO==2) || (numB==3 && endNO==2)){
endX+=Nodes.DIAMOND_BORDER+7;
}else{
endX+=Nodes.DIAMOND_BORDER-4;
}
}
break;
case 3:
if((num3<=1 && line.fromNode==node) || (numC<=1 && line.toNode==node)){
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.x<line.toNode.x){
startX+=Nodes.DIAMOND_BORDER+6;
}else{
startX+=4;
}
startY+=Nodes.DIAMOND_BORDER/2;
break;
case line.lineStyleArr[2]:
startX+=width/(num3+1)*(startNO);
startY+=Nodes.DIAMOND_BORDER;
break;
default:
startX+=width/2;
startY-=0;
break;
}
endX+=width/2;
endY+=Nodes.DIAMOND_BORDER+2;
}else{
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.x<line.toNode.x){
startX+=Nodes.DIAMOND_BORDER-13;
}else{
startX+=15;
}
startY+=Nodes.DIAMOND_BORDER/(num3+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=width/(num3+1)*(startNO);
startY+=Nodes.DIAMOND_BORDER-13;
break;
default:
startX+=width/(num3+1)*(startNO);
startY+=13;
break;
}
endX+=width/(numC+1)*(endNO);
if((num3==3 && startNO==2) || (numC==3 && endNO==2)){
endY+=Nodes.DIAMOND_BORDER+2;
}else{
endY+=Nodes.DIAMOND_BORDER-11;
}
}
break;
case 4:
if((num4<=1 && line.fromNode==node) || (numD<=1 && line.toNode==node)){
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.x<line.toNode.x){
startX+=Nodes.DIAMOND_BORDER+6;
}else{
startX+=4;
}
startY+=Nodes.DIAMOND_BORDER/2;
break;
case line.lineStyleArr[2]:
startX+=width/(num4+1)*(startNO);
startY-=0;
break;
default:
startX+=width/2;
startY+=Nodes.DIAMOND_BORDER;
break;
}
endX+=width/2;
endY-=1;
}else{
switch(line.lineStyle){
case line.lineStyleArr[1]:
if(line.fromNode.x<line.toNode.x){
startX+=Nodes.DIAMOND_BORDER-13;
}else{
startX+=15;
}
startY+=Nodes.DIAMOND_BORDER/(num4+1)*(startNO);
break;
case line.lineStyleArr[2]:
startX+=width/(num4+1)*(startNO);
startY+=13;
break;
default:
startX+=width/(num4+1)*(startNO);
startY+=Nodes.DIAMOND_BORDER-13;
break;
}
endX+=width/(numD+1)*(endNO);
if((num4==3 && startNO==2) || (numD==3 && endNO==2)){
endY-=1;
}else{
endY+=11;
}
}
break;
}
}

}
}


键盘事件类:
package com
{
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;

import mx.core.UITextField;

import net.L4cd.iTrace;

public class WFKeyboard
{
private var node:Nodes;
private var line:Line;
private var workFlow:CusWorkFlow;
private var o:Object;
/** CusWorkFlow对象的放大/缩小参数 **/
private var scaleNO:Number=.2;
/** 封装连线的对象 **/
private var lineLag1:LineLag;

public var trace:Function = iTrace.init;

public function WFKeyboard()
{

}

/** 选择键盘按键ASCII值 **/
public function chooseKey(e:KeyboardEvent,mouseE:MouseEvent):void {
o=getObjects(mouseE);
node=o.node as Nodes;
line=o.line as Line;
workFlow=o.workFlow as CusWorkFlow;
switch(e.keyCode){
case 8:
case 46:
deleteNode(node,line,workFlow);
break;
case 65:
if(!e.ctrlKey)return;

break;
case 107:
if(!e.ctrlKey)return;
workFlow.scaleX+=scaleNO;//放大CusWorkFlow对象
workFlow.scaleY+=scaleNO;
break;
case 109:
if(!e.ctrlKey)return;
workFlow.scaleX-=scaleNO;//缩小CusWorkFlow对象
workFlow.scaleY-=scaleNO;
break;
}
}

/** 删除节点或连线 **/
private function deleteNode(node:Nodes,line:Line,workFlow:CusWorkFlow):void {
if(!workFlow)return;

if(node){
var num:int=node.lineList.length;
for(var i:int=0;i<num;i++){
var lineLag:LineLag=node.lineList[i];
workFlow.removeChild(lineLag.line);

if(node==lineLag.line.fromNode){
for(var j:int=0;j<lineLag.line.toNode.lineList.length;j++){
lineLag1=lineLag.line.toNode.lineList[j] as LineLag;
if(node==lineLag1.line.fromNode){
lineLag.line.toNode.lineList.splice(j,1);
}
}
}else{
for(var k:int=0;k<lineLag.line.fromNode.lineList.length;k++){
lineLag1=lineLag.line.fromNode.lineList[k] as LineLag;
if(node==lineLag1.line.toNode){
lineLag.line.fromNode.lineList.splice(k,1);
}
}
}
}

workFlow.removeChild(node);
}else if(line){
for(var m:int=0;m<line.toNode.lineList.length;m++){
lineLag1=line.toNode.lineList[m] as LineLag;
if(line==lineLag1.line){
line.toNode.lineList.splice(m,1);
break;
}
}

for(var n:int=0;n<line.fromNode.lineList.length;n++){
lineLag1=line.fromNode.lineList[n] as LineLag;
if(line==lineLag1.line){
line.fromNode.lineList.splice(n,1);
}
}
workFlow.removeChild(line);
}
}

/** 重画节点边框,表示选中或非选中 **/
public function reDrawNode(map:Nodes):void{
switch(map.type){
case Nodes.NODE:
map.drawNode();
break;
case Nodes.DOC:
map.drawDoc();
break;
case Nodes.EMAIL:
map.drawEmail();
break;
case Nodes.RECT:
map.drawRect();
break;
case Nodes.BRECT:
map.drawBRect();
break;
case Nodes.DIAMOND:
map.drawDiamond();
break;
case Nodes.CLOCK:
map.drawClock();
break;
case Nodes.ENDNODE:
map.drawEndNode();
break;
case Nodes.LEFTDASHED:
map.drawDashed();
break;
case Nodes.RIGHTDASHED:
map.drawDashed2();
break;
}
}

/** 返回鼠标选中的对象 **/
private function getObjects(e:MouseEvent):Object{
o=new Object();
if(e.target is UITextField){
o.node=e.target.parent.parent as Nodes;
o.workFlow=e.target.parent.parent.parent as CusWorkFlow;
}else if(e.target is Nodes){
o.node=e.target as Nodes;
o.workFlow=e.target.parent as CusWorkFlow;
}else if(e.target is CusWorkFlow){
o.workFlow=e.target as CusWorkFlow;
}else if(e.target is Line){
o.line=e.target as Line;
o.workFlow=e.target.parent as CusWorkFlow;
}
return o;
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值