Exemple #1
0
			/// <summary>
			/// Returns the connector starting coordinates.
			/// </summary>
			/// <param name="info">Connector display information.</param>
			/// <returns>Point object.</returns>
			protected Point GetStartPoint(ConnectorRendererEventArgs info)
			{
				Point p=Point.Empty;

				if(info.IsRootNode)
				{
					//int toMidPoint=info.ToNode.Bounds.Top+info.ToNode.Bounds.Height/2;
					//if(info.FromNode.Bounds.Top>toMidPoint)
					if(IsAbove(info.FromNode,info.ToNode))
						p=new Point(info.FromNode.BoundsRelative.Left+info.FromNode.BoundsRelative.Width/2,info.FromNode.BoundsRelative.Top);
						//else if(info.FromNode.Bounds.Bottom<toMidPoint)
					else if(IsBelow(info.FromNode,info.ToNode))
						p=new Point(info.FromNode.BoundsRelative.Left+info.FromNode.BoundsRelative.Width/2,info.FromNode.BoundsRelative.Bottom-1);
				}

				if(p.IsEmpty)
				{
					// To element to the Left
					if(this.IsOnLeftSide(info.FromNode,info.ToNode))
						p=new Point(info.FromNode.BoundsRelative.Left,info.FromNode.BoundsRelative.Top+info.FromNode.BoundsRelative.Height/2);
					else
					{
						p=new Point(info.FromNode.BoundsRelative.Right,info.FromNode.BoundsRelative.Top+info.FromNode.BoundsRelative.Height/2);
						if(info.IsRootNode)
							p.X--;
						if(!NodeDisplay.DrawExpandPart(info.FromNode) && info.FromNode.ExpandVisibility==eNodeExpandVisibility.Auto)
							p.X-=(info.FromNode.BoundsRelative.Width-info.FromNode.ContentBounds.Width);
					}
				}

				if(!p.IsEmpty)
					p.Offset(info.Offset.X,info.Offset.Y);

				return p;
			}
Exemple #2
0
		/// <summary>
		/// Draws connector line between two nodes.
		/// </summary>
		/// <param name="info">Connector context information.</param>
		public override void DrawConnector(ConnectorRendererEventArgs info)
		{
			if(info.NodeConnector.LineColor.IsEmpty || info.NodeConnector.LineWidth<=0)
				return;

			DrawStarConnector(info);
		}
Exemple #3
0
		private void DrawStarConnector(ConnectorRendererEventArgs info)
		{
			Point pStart=this.GetStartPoint(info);
			Point[] parr=this.GetEndPoint(info);
			Point pEnd=parr[0];
			Point pEndUnderLine=parr[1];

			if(info.ConnectorPoints==null)
			{
				// Determine whether curve can be drawn
				if(Math.Abs(pStart.X-pEnd.X)<=6 || Math.Abs(pStart.Y-pEnd.Y)<=10)
				{
					DrawLineConnector(info,pStart,pEnd,pEndUnderLine);
				}
				else
				{
					Point pBottom=new Point();
					Point pTop=new Point();
					if(pEnd.X<pStart.X)
					{
						pBottom.X=pStart.X-info.NodeConnector.LineWidth;
						pTop.X=pEnd.X+1;
					}
					else
					{
						pBottom.X=pStart.X+info.NodeConnector.LineWidth;
						pTop.X=pEnd.X-1;
					}
					pBottom.Y=pStart.Y;
					pTop.Y=pEnd.Y;

					GraphicsPath path=new GraphicsPath();
					path.AddLine(pStart,pBottom);
					path.AddLine(pBottom,pEnd);
					path.AddLine(pEnd,pTop);
					path.AddLine(pTop,pStart);
					path.CloseAllFigures();

					using(Brush brush=this.GetLineBrush(info))
						info.Graphics.FillPath(brush,path);
				}
			}
			else
			{
				ConnectorPointInfo pointInfo=GetConnectorPointInfo(info,pStart,pEnd);
				
				if(pointInfo.Points2==null)
				{
					using(Pen pen=this.GetLinePen(info))
					{
						info.Graphics.DrawLines(pen,pointInfo.Points1);
					}
				}
				else
				{
					using(GraphicsPath path=new GraphicsPath())
					{
						path.AddLines(pointInfo.Points1);
						path.AddLines(pointInfo.Points2);
						path.CloseAllFigures();

						using(Brush brush=this.GetLineBrush(info))
						{
							info.Graphics.FillPath(brush,path);
						}
					}
				}
			}

			DrawEndLine(info,pStart,pEnd,pEndUnderLine);
		}
Exemple #4
0
			internal virtual ConnectorPointInfo GetConnectorPointInfo(ConnectorRendererEventArgs info, Point pStart, Point pEnd)
			{
				ConnectorPointInfo pointInfo=new ConnectorPointInfo();

				int xMulti=1/*, yMulti=1*/;
				int lineWidth=info.NodeConnector.LineWidth;

				// used for direction control
				if(pStart.X>pEnd.X)
					xMulti=-1;
				//if(pStart.Y>pEnd.Y)
				//	yMulti=-1;

				if(info.ConnectorPoints!=null)
				{
					Point connPointsOffset=info.ToNode.BoundsRelative.Location;
					connPointsOffset.Offset(info.Offset.X,info.Offset.Y);
					GraphicsPath path=new GraphicsPath();
				
					pointInfo.Points1=new Point[info.ConnectorPoints.Count+2];
					pointInfo.Points1[0]=pStart;
					pointInfo.Points1[pointInfo.Points1.Length-1]=pEnd;

					if(lineWidth>1)
					{
						pointInfo.Points2=new Point[info.ConnectorPoints.Count+2];
						pointInfo.Points2[pointInfo.Points2.Length-1]=pStart;
						pointInfo.Points2[0]=pEnd;

						int i=pointInfo.Points1.Length-2;
						int k=1;

						foreach(Point pcp in info.ConnectorPoints)
						{
							pointInfo.Points1[i]=pcp;
							pointInfo.Points1[i].Offset(connPointsOffset.X,connPointsOffset.Y);
							pointInfo.Points2[k]=new Point(pcp.X+lineWidth*xMulti,pcp.Y);
							pointInfo.Points2[k].Offset(connPointsOffset.X,connPointsOffset.Y);
							k++;
							i--;
						}
					}
					else
					{
						int i=pointInfo.Points1.Length-2;
						foreach(Point pcp in info.ConnectorPoints)
						{
							pointInfo.Points1[i]=pcp;
							pointInfo.Points1[i].Offset(connPointsOffset.X,connPointsOffset.Y);
							i--;
						}
					}	
				}
				return pointInfo;
			}
Exemple #5
0
			protected void DrawEndLine(ConnectorRendererEventArgs info,Point pStart,Point pEnd,Point pEndUnderLine)
			{
				if(pEndUnderLine.IsEmpty)
				{
					switch(info.NodeConnector.EndCap)
					{
						case eConnectorCap.Ellipse:
							{
								using(Pen pen=this.GetEndLinePen(info))
								{
									Size endCapSize=info.NodeConnector.EndCapSize;
									if(pStart.X<pEnd.X)
										info.Graphics.DrawEllipse(pen,pEnd.X-1,pEnd.Y-endCapSize.Height/2,endCapSize.Width,endCapSize.Height);
									else
										info.Graphics.DrawEllipse(pen,pEnd.X-endCapSize.Width,pEnd.Y-endCapSize.Height/2,endCapSize.Width,endCapSize.Height);
								}
								break;
							}
						case eConnectorCap.Arrow:
							{
								using(Pen pen=this.GetEndLinePen(info))
								{
									// Connects connector line to arrow
									int direction=1;
									if(pStart.X>pEnd.X)
										direction=-1;
									info.Graphics.DrawLine(pen,pEnd,new Point(pEnd.X+info.NodeConnector.EndCapSize.Width/3*direction,pEnd.Y));

									Size endCapSize=info.NodeConnector.EndCapSize;
									GraphicsPath arrow=GetArrowPath(endCapSize,pStart,pEnd);
									info.Graphics.DrawPath(pen,arrow);
								}
								break;
							}
					}
				}
				else
				{
					using(Pen pen=this.GetEndUnderlinePen(info))
					{
						info.Graphics.DrawLine(pen,pEnd,pEndUnderLine);
					
						// Connect underline to expand part
						if(NodeDisplay.DrawExpandPart(info.ToNode))
						{
							Rectangle re=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds,info.ToNode,info.Offset);
							Point p2=new Point((re.X>pEndUnderLine.X?re.X:re.Right)+(re.Width/2*(re.X>pEndUnderLine.X?1:-1)),re.Bottom);
							Point p1=new Point(p2.X,pEndUnderLine.Y+(pEndUnderLine.Y>p2.Y?(p2.Y-pEndUnderLine.Y)/2:-(p2.Y-pEndUnderLine.Y)/2));
							info.Graphics.DrawCurve(pen,new Point[]{pEndUnderLine,p1,p2},.5f);
						}
					}
				}
			}
Exemple #6
0
			/// <summary>
			/// Draws connector line between two nodes.
			/// </summary>
			/// <param name="info">Connector context information.</param>
			public virtual void DrawConnector(ConnectorRendererEventArgs info){}
Exemple #7
0
			protected Brush GetLineBrush(ConnectorRendererEventArgs info)
			{
				return new SolidBrush(info.NodeConnector.LineColor);
			}
Exemple #8
0
			/// <summary>
			/// Returns new instance of pen object for the node underline line. Caller is responsible for
			/// disposing of this object.
			/// </summary>
			/// <param name="info">Node connector display info.</param>
			/// <returns>New instance of Pen object.</returns>
			protected Pen GetEndUnderlinePen(ConnectorRendererEventArgs info)
			{
				return new Pen(info.NodeConnector.LineColor,EndLineWidth);
			}
Exemple #9
0
			/// <summary>
			/// Draws straight line connector between start and end point.
			/// </summary>
			/// <param name="info">Node connector display info.</param>
			/// <param name="pStart">Start point.</param>
			/// <param name="pEnd">End point.</param>
			/// <param name="pEndUnderLine">Underline end point if any.</param>
			protected void DrawLineConnector(ConnectorRendererEventArgs info,Point pStart,Point pEnd, Point pEndUnderLine)
			{
				if(info.NodeConnector.LineWidth>1)
				{
					// Merge lines nicely by filling and creating path...
					int rootLineWidth=this.EndLineWidth;
					int lineWidth=info.NodeConnector.LineWidth;
				
					using(Brush brush=GetLineBrush(info))
					{
						GraphicsPath path=GetConnectingPath(pStart,pEnd,lineWidth,rootLineWidth,info.IsRootNode,!(IsAbove(info.FromNode,info.ToNode) || IsBelow(info.FromNode,info.ToNode)));
						info.Graphics.FillPath(brush,path);
					}
				}
				else
				{
					using(Pen pen=this.GetLinePen(info))
					{
						info.Graphics.DrawLine(pen,pStart,pEnd);
					}
				}

				if(!pEndUnderLine.IsEmpty)
				{
					using(Pen pen=this.GetEndUnderlinePen(info))
					{
						info.Graphics.DrawLine(pen,pEnd,pEndUnderLine);
					}
				}
			}
Exemple #10
0
			/// <summary>
			/// Returns the connector end point. The array of end points. Two valid points will be returned if node needs to be underlined by connector.
			/// </summary>
			/// <param name="info">Connector display info.</param>
			/// <returns>Array of point objects.</returns>
			protected Point[] GetEndPoint(ConnectorRendererEventArgs info)
			{
				// If to element is to the right of the from node and has left border end point is the vertical mid-point
				// If to element is to the left of the from node and has right border end point is the vertical mid-point
				// If there is no border end point is text bottom
				// If this is link connector the end point is the middle bottom or top point of the node

				Point p=Point.Empty;
				Point pLineEnd=Point.Empty;
				int capWidthOffset=GetCapWidthOffset(info.NodeConnector.EndCap,info.NodeConnector.EndCapSize);
				bool leftSide=this.IsOnLeftSide(info.FromNode,info.ToNode);

				if(info.LinkConnector && info.FromNode.BoundsRelative.Top>info.ToNode.BoundsRelative.Bottom)
					p=new Point(info.ToNode.BoundsRelative.X+info.ToNode.BoundsRelative.Width/2+(leftSide?capWidthOffset:-capWidthOffset),info.ToNode.BoundsRelative.Bottom+1);
				else if(info.LinkConnector && info.FromNode.BoundsRelative.Bottom<info.ToNode.BoundsRelative.Top)
					p=new Point(info.ToNode.BoundsRelative.X+info.ToNode.BoundsRelative.Width/2+(leftSide?capWidthOffset:-capWidthOffset),info.ToNode.BoundsRelative.Top-info.NodeConnector.EndCapSize.Height);
				else
				{
					if(leftSide)
					{
						// To element is to the left of from node
						Rectangle r=info.ToNode.BoundsRelative;
						if(info.StyleToNode==null || UnderlineNode(info.StyleToNode))
						{
							p=new Point(r.Right,r.Bottom);
							if(m_EndCap)
								p.X+=capWidthOffset;

							if(info.NodeConnector.UnderlineNoBorderNode)
							{
								Rectangle rc=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,info.ToNode,Point.Empty);
								pLineEnd=new Point(rc.Left+1,r.Bottom);
							}
						}
						else
						{
							p=new Point(r.Right,r.Y+r.Height/2);
							if(m_EndCap)
								p.X+=capWidthOffset;
						}
					}
					else
					{
						// To element to the right of from node
						Rectangle r=info.ToNode.BoundsRelative;
						if(info.StyleToNode==null || UnderlineNode(info.StyleToNode))
						{
							//r=NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds,info.ToNode.Cells[0],Point.Empty);
							//r=info.ToNode.Cells[0].TextContentBounds;
							p=new Point(r.X,r.Bottom);
							if(m_EndCap)
								p.X-=capWidthOffset;
							if(info.NodeConnector.UnderlineNoBorderNode)
							{
								Rectangle rc=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,info.ToNode,Point.Empty);
								pLineEnd=new Point(rc.Right-1,r.Bottom);
							}
						}
						else
						{
							p=new Point(r.X,r.Y+r.Height/2);
							if(m_EndCap)
								p.X-=capWidthOffset;
						}
					}
				}
			
				if(!p.IsEmpty)
					p.Offset(info.Offset.X,info.Offset.Y);
				if(!pLineEnd.IsEmpty)
					pLineEnd.Offset(info.Offset.X,info.Offset.Y);

				return new Point[] {p,pLineEnd};
			}
Exemple #11
0
		/// <summary>
		/// Draws connector between nodes. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
		/// do not want default rendering to occur do not call the base implementation. You can call OnRenderConnector method so events can occur.
		/// </summary>
		/// <param name="e">Information provided for rendering.</param>
		public override void DrawConnector(ConnectorRendererEventArgs e)
		{
			NodeConnectorDisplay display = GetConnectorDisplay(e.NodeConnector);
			if(display!=null)
				display.DrawConnector(e);

			base.DrawConnector(e);
		}
Exemple #12
0
		private void DrawCurveConnector(ConnectorRendererEventArgs info)
		{
			Point pStart=this.GetStartPoint(info);
			Point[] parr=this.GetEndPoint(info);
			Point pEnd=parr[0];
			Point pEndUnderLine=parr[1];
			int lineWidth=info.NodeConnector.LineWidth;

			int xMulti=1, yMulti=1;
					
			// used for direction control
			if(pStart.X>pEnd.X)
				xMulti=-1;
			if(pStart.Y>pEnd.Y)
				yMulti=-1;

			if(info.ConnectorPoints==null || info.ConnectorPoints.Count == 0)
			{
				// Determine whether curve can be drawn
				if(Math.Abs(pStart.X-pEnd.X)<=6 || Math.Abs(pStart.Y-pEnd.Y)<=10)
				{
					DrawLineConnector(info,pStart,pEnd,pEndUnderLine);
				}
				else
				{
					// Create two points in between the start and end point
					Point[] p=new Point[4];

					p[1].X=pStart.X+(int)(Math.Abs(pStart.X-pEnd.X)*.15f*xMulti);
					p[1].Y=pStart.Y+(int)(Math.Abs(pStart.Y-pEnd.Y)*.15f*yMulti);

					p[2].X=pStart.X+(int)(Math.Abs(pStart.X-pEnd.X)*.5f*xMulti);
					p[2].Y=pEnd.Y-(int)(yMulti*(Math.Abs(pStart.Y-pEnd.Y)*.15f));

					p[0]=pStart;
					p[3]=pEnd;

					if(lineWidth>1)
					{
						GraphicsPath path=new GraphicsPath();
						
						path.AddCurve(p,.5f);
						
						// Check whether pStart is starting from left or right side
						Rectangle fromNodeRect=info.FromNode.BoundsRelative;
						fromNodeRect.Offset(info.Offset);
						fromNodeRect.Inflate(-1,-1);
//						if(pStart.Y>fromNodeRect.Y && pStart.Y<fromNodeRect.Bottom && pStart.X>=fromNodeRect.Right)
//						{
//							path.AddLine(pStart.X, pStart.Y-lineWidth*xMulti, pStart.X, pStart.Y);
//						}
						
						path.AddLine(p[0].X,p[0].Y,p[0].X+lineWidth*xMulti,p[0].Y);
						
						if(pStart.Y>fromNodeRect.Y && pStart.Y<fromNodeRect.Bottom && pStart.X>=fromNodeRect.Right && info.IsRootNode)
						{
							path.AddLine(p[0].X-1,p[0].Y,p[0].X-1,p[0].Y+lineWidth*yMulti);
							p[0].Y -= lineWidth*yMulti;
						}
						else if(pStart.Y>fromNodeRect.Y && pStart.Y<fromNodeRect.Bottom && pStart.X<=fromNodeRect.Left && info.IsRootNode)
						{
							path.AddLine(p[0].X+1,p[0].Y,p[0].X+1,p[0].Y+lineWidth*yMulti);
							p[0].Y -= lineWidth*yMulti;
						}
						else
							p[0].X+=(lineWidth*xMulti);
						
						p[1].X+=(lineWidth*xMulti);
						p[2].X+=(lineWidth*xMulti);
						p[3].Y-=yMulti;
						path.AddCurve(p,.5f);
						path.AddLine(p[3].X,p[3].Y,p[3].X,p[3].Y+yMulti);
						path.CloseAllFigures();
						using(Brush brush=this.GetLineBrush(info))
						{
							info.Graphics.FillPath(brush,path);
						}
					}
					else
					{
						using(Pen pen=this.GetLinePen(info))
						{
							info.Graphics.DrawCurve(pen,p,.5f);
						}
					}
				}
			}
			else
			{
				ConnectorPointInfo pointInfo=GetConnectorPointInfo(info,pStart,pEnd);
				
				if(pointInfo.Points2==null)
				{
					using(Pen pen=this.GetLinePen(info))
					{
						info.Graphics.DrawCurve(pen,pointInfo.Points1,.5f);
					}
				}
				else
				{
					using(GraphicsPath path=new GraphicsPath())
					{
						path.AddCurve(pointInfo.Points1,.5f);
						path.AddCurve(pointInfo.Points2,.5f);
						path.CloseAllFigures();

						using(Brush brush=this.GetLineBrush(info))
						{
							info.Graphics.FillPath(brush,path);
						}
					}
				}
			}

			DrawEndLine(info,pStart,pEnd,pEndUnderLine);
		}
Exemple #13
0
		/// <summary>
		/// Raises RenderConnector event.
		/// </summary>
		/// <param name="e">Event data.</param>
		protected virtual void OnRenderConnector(ConnectorRendererEventArgs e)
		{
			if(RenderConnector!=null)
				RenderConnector(this, e);
		}
Exemple #14
0
		/// <summary>
		/// Draws connector between nodes. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
		/// do not want default rendering to occur do not call the base implementation. You can call OnRenderConnector method so events can occur.
		/// </summary>
		/// <param name="e">Information provided for rendering.</param>
		public virtual void DrawConnector(ConnectorRendererEventArgs e)
		{
			OnRenderConnector(e);
		}