⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connection.cs

📁 英语句子自然语言处理统计分析例子 Statistical parsing of English sentences Shows how to generate parse trees for
💻 CS
字号:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Netron.Lithium
{
	/// <summary>
	/// Represents the connection between two connectors
	/// </summary>
	public class Connection : Entity
	{

		#region Fields
		/// <summary>
		/// the shape where the connection starts
		/// </summary>
		protected ShapeBase from;
		/// <summary>
		/// the shape where the connection ends
		/// </summary>
		protected ShapeBase to;
		/// <summary>
		/// the start and end points
		/// </summary>
		protected Point start, end;
		/// <summary>
		/// the pen used to draw the connection,
		/// can switch depending on the hovering state e.g.
		/// </summary>
		protected Pen currentPen;

		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets the shape where the connection starts
		/// </summary>
		public ShapeBase From
		{
			get{return from;}
			set{from = value;}
		}

		/// <summary>
		/// Gets or sets where the connection ends
		/// </summary>
		public ShapeBase To
		{
			get{return to;}
			set{to = value;}
		}

		/// <summary>
		/// Get the point where the connection starts
		/// </summary>
		public Point Start
		{
			get
			{
				
				
				return new Point(from.X+from.Width/2,from.Y+from.Height/2);	
			}
		}

		/// <summary>
		/// Gets the point where connection ends
		/// </summary>
		public Point End
		{
			get
			{
				end = new Point(to.X+to.Width/2,to.Y+to.Height/2);
				
				return end;
			}
		}

		#endregion

		#region Constructors
		/// <summary>
		/// Default ctor
		/// </summary>
		public Connection()
		{
			
		}
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="from">the shape where the connection starts</param>
		/// <param name="to">the shape where the connection ends</param>
		public Connection(ShapeBase from, ShapeBase to)
		{
			this.from = from;			
			this.to = to;
			currentPen = blackPen;
			
		}

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="from">the shape where the connection starts</param>
		/// <param name="to">the shape where the connection ends</param>
		/// <param name="color">the color of the connection</param>
		public Connection(ShapeBase from, ShapeBase to, Color color) : this(from, to)
		{
			currentPen = new Pen(color, 1f);
		}

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="from">the shape where the connection starts</param>
		/// <param name="to">the shape where the connection ends</param>
		/// <param name="color">the color of the connection</param>
		/// <param name="width">the (float) width of the connection (in pixels)</param>
		public Connection(ShapeBase from, ShapeBase to, Color color, float width) : this(from, to, color)
		{
			currentPen = new Pen(color, width);
		}
		#endregion

		#region Methods

		/// <summary>
		/// Paints the connection on the canvas
		/// The From part is always the child node while the To part is 
		/// always the parent node.
		/// Hence; 
		/// - vertical: Parent->Child <=> Top->Bottom
		/// - horizontal: Parent->Child <=> Left->Right
		/// </summary>
		/// <param name="g"></param>
		public override void Paint(System.Drawing.Graphics g)
		{
			g.SmoothingMode = SmoothingMode.AntiAlias;
			PointF p1, p2, p3, p4; //intermediate points
			if(visible)
			{
				if(hovered || isSelected)
					pen = redPen;
				else
					pen = currentPen;

				switch(site.ConnectionType)
				{
					case ConnectionType.Default:
					switch(site.LayoutDirection)
					{
						case TreeDirection.Vertical:
							p1 = new PointF(from.Left + from.Width/2, from.Top); 
							p2 = new PointF(to.Left + to.Width/2, to.Bottom+5);
							g.DrawLine(pen,p1,p2);
							break;
						case TreeDirection.Horizontal:
							p1 = new PointF(from.Left, from.Top +  from.Height/2); 
							p2 = new PointF(to.Right +4, to.Top + to.Height/2);
							g.DrawLine(pen,p1,p2);
							break;
					}
						break;
					case ConnectionType.Traditional:
					switch(site.LayoutDirection)
					{
						case TreeDirection.Vertical:
							p1 = new PointF(from.Left + from.Width/2, from.Top - (from.Top - to.Bottom)/2); 
							p2 = new PointF(to.Left + to.Width/2, from.Top - (from.Top - to.Bottom)/2);
							g.DrawLine(pen, Start,p1);
							g.DrawLine(pen, p1, p2);
							g.DrawLine(pen, End, p2);
							break;
						case TreeDirection.Horizontal:

							p1 = new PointF(to.Right + (from.Left - to.Right)/2, from.Top + from.Height/2); 
							p2 = new PointF(to.Right + (from.Left - to.Right)/2, to.Top + to.Height/2);
							g.DrawLine(pen, Start,p1);
							g.DrawLine(pen, p1, p2);
							g.DrawLine(pen, End, p2);
							break;
					}
						break;
					
					case ConnectionType.Bezier:
					switch(site.LayoutDirection)
					{
						case TreeDirection.Vertical:
							p1 = new PointF(from.Left+from.Width/2,from.Top);
							p2 = new PointF(from.Left + from.Width/2, from.Top - (from.Top - to.Bottom)/2); 
							p3 = new PointF(to.Left + to.Width/2, from.Top - (from.Top - to.Bottom)/2);
							p4 = new PointF(to.Left+to.Width/2,to.Bottom);
							g.DrawBezier(pen, p1, p2, p3, p4);
							
							break;
						case TreeDirection.Horizontal:

							p1 = new PointF(to.Right, to.Top + to.Height/2); 							
							p2 = new PointF(to.Right + (from.Left - to.Right)/2, to.Top + to.Height/2);
							p3 = new PointF(to.Right + (from.Left - to.Right)/2, from.Top + from.Height/2); 
							p4 = new PointF(from.Left,from.Top + from.Height/2);
							g.DrawBezier(pen, p1, p2, p3, p4);
							break;
					}
						break;
				}
			}
			
		}
		/// <summary>
		/// Invalidates the connection
		/// </summary>
		public override void Invalidate()
		{
			
			site.Invalidate(Rectangle.Union(from.rectangle,to.rectangle));
		}

		/// <summary>
		/// Tests if the mouse hits this connection
		/// </summary>
		/// <param name="p"></param>
		/// <returns></returns>
		public override bool Hit(Point p)
		{
			PointF p1,p2, p3, s;
			RectangleF r1, r2, r3;

			switch(site.ConnectionType)
			{
				case ConnectionType.Default:
					#region The default Hit method
					
					float o,u;
					p1 = start; p2 = end;						// p1 must be the leftmost point.					if (p1.X > p2.X) { s = p2; p2 = p1; p1 = s; }					//this is specifically necessary when the layout works horizontally					//the method beneth will not return true as should be in this case					if(p1.Y==p2.Y)					{						p1.Y+=-3;						return new RectangleF(p1,new SizeF(p2.X-p1.X,6)).Contains(p);					}					r1 = new RectangleF(p1.X, p1.Y, 0, 0);					r2 = new RectangleF(p2.X, p2.Y, 0, 0);					r1.Inflate(3, 3);					r2.Inflate(3, 3);					//this is like a topological neighborhood					//the connection is shifted left and right					//and the point under consideration has to be in between.											if (RectangleF.Union(r1, r2).Contains(p))					{										if (p1.Y < p2.Y) //SWNE						{							o = r1.Left + (((r2.Left - r1.Left) * (p.Y - r1.Bottom)) / (r2.Bottom - r1.Bottom));							u = r1.Right + (((r2.Right - r1.Right) * (p.Y - r1.Top)) / (r2.Top - r1.Top));							return ((p.X > o) && (p.X < u));						}						else //NWSE						{							o = r1.Left + (((r2.Left - r1.Left) * (p.Y - r1.Top)) / (r2.Top - r1.Top));							u = r1.Right + (((r2.Right - r1.Right) * (p.Y - r1.Bottom)) / (r2.Bottom - r1.Bottom));							return ((p.X > o) && (p.X < u));						}					}
					#endregion
					break;
				case ConnectionType.Traditional:
					#region The rectangular Hit method
						switch(site.LayoutDirection)
						{
							case TreeDirection.Vertical:
								p1 = new PointF(from.Left + from.Width/2-5, from.Top - (from.Top - to.Bottom)/2-5); //shift 5 to contain the connection
								p2 = new PointF(to.Left + to.Width/2-5, from.Top - (from.Top - to.Bottom)/2-5);
								p3 = new Point(to.Left+to.Width/2-5,to.Bottom-5);

								r1 = new RectangleF(p1, new SizeF(10,(from.Top - to.Bottom)/2+5)); 
								if(p1.X<p2.X)
									r2 = new RectangleF(p1,new SizeF(p2.X-p1.X,10));
								else
									r2 = new RectangleF(p2,new SizeF(p1.X-p2.X,10));
								r3 = new RectangleF(p3, new SizeF(10, (from.Top - to.Bottom)/2+5));
								return r1.Contains(p.X,p.Y) || r2.Contains(p.X,p.Y) || r3.Contains(p.X,p.Y) ;
								
							case TreeDirection.Horizontal:

								p1 = new PointF(to.Right + (from.Left - to.Right)/2, from.Top + from.Height/2); 
								p2 = new PointF(to.Right + (from.Left - to.Right)/2, to.Top + to.Height/2);
							
								break;
						}
					#endregion
					break;
			}


			return false;
		}

		/// <summary>
		/// Moves the connection with the given shift
		/// </summary>
		/// <param name="p"></param>
		public override void Move(Point p)
		{

		}


		#endregion

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -