using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Dongke.IBOSS.Basics.FlowSetting
{
///
/// 流程项目绘制管理器
///
internal class ItemManager
{
#region 成员变量
///
/// 流程项目自增ID
///
private int _newItemID = 0;
///
/// 管理器编码
///
private string _managerCode = Guid.NewGuid().ToString();
///
/// 画板
///
private CanvasBox _canvasBox = null;
///
/// 流程设计器
///
private FlowBox _flowBox = null;
///
/// 画布控件
///
private Control _canvasControl = null;
///
/// 流程编辑模式
///
private FlowBoxMode _flowBoxMode = FlowBoxMode.Edit;
#region 项目集合
// todo 自定义 list 管理 外部不能add,remove只能get,可以通过,itemid,onlycode,itemindex(显示顺序)取得。
///
/// 全部流程项目
///
private List _items = new List();
///
/// 选中的流程项目
///
private List _selectedItems = new List();
/////
///// 删除的流程项目
/////
//private List _deletedItems = new List();
/////
///// 选中的流程节点
/////
//private List _selectedNodes = new List();
///
/// 全部流程节点
///
private List _allNodes = new List();
///
/// 删除的流程项目
///
private List _deletedNodes = new List();
#endregion 项目集合
#region 新建项目
///
/// 鼠标操作,指定位置,新建Item
///
private FlowItem _drawingItem = null;
///
/// 鼠标操作,指定位置,新建节点
///
private FlowNode _drawingNode = null;
///
/// 鼠标操作,指定位置,新建线段
///
private FlowLine _drawingLine = null;
#endregion 新建项目
#region 鼠标操作
///
/// 鼠标动作
///
private MouseOperatingType _mouseOperatingType = MouseOperatingType.None;
///
/// 鼠标框选范围
///
private Rectangle _mouseSelectRect = Rectangle.Empty;
///
/// 鼠标按下的点
///
private Point _mouseDownPoint = Point.Empty;
///
/// 鼠标移动的点
///
private Point _mouseMovePoint = Point.Empty;
///
/// 鼠标抬起的点
///
private Point _mouseUpPoint = Point.Empty;
///
/// 鼠标是否按下
///
private bool _isMouseDown = false;
///
/// 鼠标是否移动
///
private bool _isMouseMove = false;
///
/// 鼠标是否抬起
///
private bool _isMouseUp = false;
///
/// 进行改变大小操作的节点
///
private FlowNode _nodeSizeChanging = null;
///
/// 进行改变大小操作的线段
///
private FlowLine _linePointChanging = null;
///
/// 正在显示锚点的节点
///
private FlowNode _nodeAnchorShowing = null;
#endregion 鼠标操作
#region 绘制项目
// TODO 使用后销毁??
///
/// 画节点笔
///
private Pen _penDrawNode = new Pen(Consts.NODE_BORDERCOLOR_DEFAULT);
///
/// 画线段笔
///
private Pen _penDrawLine = new Pen(Consts.LINE_COLOR_DEFAULT, Consts.LINE_WIDTH_DEFAULT);
///
/// 写字笔
///
private Pen _penDrawString = new Pen(Consts.FONT_COLOR_DEFAULT);
#endregion 绘制项目
#endregion 成员变量
#region 构造函数
///
/// 构造函数
///
/// 流程设计器
/// 画板
internal ItemManager(FlowBox flowBox, CanvasBox canvasBox)
{
this._flowBox = flowBox;
this._canvasBox = canvasBox;
this._canvasControl = canvasBox.CanvasControl;
this._flowBoxMode = flowBox.BoxMode;
// 线段连接线 以圆点开始,箭头结束
AdjustableArrowCap myArrow = new AdjustableArrowCap(4, 4);
CustomLineCap customArrow = myArrow;
this._penDrawLine.CustomEndCap = myArrow;
//this._penDrawLine.StartCap = LineCap.RoundAnchor;
this.SetDefaultCursor();
}
#endregion 构造函数
#region 属性
///
/// 获取全部流程项目
///
public List Items
{
get
{
return this._items;
}
}
///
/// 获取选择的流程项目
///
public List SelectedItems
{
get
{
return this._selectedItems;
}
}
///
/// 获取删除的节点
///
public List DeletedNodes
{
get
{
return this._deletedNodes;
}
}
///
/// 获取全部的节点(包括删除的)
///
public List AllNodes
{
get
{
return this._allNodes;
}
}
///
/// 获取或设置管理器编码
///
internal string ManagerCode
{
get
{
return this._managerCode;
}
set
{
this._managerCode = value;
}
}
///
/// 获取或设置流程编辑模式
///
internal FlowBoxMode BoxMode
{
get
{
return this._flowBoxMode;
}
set
{
this._flowBoxMode = value;
}
}
///
/// 获取或设置新的itemID
///
internal int NewItemID
{
get
{
return ++this._newItemID;
}
}
///
/// 获取或设置画板的鼠标样式
///
private Cursor CanvasCursor
{
get
{
return this._canvasControl.Cursor;
}
set
{
this._canvasControl.Cursor = value;
}
}
#endregion 属性
#region 公有方法
#region 新建项目
///
/// 停止新建节点(鼠标操作)
///
public void StopDrawingItem()
{
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
this.SetDefaultCursor();
}
///
/// 新建节点(鼠标操作,指定位置)
///
public FlowNode DrawingNode()
{
this._drawingNode = new FlowNode(this);
this._drawingLine = null;
this._drawingItem = this._drawingNode;
this.SetDrawingNodeCursor();
return this._drawingNode;
}
///
/// 新建线段(鼠标操作,指定位置)
///
public FlowLine DrawingLine()
{
this._drawingNode = null;
this._drawingLine = new FlowLine(this);
this._drawingItem = this._drawingLine;
this.SetDrawingLineCursor();
return this._drawingLine;
}
///
/// 新建节点(默认位置)
///
/// 节点
public FlowNode NewNode()
{
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
return this.NewNodeInternal(null);
}
///
/// 新建节点(指定位置)
///
/// 节点位置
public FlowNode NewNode(Point location)
{
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
return this.NewNodeInternal(location);
}
///
/// 新建线段(默认位置)
///
/// 线段
public FlowLine NewLine()
{
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
return this.NewLineInternal(null, null);
}
///
/// 新建线段(指定位置)
///
/// 起始点
/// 结束点
/// 线段
public FlowLine NewLine(Point pointBegin, Point pointEnd)
{
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
return this.NewLineInternal(pointBegin, pointEnd);
}
#endregion 新建项目
#region 刷项目
/////
///// 刷新未激活Item的图片
/////
//public void RefreshStaticItems()
//{
// // 清除画布
// Graphics graphics = this._canvasBox.Canvas;
// graphics.Clear(Color.Transparent);
// // 绘制未激活的Item
// this.DrawStaticItems(graphics);
// // 设定未激活的Item为图片
// this._canvasBox.SetItemsImage(this._canvasBox.CanvasImage);
//}
/////
///// 刷新激活Item的图片
/////
//public void RefreshActiveItems()
//{
// // 清除画布
// Graphics graphics = this._canvasBox.Canvas;
// graphics.Clear(Color.Transparent);
// // 绘制激活的Item
// this.DrawActiveItems(graphics);
// // 设定未激活的Item为图片
// this._canvasBox.SetItemsImage(this._canvasBox.CanvasImage);
//}
/////
///// 刷新激活Item
/////
/////
//public void RefreshActiveItems(Graphics graphics)
//{
// // todo 在paint绘制事件中绘制激活的item,未激活item作为背景
// // 绘制激活的Item
// this.DrawActiveItems(graphics);
//}
///
/// 刷新Item的图片
///
public void RefreshItems()
{
// 清除画布
Graphics graphics = this._canvasBox.Canvas;
graphics.Clear(Color.Transparent);
// 绘制激活的Item
this.DrawItems(graphics);
// 设定未激活的Item为图片
this._canvasBox.SetItemsImage(this._canvasBox.CanvasImage);
GC.Collect();
}
#endregion 刷新项目
#region 操作项目
///
/// 全部不选择
///
public void ClearSelection()
{
foreach (FlowItem item in this._selectedItems)
{
item.MouseOperating = false;
item.Selected = false;
}
this._selectedItems.Clear();
}
///
/// 全部选择
///
public void SelectAllItems()
{
foreach (FlowItem item in this._items)
{
if (!item.Selected)
{
this._selectedItems.Add(item);
item.Selected = true;
}
}
}
///
/// 删除全部项目
///
public void DeleteAllItems()
{
foreach (FlowItem item in this._items)
{
item.MouseOperating = false;
item.Selected = false;
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
node.ShowAnchor = false;
node.InLines.Clear();
node.OutLines.Clear();
node.TopLines.Clear();
node.LeftLines.Clear();
node.RightLines.Clear();
node.BottomLines.Clear();
node.PreNodes.Clear();
node.NextNodes.Clear();
if (node.NodeState == FlowNodeState.Added ||
node.NodeState == FlowNodeState.Detached)
{
node.NodeState = FlowNodeState.Detached;
}
else
{
node.NodeState = FlowNodeState.Deleted;
}
this._deletedNodes.Add(item as FlowNode);
continue;
}
if (item is FlowLine)
{
FlowLine line = item as FlowLine;
line.AnchorBegin = AnchorKind.None;
line.AnchorEnd = AnchorKind.None;
line.NodeBegin = null;
line.NodeEnd = null;
line.NodeCodeBegin = null;
line.NodeCodeEnd = null;
continue;
}
}
this._selectedItems.Clear();
this._items.Clear();
}
///
/// 删除选择项目
///
public void DeleteSelectedItems()
{
foreach (FlowItem item in this._selectedItems)
{
item.MouseOperating = false;
item.Selected = false;
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
node.ShowAnchor = false;
foreach (FlowLine line in node.InLines)
{
//if (!line.Selected)
{
line.NodeEnd = null;
line.AnchorEnd = AnchorKind.None;
}
}
foreach (FlowLine line in node.OutLines)
{
//if (!line.Selected)
{
line.NodeBegin = null;
line.AnchorBegin = AnchorKind.None;
}
}
node.InLines.Clear();
node.OutLines.Clear();
node.TopLines.Clear();
node.LeftLines.Clear();
node.RightLines.Clear();
node.BottomLines.Clear();
node.PreNodes.Clear();
node.NextNodes.Clear();
if (node.NodeState == FlowNodeState.Added ||
node.NodeState == FlowNodeState.Detached)
{
node.NodeState = FlowNodeState.Detached;
}
else
{
node.NodeState = FlowNodeState.Deleted;
}
this._items.Remove(node);
this._deletedNodes.Add(item as FlowNode);
continue;
}
if (item is FlowLine)
{
FlowLine line = item as FlowLine;
if (line.NodeBegin != null && !line.NodeBegin.Selected)
{
line.NodeBegin.OutLines.Remove(line);
switch (line.AnchorBegin)
{
case AnchorKind.Top:
line.NodeBegin.TopLines.Remove(line);
break;
case AnchorKind.Left:
line.NodeBegin.LeftLines.Remove(line);
break;
case AnchorKind.Right:
line.NodeBegin.RightLines.Remove(line);
break;
case AnchorKind.Bottom:
line.NodeBegin.BottomLines.Remove(line);
break;
default:
break;
}
}
if (line.NodeEnd != null && !line.NodeEnd.Selected)
{
line.NodeEnd.InLines.Remove(line);
switch (line.AnchorEnd)
{
case AnchorKind.Top:
line.NodeEnd.TopLines.Remove(line);
break;
case AnchorKind.Left:
line.NodeEnd.LeftLines.Remove(line);
break;
case AnchorKind.Right:
line.NodeEnd.RightLines.Remove(line);
break;
case AnchorKind.Bottom:
line.NodeEnd.BottomLines.Remove(line);
break;
default:
break;
}
}
line.AnchorBegin = AnchorKind.None;
line.AnchorEnd = AnchorKind.None;
line.NodeBegin = null;
line.NodeEnd = null;
this._items.Remove(line);
continue;
}
}
this._selectedItems.Clear();
}
///
/// 对齐选定的节点
///
/// 对齐方式
public void ArrangeNodes(ArrangeType arrangeType)
{
switch (arrangeType)
{
case ArrangeType.Left:
ArrangeNodesLeft();
break;
case ArrangeType.Right:
ArrangeNodesRight();
break;
case ArrangeType.HorizontalCenter:
ArrangeNodesHorizontalCenter();
break;
case ArrangeType.Top:
ArrangeNodesTop();
break;
case ArrangeType.Bottom:
ArrangeNodesBottom();
break;
case ArrangeType.VerticalCenter:
ArrangeNodesVerticalCenter();
break;
default:
break;
}
}
///
/// 顶部对齐所有选中的节点
///
public void ArrangeNodesTop()
{
int minTop = this._canvasControl.Height;
foreach (FlowItem item in this._selectedItems)
{
FlowNode node = item as FlowNode;
if (node != null)
{
minTop = Math.Min(node.Top, minTop);
}
}
foreach (FlowItem item in this._selectedItems)
{
FlowNode node = item as FlowNode;
if (node != null)
{
node.Top = minTop;
}
}
}
///
/// 底部对齐所有选中的节点
///
public void ArrangeNodesBottom()
{
}
///
/// 左侧对齐所有选中的节点
///
public void ArrangeNodesLeft()
{
}
///
/// 右侧对齐所有选中的节点
///
public void ArrangeNodesRight()
{
}
///
/// 垂直方向中心对齐所有选中的节点
///
public void ArrangeNodesVerticalCenter()
{
}
///
/// 水平方向中心对齐所有选中的节点
///
public void ArrangeNodesHorizontalCenter()
{
}
#endregion 操作项目
#endregion 公有方法
#region 内部方法
///
/// 获取新ItemID(用于流程保存)
///
/// ItemID
internal int GetNewItemID()
{
return this._newItemID;
}
///
/// 设置新ItemID(用于流程读取)
///
/// ItemID
internal void SetNewItemID(int itemID)
{
this._newItemID = itemID;
}
#region 刷新项目
///
/// 刷新鼠标框选范围
///
internal void RefreshMouseSelectRect(Graphics graphics)
{
if (this._mouseOperatingType == MouseOperatingType.RectSelect)
{
ControlPaint.DrawFocusRectangle(graphics, this._mouseSelectRect,
this._canvasControl.BackColor, Color.Transparent);
}
}
#endregion 刷新项目
#region 鼠标操作
///
/// 处理鼠标按下事件
///
///
internal void MouseDown(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
{
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
this.SetDefaultCursor();
return;
}
this._mouseDownPoint = e.Location;
this._mouseMovePoint = e.Location;
this._isMouseDown = true;
this._isMouseMove = false;
this._isMouseUp = false;
if (this._mouseOperatingType != MouseOperatingType.Move)
{
this.CanvasCursor = Cursors.Cross;
}
// 鼠标绘制item
if (this._drawingItem != null)
{
//// 节点
//if (this._drawingItem is FlowNode)
//{
// FlowNode node = this._drawingItem as FlowNode;
// node.Location = e.Location;
// node.Size = Size.Empty;
// return;
//}
//// 线段
//if (this._drawingItem is FlowLine)
//{
// FlowLine line = this._drawingItem as FlowLine;
// line.PointBegin = e.Location;
// line.PointEnd = e.Location;
// return;
//}
return;
}
// 改变节点大小
if (this._mouseOperatingType == MouseOperatingType.NodeTopAndLeft ||
this._mouseOperatingType == MouseOperatingType.NodeTopAndRight ||
this._mouseOperatingType == MouseOperatingType.NodeBottomAndLeft ||
this._mouseOperatingType == MouseOperatingType.NodeBottomAndRight ||
this._mouseOperatingType == MouseOperatingType.NodeTop ||
this._mouseOperatingType == MouseOperatingType.NodeBottom ||
this._mouseOperatingType == MouseOperatingType.NodeLeft ||
this._mouseOperatingType == MouseOperatingType.NodeRight)
{
// 选择的节点随着改变 begin
//foreach (FlowItem selectedItem in this._selectedItems)
//{
// if (selectedItem is FlowNode)
// {
// FlowNode node = selectedItem as FlowNode;
// node.MouseDownRect = node.Bounds;
// }
//}
// 选择的节点随着改变 end
// 只改变当前节点 begin
this.ClearSelection();
if (this._nodeSizeChanging != null)
{
this._nodeSizeChanging.Selected = true;
this._selectedItems.Add(this._nodeSizeChanging);
this._nodeSizeChanging.MouseDownRect = this._nodeSizeChanging.Bounds;
}
this.RefreshItems();
// 只改变当前节点 end
return;
}
// 改变线段端点位置
if (this._mouseOperatingType == MouseOperatingType.LineBegin ||
this._mouseOperatingType == MouseOperatingType.LineEnd)
{
if (this._flowBoxMode != FlowBoxMode.Edit)
{
return;
}
// 取消其他item选择状态 begin
this.ClearSelection();
if (this._linePointChanging != null)
{
this._linePointChanging.Selected = true;
this._selectedItems.Add(this._linePointChanging);
}
this.RefreshItems();
// 取消其他item选择状态 end
return;
}
// 正在进行其他操作
if (this._mouseOperatingType != MouseOperatingType.None)
{
return;
}
// 选择item
FlowItem item = this.SelectItemByPoint(e.Location);
if (item != null)
{
// 点选
if (!item.Selected)
{
this.ClearSelection();
item.Selected = true;
this._selectedItems.Add(item);
}
this.SetMoveCursor();
this.RefreshItems();
return;
}
else
{
// 框选
this._mouseSelectRect = new Rectangle(e.Location, Size.Empty);
this.SetRectSelectCursor();
// 框选开始就清空选择 begin
//this.ClearSelectItem();
//this.RefreshItems();
// 框选开始就清空选择 end
return;
}
}
///
/// 处理鼠标移动事件
///
///
internal void MouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.None && this._drawingItem == null)
{
this.SetMouseCursorByMove(e.Location);
return;
}
if (e.Button != MouseButtons.Left)
{
return;
}
Point mouseBeginPoint = this._mouseMovePoint;
this._mouseMovePoint = e.Location;
this._isMouseMove = true;
bool hasRefreshItems = false;
#region 鼠标绘制item
if (this._drawingItem != null)
{
// 节点
if (this._mouseOperatingType == MouseOperatingType.DrawingNode)
{
//FlowNode node = this._drawingItem as FlowNode;
this._drawingNode.Location = mouseBeginPoint;
this._drawingNode.Size = Size.Empty;
this._drawingNode.Selected = true;
this._drawingNode.NodeState = FlowNodeState.Added;
this.ClearSelection();
this._items.Add(this._drawingNode);
this._allNodes.Add(this._drawingNode);
this._selectedItems.Add(this._drawingNode);
this._drawingNode.MouseDownRect = this._drawingNode.Bounds;
this._nodeSizeChanging = this._drawingNode;
this._drawingItem = null;
}
// 线段
if (this._mouseOperatingType == MouseOperatingType.DrawingLine)
{
//FlowLine line = this._drawingItem as FlowLine;
this._drawingLine.PointBegin = mouseBeginPoint;
this._drawingLine.PointEnd = e.Location;
this._drawingLine.Selected = true;
this.ClearSelection();
this._items.Add(this._drawingLine);
this._selectedItems.Add(this._drawingLine);
this._linePointChanging = this._drawingLine;
this._drawingItem = null;
}
}
#endregion 鼠标绘制item
#region 激活item
if (this._isMouseDown)
{
hasRefreshItems = true;
foreach (FlowItem item in this._selectedItems)
{
item.MouseOperating = true;
}
this._isMouseDown = false;
// todo 在paint绘制事件中绘制激活的item,未激活item作为背景
//this.RefreshStaticItems();
}
//// 取消激活item
//if (this._isMouseUp)
//{
// hasRefreshItems = true;
// foreach (FlowItem item in this._selectedItems)
// {
// item.MouseOperating = false;
// }
// this._isMouseUp = false;
// // todo 在paint绘制事件中绘制激活的item,未激活item作为背景
// //this.RefreshStaticItems();
//}
#endregion 激活item
#region 框选
if (this._mouseOperatingType == MouseOperatingType.RectSelect)
{
this._mouseSelectRect = this.GetNewRect(this._mouseSelectRect, this._mouseDownPoint, e.Location);
this._canvasControl.Invalidate();
return;
}
#endregion 框选
#region 移动
if (this._mouseOperatingType == MouseOperatingType.Move)
{
int xMove = e.X - mouseBeginPoint.X;
int yMove = e.Y - mouseBeginPoint.Y;
this.MoveSelectedItems(xMove, yMove);
this.RefreshItems();
return;
}
#endregion 移动
#region 左上角
if (this._mouseOperatingType == MouseOperatingType.NodeTopAndLeft)
{
if (this._nodeSizeChanging == null)
{
return;
}
Point point = this.GetRectTopAndLeft(this._nodeSizeChanging.MouseDownRect);
int xRect = e.X - point.X;
int yRect = e.Y - point.Y;
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
Point fixedPoint = this.GetRectBottomAndRight(node.MouseDownRect);
node.Bounds = new Rectangle(fixedPoint, new Size(xRect - node.MouseDownRect.Width, yRect - node.MouseDownRect.Height));
// 移动连接线
foreach (FlowLine line in node.InLines)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
}
this.RefreshItems();
return;
}
#endregion 左上角
#region 右上角
if (this._mouseOperatingType == MouseOperatingType.NodeTopAndRight)
{
if (this._nodeSizeChanging == null)
{
return;
}
Point point = this.GetRectTopAndRight(this._nodeSizeChanging.MouseDownRect);
int xRect = e.X - point.X;
int yRect = e.Y - point.Y;
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
Point fixedPoint = this.GetRectBottomAndLeft(node.MouseDownRect);
node.Bounds = new Rectangle(fixedPoint, new Size(xRect + node.MouseDownRect.Width, yRect - node.MouseDownRect.Height));
// 移动连接线
foreach (FlowLine line in node.InLines)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
}
this.RefreshItems();
return;
}
#endregion 右上角
#region 左下角
if (this._mouseOperatingType == MouseOperatingType.NodeBottomAndLeft)
{
if (this._nodeSizeChanging == null)
{
return;
}
Point point = this.GetRectBottomAndLeft(this._nodeSizeChanging.MouseDownRect);
int xRect = e.X - point.X;
int yRect = e.Y - point.Y;
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
Point fixedPoint = this.GetRectTopAndRight(node.MouseDownRect);
node.Bounds = new Rectangle(fixedPoint, new Size(xRect - node.MouseDownRect.Width, yRect + node.MouseDownRect.Height));
// 移动连接线
foreach (FlowLine line in node.InLines)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
}
this.RefreshItems();
return;
}
#endregion 左下角
#region 右下角
if (this._mouseOperatingType == MouseOperatingType.NodeBottomAndRight ||
this._mouseOperatingType == MouseOperatingType.DrawingNode)
{
if (this._nodeSizeChanging == null)
{
return;
}
Point point = this.GetRectBottomAndRight(this._nodeSizeChanging.MouseDownRect);
int xRect = e.X - point.X;
int yRect = e.Y - point.Y;
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
Point fixedPoint = this.GetRectTopAndLeft(node.MouseDownRect);
node.Bounds = new Rectangle(fixedPoint, new Size(xRect + node.MouseDownRect.Width, yRect + node.MouseDownRect.Height));
// 移动连接线
foreach (FlowLine line in node.InLines)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
}
this.RefreshItems();
return;
}
#endregion 右下角
#region 上中
if (this._mouseOperatingType == MouseOperatingType.NodeTop)
{
if (this._nodeSizeChanging == null)
{
return;
}
Point point = this.GetRectTop(this._nodeSizeChanging.MouseDownRect);
int xRect = 0;
int yRect = e.Y - point.Y;
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
Point fixedPoint = this.GetRectBottomAndLeft(node.MouseDownRect);
node.Bounds = new Rectangle(fixedPoint, new Size(xRect + node.MouseDownRect.Width, yRect - node.MouseDownRect.Height));
// 移动连接线
foreach (FlowLine line in node.InLines)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
}
this.RefreshItems();
return;
}
#endregion 上中
#region 下中
if (this._mouseOperatingType == MouseOperatingType.NodeBottom)
{
if (this._nodeSizeChanging == null)
{
return;
}
Point point = this.GetRectBottom(this._nodeSizeChanging.MouseDownRect);
int xRect = 0;
int yRect = e.Y - point.Y;
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
Point fixedPoint = this.GetRectTopAndLeft(node.MouseDownRect);
node.Bounds = new Rectangle(fixedPoint, new Size(xRect + node.MouseDownRect.Width, yRect + node.MouseDownRect.Height));
// 移动连接线
foreach (FlowLine line in node.InLines)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
}
this.RefreshItems();
return;
}
#endregion 下中
#region 左中
if (this._mouseOperatingType == MouseOperatingType.NodeLeft)
{
if (this._nodeSizeChanging == null)
{
return;
}
Point point = this.GetRectLeft(this._nodeSizeChanging.MouseDownRect);
int xRect = e.X - point.X;
int yRect = 0;
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
Point fixedPoint = this.GetRectTopAndRight(node.MouseDownRect);
node.Bounds = new Rectangle(fixedPoint, new Size(xRect - node.MouseDownRect.Width, yRect + node.MouseDownRect.Height));
// 移动连接线
foreach (FlowLine line in node.InLines)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
}
this.RefreshItems();
return;
}
#endregion 左中
#region 右中
if (this._mouseOperatingType == MouseOperatingType.NodeRight)
{
if (this._nodeSizeChanging == null)
{
return;
}
Point point = this.GetRectRight(this._nodeSizeChanging.MouseDownRect);
int xRect = e.X - point.X;
int yRect = 0;
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
Point fixedPoint = this.GetRectTopAndLeft(node.MouseDownRect);
node.Bounds = new Rectangle(fixedPoint, new Size(xRect + node.MouseDownRect.Width, yRect + node.MouseDownRect.Height));
// 移动连接线
foreach (FlowLine line in node.InLines)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
}
this.RefreshItems();
return;
}
#endregion 右中
#region 线段开始点
if (this._mouseOperatingType == MouseOperatingType.LineBegin)
{
if (this._linePointChanging == null)
{
return;
}
FlowLine line = this._linePointChanging;
line.PointBegin = e.Location;
// 断开连接
if (line.NodeBegin != null)
{
this.DisconnectL2NPointBegin(line);
}
// 查询可连接的锚点
FlowNode rectNode = this.GetL2N(e.Location);
this._nodeAnchorShowing = rectNode;
// 连接
if (rectNode != null)
{
rectNode.ShowAnchor = true;
Rectangle[] rects = rectNode.GetAnchorRects();
for (int i = 0; i < rects.Length; i++)
{
Rectangle rect = rects[i];
rect.Inflate(Consts.L2N_PRECISION_EDGE, Consts.L2N_PRECISION_EDGE);
if (rect.Contains(e.Location))
{
AnchorKind anchorKind = (AnchorKind)i;
this.ConnectL2NPointBegin(line, rectNode, anchorKind);
}
}
}
this.RefreshItems();
return;
}
#endregion 线段开始点
#region 线段结束点
if (this._mouseOperatingType == MouseOperatingType.LineEnd ||
this._mouseOperatingType == MouseOperatingType.DrawingLine)
{
if (this._linePointChanging == null)
{
return;
}
FlowLine line = this._linePointChanging;
line.PointEnd = e.Location;
// 断开连接
if (line.NodeEnd != null)
{
this.DisconnectL2NPointEnd(line);
}
// 查询可连接的锚点
FlowNode rectNode = this.GetL2N(e.Location);
this._nodeAnchorShowing = rectNode;
// 连接
if (rectNode != null)
{
rectNode.ShowAnchor = true;
Rectangle[] rects = rectNode.GetAnchorRects();
for (int i = 0; i < rects.Length; i++)
{
Rectangle rect = rects[i];
rect.Inflate(Consts.L2N_PRECISION_EDGE, Consts.L2N_PRECISION_EDGE);
if (rect.Contains(e.Location))
{
AnchorKind anchorKind = (AnchorKind)i;
this.ConnectL2NPointEnd(line, rectNode, anchorKind);
}
}
}
this.RefreshItems();
return;
}
#endregion 线段结束点
// todo 在paint绘制事件中绘制激活的item,未激活item作为背景
//this._canvasControl.Invalidate();
if (hasRefreshItems)
{
this.RefreshItems();
}
}
///
/// 处理鼠标抬起事件
///
///
internal void MouseUp(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
{
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
return;
}
this._mouseUpPoint = e.Location;
this._isMouseDown = false;
this._isMouseUp = true;
bool hasRefreshItems = false;
#region 取消激活item
if (this._isMouseMove)
{
hasRefreshItems = true;
foreach (FlowItem item in this._selectedItems)
{
item.MouseOperating = false;
}
this._isMouseMove = false;
if (this._nodeAnchorShowing != null)
{
this._nodeAnchorShowing.ShowAnchor = false;
this._nodeAnchorShowing = null;
}
this._nodeSizeChanging = null;
this._linePointChanging = null;
// todo 在paint绘制事件中绘制激活的item,未激活item作为背景
//this.RefreshStaticItems();
}
#endregion 取消激活item
#region 鼠标绘制item
if (this._drawingItem != null)
{
if (this._mouseOperatingType == MouseOperatingType.DrawingNode)
{
this.NewNodeInternal(e.Location);
}
if (this._mouseOperatingType == MouseOperatingType.DrawingLine)
{
Point pBegin = e.Location;
Point pEnd = pBegin;
pEnd.Offset(Consts.LINE_POINT_END_DEFAULT);
this.NewLineInternal(pBegin, pEnd);
}
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
this.RefreshItems();
return;
}
else
{
// 用新加线段连接节点
if (this._mouseOperatingType == MouseOperatingType.DrawingLine)
{
Point pBegin = this._drawingLine.PointBegin;
Point pEnd = this._drawingLine.PointEnd;
FlowNode nodeBegin = this.SelectNodeByPoint(pBegin);
FlowNode nodeEnd = this._drawingLine.NodeEnd;
if (nodeEnd == null)
{
nodeEnd = this.SelectNodeByPoint(pEnd);
}
if ((nodeBegin == null && nodeEnd != null) ||
(nodeBegin != null && nodeEnd == null) ||
(nodeBegin != null && nodeEnd != null && nodeBegin.ItemCode != nodeEnd.ItemCode))
{
if (nodeBegin != null)
{
Point np1 = this.GetRectTopAndLeft(nodeBegin.Bounds);
Point np2 = this.GetRectTopAndRight(nodeBegin.Bounds);
Point np3 = this.GetRectBottomAndLeft(nodeBegin.Bounds);
Point np4 = this.GetRectBottomAndRight(nodeBegin.Bounds);
if (this.IsSegmentIntersect(pBegin, pEnd, np1, np2))
{
this.ConnectL2NPointBegin(this._drawingLine, nodeBegin, AnchorKind.Top);
}
else if (this.IsSegmentIntersect(pBegin, pEnd, np3, np4))
{
this.ConnectL2NPointBegin(this._drawingLine, nodeBegin, AnchorKind.Bottom);
}
else if (this.IsSegmentIntersect(pBegin, pEnd, np1, np3))
{
this.ConnectL2NPointBegin(this._drawingLine, nodeBegin, AnchorKind.Left);
}
else if (this.IsSegmentIntersect(pBegin, pEnd, np2, np4))
{
this.ConnectL2NPointBegin(this._drawingLine, nodeBegin, AnchorKind.Right);
}
}
if (this._drawingLine.AnchorEnd == AnchorKind.None && nodeEnd != null)
{
Point np1 = this.GetRectTopAndLeft(nodeEnd.Bounds);
Point np2 = this.GetRectTopAndRight(nodeEnd.Bounds);
Point np3 = this.GetRectBottomAndLeft(nodeEnd.Bounds);
Point np4 = this.GetRectBottomAndRight(nodeEnd.Bounds);
if (this.IsSegmentIntersect(pBegin, pEnd, np1, np2))
{
this.ConnectL2NPointEnd(this._drawingLine, nodeEnd, AnchorKind.Top);
}
else if (this.IsSegmentIntersect(pBegin, pEnd, np3, np4))
{
this.ConnectL2NPointEnd(this._drawingLine, nodeEnd, AnchorKind.Bottom);
}
else if (this.IsSegmentIntersect(pBegin, pEnd, np1, np3))
{
this.ConnectL2NPointEnd(this._drawingLine, nodeEnd, AnchorKind.Left);
}
else if (this.IsSegmentIntersect(pBegin, pEnd, np2, np4))
{
this.ConnectL2NPointEnd(this._drawingLine, nodeEnd, AnchorKind.Right);
}
}
}
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
this.RefreshItems();
return;
}
this._drawingNode = null;
this._drawingLine = null;
}
#endregion 鼠标绘制item
#region 框选
if (this._mouseOperatingType == MouseOperatingType.RectSelect)
{
this.SelectItemByRect(this._mouseSelectRect);
this._mouseSelectRect = Rectangle.Empty;
this.RefreshItems();
//this._canvasControl.Invalidate();
return;
}
#endregion 框选
//this.SetDefaultCursor();
if (hasRefreshItems)
{
this.RefreshItems();
}
}
///
/// 鼠标双击
///
///
///
internal FlowNode MouseDoubleClick(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (this._selectedItems.Count == 1)
{
FlowItem item = this._selectedItems[0];
if (item is FlowNode)
{
return item as FlowNode;
}
}
}
return null;
}
///
/// 移动选择的项目
///
/// X轴的移动量
/// Y轴的移动量
internal void MoveSelectedItems(int xMove, int yMove)
{
foreach (FlowItem item in this._selectedItems)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
node.Left += xMove;
node.Top += yMove;
// 移动连接线
foreach (FlowLine line in node.InLines)
{
if (!line.Selected)
{
line.PointEnd = node.GetAnchor(line.AnchorEnd);
}
}
// 移动连接线
foreach (FlowLine line in node.OutLines)
{
if (!line.Selected)
{
line.PointBegin = node.GetAnchor(line.AnchorBegin);
}
}
continue;
}
if (item is FlowLine)
{
FlowLine line = item as FlowLine;
Point p = line.PointBegin;
p.X += xMove;
p.Y += yMove;
line.PointBegin = p;
p = line.PointEnd;
p.X += xMove;
p.Y += yMove;
line.PointEnd = p;
// 断开连接
if (line.NodeBegin != null && !line.NodeBegin.Selected)
{
this.DisconnectL2NPointBegin(line);
}
if (line.NodeEnd != null && !line.NodeEnd.Selected)
{
this.DisconnectL2NPointEnd(line);
}
continue;
}
}
}
#endregion 鼠标操作
#endregion 内部方法
#region 私有方法
#region 新建项目
///
/// 新建节点
///
/// 节点位置
/// 节点
private FlowNode NewNodeInternal(Point? location)
{
//FlowNode node = this._drawingItem as FlowNode;
FlowNode newNode = (this._drawingNode == null) ? new FlowNode(this) : this._drawingNode;
newNode.Selected = true;
if (location.HasValue)
{
newNode.Location = location.Value;
}
if (newNode.Bounds.IsEmpty)
{
newNode.Bounds = Consts.NODE_BOUNDS_DEFAULT;
}
if (newNode.Size.IsEmpty)
{
newNode.Size = Consts.NODE_BOUNDS_DEFAULT.Size;
}
newNode.NodeState = FlowNodeState.Added;
this.ClearSelection();
this._items.Add(newNode);
this._allNodes.Add(newNode);
this._selectedItems.Add(newNode);
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
this.SetDefaultCursor();
return newNode;
}
///
/// 新建线段
///
/// 起始点
/// 结算点
/// 线段
private FlowLine NewLineInternal(Point? pointBegin, Point? pointEnd)
{
//FlowLine line = this._drawingItem as FlowLine;
FlowLine newLine = (this._drawingLine == null) ? new FlowLine(this) : this._drawingLine;
newLine.Selected = true;
if (pointBegin.HasValue)
{
newLine.PointBegin = pointBegin.Value;
newLine.PointEnd = pointEnd.Value;
}
else
{
newLine.PointBegin = Consts.LINE_POINT_Begin_DEFAULT;
newLine.PointEnd = Consts.LINE_POINT_END_DEFAULT;
}
this.ClearSelection();
this._items.Add(newLine);
this._selectedItems.Add(newLine);
this._drawingItem = null;
this._drawingNode = null;
this._drawingLine = null;
this.SetDefaultCursor();
return newLine;
}
#endregion 新建项目
#region 绘制项目
///
/// 绘制Item
///
/// Graphics
private void DrawItems(Graphics graphics)
{
foreach (FlowItem item in this._items)
{
this.DrawItem(graphics, item);
}
foreach (FlowItem item in this._items)
{
this.DrawSelectedItem(graphics, item);
}
}
/////
///// 绘制未激活的Item
/////
///// Graphics
//private void DrawStaticItems(Graphics graphics)
//{
// foreach (FlowItem item in this._items)
// {
// // 不绘制激活的item
// if (item.MouseOperating)
// {
// continue;
// }
// this.DrawItem(graphics, item);
// }
//}
/////
///// 绘制激活的Item
/////
///// Graphics
//private void DrawActiveItems(Graphics graphics)
//{
// foreach (FlowItem item in this._items)
// {
// // 绘制激活的item
// if (!item.MouseOperating)
// {
// continue;
// }
// this.DrawItem(graphics, item);
// }
//}
///
/// 绘制图片
///
///
///
///
private void DrawImage(Graphics graphics, Image image, Rectangle rect)
{
graphics.DrawImage(image, rect);
}
///
/// 绘制Item
///
/// Graphics
/// item
private void DrawItem(Graphics graphics, FlowItem item)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
this.DrawNode(graphics, node);
return;
}
if (item is FlowLine)
{
FlowLine line = item as FlowLine;
this.DrawLine(graphics, line);
return;
}
}
///
/// 绘制选中状态Item的附属
///
/// Graphics
/// item
private void DrawSelectedItem(Graphics graphics, FlowItem item)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
this.DrawSelectedNode(graphics, node);
return;
}
if (item is FlowLine)
{
FlowLine line = item as FlowLine;
this.DrawSelectedLine(graphics, line);
return;
}
}
///
/// 绘制节点
///
/// Graphics
/// 节点
private void DrawNode(Graphics graphics, FlowNode node)
{
// 填充颜色
if (node.FillColor.HasValue && node.FillColor != Color.Transparent)
{
this._penDrawNode.Color = node.FillColor.Value;
graphics.FillRectangle(this._penDrawNode.Brush, node.Bounds);
}
// 画图
if (node.NodeImage != null)
{
this.DrawImage(graphics, node.NodeImage, node.Bounds);
}
// 画边框
if (node.BorderWidth > 0 && node.BorderColor != Color.Transparent)
{
this._penDrawNode.Color = node.BorderColor;
this._penDrawNode.Width = node.BorderWidth;
graphics.DrawRectangle(this._penDrawNode, node.Bounds);
}
// 显示名称
if (node.ShowName)
{
Point p5 = this.GetRectBottom(node.Bounds);
SizeF size = graphics.MeasureString(node.Name, node.Font);
this._penDrawString.Color = node.FontColor;
graphics.DrawString(node.Name, node.Font, this._penDrawString.Brush, p5.X - size.Width / 2, p5.Y + Consts.NODE_STRING_MARGIN);
}
// this.DrawSelectedNode(graphics, node);
}
///
/// 绘制选中节点的附属
///
/// Graphics
/// 节点
private void DrawSelectedNode(Graphics graphics, FlowNode node)
{
Rectangle[] rects = node.GetSelectedStyle();
// 画激活状态
if (node.MouseOperating)
{
for (int i = 0; i < rects.Length; i++)
{
bool isAnchor = false;
switch ((NodePointKind)i)
{
case NodePointKind.Top:
if (node.TopLines != null && node.TopLines.Count > 0)
{
isAnchor = true;
}
break;
case NodePointKind.Bottom:
if (node.BottomLines != null && node.BottomLines.Count > 0)
{
isAnchor = true;
}
break;
case NodePointKind.Left:
if (node.LeftLines != null && node.LeftLines.Count > 0)
{
isAnchor = true;
}
break;
case NodePointKind.Right:
if (node.RightLines != null && node.RightLines.Count > 0)
{
isAnchor = true;
}
break;
default:
break;
}
this.DrawSelected(graphics, rects[i], isAnchor, true);
}
}
// 画选择状态
else if (node.Selected)
{
for (int i = 0; i < rects.Length; i++)
{
bool isAnchor = false;
switch ((NodePointKind)i)
{
case NodePointKind.Top:
if (node.TopLines != null && node.TopLines.Count > 0)
{
isAnchor = true;
}
break;
case NodePointKind.Bottom:
if (node.BottomLines != null && node.BottomLines.Count > 0)
{
isAnchor = true;
}
break;
case NodePointKind.Left:
if (node.LeftLines != null && node.LeftLines.Count > 0)
{
isAnchor = true;
}
break;
case NodePointKind.Right:
if (node.RightLines != null && node.RightLines.Count > 0)
{
isAnchor = true;
}
break;
default:
break;
}
this.DrawSelected(graphics, rects[i], isAnchor, false);
}
}
if (node.ShowAnchor)
{
Rectangle[] anchorRects = node.GetAnchorRects();
foreach (Rectangle rect in anchorRects)
{
this.DrawSelected(graphics, rect, true, true);
}
}
}
///
/// 绘制线段
///
/// Graphics
/// 线段
private void DrawLine(Graphics graphics, FlowLine line)
{
this._penDrawLine.Color = line.LineColor;
this._penDrawLine.Width = line.LineWidth;
// 画线段
graphics.DrawLine(this._penDrawLine, line.PointBegin, line.PointEnd);
// 显示名称
if (line.ShowName)
{
Point mp = this.GetLineMidpoint(line.PointBegin, line.PointEnd);
SizeF size = graphics.MeasureString(line.Name, line.Font);
this._penDrawString.Color = line.FontColor;
graphics.DrawString(line.Name, line.Font, this._penDrawString.Brush, mp.X - size.Width / 2, mp.Y - size.Height / 2);
}
// this.DrawSelectedLine(graphics, node);
}
///
/// 绘制选中线段的附属
///
/// Graphics
/// 线段
private void DrawSelectedLine(Graphics graphics, FlowLine line)
{
Rectangle[] rects = line.GetSelectedStyle();
// 画激活状态
if (line.MouseOperating)
{
if (line.NodeBegin != null)
{
if (!line.NodeBegin.Selected)
{
this.DrawSelected(graphics, rects[0], true, true);
}
}
else
{
this.DrawSelected(graphics, rects[0], false, true);
}
if (line.NodeEnd != null)
{
if (!line.NodeEnd.Selected)
{
this.DrawSelected(graphics, rects[1], true, true);
}
}
else
{
this.DrawSelected(graphics, rects[1], false, true);
}
}
// 画选择状态
else if (line.Selected)
{
if (line.NodeBegin != null)
{
if (!line.NodeBegin.Selected)
{
this.DrawSelected(graphics, rects[0], true, false);
}
}
else
{
this.DrawSelected(graphics, rects[0], false, false);
}
if (line.NodeEnd != null)
{
if (!line.NodeEnd.Selected)
{
this.DrawSelected(graphics, rects[1], true, false);
}
}
else
{
this.DrawSelected(graphics, rects[1], false, false);
}
}
}
///
/// 绘制折线
///
///
///
private void DrawPolyline(Graphics graphics, FlowPolyline line)
{
}
///
/// 绘制选择Item的附属
///
///
///
///
///
private void DrawSelected(Graphics graphics, Rectangle rect, bool isAnchor, bool operating)
{
if (operating)
{
if (isAnchor)
{
graphics.FillEllipse(Consts.SELECT_POINT_BRUSH_LINE_TO_NODE, rect);
graphics.DrawEllipse(Consts.SELECT_POINT_PEN, rect);
}
else
{
graphics.FillEllipse(Consts.SELECT_POINT_BRUSH, rect);
graphics.DrawEllipse(Consts.SELECT_POINT_PEN, rect);
}
}
else
{
if (isAnchor)
{
graphics.FillRectangle(Consts.SELECT_POINT_BRUSH_LINE_TO_NODE, rect);
graphics.DrawRectangle(Consts.SELECT_POINT_PEN, rect);
}
else
{
graphics.FillRectangle(Consts.SELECT_POINT_BRUSH, rect);
graphics.DrawRectangle(Consts.SELECT_POINT_PEN, rect);
}
}
}
#endregion 绘制项目
#region 鼠标样式
///
/// 设置鼠标样式
///
///
private void SetCursor(MouseOperatingType type)
{
this._mouseOperatingType = type;
switch (type)
{
case MouseOperatingType.None:
this.CanvasCursor = Cursors.Default;
break;
case MouseOperatingType.RectSelect:
this.CanvasCursor = Cursors.Cross;
break;
case MouseOperatingType.Move:
this.CanvasCursor = Cursors.SizeAll;
break;
case MouseOperatingType.NodeTopAndLeft:
case MouseOperatingType.NodeBottomAndRight:
this.CanvasCursor = Cursors.SizeNWSE;
break;
case MouseOperatingType.NodeTopAndRight:
case MouseOperatingType.NodeBottomAndLeft:
this.CanvasCursor = Cursors.SizeNESW;
break;
case MouseOperatingType.NodeTop:
case MouseOperatingType.NodeBottom:
this.CanvasCursor = Cursors.SizeNS;
break;
case MouseOperatingType.NodeLeft:
case MouseOperatingType.NodeRight:
this.CanvasCursor = Cursors.SizeWE;
break;
case MouseOperatingType.LineBegin:
case MouseOperatingType.LineEnd:
this.CanvasCursor = Cursors.Hand;
break;
case MouseOperatingType.DrawingNode:
this.CanvasCursor = ItemCursor.NodeCursor;
break;
case MouseOperatingType.DrawingLine:
this.CanvasCursor = ItemCursor.LineCursor;
break;
default:
this.CanvasCursor = Cursors.Default;
break;
}
}
///
/// 设置手动画节点时鼠标样式
///
private void SetDrawingNodeCursor()
{
this.SetCursor(MouseOperatingType.DrawingNode);
}
///
/// 设置手动画节点时鼠标样式
///
private void SetDrawingLineCursor()
{
this.SetCursor(MouseOperatingType.DrawingLine);
}
///
/// 设置框选时鼠标样式
///
private void SetRectSelectCursor()
{
this.SetCursor(MouseOperatingType.RectSelect);
}
///
/// 设置默认鼠标样式
///
private void SetDefaultCursor()
{
this.SetCursor(MouseOperatingType.None);
}
///
/// 设置移动时鼠标样式
///
private void SetMoveCursor()
{
this.SetCursor(MouseOperatingType.Move);
}
///
/// 设置改变节点大小时鼠标样式
///
/// 节点端点
private void SetNodeResizeCursor(NodePointKind kind)
{
MouseOperatingType type = MouseOperatingType.None;
switch (kind)
{
case NodePointKind.TopAndLeft:
type = MouseOperatingType.NodeTopAndLeft;
break;
case NodePointKind.TopAndRight:
type = MouseOperatingType.NodeTopAndRight;
break;
case NodePointKind.BottomAndLeft:
type = MouseOperatingType.NodeBottomAndLeft;
break;
case NodePointKind.BottomAndRight:
type = MouseOperatingType.NodeBottomAndRight;
break;
case NodePointKind.Top:
type = MouseOperatingType.NodeTop;
break;
case NodePointKind.Bottom:
type = MouseOperatingType.NodeBottom;
break;
case NodePointKind.Left:
type = MouseOperatingType.NodeLeft;
break;
case NodePointKind.Right:
type = MouseOperatingType.NodeRight;
break;
default:
type = MouseOperatingType.None;
break;
}
this.SetCursor(type);
}
///
/// 设置改变线段端点时鼠标样式
///
/// 线段端点
private void SetLineResizeCursor(LinePointKind kind)
{
MouseOperatingType type = MouseOperatingType.None;
switch (kind)
{
case LinePointKind.Begin:
type = MouseOperatingType.LineBegin;
break;
case LinePointKind.End:
type = MouseOperatingType.LineEnd;
break;
default:
type = MouseOperatingType.None;
break;
}
this.SetCursor(type);
}
///
/// 鼠标移动时,根据鼠标位置设置鼠标样式
///
/// 鼠标位置
private void SetMouseCursorByMove(Point point)
{
this._nodeSizeChanging = null;
this._linePointChanging = null;
// item附属判断
for (int i = this._items.Count - 1; i >= 0; i--)
{
FlowItem item = this._items[i];
if (!item.Selected)
{
continue;
}
Rectangle[] rects = item.GetSelectedStyle();
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
for (int index = 0; index < rects.Length; index++)
{
if (rects[index].Contains(point))
{
NodePointKind kind = (NodePointKind)index;
// 优先操作连接节点的线段
switch (kind)
{
case NodePointKind.Top:
if (!this.CanOperateNode(node.TopLines))
{
continue;
}
break;
case NodePointKind.Bottom:
if (!this.CanOperateNode(node.BottomLines))
{
continue;
}
break;
case NodePointKind.Left:
if (!this.CanOperateNode(node.LeftLines))
{
continue;
}
break;
case NodePointKind.Right:
if (!this.CanOperateNode(node.RightLines))
{
continue;
}
break;
default:
break;
}
this.SetNodeResizeCursor(kind);
this._nodeSizeChanging = node;
return;
}
}
}
if (this._flowBoxMode != FlowBoxMode.Edit)
{
continue;
}
if (item is FlowLine)
{
for (int index = 0; index < rects.Length; index++)
{
if (rects[index].Contains(point))
{
LinePointKind kind = (LinePointKind)index;
this.SetLineResizeCursor(kind);
this._linePointChanging = item as FlowLine;
return;
}
}
}
}
// item内部判断
for (int i = this._items.Count - 1; i >= 0; i--)
{
FlowItem item = this._items[i];
if (!item.Selected)
{
continue;
}
if (item is FlowNode)
{
if (this.IsPointOnNode(point, item as FlowNode))
{
this.SetMoveCursor();
return;
}
}
if (this._flowBoxMode != FlowBoxMode.Edit)
{
continue;
}
if (item is FlowLine)
{
if (this.IsPointOnLine(point, item as FlowLine))
{
this.SetMoveCursor();
return;
}
}
}
this._nodeSizeChanging = null;
this._linePointChanging = null;
this.SetDefaultCursor();
}
#endregion 鼠标样式
#region 流程控制
///
/// 连接PointBegin到节点
///
/// 线段
/// 节点
/// 锚点
private void ConnectL2NPointBegin(FlowLine line, FlowNode node, AnchorKind anchorKind)
{
line.AnchorBegin = anchorKind;
// 连接节点
line.PointBegin = node.GetAnchor(anchorKind);
line.NodeBegin = node;
node.OutLines.Add(line);
switch (anchorKind)
{
case AnchorKind.Top:
node.TopLines.Add(line);
break;
case AnchorKind.Bottom:
node.BottomLines.Add(line);
break;
case AnchorKind.Left:
node.LeftLines.Add(line);
break;
case AnchorKind.Right:
node.RightLines.Add(line);
break;
default:
break;
}
}
///
/// 连接PointEnd到节点
///
/// 线段
/// 节点
/// 锚点
private void ConnectL2NPointEnd(FlowLine line, FlowNode node, AnchorKind anchorKind)
{
line.AnchorEnd = anchorKind;
// 连接节点
line.PointEnd = node.GetAnchor(anchorKind);
line.NodeEnd = node;
node.InLines.Add(line);
switch (anchorKind)
{
case AnchorKind.Top:
node.TopLines.Add(line);
break;
case AnchorKind.Bottom:
node.BottomLines.Add(line);
break;
case AnchorKind.Left:
node.LeftLines.Add(line);
break;
case AnchorKind.Right:
node.RightLines.Add(line);
break;
default:
break;
}
}
///
/// 断开PointBegin的连接
///
/// 线段
private void DisconnectL2NPointBegin(FlowLine line)
{
switch (line.AnchorBegin)
{
case AnchorKind.Top:
line.NodeBegin.TopLines.Remove(line);
break;
case AnchorKind.Bottom:
line.NodeBegin.BottomLines.Remove(line);
break;
case AnchorKind.Left:
line.NodeBegin.LeftLines.Remove(line);
break;
case AnchorKind.Right:
line.NodeBegin.RightLines.Remove(line);
break;
default:
break;
}
line.NodeBegin.OutLines.Remove(line);
line.NodeBegin = null;
line.AnchorBegin = AnchorKind.None;
}
///
/// 断开PointEnd的连接
///
/// 线段
private void DisconnectL2NPointEnd(FlowLine line)
{
switch (line.AnchorEnd)
{
case AnchorKind.Top:
line.NodeEnd.TopLines.Remove(line);
break;
case AnchorKind.Bottom:
line.NodeEnd.BottomLines.Remove(line);
break;
case AnchorKind.Left:
line.NodeEnd.LeftLines.Remove(line);
break;
case AnchorKind.Right:
line.NodeEnd.RightLines.Remove(line);
break;
default:
break;
}
line.NodeEnd.InLines.Remove(line);
line.NodeEnd = null;
line.AnchorEnd = AnchorKind.None;
}
///
/// 获得可连接的节点
///
/// 鼠标位置
/// 可连接的节点
private FlowNode GetL2N(Point point)
{
FlowNode inNode = null;
FlowNode edgeNode = null;
for (int i = this._items.Count - 1; i >= 0; i--)
{
FlowNode node = this._items[i] as FlowNode;
if (node == null)
{
continue;
}
node.ShowAnchor = false;
// 在节点范围内
if (node.Bounds.Contains(point))
{
inNode = node;
}
// 在节点边缘
Rectangle rect = node.Bounds;
rect.Inflate(Consts.L2N_PRECISION_EDGE, Consts.L2N_PRECISION_EDGE);
if (rect.Contains(point))
{
edgeNode = node;
}
}
if (inNode != null)
{
inNode.ShowAnchor = true;
return inNode;
}
if (edgeNode != null)
{
edgeNode.ShowAnchor = true;
return edgeNode;
}
return null;
}
#endregion 流程控制
#region 鼠标操作
///
/// 框选Item
///
/// 框选范围
private void SelectItemByRect(Rectangle rect)
{
this.ClearSelection();
foreach (FlowItem item in this._items)
{
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
if (rect.IntersectsWith(node.Bounds))
{
node.Selected = true;
this._selectedItems.Add(node);
}
else
{
node.Selected = false;
}
continue;
}
if (this._flowBoxMode != FlowBoxMode.Edit)
{
continue;
}
if (item is FlowLine)
{
FlowLine line = item as FlowLine;
if (rect.Contains(line.PointBegin) || rect.Contains(line.PointEnd))
{
line.Selected = true;
this._selectedItems.Add(line);
}
else
{
line.Selected = false;
}
continue;
}
}
}
///
/// 点选Item
///
/// 鼠标点
/// 选中的item
private FlowItem SelectItemByPoint(Point point)
{
for (int i = this._items.Count - 1; i >= 0; i--)
{
FlowItem item = this._items[i];
if (item is FlowNode)
{
if (this.IsPointOnNode(point, item as FlowNode))
{
return item;
}
}
if (this._flowBoxMode != FlowBoxMode.Edit)
{
continue;
}
if (item is FlowLine)
{
if (this.IsPointOnLine(point, item as FlowLine))
{
return item;
}
}
//if (item is FlowPolyline)
//{
// if (this.IsPointOnPolyLine(point, item as FlowPolyline))
// {
// return item;
// }
//}
}
return null;
}
///
/// 点选节点
///
/// 鼠标点
/// 选中的节点
private FlowNode SelectNodeByPoint(Point point)
{
for (int i = this._items.Count - 1; i >= 0; i--)
{
FlowItem item = this._items[i];
if (item is FlowNode)
{
FlowNode node = item as FlowNode;
if (this.IsPointOnNode(point, node))
{
return node;
}
}
}
return null;
}
///
/// 能否操作节点(鼠标在锚点)
///
/// 连接的线段
/// 能否操作节点
private bool CanOperateNode(List lines)
{
if (lines != null && lines.Count > 0)
{
foreach (FlowLine line in lines)
{
if (line.Selected)
{
return false;
}
}
}
return true;
}
#endregion 鼠标操作
#region 工具
///
/// 判断线段是否相交
///
/// 线段1的开始点
/// 线段1的结束点
/// 线段2的开始点
/// 线段2的结束点
/// 是否相交
private bool IsSegmentIntersect(Point p1, Point p2, Point p3, Point p4)
{
double d1 = this.GetDirection(p3, p4, p1);
double d2 = this.GetDirection(p3, p4, p2);
double d3 = this.GetDirection(p1, p2, p3);
double d4 = this.GetDirection(p1, p2, p4);
if (d1 * d2 < 0 && d3 * d4 < 0)
{
return true;
}
else if (d1 == 0 && this.IsOnSegment(p3, p4, p1))
{
return true;
}
else if (d2 == 0 && this.IsOnSegment(p3, p4, p2))
{
return true;
}
else if (d3 == 0 && this.IsOnSegment(p1, p2, p3))
{
return true;
}
else if (d4 == 0 && this.IsOnSegment(p1, p2, p4))
{
return true;
}
else
{
return false;
}
}
///
/// 获取点1到点2和点3的向量的叉乘
///
/// 点1
/// 点2
/// 点3
///
private int GetDirection(Point p1, Point p2, Point p3)
{
Point v1 = new Point(p3.X - p1.X, p3.Y - p1.Y);
Point v2 = new Point(p2.X - p1.X, p2.Y - p1.Y);
return v1.X * v2.Y - v1.Y * v2.X;
}
///
/// 点3在线上时,判断点3在线段上,还是在线段的延长线上
///
/// 线段的开始点
/// 线段的结束点
/// 点3
///
private bool IsOnSegment(Point p1, Point p2, Point p3)
{
int x_min, x_max, y_min, y_max;
if (p1.X < p2.X)
{
x_min = p1.X;
x_max = p2.X;
}
else
{
x_min = p2.X;
x_max = p1.X;
}
if (p1.Y < p2.Y)
{
y_min = p1.Y;
y_max = p2.Y;
}
else
{
y_min = p2.Y;
y_max = p1.Y;
}
if (p3.X < x_min || p3.X > x_max || p3.Y < y_min || p3.Y > y_max)
{
return false;
}
else
{
return true;
}
}
///
/// 点是否在节点上
///
/// 点
/// 节点
/// 是否在节点上
private bool IsPointOnNode(Point point, FlowNode node)
{
return node.Bounds.Contains(point);
}
///
/// 点是否在线段上
///
/// 点
/// 线段
/// 否在线段上
private bool IsPointOnLine(Point point, FlowLine line)
{
double p2ls = this.GetP2LSDistance(point, line.PointBegin, line.PointEnd);
//if (p2ls <= (line.LineWidth - 1) / 2 + Consts.P2L_PRECISION)
if (p2ls <= (line.LineWidth) / 2 + Consts.P2L_PRECISION)
{
return true;
}
return false;
}
///
/// 获取点到线段的距离
///
/// 点
/// 线段的端点
/// 线段的端点
/// 点到线段的距离
private double GetP2LSDistance(Point p, Point pBegin, Point pEnd)
{
// 点在线段端点
double pp1 = this.GetP2PDistance(p, pBegin);
if (pp1 < Consts.DOUBLE_PRECISION)
{
return pp1;
}
double pp2 = this.GetP2PDistance(p, pEnd);
if (pp2 < Consts.DOUBLE_PRECISION)
{
return pp2;
}
double p1p2 = this.GetP2PDistance(pBegin, pEnd);
// 线段端点相同
if (p1p2 < Consts.DOUBLE_PRECISION)
{
return pp1;
}
// 点在线段端点外
double pp12 = pp1 * pp1;
double pp22 = pp2 * pp2;
double p1p22 = p1p2 * p1p2;
if (pp12 >= pp22 + p1p22)
{
return pp22;
}
if (pp22 >= pp12 + p1p22)
{
return pp12;
}
// 点在线段端点内
// 周长的一半
double l = (pp1 + pp2 + p1p2) / 2;
// 海伦公式求面积,也可以用矢量求
double s = Math.Sqrt(l * (l - pp1) * (l - pp2) * (l - p1p2));
return 2 * s / p1p2;
}
///
/// 获取两点间的距离
///
///
///
/// 两点间的距离
private double GetP2PDistance(Point point1, Point point2)
{
return Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y));
}
///
/// 获取鼠标操作后的新范围
///
/// 源范围
/// 固定点
/// 移动点
/// 新范围
private Rectangle GetNewRect(Rectangle rect, Point fixedPoint, Point newPoint)
{
int xRect = newPoint.X - fixedPoint.X;
int yRect = newPoint.Y - fixedPoint.Y;
if (xRect < 0)
{
rect.X = newPoint.X;
rect.Width = -xRect;
}
else
{
rect.X = fixedPoint.X;
rect.Width = xRect;
}
if (yRect < 0)
{
rect.Y = newPoint.Y;
rect.Height = -yRect;
}
else
{
rect.Y = fixedPoint.Y;
rect.Height = yRect;
}
return rect;
}
///
/// 获取鼠标操作后的新范围
///
/// 源范围
/// 固定点
/// x方向移动距离
/// y方向移动距离
/// 新范围
private Rectangle GetNewRect(Rectangle rect, Point fixedPoint, int xRect, int yRect)
{
if (xRect < 0)
{
rect.X = fixedPoint.X + xRect;
rect.Width = -xRect;
}
else
{
rect.X = fixedPoint.X;
rect.Width = xRect;
}
if (yRect < 0)
{
rect.Y = fixedPoint.Y + yRect;
rect.Height = -yRect;
}
else
{
rect.Y = fixedPoint.Y;
rect.Height = yRect;
}
return rect;
}
///
/// 获得矩形的左上角
///
/// 矩形
/// 左上角
private Point GetRectTopAndLeft(Rectangle rect)
{
return rect.Location;
}
///
/// 获得矩形的右上角
///
/// 矩形
/// 右上角
private Point GetRectTopAndRight(Rectangle rect)
{
return new Point(rect.Right, rect.Top);
}
///
/// 获得矩形的左下角
///
/// 矩形
/// 左下角
private Point GetRectBottomAndLeft(Rectangle rect)
{
return new Point(rect.Left, rect.Bottom);
}
///
/// 获得矩形的右下角
///
/// 矩形
/// 右下角
private Point GetRectBottomAndRight(Rectangle rect)
{
return new Point(rect.Right, rect.Bottom);
}
///
/// 获得矩形的上中点
///
/// 矩形
/// 上中点
private Point GetRectTop(Rectangle rect)
{
return new Point(rect.Left + rect.Width / 2, rect.Top);
}
///
/// 获得矩形的下中点
///
/// 矩形
/// 下中点
private Point GetRectBottom(Rectangle rect)
{
return new Point(rect.Left + rect.Width / 2, rect.Bottom);
}
///
/// 获得矩形的左中点
///
/// 矩形
/// 左中点
private Point GetRectLeft(Rectangle rect)
{
return new Point(rect.Left, rect.Top + rect.Height / 2);
}
///
/// 获得矩形的右中点
///
/// 矩形
/// 右中点
private Point GetRectRight(Rectangle rect)
{
return new Point(rect.Right, rect.Top + rect.Height / 2);
}
///
/// 获得线段的中点
///
/// 线段开始点
/// 线段结束点
/// 中点
private Point GetLineMidpoint(Point pointBegin, Point pointEnd)
{
return new Point((pointBegin.X + pointEnd.X) / 2, (pointBegin.Y + pointEnd.Y) / 2);
}
#endregion 工具
#endregion 私有方法
}
}