/// <summary> /// Starts a new diagram and forgets about everything /// You need to call the Save method before this if you wish to keep the current diagram. /// </summary> public void NewDiagram() { this.graphAbstract = new GraphAbstract(); this.AddRoot(defaultRootName); CenterRoot(); Invalidate(); }
/// <summary> /// Serializes the given graph to xml /// </summary> public void Serialize(XmlWriter writer) { GraphType graph = new GraphType(); GraphAbstract g = site.graphAbstract; //here you can serialize whatever global pros graph.Description = g.Description; graph.ID = "id1"; foreach (ShapeBase s in g.Shapes) { graph.Nodes.Add(SerializeNode(s)); } foreach (Connection c in g.Connections) { graph.Edges.Add(SerializeEdge(c)); } // serialize XmlSerializer ser = new XmlSerializer(typeof(GraphType)); ser.Serialize(writer, graph); }
/// <summary> /// Starts a new diagram and forgets about everything /// You need to call the Save method before this if you wish to keep the current diagram. /// </summary> /// <param name="rootName">the text of the root in the new diagram</param> public void NewDiagram(string rootName) { this.graphAbstract = new GraphAbstract(); this.AddRoot(rootName); CenterRoot(); Invalidate(); }
/// <summary> /// Default ctor /// </summary> public LithiumControl() { //double-buffering SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.DoubleBuffer, true); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.ResizeRedraw, true); //init the abstract graphAbstract = new GraphAbstract(); graphAbstract.Shapes.OnShapeAdded += new ShapeData(OnShapeAdded); AddRoot(defaultRootName); //default menu, can be overwritten in the design of the application menu = new ContextMenu(); BuildMenu(); this.ContextMenu = menu; //init the randomizer rnd = new Random(); //init the proxy proxy = new Proxy(this); //allow scrolling this.AutoScroll = true; this.HScroll = true; this.VScroll = true; }
/// <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(); }
/// <summary> /// Starts a new diagram and forgets about everything /// You need to call the Save method before this if you wish to keep the current diagram. /// </summary> /// <param name="rootName">the text of the root in the new diagram</param> public void NewDiagram(string rootName) { this.graphAbstract=new GraphAbstract(); this.AddRoot(rootName); CenterRoot(); Invalidate(); }
/// <summary> /// Default ctor /// </summary> public LithiumControl() { //double-buffering SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.DoubleBuffer, true); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.ResizeRedraw, true); //init the abstract graphAbstract = new GraphAbstract(); graphAbstract.Shapes.OnShapeAdded+=new ShapeData(OnShapeAdded); AddRoot(defaultRootName); //default menu, can be overwritten in the design of the application menu = new ContextMenu(); BuildMenu(); this.ContextMenu = menu; //init the randomizer rnd = new Random(); //init the proxy proxy = new Proxy(this); //allow scrolling this.AutoScroll=true; this.HScroll=true; this.VScroll=true; }
/// <summary> /// Constructor /// </summary> /// <param name="graphAbstract">a GraphAbstract instance</param> public DeleteVisitor(GraphAbstract graphAbstract) { this.graphAbstract = graphAbstract; }
/// <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); }
/// <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; }