コード例 #1
0
ファイル: GraphFile.cs プロジェクト: shaneasd/ConEdit
        public void Add(IEnumerable <ConversationNode> nodes, IEnumerable <NodeGroup> groups, ILocalizationEngine localization)
        {
            nodes  = nodes.Evaluate();
            groups = groups.ToList();

            SimpleUndoPair addActions = InnerAddNodes(nodes, groups, localization);

            bool addedNodes  = nodes.Any();
            bool addedGroups = groups.Any();

            if (addedNodes && addedGroups)
            {
                UndoableFile.Change(new GenericUndoAction(addActions.Undo, addActions.Redo, "Added nodes and groups"));
            }
            else if (addedNodes)
            {
                UndoableFile.Change(new GenericUndoAction(addActions.Undo, addActions.Redo, "Added nodes"));
            }
            else if (addedGroups)
            {
                UndoableFile.Change(new GenericUndoAction(addActions.Undo, addActions.Redo, "Added groups"));
            }
            else
            {
                throw new InternalLogicException("why would you do this?");
            }
        }
コード例 #2
0
ファイル: GraphFile.cs プロジェクト: shaneasd/ConEdit
        //TODO: MouseController and this should use the same logic (not sure which is better)
        public void Move(IEnumerable <ValueTuple <ConversationNode, PointF> > move)
        {
            //TODO: What happens if the nodes are in groups?
            Action undo = () => { };
            Action redo = () => { };

            foreach ((var node, var point) in move)
            {
                PointF origin = node.Renderer.Area.Center();
                undo += () => node.Renderer.MoveTo(origin);
                redo += () => node.Renderer.MoveTo(point);
            }
            UndoableFile.Change(new GenericUndoAction(undo, redo, "Moved nodes"));
        }
コード例 #3
0
ファイル: GraphFile.cs プロジェクト: shaneasd/ConEdit
        public Tuple <IEnumerable <ConversationNode>, IEnumerable <NodeGroup> > InsertInto(IEnumerable <GraphAndUI <NodeUIData> > nodeData, IEnumerable <NodeGroup> groups, PointF location, ILocalizationEngine localization)
        {
            var    nodes  = nodeData.Select(gnu => MakeNode(gnu.GraphData, gnu.UIData)).Evaluate();
            var    area   = NodeSet.GetArea(nodes.Concat <IRenderable <IGui> >(groups));
            PointF offset = location.Take(area.Center());

            foreach (var node in nodes)
            {
                node.Renderer.Offset(offset);
            }
            foreach (var group in groups)
            {
                group.Renderer.Offset(offset);
            }
            SimpleUndoPair addActions = InnerAddNodes(nodes, groups, localization);

            UndoableFile.Change(new GenericUndoAction(addActions, "Pasted"));
            return(Tuple.Create(nodes, groups));
        }
コード例 #4
0
ファイル: GraphFile.cs プロジェクト: shaneasd/ConEdit
 public void RemoveLinks(Output o)
 {
     UndoableFile.Change(new GenericUndoAction(o.DisconnectAllActions(), "Removed links"));
 }
コード例 #5
0
ファイル: GraphFile.cs プロジェクト: shaneasd/ConEdit
        public bool Remove(IEnumerable <ConversationNode> nodes, IEnumerable <NodeGroup> groups, ILocalizationEngine localization)
        {
            nodes  = nodes.ToList();
            groups = groups.ToList();
            bool removeNodes  = nodes.Any();
            bool removeGroups = groups.Any();

            List <Action> undoActions = new List <Action>();
            List <Action> redoActions = new List <Action>();

            if (nodes.Any(n => !CanRemoveFromData(n, () => false)))
            {
                if (!PromptNodeDeletion())
                {
                    return(false);
                }
            }

            if (removeNodes)
            {
                //Make sure all the nodes are added before trying to link them
                foreach (var node in nodes)
                {
                    var n = node;
                    undoActions.Add(() => { m_nodes.Add(n); });
                }

                foreach (var node in nodes)
                {
                    var n       = node;
                    var actions = n.GetNodeRemoveActions();

                    //Ensure that the localization engine is up to date in terms of usage of localized data
                    foreach (var parameter in n.Data.Parameters.OfType <ILocalizedStringParameter>())
                    {
                        SimpleUndoPair clearLocalization = localization.ClearLocalizationAction(Id <LocalizedStringType> .ConvertFrom(parameter.TypeId), parameter.Value);
                        undoActions.Add(clearLocalization.Undo);
                        redoActions.Add(clearLocalization.Redo);
                    }

                    var containingGroups = m_groups.Where(g => g.Contents.Contains(n.Data.NodeId)).Evaluate();
                    undoActions.Add(() =>
                    {
                        actions.Undo(); //Connect after adding the node
                        foreach (var group in containingGroups)
                        {
                            group.Contents.Add(n.Data.NodeId);
                        }
                        m_audioProvider.UpdateUsage(n);
                    });
                    redoActions.Add(() =>
                    {
                        actions.Redo(); //Disconnect before removing the node
                        m_nodes.Remove(n);
                        foreach (var group in containingGroups)
                        {
                            group.Contents.Remove(n.Data.NodeId);
                        }
                        NodesDeleted.Execute();
                    });
                }
            }
            if (removeGroups)
            {
                List <NodeGroup> toAdd = new List <NodeGroup>(groups);
                undoActions.Add(() =>
                {
                    m_groups.AddRange(toAdd);
                });
                redoActions.Add(() =>
                {
                    m_groups.RemoveRange(toAdd);
                });
            }

            Action undo = () => { using (m_audioProvider.SuppressUpdates()) foreach (Action action in undoActions)
                                      {
                                          action();
                                      }
            };
            Action redo = () => { using (m_audioProvider.SuppressUpdates()) foreach (Action action in redoActions)
                                      {
                                          action();
                                      }
            };

            string message;

            if (removeNodes && removeGroups)
            {
                message = "Deleted elements";
            }
            else if (removeNodes)
            {
                message = "Deleted nodes";
            }
            else if (removeGroups)
            {
                message = "Removed groupings";
            }
            else
            {
                throw new InternalLogicException("Something went wrong :(");
            }

            UndoableFile.Change(new GenericUndoAction(undo, redo, message));

            return(true);
        }
コード例 #6
0
ファイル: GraphFile.cs プロジェクト: shaneasd/ConEdit
        //TODO: Duplicate the IEditable with a new ID (must be deep copy of parameters)
        public Tuple <IEnumerable <ConversationNode>, IEnumerable <NodeGroup> > DuplicateInto(IEnumerable <GraphAndUI <NodeUIData> > nodeData, IEnumerable <NodeGroup> groups, PointF location, ILocalizationEngine localization)
        {
            var nodes = nodeData.Select(gnu => MakeNode(gnu.GraphData, gnu.UIData)).Evaluate();

            IEnumerable <IDynamicEnumParameter> localDynamicEnumerationParameters = nodes.SelectMany(n => n.Data.Parameters.OfType <IDynamicEnumParameter>().Where(p => p.Local));

            foreach (var ldep in localDynamicEnumerationParameters)
            {
                ldep.MergeInto(m_getDocumentSource(ldep));
            }

            if (nodes.Any() || groups.Any())
            {
                List <Action> undoActions = new List <Action>();
                List <Action> redoActions = new List <Action>();

                //Changes to these nodes don't need to be undoable as they're new nodes
                foreach (var node in nodes)
                {
                    //Duplicate the id of any localized string parameters to avoid the new node using the same id(s) as the old one
                    foreach (var p in node.Data.Parameters.OfType <LocalizedStringParameter>())
                    {
                        var result = localization.DuplicateActions(p.Value);
                        var action = p.SetValueAction(result.Item1);
                        if (action != null)
                        {
                            //Don't this node is a duplicate of another. The old node's localization data is irrelevant. We should never return to it.
                            //undoActions.Add(action.Value.Undo);
                            redoActions.Add(action.Value.Redo);
                            action.Value.Redo(); //Change the value immediately. The old value is irrelevant and we should never return to it.
                        }
                        result.Item2.Redo();     //Add the localization immediately. Otherwise when adding the node we won't know how to undo deletion of the node's localization data.
                        undoActions.Add(result.Item2.Undo);
                        redoActions.Add(result.Item2.Redo);
                    }

                    //TODO: AUDIO: Do we want to treat audio parameters like strings in that they have a meaningful value
                    //      or like localized strings in that they are a key into another system?
                    //foreach (var p in node.Data.Parameters.OfType<IAudioParameter>())
                    //{
                    //    //No need to update audio usage as this will occur when the node is added/removed
                    //    var audio = m_generateAudio(this);
                    //    var actions = p.SetValueAction(audio); //TODO: AUDIO: Investigate what happens to Audio parameter usage if you duplicate a node and then undo
                    //    undoActions.Add(actions.Value.Undo);
                    //    redoActions.Add(actions.Value.Redo);
                    //}
                    //foreach (var p in node.Data.Parameters.OfType<IAudioParameter>())
                    //{
                    //    var action = p.SetValueAction(new Audio(Guid.NewGuid().ToString()));
                    //    if (action != null)
                    //        action.Value.Redo(); //If we undo the whole operation the parameter wont exist so no need to ever undo this value change.
                    //}

                    var oldID = node.Data.NodeId;
                    node.Data.ChangeId(Id <NodeTemp> .New());
                    foreach (var group in groups)
                    {
                        if (group.Contents.Contains(oldID))
                        {
                            group.Contents.Remove(oldID);
                            group.Contents.Add(node.Data.NodeId);
                        }
                    }
                }

                var    area   = NodeSet.GetArea(nodes.Concat <IRenderable <IGui> >(groups));
                PointF offset = location.Take(area.Center());
                foreach (var node in nodes)
                {
                    node.Renderer.Offset(offset);
                }
                foreach (var group in groups)
                {
                    group.Renderer.Offset(offset);
                }

                SimpleUndoPair addActions = InnerAddNodes(nodes, groups, localization);

                Action undo = () =>
                {
                    undoActions.ForEach(a => a());
                    addActions.Undo();
                };
                Action redo = () =>
                {
                    redoActions.ForEach(a => a());
                    addActions.Redo();
                };

                UndoableFile.Change(new GenericUndoAction(undo, redo, "Pasted"));
            }

            return(Tuple.Create(nodes, groups));
        }