예제 #1
0
파일: Utils.cs 프로젝트: codyn-net/studio
        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);
        }
예제 #2
0
파일: Utils.cs 프로젝트: codyn-net/studio
        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);
                }
            }
        }
예제 #3
0
        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));
        }
예제 #4
0
        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());
        }
예제 #5
0
        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);
        }
예제 #6
0
        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());
        }
예제 #7
0
        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);
        }
예제 #8
0
파일: Anchor.cs 프로젝트: codyn-net/studio
 public Anchor(Wrappers.Edge link, Point location, bool isFrom)
 {
     d_edge     = link;
     d_location = new Point(location);
     d_isFrom   = isFrom;
 }