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

📄 lithiumcontrol.cs

📁 英语句子自然语言处理统计分析例子 Statistical parsing of English sentences Shows how to generate parse trees for
💻 CS
📖 第 1 页 / 共 3 页
字号:
					Pickup(shape.childNodes[k]);
			}

		}

		

		#endregion

		/// <summary>
		/// Resets the hovering status of the control, i.e. the hoverEntity is set to null.
		/// </summary>
		private void HoverNone()
		{
			if(hoveredEntity!=null) 
			{
				hoveredEntity.hovered = false;
				hoveredEntity.Invalidate();
			}
			hoveredEntity = null;
		}



		/// <summary>
		/// Collapses the whole diagram
		/// </summary>
		public void CollapseAll()
		{
			this.Root.Collapse(true);
		}

		/// <summary>
		/// Deletes the currently selected shape
		/// </summary>
		public void Delete()
		{
			if(selectedEntity==null) return;
			ShapeBase sh = selectedEntity as ShapeBase;
			if(sh!=null)
			{
				if(sh.IsRoot) return; //cannot delete the root
				//delete the node from the parent's children
				sh.parentNode.childNodes.Remove(sh);
				//delete everything underneath the node 
				DeleteVisitor visitor = new DeleteVisitor(this.graphAbstract);
				visitor.OnDelete+=new ShapeData(visitor_OnDelete);
				graphAbstract.DepthFirstTraversal(visitor,sh);
				DrawTree();
			}
			//Invalidate();
				
		}

		/// <summary>
		/// Expands the whole diagram
		/// </summary>
		public void ExpandAll()
		{
			IVisitor expander = new ExpanderVisitor();
			this.graphAbstract.DepthFirstTraversal(expander);
			DrawTree();
			
		}

		/// <summary>
		/// Saves the diagram to file in XML format (XML serialization)
		/// </summary>
		/// <param name="filePath"></param>
		public void SaveGraphAs(string filePath)		{			XmlTextWriter tw = new XmlTextWriter(filePath,System.Text.Encoding.Unicode);
			GraphSerializer g = new GraphSerializer(this);
			g.Serialize(tw);
			tw.Close();		}
		/// <summary>
		/// Opens a diagram which was saved to XML previously (XML deserialization)
		/// </summary>
		/// <param name="filePath"></param>
		public void OpenGraph(string filePath)
		{
			XmlTextReader reader = new XmlTextReader(filePath);
			GraphSerializer ser = new GraphSerializer(this);
			graphAbstract = ser.Deserialize(reader) as GraphAbstract;
			reader.Close();
			DrawTree();
			Invalidate();
		}


		#region Layout algorithm

		int marginLeft = 10;			
		
		
	

		

		/// <summary>
		/// Generic entry point to layout the diagram on the canvas.
		/// The default LayoutDirection is vertical. If you wish to layout the tree in a certain
		/// direction you need to specify this property first. Also, the direction is global, you cannot have 
		/// different parts being drawn in different ways though it can be implemented.
		/// 
		/// </summary>
		public void DrawTree()
		{
			if(!layoutEnabled) return;
			Point p = Point.Empty; //the shift vector difference between the original and the moved root
			try
			{
				//start the recursion
				//the layout will move the root but it's reset to its original position
				switch(layoutDirection)
				{
					case TreeDirection.Vertical:
						
						p = new Point(graphAbstract.Root.X, graphAbstract.Root.Y);
						VerticalDrawTree(graphAbstract.Root,false,marginLeft,this.graphAbstract.Root.Y);						
						p = new Point(-graphAbstract.Root.X+p.X, -graphAbstract.Root.Y+ p.Y);						
						MoveDiagram(p);						
						break;
					case TreeDirection.Horizontal:
						p = new Point(graphAbstract.Root.X, graphAbstract.Root.Y);
						HorizontalDrawTree(graphAbstract.Root,false,marginLeft,10);
						p = new Point(-graphAbstract.Root.X+p.X, -graphAbstract.Root.Y+ p.Y);		
						MoveDiagram(p);	
						break;
				}

				int maxY = 0;
				foreach (ShapeBase shape in Shapes)
				{
					if (shape.ShapeColor == Color.Ivory)
					{
						if (shape.Visible)
						{
							if (shape.Y > maxY)
							{
								maxY = shape.Y;
							}
						}
					}
				}

				foreach (ShapeBase shape in Shapes)
				{
					if (shape.ShapeColor == Color.Ivory)
					{
						if (shape.Visible)
						{
							shape.Move(new Point(0, maxY - shape.Y));
						}
					}
				}

				CalculateScrollBars();
				
				Invalidate();
			}
			catch(Exception exc)
			{
				Trace.WriteLine(exc.Message);				
			}
		}

		private void CalculateScrollBars()
		{
			Point minPoint = new Point(int.MaxValue,int.MaxValue);
			Size maxSize = new Size(0,0);
			foreach(ShapeBase shape in Shapes)
			{
				if (shape.Visible)
				{
					if (shape.X + shape.Width > maxSize.Width)
					{
						maxSize.Width = shape.X + shape.Width;
					}

					if (shape.Y + shape.Height > maxSize.Height)
					{
						maxSize.Height = shape.Y + shape.Height;
					}

					if (shape.X < minPoint.X)
					{
						minPoint.X = shape.X;
					}

					if (shape.Y < minPoint.Y)
					{
						minPoint.Y = shape.Y;
					}
				}
			}

			MoveDiagram(new Point(50 - minPoint.X, 50 - minPoint.Y)); 

			maxSize.Width = maxSize.Width - minPoint.X + 100;
			maxSize.Height = maxSize.Height - minPoint.Y + 100;
			this.AutoScrollMinSize = maxSize;
		}
		/// <summary>
		/// Positions everything underneath the node and returns the total width of the kids
		/// </summary>
		/// <param name="containerNode"></param>
		/// <param name="first"></param>
		/// <param name="shiftLeft"></param>
		/// <param name="shiftTop"></param>
		/// <returns></returns>
		private int VerticalDrawTree(ShapeBase containerNode, bool first, int shiftLeft, int shiftTop)
		{
			bool isFirst = false;
			bool isParent = containerNode.childNodes.Count>0? true: false;
			int childrenWidth = 0;
			int thisX, thisY;		
			int returned = 0;
			int verticalDelta = branchHeight ; //the applied vertical shift of the child depends on the Height of the containerNode
			#region Children width
			for(int i =0; i<containerNode.childNodes.Count; i++)
			{
				//determine the width of the label
				if(i==0)			
					isFirst = true;				
				else 				
					isFirst = false;
				if(containerNode.childNodes[i].visible)
				{
					if((branchHeight - containerNode.Height) < 30) //if too close to the child, shift it with 40 units
						verticalDelta = containerNode.Height + 40;
					returned = VerticalDrawTree(containerNode.childNodes[i], isFirst, shiftLeft + childrenWidth, shiftTop + verticalDelta );									
					childrenWidth += returned;
					
				}		

			}
			if(childrenWidth>0 && containerNode.expanded)
				childrenWidth=Math.Max(Convert.ToInt32(childrenWidth + (containerNode.Width-childrenWidth)/2), childrenWidth); //in case the length of the containerNode is bigger than the total length of the children
			#endregion

			if(childrenWidth==0) //there are no children; this is the branch end
				childrenWidth = containerNode.Width+wordSpacing;
			
			#region Positioning
			thisY = shiftTop;			
			if(containerNode.childNodes.Count>0 && containerNode.expanded)
			{
				if(containerNode.childNodes.Count==1)
				{

					thisX = Convert.ToInt32(containerNode.childNodes[0].X+containerNode.childNodes[0].Width/2 - containerNode.Width/2);
				}
				else
				{
					float firstChild = containerNode.childNodes[0].Left+ containerNode.childNodes[0].Width/2;
					float lastChild = containerNode.childNodes[containerNode.childNodes.Count-1].Left + containerNode.childNodes[containerNode.childNodes.Count-1].Width/2;
					//the following max in case the containerNode is larger than the childrenWidth
					thisX = Convert.ToInt32(Math.Max(firstChild + (lastChild -firstChild - containerNode.Width)/2, firstChild));
				}
			}
			else
			{
				thisX = shiftLeft;		
				
			}
			
			containerNode.rectangle.X = thisX;
			containerNode.rectangle.Y = thisY;
			#endregion

			return childrenWidth;
		}

		/// <summary>
		/// Horizontal layout algorithm
		/// </summary>
		/// <param name="containerNode"></param>
		/// <param name="first"></param>
		/// <param name="shiftLeft"></param>
		/// <param name="shiftTop"></param>
		/// <returns></returns>
		private int HorizontalDrawTree(ShapeBase containerNode, bool first, int shiftLeft, int shiftTop)
		{
			bool isFirst = false;
			bool isParent = containerNode.childNodes.Count>0? true: false;
			int childrenHeight = 0;
			int thisX, thisY;		
			int returned = 0;
			int horizontalDelta = branchHeight;
			#region Children width
			for(int i =0; i<containerNode.childNodes.Count; i++)
			{
				//determine the width of the label
				if(i==0)			
					isFirst = true;				
				else 				
					isFirst = false;
				if(containerNode.childNodes[i].visible)
				{
					if((branchHeight - containerNode.Width) < 30) //if too close to the child, shift it with 40 units
						horizontalDelta = containerNode.Width + 40;
					returned = HorizontalDrawTree(containerNode.childNodes[i], isFirst, shiftLeft + horizontalDelta , shiftTop + childrenHeight );					
					childrenHeight += returned;
				}
				

			}
			#endregion

			if(childrenHeight==0) //there are no children; this is the branch end
				childrenHeight = containerNode.Height+wordSpacing;
			
			#region Positioning
			thisX = shiftLeft;			
			if(containerNode.childNodes.Count>0 && containerNode.expanded)
			{
				
					int firstChild = containerNode.childNodes[0].Y;
					int lastChild = containerNode.childNodes[containerNode.childNodes.Count-1].Y;
					thisY = Convert.ToInt32(firstChild + (lastChild - firstChild)/2);
				
			}
			else
			{
				thisY = Convert.ToInt32(shiftTop);		
				
			}
			
			containerNode.rectangle.X = thisX;
			containerNode.rectangle.Y = thisY;
			#endregion

			return childrenHeight;
		}

		private int Measure(string text)
		{
			Graphics g = Graphics.FromHwnd(this.Handle);

			return Size.Round(g.MeasureString(text,Font)).Width +37;
		}
		/// <summary>
		/// Resizes the shape to fit the text
		/// </summary>
		/// <param name="shape"></param>
		public void Fit(ShapeBase shape)
		{
			Graphics g = Graphics.FromHwnd(this.Handle);
			Size s =  Size.Round(g.MeasureString(shape.Text,Font));
			shape.Width =s.Width +20;
			shape.Height = s.Height+8;
		}

		private void FitAll()
		{
			foreach(ShapeBase shape in graphAbstract.Shapes)
				Fit(shape);
			Invalidate();
		}


	

		/// <summary>
		/// When the font of the control is changed all shapes get
		/// the new font assigned
		/// </summary>
		/// <param name="e"></param>
		protected override void OnFontChanged(EventArgs e)
		{
			base.OnFontChanged (e);

			foreach(ShapeBase shape in graphAbstract.Shapes)
				shape.Font = Font;
		}

		/// <summary>
		/// Adds a child node to the currently selected one
		/// </summary>
		public void AddChild()
		{
			if(selectedEntity==null) return;

			ShapeBase sh = selectedEntity as ShapeBase;
			if(sh!=null)
			{
				sh.AddChild("New node");
				DrawTree();
			}

		}

		/// <summary>
		/// DFT of the diagram with the given visitor, starting from the given shape
		/// </summary>
		/// <param name="visitor"></param>
		/// <param name="shape"></param>
		public void DepthFirstTraversal(IVisitor visitor, ShapeBase shape)
		{
			graphAbstract.DepthFirstTraversal(visitor, shape);
		}


		/// <summary>
		/// DFT of the diagram with the given visitor, starting from the root
		/// </summary>
		/// <param name="visitor"></param>
		public void DepthFirstTraversal(IVisitor visitor)
		{
			graphAbstract.DepthFirstTraversal(visitor);
		}

		/// <summary>
		/// BFT of the diagram with the given visitor, starting from the root
		/// </summary>
		/// <param name="visitor"></param>
		public void BreadthFirstTraversal(IVisitor visitor)
		{
			graphAbstract.BreadthFirstTraversal(visitor);
		}

		/// <summary>
		/// BFT of the diagram with the given visitor, starting from the given shape
		/// </summary>
		/// <param name="visitor"></param>
		/// <param name="shape"></param>
		public void BreadthFirstTraversal(IVisitor visitor, ShapeBase shape)
		{
			graphAbstract.BreadthFirstTraversal(visitor, shape);
		}



		#endregion

		#endregion

		
	}

	
}

⌨️ 快捷键说明

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