public static Point MeanPosition(IEnumerable <Wrappers.Wrapper> objects) { Point ret = new Point(0, 0); int num = 0; foreach (Wrappers.Wrapper obj in objects) { Wrappers.Edge link = obj as Wrappers.Edge; if (link != null && (link.Input != null || link.Output != null)) { continue; } ret.X += obj.Allocation.X + obj.Allocation.Width / 2.0; ret.Y += obj.Allocation.Y + obj.Allocation.Height / 2.0; num += 1; } if (num != 0) { ret.X = ret.X / num; ret.Y = ret.Y / num; } return(ret); }
public static IEnumerable <Wrappers.Edge> FilterLink(IEnumerable <Wrappers.Wrapper> wrappers) { foreach (Wrappers.Wrapper wrapper in wrappers) { Wrappers.Edge link = wrapper as Wrappers.Edge; if (link != null) { yield return(link); } } }
public void Paste(Wrappers.Node parent, Wrappers.Wrapper[] selection, int dx, int dy) { if (Clipboard.Internal.Empty) { return; } // See if this is a special link only paste List <Wrappers.Wrapper> clip = new List <Wrappers.Wrapper>(Clipboard.Internal.Objects); List <Undo.IAction> actions = new List <Undo.IAction>(); if (OnlyLinks(clip)) { // Add links between each first selected N-1 objects and selected object N List <KeyValuePair <Wrappers.Node, Wrappers.Node> > pairs = new List <KeyValuePair <Wrappers.Node, Wrappers.Node> >(GetLinkPairs(selection)); foreach (Wrappers.Wrapper obj in clip) { Wrappers.Edge link = (Wrappers.Edge)obj; foreach (KeyValuePair <Wrappers.Node, Wrappers.Node> pair in pairs) { Wrappers.Edge copy = (Wrappers.Edge)link.Copy(); copy.Attach(pair.Key, pair.Value); actions.Add(new Undo.AddObject(parent, copy)); } } } else { // Paste the new objects by making a copy (yes, again) Wrappers.Wrapper[] copied = MakeCopy(Clipboard.Internal.Objects); Point xy; xy = Utils.MeanPosition(copied); dx -= (int)xy.X; dy -= (int)xy.Y; foreach (Wrappers.Wrapper wrapper in copied) { wrapper.Allocation.X += dx; wrapper.Allocation.Y += dy; actions.Add(new Undo.AddObject(parent, wrapper)); } } Do(new Undo.Group(actions)); }
public Wrappers.Edge[] AddEdge(Wrappers.Node parent, Wrappers.Edge temp, Wrappers.Wrapper[] selection, double cx, double cy) { // Add links from source to target selection. If there is no target selection, use source selection also as target selection List <Undo.IAction> actions = new List <Undo.IAction>(); List <Wrappers.Edge> ret = new List <Wrappers.Edge>(); foreach (KeyValuePair <Wrappers.Node, Wrappers.Node> pair in GetLinkPairs(selection)) { Wrappers.Edge link; string name; if (pair.Key != null && pair.Value != null) { name = String.Format("{0}_to_{1}", pair.Key.Id, pair.Value.Id); } else { name = "link"; } if (temp == null) { link = (Wrappers.Edge)Wrappers.Wrapper.Wrap(new Cdn.Edge(name, pair.Key, pair.Value)); } else { link = (Wrappers.Edge)temp.CopyAsTemplate(); link.Id = name; link.Attach(pair.Key, pair.Value); } if (link.Empty) { link.Allocation.X = cx; link.Allocation.Y = cy; } ret.Add(link); actions.Add(new Undo.AddObject(parent, link)); } Do(new Undo.Group(actions)); return(ret.ToArray()); }
private List <Wrappers.Wrapper> NormalizeSelection(Wrappers.Node parent, Wrappers.Wrapper[] selection) { List <Wrappers.Wrapper> sel = new List <Wrappers.Wrapper>(selection); if (parent != null) { foreach (Wrappers.Wrapper child in parent.Children) { if (sel.Contains(child) || !(child is Wrappers.Edge)) { continue; } Wrappers.Edge link = (Wrappers.Edge)child; if (sel.Contains(link.Output) || sel.Contains(link.Input)) { sel.Insert(0, link); } } } else { if (OnlyLinks(sel)) { // Only links, that is fine and special! return(sel); } sel.RemoveAll(delegate(Wrappers.Wrapper wrapper) { Wrappers.Edge link = wrapper as Wrappers.Edge; return(link != null && !(sel.Contains(link.Output) && sel.Contains(link.Input))); }); } return(sel); }
private Wrappers.Wrapper[] MakeCopy(Wrappers.Wrapper[] selection) { List <Wrappers.Wrapper> sel = NormalizeSelection(selection); if (sel.Count == 0) { return(new Wrappers.Wrapper[] {}); } Dictionary <Cdn.Object, Wrappers.Wrapper> map = new Dictionary <Cdn.Object, Wrappers.Wrapper>(); List <Wrappers.Wrapper> copied = new List <Wrappers.Wrapper>(); // Create copies and store in a map the mapping from the orig to the copy foreach (Wrappers.Wrapper wrapper in sel) { Wrappers.Wrapper copy = wrapper.Copy(); map[wrapper] = copy; copied.Add(copy); } // Reconnect links foreach (Wrappers.Edge link in Utils.FilterLink(sel)) { if ((link.Input != null && map.ContainsKey(link.Input)) && (link.Output != null && map.ContainsKey(link.Output))) { Wrappers.Node from = map[link.Input] as Wrappers.Node; Wrappers.Node to = map[link.Output] as Wrappers.Node; Wrappers.Edge target = (Wrappers.Edge)map[link.WrappedObject]; target.Attach(from, to); } } return(copied.ToArray()); }
public Wrappers.Node Group(Wrappers.Node parent, Wrappers.Wrapper[] selection) { List <Wrappers.Wrapper> sel = new List <Wrappers.Wrapper>(selection); // Find all the links that go from or to the group, but are not fully in there // TODO: automatically create interfaces when needed foreach (Wrappers.Edge link in Utils.FilterLink(parent.Children)) { bool containsTo = sel.Contains(link.Output); bool containsFrom = sel.Contains(link.Input); if (containsTo != containsFrom) { throw new Exception(String.Format("Links outside the group are acting on different objects in the group. The current behavior of the network cannot be preserved.")); } else if (containsTo && containsFrom && !sel.Contains(link)) { sel.Add(link); } } // Collect all objects and link fully encapsulated in the group List <Wrappers.Wrapper> ingroup = new List <Wrappers.Wrapper>(); List <Undo.IAction> actions = new List <Undo.IAction>(); foreach (Wrappers.Wrapper wrapper in sel) { Wrappers.Edge link = wrapper as Wrappers.Edge; if (link == null || (sel.Contains(link.Output) && sel.Contains(link.Input))) { ingroup.Add(wrapper); } // Also fill the first actions that remove all the objects from the parent actions.Add(new Undo.RemoveObject(parent, wrapper)); } // After objects are removed, we create a new group Point xy; xy = Utils.MeanPosition(ingroup); Wrappers.Node newGroup = new Wrappers.Node(); newGroup.Allocation.X = (int)xy.X; newGroup.Allocation.Y = (int)xy.Y; actions.Add(new Undo.AddObject(parent, newGroup)); // Then we add all the 'ingroup' objects to the group foreach (Wrappers.Wrapper wrapper in ingroup) { // Move object to center at 0, 0 in the group if (!(wrapper is Wrappers.Edge)) { actions.Add(new Undo.MoveObject(wrapper, -(int)xy.X, -(int)xy.Y)); } // Add object to the group actions.Add(new Undo.AddObject(newGroup, wrapper)); } Do(new Undo.AddNode(newGroup, actions)); return(newGroup); }
public Anchor(Wrappers.Edge link, Point location, bool isFrom) { d_edge = link; d_location = new Point(location); d_isFrom = isFrom; }