| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174 |
-
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Windows.Forms;
- namespace Dongke.IBOSS.Basics.FlowSetting
- {
- /// <summary>
- /// 流程项目绘制管理器
- /// </summary>
- internal class ItemManager
- {
- #region 成员变量
- /// <summary>
- /// 流程项目自增ID
- /// </summary>
- private int _newItemID = 0;
- /// <summary>
- /// 管理器编码
- /// </summary>
- private string _managerCode = Guid.NewGuid().ToString().ToUpper();
- /// <summary>
- /// 画板
- /// </summary>
- private CanvasBox _canvasBox = null;
- /// <summary>
- /// 流程设计器
- /// </summary>
- private FlowBox _flowBox = null;
- /// <summary>
- /// 画布控件
- /// </summary>
- private Control _canvasControl = null;
- /// <summary>
- /// 流程编辑模式
- /// </summary>
- private FlowBoxMode _flowBoxMode = FlowBoxMode.Edit;
- #region 项目集合
- // todo 自定义 list 管理 外部不能add,remove只能get,可以通过,itemid,onlycode,itemindex(显示顺序)取得。
- /// <summary>
- /// 全部流程项目
- /// </summary>
- private List<FlowItem> _items = new List<FlowItem>();
- /// <summary>
- /// 选中的流程项目
- /// </summary>
- private List<FlowItem> _selectedItems = new List<FlowItem>();
- ///// <summary>
- ///// 删除的流程项目
- ///// </summary>
- //private List<FlowItem> _deletedItems = new List<FlowItem>();
- ///// <summary>
- ///// 选中的流程节点
- ///// </summary>
- //private List<FlowNode> _selectedNodes = new List<FlowNode>();
- /// <summary>
- /// 全部流程节点
- /// </summary>
- private List<FlowNode> _allNodes = new List<FlowNode>();
- /// <summary>
- /// 删除的流程项目
- /// </summary>
- private List<FlowNode> _deletedNodes = new List<FlowNode>();
- #endregion 项目集合
- #region 新建项目
- /// <summary>
- /// 鼠标操作,指定位置,新建Item
- /// </summary>
- private FlowItem _drawingItem = null;
- /// <summary>
- /// 鼠标操作,指定位置,新建节点
- /// </summary>
- private FlowNode _drawingNode = null;
- /// <summary>
- /// 鼠标操作,指定位置,新建线段
- /// </summary>
- private FlowLine _drawingLine = null;
- #endregion 新建项目
- #region 鼠标操作
- /// <summary>
- /// 鼠标动作
- /// </summary>
- private MouseOperatingType _mouseOperatingType = MouseOperatingType.None;
- /// <summary>
- /// 鼠标框选范围
- /// </summary>
- private Rectangle _mouseSelectRect = Rectangle.Empty;
- /// <summary>
- /// 鼠标按下的点
- /// </summary>
- private Point _mouseDownPoint = Point.Empty;
- /// <summary>
- /// 鼠标移动的点
- /// </summary>
- private Point _mouseMovePoint = Point.Empty;
- /// <summary>
- /// 鼠标抬起的点
- /// </summary>
- private Point _mouseUpPoint = Point.Empty;
- /// <summary>
- /// 鼠标是否按下
- /// </summary>
- private bool _isMouseDown = false;
- /// <summary>
- /// 鼠标是否移动
- /// </summary>
- private bool _isMouseMove = false;
- /// <summary>
- /// 鼠标是否抬起
- /// </summary>
- private bool _isMouseUp = false;
- /// <summary>
- /// 进行改变大小操作的节点
- /// </summary>
- private FlowNode _nodeSizeChanging = null;
- /// <summary>
- /// 进行改变大小操作的线段
- /// </summary>
- private FlowLine _linePointChanging = null;
- /// <summary>
- /// 正在显示锚点的节点
- /// </summary>
- private FlowNode _nodeAnchorShowing = null;
- #endregion 鼠标操作
- #region 绘制项目
- // TODO 使用后销毁??
- /// <summary>
- /// 画节点笔
- /// </summary>
- private Pen _penDrawNode = new Pen(Consts.NODE_BORDERCOLOR_DEFAULT);
- /// <summary>
- /// 画线段笔
- /// </summary>
- private Pen _penDrawLine = new Pen(Consts.LINE_COLOR_DEFAULT, Consts.LINE_WIDTH_DEFAULT);
- /// <summary>
- /// 写字笔
- /// </summary>
- private Pen _penDrawString = new Pen(Consts.FONT_COLOR_DEFAULT);
- #endregion 绘制项目
- #endregion 成员变量
- private StringFormat _stringFormat = new StringFormat();
- #region 构造函数
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="flowBox">流程设计器</param>
- /// <param name="canvasBox">画板</param>
- internal ItemManager(FlowBox flowBox, CanvasBox canvasBox)
- {
- _stringFormat.Alignment = StringAlignment.Center;
- _stringFormat.LineAlignment = StringAlignment.Near;
- _stringFormat.FormatFlags = StringFormatFlags.FitBlackBox;
- 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 属性
- /// <summary>
- /// 获取全部流程项目
- /// </summary>
- public List<FlowItem> Items
- {
- get
- {
- return this._items;
- }
- }
- /// <summary>
- /// 获取选择的流程项目
- /// </summary>
- public List<FlowItem> SelectedItems
- {
- get
- {
- return this._selectedItems;
- }
- }
- /// <summary>
- /// 获取删除的节点
- /// </summary>
- public List<FlowNode> DeletedNodes
- {
- get
- {
- return this._deletedNodes;
- }
- }
- /// <summary>
- /// 获取全部的节点(包括删除的)
- /// </summary>
- public List<FlowNode> AllNodes
- {
- get
- {
- return this._allNodes;
- }
- }
- /// <summary>
- /// 获取或设置管理器编码
- /// </summary>
- internal string ManagerCode
- {
- get
- {
- return this._managerCode;
- }
- set
- {
- this._managerCode = value;
- }
- }
- /// <summary>
- /// 获取或设置流程编辑模式
- /// </summary>
- internal FlowBoxMode BoxMode
- {
- get
- {
- return this._flowBoxMode;
- }
- set
- {
- this._flowBoxMode = value;
- }
- }
- /// <summary>
- /// 获取或设置新的itemID
- /// </summary>
- internal int NewItemID
- {
- get
- {
- return ++this._newItemID;
- }
- }
- /// <summary>
- /// 获取或设置画板的鼠标样式
- /// </summary>
- private Cursor CanvasCursor
- {
- get
- {
- return this._canvasControl.Cursor;
- }
- set
- {
- this._canvasControl.Cursor = value;
- }
- }
- #endregion 属性
- #region 公有方法
- #region 新建项目
- /// <summary>
- /// 停止新建节点(鼠标操作)
- /// </summary>
- public void StopDrawingItem()
- {
- this._drawingItem = null;
- this._drawingNode = null;
- this._drawingLine = null;
- this.SetDefaultCursor();
- }
- /// <summary>
- /// 新建节点(鼠标操作,指定位置)
- /// </summary>
- public FlowNode DrawingNode()
- {
- this._drawingNode = new FlowNode(this);
- this._drawingLine = null;
- this._drawingItem = this._drawingNode;
- this.SetDrawingNodeCursor();
- return this._drawingNode;
- }
- /// <summary>
- /// 新建线段(鼠标操作,指定位置)
- /// </summary>
- public FlowLine DrawingLine()
- {
- this._drawingNode = null;
- this._drawingLine = new FlowLine(this);
- this._drawingItem = this._drawingLine;
- this.SetDrawingLineCursor();
- return this._drawingLine;
- }
- /// <summary>
- /// 新建节点(默认位置)
- /// </summary>
- /// <returns>节点</returns>
- public FlowNode NewNode()
- {
- this._drawingItem = null;
- this._drawingNode = null;
- this._drawingLine = null;
- return this.NewNodeInternal(null);
- }
- /// <summary>
- /// 新建节点(指定位置)
- /// </summary>
- /// <param name="location">节点位置</param>
- public FlowNode NewNode(Point location)
- {
- this._drawingItem = null;
- this._drawingNode = null;
- this._drawingLine = null;
- return this.NewNodeInternal(location);
- }
- /// <summary>
- /// 新建线段(默认位置)
- /// </summary>
- /// <returns>线段</returns>
- public FlowLine NewLine()
- {
- this._drawingItem = null;
- this._drawingNode = null;
- this._drawingLine = null;
- return this.NewLineInternal(null, null);
- }
- /// <summary>
- /// 新建线段(指定位置)
- /// </summary>
- /// <param name="pointBegin">起始点</param>
- /// <param name="pointEnd">结束点</param>
- /// <returns>线段</returns>
- public FlowLine NewLine(Point pointBegin, Point pointEnd)
- {
- this._drawingItem = null;
- this._drawingNode = null;
- this._drawingLine = null;
- return this.NewLineInternal(pointBegin, pointEnd);
- }
- #endregion 新建项目
- #region 刷项目
- ///// <summary>
- ///// 刷新未激活Item的图片
- ///// </summary>
- //public void RefreshStaticItems()
- //{
- // // 清除画布
- // Graphics graphics = this._canvasBox.Canvas;
- // graphics.Clear(Color.Transparent);
- // // 绘制未激活的Item
- // this.DrawStaticItems(graphics);
- // // 设定未激活的Item为图片
- // this._canvasBox.SetItemsImage(this._canvasBox.CanvasImage);
- //}
- ///// <summary>
- ///// 刷新激活Item的图片
- ///// </summary>
- //public void RefreshActiveItems()
- //{
- // // 清除画布
- // Graphics graphics = this._canvasBox.Canvas;
- // graphics.Clear(Color.Transparent);
- // // 绘制激活的Item
- // this.DrawActiveItems(graphics);
- // // 设定未激活的Item为图片
- // this._canvasBox.SetItemsImage(this._canvasBox.CanvasImage);
- //}
- ///// <summary>
- ///// 刷新激活Item
- ///// </summary>
- ///// <param name="graphics"></param>
- //public void RefreshActiveItems(Graphics graphics)
- //{
- // // todo 在paint绘制事件中绘制激活的item,未激活item作为背景
- // // 绘制激活的Item
- // this.DrawActiveItems(graphics);
- //}
- /// <summary>
- /// 刷新Item的图片
- /// </summary>
- 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 操作项目
- /// <summary>
- /// 全部不选择
- /// </summary>
- public void ClearSelection()
- {
- foreach (FlowItem item in this._selectedItems)
- {
- item.MouseOperating = false;
- item.Selected = false;
- }
- this._selectedItems.Clear();
- }
- /// <summary>
- /// 全部选择
- /// </summary>
- public void SelectAllItems()
- {
- foreach (FlowItem item in this._items)
- {
- if (!item.Selected)
- {
- this._selectedItems.Add(item);
- item.Selected = true;
- }
- }
- }
- /// <summary>
- /// 删除全部项目
- /// </summary>
- 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();
- }
- /// <summary>
- /// 删除选择项目
- /// </summary>
- 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();
- }
- /// <summary>
- /// 对齐选定的节点
- /// </summary>
- /// <param name="arrangeType">对齐方式</param>
- 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;
- }
- }
- /// <summary>
- /// 顶部对齐所有选中的节点
- /// </summary>
- 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;
- }
- }
- }
- /// <summary>
- /// 底部对齐所有选中的节点
- /// </summary>
- public void ArrangeNodesBottom()
- {
- }
- /// <summary>
- /// 左侧对齐所有选中的节点
- /// </summary>
- public void ArrangeNodesLeft()
- {
- }
- /// <summary>
- /// 右侧对齐所有选中的节点
- /// </summary>
- public void ArrangeNodesRight()
- {
- }
- /// <summary>
- /// 垂直方向中心对齐所有选中的节点
- /// </summary>
- public void ArrangeNodesVerticalCenter()
- {
- }
- /// <summary>
- /// 水平方向中心对齐所有选中的节点
- /// </summary>
- public void ArrangeNodesHorizontalCenter()
- {
- }
- #endregion 操作项目
- #endregion 公有方法
- #region 内部方法
- /// <summary>
- /// 获取新ItemID(用于流程保存)
- /// </summary>
- /// <returns>ItemID</returns>
- internal int GetNewItemID()
- {
- return this._newItemID;
- }
- /// <summary>
- /// 设置新ItemID(用于流程读取)
- /// </summary>
- /// <param name="itemID">ItemID</param>
- internal void SetNewItemID(int itemID)
- {
- this._newItemID = itemID;
- }
- #region 刷新项目
- /// <summary>
- /// 刷新鼠标框选范围
- /// </summary>
- internal void RefreshMouseSelectRect(Graphics graphics)
- {
- if (this._mouseOperatingType == MouseOperatingType.RectSelect)
- {
- ControlPaint.DrawFocusRectangle(graphics, this._mouseSelectRect,
- this._canvasControl.BackColor, Color.Transparent);
- }
- }
- #endregion 刷新项目
- #region 鼠标操作
- /// <summary>
- /// 处理鼠标按下事件
- /// </summary>
- /// <param name="e"></param>
- 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;
- }
- }
- /// <summary>
- /// 处理鼠标移动事件
- /// </summary>
- /// <param name="e"></param>
- 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();
- }
- }
- /// <summary>
- /// 处理鼠标抬起事件
- /// </summary>
- /// <param name="e"></param>
- 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();
- }
- }
- /// <summary>
- /// 鼠标双击
- /// </summary>
- /// <param name="e"></param>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 移动选择的项目
- /// </summary>
- /// <param name="xMove">X轴的移动量</param>
- /// <param name="yMove">Y轴的移动量</param>
- 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 新建项目
- /// <summary>
- /// 新建节点
- /// </summary>
- /// <param name="location">节点位置</param>
- /// <returns>节点</returns>
- 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;
- }
- /// <summary>
- /// 新建线段
- /// </summary>
- /// <param name="pointBegin">起始点</param>
- /// <param name="pointEnd">结算点</param>
- /// <returns>线段</returns>
- 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 绘制项目
- /// <summary>
- /// 绘制Item
- /// </summary>
- /// <param name="graphics">Graphics</param>
- private void DrawItems(Graphics graphics)
- {
- foreach (FlowItem item in this._items)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!item.IsShow)
- {
- continue;
- }
- this.DrawItem(graphics, item);
- }
- foreach (FlowItem item in this._items)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!item.IsShow)
- {
- continue;
- }
- this.DrawSelectedItem(graphics, item);
- }
- }
- ///// <summary>
- ///// 绘制未激活的Item
- ///// </summary>
- ///// <param name="graphics">Graphics</param>
- //private void DrawStaticItems(Graphics graphics)
- //{
- // foreach (FlowItem item in this._items)
- // {
- // // 不绘制激活的item
- // if (item.MouseOperating)
- // {
- // continue;
- // }
- // this.DrawItem(graphics, item);
- // }
- //}
- ///// <summary>
- ///// 绘制激活的Item
- ///// </summary>
- ///// <param name="graphics">Graphics</param>
- //private void DrawActiveItems(Graphics graphics)
- //{
- // foreach (FlowItem item in this._items)
- // {
- // // 绘制激活的item
- // if (!item.MouseOperating)
- // {
- // continue;
- // }
- // this.DrawItem(graphics, item);
- // }
- //}
- /// <summary>
- /// 绘制图片
- /// </summary>
- /// <param name="graphics"></param>
- /// <param name="image"></param>
- /// <param name="rect"></param>
- private void DrawImage(Graphics graphics, Image image, Rectangle rect)
- {
- graphics.DrawImage(image, rect);
- }
- /// <summary>
- /// 绘制Item
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="item">item</param>
- private void DrawItem(Graphics graphics, FlowItem item)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!item.IsShow)
- {
- return;
- }
- 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;
- }
- }
- /// <summary>
- /// 绘制选中状态Item的附属
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="item">item</param>
- private void DrawSelectedItem(Graphics graphics, FlowItem item)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!item.IsShow)
- {
- return;
- }
- 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;
- }
- }
- /// <summary>
- /// 绘制节点
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="node">节点</param>
- private void DrawNode(Graphics graphics, FlowNode node)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!node.IsShow)
- {
- return;
- }
- // 填充颜色
- 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);
- int mm = 40;
- int mh = 20; // mm / 2;
- int ww = node.Bounds.Width + mm;
- int xx = node.Bounds.X - mh;
- SizeF size = graphics.MeasureString(node.Name, node.Font, ww, _stringFormat);
- 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);
- RectangleF ff = new RectangleF(xx, (float)(node.Bounds.Bottom + Consts.NODE_STRING_MARGIN), ww, size.Height);
- string nn = node.ShortName;
- if (string.IsNullOrEmpty(nn))
- {
- nn = node.Name;
- }
- /*
- int ida = nn.IndexOf('-');
- if (ida > 0)
- {
- nn = nn.Substring(ida + 1);
- ida = nn.IndexOf('-');
- if (ida > 0)
- {
- nn = nn.Substring(ida + 1);
- }
- }
- */
- graphics.DrawString(nn, node.Font, this._penDrawString.Brush, ff, _stringFormat);
- }
- // this.DrawSelectedNode(graphics, node);
- }
- /// <summary>
- /// 绘制选中节点的附属
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="node">节点</param>
- private void DrawSelectedNode(Graphics graphics, FlowNode node)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!node.IsShow)
- {
- return;
- }
- 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);
- }
- }
- }
- /// <summary>
- /// 绘制线段
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="line">线段</param>
- private void DrawLine(Graphics graphics, FlowLine line)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!line.IsShow)
- {
- return;
- }
- 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);
- }
- /// <summary>
- /// 绘制选中线段的附属
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="line">线段</param>
- private void DrawSelectedLine(Graphics graphics, FlowLine line)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!line.IsShow)
- {
- return;
- }
- 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);
- }
- }
- }
- /// <summary>
- /// 绘制折线
- /// </summary>
- /// <param name="graphics"></param>
- /// <param name="line"></param>
- private void DrawPolyline(Graphics graphics, FlowPolyline line)
- {
- }
- /// <summary>
- /// 绘制选择Item的附属
- /// </summary>
- /// <param name="graphics"></param>
- /// <param name="rect"></param>
- /// <param name="isAnchor"></param>
- /// <param name="operating"></param>
- 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 鼠标样式
- /// <summary>
- /// 设置鼠标样式
- /// </summary>
- /// <param name="type"></param>
- 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;
- }
- }
- /// <summary>
- /// 设置手动画节点时鼠标样式
- /// </summary>
- private void SetDrawingNodeCursor()
- {
- this.SetCursor(MouseOperatingType.DrawingNode);
- }
- /// <summary>
- /// 设置手动画节点时鼠标样式
- /// </summary>
- private void SetDrawingLineCursor()
- {
- this.SetCursor(MouseOperatingType.DrawingLine);
- }
- /// <summary>
- /// 设置框选时鼠标样式
- /// </summary>
- private void SetRectSelectCursor()
- {
- this.SetCursor(MouseOperatingType.RectSelect);
- }
- /// <summary>
- /// 设置默认鼠标样式
- /// </summary>
- private void SetDefaultCursor()
- {
- this.SetCursor(MouseOperatingType.None);
- }
- /// <summary>
- /// 设置移动时鼠标样式
- /// </summary>
- private void SetMoveCursor()
- {
- this.SetCursor(MouseOperatingType.Move);
- }
- /// <summary>
- /// 设置改变节点大小时鼠标样式
- /// </summary>
- /// <param name="kind">节点端点</param>
- 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);
- }
- /// <summary>
- /// 设置改变线段端点时鼠标样式
- /// </summary>
- /// <param name="kind">线段端点</param>
- 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);
- }
- /// <summary>
- /// 鼠标移动时,根据鼠标位置设置鼠标样式
- /// </summary>
- /// <param name="point">鼠标位置</param>
- 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 流程控制
- /// <summary>
- /// 连接PointBegin到节点
- /// </summary>
- /// <param name="line">线段</param>
- /// <param name="node">节点</param>
- /// <param name="anchorKind">锚点</param>
- private void ConnectL2NPointBegin(FlowLine line, FlowNode node, AnchorKind anchorKind)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!node.IsShow)
- {
- return;
- }
- 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;
- }
- }
- /// <summary>
- /// 连接PointEnd到节点
- /// </summary>
- /// <param name="line">线段</param>
- /// <param name="node">节点</param>
- /// <param name="anchorKind">锚点</param>
- private void ConnectL2NPointEnd(FlowLine line, FlowNode node, AnchorKind anchorKind)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!node.IsShow)
- {
- return;
- }
- 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;
- }
- }
- /// <summary>
- /// 断开PointBegin的连接
- /// </summary>
- /// <param name="line">线段</param>
- 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;
- }
- /// <summary>
- /// 断开PointEnd的连接
- /// </summary>
- /// <param name="line">线段</param>
- 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;
- }
- /// <summary>
- /// 获得可连接的节点
- /// </summary>
- /// <param name="point">鼠标位置</param>
- /// <returns>可连接的节点</returns>
- 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;
- // 不显示无效节点 2024-11-27 by chenxy
- if (node == null)
- {
- continue;
- }
- if (!node.IsShow)
- {
- 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 鼠标操作
- /// <summary>
- /// 框选Item
- /// </summary>
- /// <param name="rect">框选范围</param>
- private void SelectItemByRect(Rectangle rect)
- {
- this.ClearSelection();
- foreach (FlowItem item in this._items)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!item.IsShow)
- {
- continue;
- }
- 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;
- }
- }
- }
- /// <summary>
- /// 点选Item
- /// </summary>
- /// <param name="point">鼠标点</param>
- /// <returns>选中的item</returns>
- private FlowItem SelectItemByPoint(Point point)
- {
- for (int i = this._items.Count - 1; i >= 0; i--)
- {
- FlowItem item = this._items[i];
- // 不显示无效节点 2024-11-27 by chenxy
- if (!item.IsShow)
- {
- continue;
- }
- 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;
- }
- /// <summary>
- /// 点选节点
- /// </summary>
- /// <param name="point">鼠标点</param>
- /// <returns>选中的节点</returns>
- 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;
- // 不显示无效节点 2024-11-27 by chenxy
- if (!item.IsShow)
- {
- continue;
- }
- if (this.IsPointOnNode(point, node))
- {
- return node;
- }
- }
- }
- return null;
- }
- /// <summary>
- /// 能否操作节点(鼠标在锚点)
- /// </summary>
- /// <param name="lines">连接的线段</param>
- /// <returns>能否操作节点</returns>
- private bool CanOperateNode(List<FlowLine> lines)
- {
- if (lines != null && lines.Count > 0)
- {
- foreach (FlowLine line in lines)
- {
- if (line.Selected)
- {
- return false;
- }
- }
- }
- return true;
- }
- #endregion 鼠标操作
- #region 工具
- /// <summary>
- /// 判断线段是否相交
- /// </summary>
- /// <param name="p1">线段1的开始点</param>
- /// <param name="p2">线段1的结束点</param>
- /// <param name="p3">线段2的开始点</param>
- /// <param name="p4">线段2的结束点</param>
- /// <returns>是否相交</returns>
- 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;
- }
- }
- /// <summary>
- /// 获取点1到点2和点3的向量的叉乘
- /// </summary>
- /// <param name="p1">点1</param>
- /// <param name="p2">点2</param>
- /// <param name="p3">点3</param>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 点3在线上时,判断点3在线段上,还是在线段的延长线上
- /// </summary>
- /// <param name="p1">线段的开始点</param>
- /// <param name="p2">线段的结束点</param>
- /// <param name="p3">点3</param>
- /// <returns></returns>
- 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;
- }
- }
- /// <summary>
- /// 点是否在节点上
- /// </summary>
- /// <param name="point">点</param>
- /// <param name="node">节点</param>
- /// <returns>是否在节点上</returns>
- private bool IsPointOnNode(Point point, FlowNode node)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!node.IsShow)
- {
- return false;
- }
- return node.Bounds.Contains(point);
- }
- /// <summary>
- /// 点是否在线段上
- /// </summary>
- /// <param name="point">点</param>
- /// <param name="line">线段</param>
- /// <returns>否在线段上</returns>
- private bool IsPointOnLine(Point point, FlowLine line)
- {
- // 不显示无效节点 2024-11-27 by chenxy
- if (!line.IsShow)
- {
- return false;
- }
- 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;
- }
- /// <summary>
- /// 获取点到线段的距离
- /// </summary>
- /// <param name="p">点</param>
- /// <param name="pBegin">线段的端点</param>
- /// <param name="pEnd">线段的端点</param>
- /// <returns>点到线段的距离</returns>
- 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;
- }
- /// <summary>
- /// 获取两点间的距离
- /// </summary>
- /// <param name="point1"></param>
- /// <param name="point2"></param>
- /// <returns>两点间的距离</returns>
- 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));
- }
- /// <summary>
- /// 获取鼠标操作后的新范围
- /// </summary>
- /// <param name="rect">源范围</param>
- /// <param name="fixedPoint">固定点</param>
- /// <param name="newPoint">移动点</param>
- /// <returns>新范围</returns>
- 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;
- }
- /// <summary>
- /// 获取鼠标操作后的新范围
- /// </summary>
- /// <param name="rect">源范围</param>
- /// <param name="fixedPoint">固定点</param>
- /// <param name="xRect">x方向移动距离</param>
- /// <param name="yRect">y方向移动距离</param>
- /// <returns>新范围</returns>
- 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;
- }
- /// <summary>
- /// 获得矩形的左上角
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>左上角</returns>
- private Point GetRectTopAndLeft(Rectangle rect)
- {
- return rect.Location;
- }
- /// <summary>
- /// 获得矩形的右上角
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>右上角</returns>
- private Point GetRectTopAndRight(Rectangle rect)
- {
- return new Point(rect.Right, rect.Top);
- }
- /// <summary>
- /// 获得矩形的左下角
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>左下角</returns>
- private Point GetRectBottomAndLeft(Rectangle rect)
- {
- return new Point(rect.Left, rect.Bottom);
- }
- /// <summary>
- /// 获得矩形的右下角
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>右下角</returns>
- private Point GetRectBottomAndRight(Rectangle rect)
- {
- return new Point(rect.Right, rect.Bottom);
- }
- /// <summary>
- /// 获得矩形的上中点
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>上中点</returns>
- private Point GetRectTop(Rectangle rect)
- {
- return new Point(rect.Left + rect.Width / 2, rect.Top);
- }
- /// <summary>
- /// 获得矩形的下中点
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>下中点</returns>
- private Point GetRectBottom(Rectangle rect)
- {
- return new Point(rect.Left + rect.Width / 2, rect.Bottom);
- }
- /// <summary>
- /// 获得矩形的左中点
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>左中点</returns>
- private Point GetRectLeft(Rectangle rect)
- {
- return new Point(rect.Left, rect.Top + rect.Height / 2);
- }
- /// <summary>
- /// 获得矩形的右中点
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>右中点</returns>
- private Point GetRectRight(Rectangle rect)
- {
- return new Point(rect.Right, rect.Top + rect.Height / 2);
- }
- /// <summary>
- /// 获得线段的中点
- /// </summary>
- /// <param name="pointBegin">线段开始点</param>
- /// <param name="pointEnd">线段结束点</param>
- /// <returns>中点</returns>
- private Point GetLineMidpoint(Point pointBegin, Point pointEnd)
- {
- return new Point((pointBegin.X + pointEnd.X) / 2, (pointBegin.Y + pointEnd.Y) / 2);
- }
- #endregion 工具
- #endregion 私有方法
- }
- }
|