www.pudn.com > WorkflowDesigner.rar > WfTransition.cs, change:2007-11-28,size:16252b


using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Drawing.Imaging; 
namespace WorkflowDesigner.Designer 
{ 
    /// <summary> 
    /// 流转可视化对象 
    /// </summary> 
    public class WfTransition :DesignerVisualObject 
    { 
        #region 字段 
 
        /// <summary> 
        /// 开始节点 
        /// </summary> 
        private WfAbstractActivity _start; 
 
        /// <summary> 
        /// 结束节点 
        /// </summary> 
        private WfAbstractActivity _end; 
         
        /// <summary> 
        /// 当前流转中间位置的x轴坐标 
        /// </summary> 
        private int _x; 
 
        /// <summary> 
        /// 当前流转中间位置的y轴坐标 
        /// </summary> 
        private int _y; 
 
        /// <summary> 
        /// 存放图标矩形框 
        /// </summary> 
        private Rectangle _rect; 
 
        /// <summary> 
        /// 条件 
        /// </summary> 
        private IList<TransCondition> conditions = new List<TransCondition>(); 
 
 
        private String _name = ""; 
 
        
        //参数集合 
        #endregion 
 
        #region 属性 
 
        public String Name 
        { 
            get { return _name; } 
            set { _name = value; } 
        } 
 
        /// <summary> 
        /// 条件 
        /// </summary> 
        public IList<TransCondition> Conditions 
        { 
            get { return conditions; } 
            set { conditions = value; } 
        } 
        /// <summary> 
        /// 当前流转中间位置的y轴坐标 
        /// </summary> 
        public int Y 
        { 
            get 
            { 
                return _y; 
            } 
            set 
            { 
                _y = value; 
                _rect = new Rectangle(_x - 4, _y - 4, 8, 8); 
            } 
        } 
        /// <summary> 
        /// 当前流转中间位置的x轴坐标 
        /// </summary> 
        public int X 
        { 
            get 
            { 
                return _x; 
            } 
            set 
            { 
                _x = value; 
                _rect = new Rectangle(_x - 4, _y - 4, 8, 8); 
            } 
        } 
        /// <summary> 
        /// 开始节点 
        /// </summary> 
        public WfAbstractActivity StartActivity 
        { 
            get 
            { 
                return _start; 
            } 
            set 
            { 
                _start = value; 
            } 
        } 
        /// <summary> 
        /// 结束节点 
        /// </summary> 
        public WfAbstractActivity EndActivity 
        { 
            get 
            { 
                return _end; 
            } 
            set 
            { 
                _end = value; 
            } 
        } 
        #endregion 
 
        #region 构造函数 
        /// <summary> 
        /// 构造函数 
        /// </summary> 
        public WfTransition(WfAbstractActivity start, WfAbstractActivity end) 
        { 
            //设置开始节点 
            this._start = start; 
            //设置结束节点 
            this._end = end; 
            //得到中心点坐标 
            this._x = start.X + (end.X - start.X) / 2; 
            this._y = start.Y + (end.Y - start.Y) / 2; 
            //根据中心点坐标绘制调整节点矩形 
            _rect = new Rectangle(_x-4,_y-4, 8, 8); 
             
        } 
        #endregion 
 
        #region 操作 
 
        #region 私有 
        #endregion 
 
        #region 保护 
 
        #endregion 
 
        #region 公用 
 
        /// <summary> 
        /// 判断鼠标点击出是否有可视化对象 
        /// </summary> 
        /// <param name="x">鼠标所在位置的x轴坐标</param> 
        /// <param name="y">鼠标所在位置的y轴坐标</param> 
        /// <returns>点击出的可视化对象</returns> 
        public override HitTestState HitTest(int x, int y) 
        { 
             
            if (_rect.Contains(x, y)) 
            { 
                return HitTestState.Center; 
            } 
            else 
            { 
                return HitTestState.None; 
            } 
        } 
         
 
        /// <summary> 
        /// 对齐到画布上的表格 
        /// </summary> 
        public override void AlignToGrid() 
        { 
            //如果中间点的x轴坐标小于0那么中间点的x轴坐标为0 
            if (_x < 0) 
            { 
                _x = 0; 
            } 
            //如果中间点的x轴坐标大于等于2000那么中间点的x轴坐标为2000 
            else if (_x >= 2000) 
            { 
                _x = 2000; 
            } 
            else 
            { 
                //否则对齐到最近的表格线位置 
                _x = AlignToNumber(_x, GridSize); 
            } 
            //如果中间点的x轴坐标小于0那么中间点的y轴坐标为0 
            if (_y < 0) 
            { 
                _y = 0; 
            } 
            //如果中间点的y轴坐标大于等于2000那么中间点的x轴坐标为2000 
            else if (_y >= 2000) 
            { 
                _y = 2000; 
            } 
            else 
            { 
                //否则对齐到最近的表格线位置 
                _y = AlignToNumber(_y, GridSize); 
            } 
            //重新画中间点的矩形 
            _rect = new Rectangle(_x - 4, _y - 4, 8, 8); 
        } 
 
        /// <summary> 
        /// 框选 
        /// </summary> 
        /// <param name="rect">选中的矩形范围</param> 
        public override void RangeSelect(Rectangle rect) 
        { 
            //判断流转中间调整点是否在大的橡皮筋框内,如果在内则将属性设置为被选中 
            if (rect.Contains(this._rect)) 
            { 
                this.IsSelected = true; 
            } 
        } 
 
        /// <summary> 
        /// 绘制 
        /// </summary> 
        /// <param name="g">绘图图面</param> 
        public override void Draw(Graphics g) 
        { 
            //定义画笔 
            using (Pen pen = new Pen(Color.Green)) 
            { 
                //根据开始节点和中间控制点位置画线 
                g.DrawLine(pen, StartActivity.X, StartActivity.Y, _x, _y); 
                //根据中间控制点和结束节点位置画线 
                g.DrawLine(pen, _x, _y, EndActivity.X, EndActivity.Y); 
            } 
            Color nodeColor; 
            //如果选中,中间控制点是以红色填充的否则以蓝色填充 
            if (IsSelected) 
            { 
                
                nodeColor = Color.Red; 
            } 
            else 
            { 
                nodeColor = Color.Blue; 
            } 
            //填充中间控制点矩形的颜色 
            using (Brush brush = new SolidBrush(nodeColor)) 
            { 
                g.FillEllipse(brush, _rect); 
            } 
            //得到起始位置(中间控制点位置) 
            Point source = new Point(_x, _y); 
            //得到目标位置(结束节点的位置) 
            Point target = new Point(EndActivity.X, EndActivity.Y); 
            //旋转角度 
            double angle = 0; 
 
            double x = (target.X - source.X); 
            double y = (target.Y - source.Y); 
 
            int x1 = 0; 
            int y1 = 0; 
 
            //长或宽的一半 
            int halfWfActivityWidthOrHeight = WfActivity.WidthAndHeight / 2; 
            // 垂直 x 或 y方向 
            // 特殊处理以防止除0 
            if (x == 0 || y == 0) 
            { 
                //如果x=0and y>0为90度y轴-长或宽的一半(确定画图标的位置) 如果x=0and y<0则为270度 
                if (x == 0) 
                { 
                     
                    if (y > 0) 
                    { 
                        angle = 90; 
                        x1 = target.X; 
                        y1 = target.Y - halfWfActivityWidthOrHeight; 
                    } 
                    else 
                    { 
                        angle = 270; 
                        x1 = target.X; 
                        y1 = target.Y + halfWfActivityWidthOrHeight; 
                    } 
                } 
                //如果y=0and x>0为0度x轴-长或宽的一半(确定画图标的位置) 如果y=0and x<0则为180度 
                else if (y == 0) 
                { 
                    if (x > 0) 
                    { 
                        angle = 0; 
                        x1 = target.X - halfWfActivityWidthOrHeight; 
                        y1 = target.Y; 
                    } 
                    else 
                    { 
                        angle = 180; 
                        x1 = target.X + halfWfActivityWidthOrHeight; 
                        y1 = target.Y; 
                    } 
                } 
            } 
            else 
            { 
                //计算角度 并计算图片的坐标 
                double xDIVy = x / y; 
                double yDIVx = y / x; 
                double c = Math.Atan(xDIVy); 
                angle = -(c * 180 / Math.PI); 
                angle += 90; 
                double c1 = Math.Atan(yDIVx); 
                if (xDIVy == 1) 
                { 
                    if (x > 0) 
                    { 
                        x1 = target.X - halfWfActivityWidthOrHeight; 
                        y1 = target.Y - halfWfActivityWidthOrHeight; 
                    } 
                    else 
                    { 
                        angle += 180; 
                        x1 = target.X + halfWfActivityWidthOrHeight; 
                        y1 = target.Y + halfWfActivityWidthOrHeight; 
                    } 
                } 
                else if (xDIVy == -1) 
                { 
                    if (x > 0) 
                    { 
                        angle += 180; 
                        x1 = target.X - halfWfActivityWidthOrHeight; 
                        y1 = target.Y + halfWfActivityWidthOrHeight; 
                    } 
                    else 
                    { 
                        x1 = target.X + halfWfActivityWidthOrHeight; 
                        y1 = target.Y - halfWfActivityWidthOrHeight; 
                    } 
                } 
                else if (xDIVy < -1) 
                { 
                    x1 = halfWfActivityWidthOrHeight; 
                    y1 = (int)(x1 / Math.Tan(c)); 
                    if (x > 0) 
                    { 
                        angle += 180; 
                        x1 = target.X - x1; 
                    } 
                    else 
                    { 
                        x1 = target.X + x1; 
                    } 
 
                    if (y > 0) 
                    { 
                        y1 = target.Y + y1; 
                    } 
                    else 
                    { 
                        y1 = target.Y - y1; 
                    } 
                } 
                else if (xDIVy > 1) 
                { 
                    x1 = halfWfActivityWidthOrHeight; 
                    y1 = (int)(x1 / Math.Tan(c)); 
                    if (x > 0) 
                    { 
                        x1 = target.X - x1; 
                    } 
                    else 
                    { 
                        angle += 180; 
                        x1 = target.X + x1; 
                    } 
 
                    if (y > 0) 
                    { 
                        y1 = target.Y - y1; 
                    } 
                    else 
                    { 
                        y1 = target.Y + y1; 
                    } 
                } 
                else if (xDIVy > -1 && xDIVy < 0) 
                { 
                    y1 = halfWfActivityWidthOrHeight; 
                    x1 = (int)(y1 / Math.Tan(c1)); 
                    if (x > 0) 
                    { 
                        angle += 180; 
                        x1 = target.X + x1; 
                    } 
                    else 
                    { 
                        x1 = target.X - x1; 
                    } 
 
                    if (y > 0) 
                    { 
                        y1 = target.Y - y1; 
                    } 
                    else 
                    { 
                        y1 = target.Y + y1; 
                    } 
                } 
                else if (xDIVy < 1 && xDIVy > 0) 
                { 
                    y1 = halfWfActivityWidthOrHeight; 
                    x1 = (int)(y1 / Math.Tan(c1)); 
                    if (x > 0) 
                    { 
                        x1 = target.X - x1; 
                    } 
                    else 
                    { 
                        angle += 180; 
                        x1 = target.X + x1; 
                    } 
 
                    if (y > 0) 
                    { 
                        y1 = target.Y - y1; 
                    } 
                    else 
                    { 
                        y1 = target.Y + y1; 
                    } 
                } 
            } 
            ImageAttributes imAtt = new ImageAttributes(); 
            //设置颜色键 
            imAtt.SetColorKey(Color.FromArgb(255, 0, 255), Color.FromArgb(255, 0, 255)); 
            // 画箭头 
            Bitmap arrowBitmap = WorkflowDesigner.Properties.Resources.trans_arrow; 
 
            int imgWidth = arrowBitmap.Width; 
            int imgHeight = arrowBitmap.Height; 
 
            Rectangle rcDest = new Rectangle(); 
            rcDest.X = -imgWidth / 2; 
            rcDest.Y = -imgHeight / 2; 
            rcDest.Width = imgWidth; 
            rcDest.Height = imgWidth; 
 
 
            GraphicsState gs = g.Save(); 
            //平移(世界变换矩阵平移) 
            g.TranslateTransform(x1, y1); 
            //根据角度旋转(世界变换旋转) 
            g.RotateTransform((float)angle); 
            //绘制图片 
            g.DrawImage(arrowBitmap, rcDest, 
                0, 0, 
                imgWidth, 
                imgWidth, 
                GraphicsUnit.Pixel, 
                imAtt); 
            //释放 
            imAtt.Dispose(); 
            arrowBitmap.Dispose(); 
            //还原到原来的表示状态 
            g.Restore(gs); 
 
 
            // sm add 
            if ((this.Name != "") || (this.conditions.Count > 0)) 
            { 
                StringFormat format1 = new StringFormat(StringFormatFlags.NoClip); 
                format1.Alignment = StringAlignment.Center; 
                format1.LineAlignment = StringAlignment.Near; 
                Brush brushString = new SolidBrush(Color.Black); 
                Font font = new Font("新宋体", 9); 
                String Caption = this.Name; 
                if (this.conditions.Count > 0) 
                { 
                    if (Caption != "") 
                    { 
                        Caption = Caption + "\r\n [" + this.conditions.Count.ToString() + "个判断条件]"; 
 
                    } 
                    else 
                        Caption =" [" + this.conditions.Count.ToString() + "个判断条件]"; 
                } 
                g.DrawString(Caption, font, brushString, new PointF(_x, _y + 9), format1); 
                format1.Dispose(); 
                font.Dispose(); 
                brushString.Dispose(); 
            } 
        } 
 
 
        /// <summary> 
        /// 移动 
        /// </summary> 
        /// <param name="offX">移动新位置与原坐标偏移值的x轴坐标</param> 
        /// <param name="offY">>移动新位置与原坐标偏移值的y轴坐标</param> 
        public override void Move(int offX, int offY) 
        { 
            //将中心点坐标加上偏移值,得到最新的流转中间调整点 
            _x += offX; 
            _y += offY; 
            //根据中心点坐标绘制调整节点矩形 
            _rect = new Rectangle(_x - 4, _y - 4, 8, 8); 
        } 
 
        /// <summary> 
        /// 打开属性对话框 
        /// </summary> 
        public override void OpenPropertyDialog() 
        { 
            TransitionInfoDlg dlg = new TransitionInfoDlg(); 
            dlg.WfTransition = this; 
            //dlg.List = this.conditions; 
            dlg.ShowDialog(); 
            dlg.Dispose(); 
        } 
 
        /// <summary> 
        /// 图形矩阵 
        /// </summary> 
        /// <returns>返回一个图形矩阵</returns> 
        public override Rectangle GetRange() 
        { 
            return new Rectangle(0, 0, 0, 0); 
        } 
        #endregion 
        #endregion 
    } 
}