public void updateUndoStatus(String oldMarkup, bool check = false, TwoWayCommand additionalUndoOperations = null)
        {
            //This is a hacky way to check for changes (optionally) it should not be needed when the popup editor is overhauled.
            //You can remove check and keep only the line in the if statement when you no longer need the check.
            String currentMarkup = UnformattedRml;

            if (!check || currentMarkup != oldMarkup)
            {
                if (additionalUndoOperations == null)
                {
                    undoBuffer.pushAndSkip(new TwoWayDelegateCommand <String, String>(currentMarkup, oldMarkup, new TwoWayDelegateCommand <string, string> .Funcs()
                    {
                        ExecuteFunc = undoRedoCallback,
                        UndoFunc    = undoRedoCallback
                    }));
                }
                else
                {
                    undoBuffer.pushAndSkip(new TwoWayDelegateCommand <String, String>(currentMarkup, oldMarkup, new TwoWayDelegateCommand <string, string> .Funcs()
                    {
                        ExecuteFunc = rml =>
                        {
                            undoRedoCallback(rml);
                            additionalUndoOperations.execute();
                        },
                        UndoFunc = rml =>
                        {
                            undoRedoCallback(rml);
                            additionalUndoOperations.undo();
                        }
                    }));
                }
            }
        }
        public void editSlide(Slide slide)
        {
            bool openedEditContext = false;

            if (slide != lastEditSlide)
            {
                openedEditContext = openEditorContextForSlide(slide);
            }
            else
            {
                if (slideEditorContext != null)
                {
                    slideEditorContext.slideNameChanged("Slide " + (slideshow.indexOf(slide) + 1));
                }
                else
                {
                    openEditorContextForSlide(slide); //If the slide context is null the timeline editor is open, switch back to slide editing.
                    //We ignore the context open result, because we do not care about undo in this situation
                }
            }

            if (openedEditContext)
            {
                if (lastEditSlide != null && allowUndoCreation)
                {
                    undoBuffer.pushAndSkip(new TwoWayDelegateCommand <Slide, Slide>(slide, lastEditSlide, new TwoWayDelegateCommand <Slide, Slide> .Funcs()
                    {
                        ExecuteFunc = (redoItem) =>
                        {
                            //Hacky, but we cannot modify the active slide without messing up the classes that triggered this.
                            ThreadManager.invoke(new Action(delegate()
                            {
                                allowUndoCreation = false;
                                if (SlideSelected != null)
                                {
                                    SlideSelected.Invoke(redoItem, IEnumerableUtil <Slide> .EmptyIterator);
                                }
                                allowUndoCreation = true;
                            }));
                        },
                        UndoFunc = (undoItem) =>
                        {
                            //Hacky, but we cannot modify the active slide without messing up the classes that triggered this.
                            ThreadManager.invoke(new Action(delegate()
                            {
                                allowUndoCreation = false;
                                if (SlideSelected != null)
                                {
                                    SlideSelected.Invoke(undoItem, IEnumerableUtil <Slide> .EmptyIterator);
                                }
                                allowUndoCreation = true;
                            }));
                        },
                    })
                                           );
                }
                lastEditSlide = slide;
                uiCallback.CurrentDirectory = slide.UniqueName;
            }
        }
 /// <summary>
 /// Push a new state onto the undo/redo buffer, will erase anything after the current undo.
 /// This will use the passed states for undo and redo.
 /// </summary>
 public void pushUndoState(CameraPosition undoState, CameraPosition redoState)
 {
     //Make sure the undo and redo states are sufficiently different, otherwise ignore this new entry
     if ((undoState.Translation - redoState.Translation).length2() > 0.001 || (undoState.LookAt - redoState.LookAt).length2() > 0.001)
     {
         undoRedoBuffer.pushAndSkip(new TwoWayDelegateCommand <CameraPosition, CameraPosition>(redoState, undoState, new TwoWayDelegateCommand <CameraPosition, CameraPosition> .Funcs()
         {
             ExecuteFunc = state =>
             {
                 this.setPosition(state, GuiFrameworkCamerasInterface.CameraTransitionTime);
                 if (OnRedo != null)
                 {
                     OnRedo.Invoke(this);
                 }
             },
             UndoFunc = state =>
             {
                 this.setPosition(state, GuiFrameworkCamerasInterface.CameraTransitionTime);
                 if (OnUndo != null)
                 {
                     OnUndo.Invoke(this);
                 }
             }
         }));
         if (OnUndoRedoChanged != null)
         {
             OnUndoRedoChanged.Invoke(this);
         }
     }
 }
 /// <summary>
 /// Push a new state onto the undo/redo buffer, will erase anything after the current undo.
 /// This will use the passed states for undo and redo.
 /// </summary>
 public void pushUndoState(MusclePosition undoPosition, MusclePosition redoPosition)
 {
     poseUndoRedoBuffer.pushAndSkip(new TwoWayDelegateCommand <MusclePosition, MusclePosition>(redoPosition, undoPosition, new TwoWayDelegateCommand <MusclePosition, MusclePosition> .Funcs()
     {
         ExecuteFunc = position =>
         {
             position.preview();
             if (OnRedo != null)
             {
                 OnRedo.Invoke(this);
             }
         },
         UndoFunc = position =>
         {
             position.preview();
             if (OnUndo != null)
             {
                 OnUndo.Invoke(this);
             }
         }
     }));
     if (OnUndoRedoChanged != null)
     {
         OnUndoRedoChanged.Invoke(this);
     }
 }