| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062 |
-
- 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();
- /// <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 成员变量
- #region 构造函数
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="flowBox">流程设计器</param>
- /// <param name="canvasBox">画板</param>
- 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 属性
- /// <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)
- {
- this.DrawItem(graphics, item);
- }
- foreach (FlowItem item in this._items)
- {
- 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)
- {
- 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)
- {
- 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)
- {
- // 填充颜色
- 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);
- }
- /// <summary>
- /// 绘制选中节点的附属
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="node">节点</param>
- 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);
- }
- }
- }
- /// <summary>
- /// 绘制线段
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="line">线段</param>
- 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);
- }
- /// <summary>
- /// 绘制选中线段的附属
- /// </summary>
- /// <param name="graphics">Graphics</param>
- /// <param name="line">线段</param>
- 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);
- }
- }
- }
- /// <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)
- {
- 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)
- {
- 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;
- 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 鼠标操作
- /// <summary>
- /// 框选Item
- /// </summary>
- /// <param name="rect">框选范围</param>
- 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;
- }
- }
- }
- /// <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];
- 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;
- 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)
- {
- return node.Bounds.Contains(point);
- }
- /// <summary>
- /// 点是否在线段上
- /// </summary>
- /// <param name="point">点</param>
- /// <param name="line">线段</param>
- /// <returns>否在线段上</returns>
- 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;
- }
- /// <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 私有方法
- }
- }
|