Beispiel #1
0
		/// <summary>
		/// Handles the mouse-up event
		/// </summary>
		/// <param name="e"></param>
		protected override void OnMouseUp(MouseEventArgs e)
		{
			base.OnMouseUp (e);
			globalMove = false;
			Connection con = null;
			//test if we connected a connection
			if(tracking)
			{
			
				tracking = false;
				//make the volatile solid
				if(neoCon!=null)
				{
					con = new Connection(neoCon.To, neoCon.From);
					con.site = this;
					Connections.Add(con);
					//the From is the shape seeking a parent
					neoCon.To.childNodes.Add(neoCon.From);
					neoCon.From.parentNode = neoCon.To;
					con.visible = true;
					neoCon.To.Expand();
					neoCon.From.connection = con;
				}
				else //the user hasn't released near anything, so reset to the original situation
				{
					con = new Connection(memChild, memParent);
					con.site = this;
					Connections.Add(con);
					memParent.childNodes.Add(memChild);
					memChild.parentNode = memParent;
					con.visible = true;
					memChild.connection = con;
				}

				//either case, restart the process next
				neoCon = null;
				memChild = null;
				memParent = null;
				DrawTree();

			}
			
		}
Beispiel #2
0
		/// <summary>
		/// Find a new parent for the given shape. This creates a new volatile connection which will be solidified
		/// in the MouseUp handler.
		/// </summary>
		/// <param name="shape">the shape being moved around by the user</param>
		private void SeekNewParent(ShapeBase shape)
		{
			/* this is the fast way but gives problems when the shape is surrounded by other shapes
			 * which makes it difficult to attach it to one you want
			for(int k=0;k<Shapes.Count; k++)
			{
				if(Shapes[k]!=shape && Environment(Shapes[k],shape) && Shapes[k].parentNode!=shape && !Shapes[k].pickup)
				{
					neoCon = new Connection(shape, Shapes[k],  Color.Red,2f);
					neoCon.visible = true;
					Invalidate();
					return;
				}
			}
			*/
			double best = 10000d; 
			int chosen = -1;
			double dist;
			ShapeBase other;
			for(int k=0;k<Shapes.Count; k++)
			{
				other = Shapes[k];
				if(other!=shape && other.visible && other.parentNode!=shape && !other.pickup)
				{
					dist = Math.Sqrt((other.X-shape.X)*(other.X-shape.X)+(other.Y-shape.Y)*(other.Y-shape.Y));
					if(dist<best && dist< 120)
						chosen = k;				
				}
			}
			if(chosen>-1)
			{
				neoCon = new Connection(shape, Shapes[chosen],  Color.Red,2f);
				neoCon.visible = true;
				neoCon.site = this;
				return;
			}

			neoCon = null;
		}
		/// <summary>
		/// Removes a connection from the collection
		/// </summary>
		/// <param name="con">a connection object</param>
		public void Remove(Connection con)
		{
			this.InnerList.Remove(con);
		}
		/// <summary>
		/// Adds a connection to the collection
		/// </summary>
		/// <param name="con">a connection</param>
		/// <returns>the index of the added element in the collection</returns>
		public int Add(Connection con)
		{
			return this.InnerList.Add(con);
		}
Beispiel #5
0
        /// <summary>
        /// Adds a child to this shape
        /// </summary>
        /// <param name="text">the text of the newly created shape</param>
        /// <returns>the create shape</returns>
        public ShapeBase AddChild(string text)
        {
            SimpleRectangle shape = new SimpleRectangle(site);
            shape.Location = new Point(Width/2+50,Height/2+50);
            shape.Width = 50;
            shape.Height = 25;
            shape.Text = text;
            shape.ShapeColor = Color.Linen;
            shape.IsRoot = false;
            shape.parentNode = this;
            shape.Font = font;
            shape.level = level+1;
            shape.Fit(); //fit the child

            //add to the collections
            site.graphAbstract.Shapes.Add(shape);
            this.childNodes.Add(shape);

            //add a connection; From=child, To=parent
            Connection con = new Connection(shape, this);
            site.Connections.Add(con);
            con.site = this.site;
            con.visible = true;
            shape.connection = con;

            if(visible)
                Expand();
            else
            {
                shape.visible = false;
                con.visible = false;
            }
            Fit(); //the cild count added at the end will enlarge the rectangle, so we have to fit
            return shape;
        }
        /// <summary>
        /// Serializes a diagram edge
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        private EdgeType SerializeEdge(Connection c)
        {
            Hashtable attributes = GraphDataAttribute.GetValuesOfTaggedFields(c);

            EdgeType edge = new EdgeType();
            //edge.Source = c.From.Text;
            //edge.Target = c.To.Text;
            edge.From = c.From.UID.ToString();
            edge.To = c.To.UID.ToString();
            //since there is only one type of edge we don't need the next one
            //edge.Data.Add(DataTypeFromEntity(c));

            foreach(DataType dt in DataTypesFromAttributes(attributes))
            {
                edge.Data.Add(dt);
            }

            return edge;
        }
        /// <summary>
        /// Deserializes the graphtype
        /// </summary>
        /// <param name="g">the graphtype which acts as an intermediate storage between XML and the GraphAbstract
        /// </param>
        /// <returns></returns>
        private GraphAbstract Deserialize(GraphType g)
        {
            GraphAbstract abs = new GraphAbstract();

            abs.Description = g.Description;
            ShapeBase shape = null, from = null, to = null;
            NodeType node;
            DataType dt;

            Connection con;

            ParentChildCollection pcs = new ParentChildCollection(); //temporary store for parent-child relations

            #region Load the nodes
            for(int k =0; k<g.Nodes.Count;k++) //loop over all serialized nodes
            {
                try
                {
                    #region find out which type of shape needs to be instantiated

                    node = g.Nodes[k] as NodeType;

                    Type shapeType = Type.GetType(node.Type);

                    if (shapeType != null)
                    {
                        object[] args = {this.site};
                        shape = Activator.CreateInstance(shapeType, args) as ShapeBase;
                    }

                    #endregion

                    #region use the attribs again to reconstruct the props
                    for(int m=0; m<node.Items.Count;m++) //loop over the serialized data
                    {
                        dt = node.Items[m] as DataType;

                        if(dt.Key=="ParentNode")
                        {
                            //forget the parenting, it's done in a separate loop to be sure all shapes are loaded
                            if(dt.Text.Count>0) //could be if the shape is the root
                                pcs.Add(new ParentChild(shape, dt.Text[0].ToString()));
                            else
                            {
                                shape.IsRoot = true;
                                abs.Root = shape;
                            }

                            continue;
                        }
                        foreach (PropertyInfo pi in shape.GetType().GetProperties())
                        {
                            if (Attribute.IsDefined(pi, typeof(GraphDataAttribute)))
                            {
                                if(pi.Name==dt.Key)
                                {

                                    if(pi.GetIndexParameters().Length==0)
                                    {
                                        if(pi.PropertyType.Equals(typeof(int)))
                                            pi.SetValue(shape,Convert.ToInt32(dt.Text[0]),null);
                                        else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer
                                            pi.SetValue(shape,Color.FromArgb(int.Parse(dt.Text[0].ToString())),null);
                                        else if(pi.PropertyType.Equals(typeof(string)))
                                            pi.SetValue(shape,(string)(dt.Text[0]),null);
                                        else if(pi.PropertyType.Equals(typeof(bool)))
                                            pi.SetValue(shape,Convert.ToBoolean(dt.Text[0]),null);
                                        else if(pi.PropertyType.Equals(typeof(Guid)))
                                            pi.SetValue(shape,new Guid((string) dt.Text[0]),null);
                                    }
                                    else
                                        pi.SetValue(shape,dt.Text,null);
                                    break;
                                }

                            }
                        }

                    }
                    #endregion
                    shape.Font = site.Font;
                    shape.Fit();
                    abs.Shapes.Add(shape);
                }
                catch(Exception exc)
                {
                    Trace.WriteLine(exc.Message);
                    continue;
                }

            }//loop over nodes
            #endregion

            //now for the edges;
            //every node has precisely one parent and one connection to it, unless it's the root

            for(int n=0; n<pcs.Count; n++)
            {
                from = pcs[n].ChildShape;
                to = abs.Shapes[pcs[n].Parent];
                con = new Connection(from, to );
                abs.Connections.Add(con);
                con.site = site;
                if(pcs[n].ChildShape.visible)
                    con.visible = true;
                from.connection = con;	//a lot of crossing...to make life easy really
                from.parentNode =to;
                to.childNodes.Add(from);

            }

            return abs;
        }