From 340004608051248e80c915c25ffa2ad6f7e42f25 Mon Sep 17 00:00:00 2001 From: codeimp Date: Fri, 10 Jul 2009 13:56:22 +0000 Subject: [PATCH] @ some undo/redo fixes @ working on NumericTextbox versions with up/down buttons and dropdown lists --- Source/Core/Builder.csproj | 10 +-- ...r.cs => ButtonsNumericTextbox.Designer.cs} | 7 +- ...ricTextbox.cs => ButtonsNumericTextbox.cs} | 73 +++++++++++++------ ...extbox.resx => ButtonsNumericTextbox.resx} | 0 Source/Core/Controls/NumericTextbox.cs | 7 ++ Source/Core/Editing/CopyPasteManager.cs | 6 +- Source/Core/Editing/EditModeInfo.cs | 2 +- Source/Core/Editing/EditingManager.cs | 41 ++++++++++- Source/Core/Editing/UndoManager.cs | 66 +++++++++++------ Source/Core/General/General.cs | 48 ++---------- Source/Core/General/MapManager.cs | 2 +- .../ClassicModes/BrightnessMode.cs | 8 +- .../ClassicModes/EditSelectionMode.cs | 4 + .../BuilderModes/Interface/FindReplaceForm.cs | 4 +- 14 files changed, 170 insertions(+), 108 deletions(-) rename Source/Core/Controls/{ClickableNumericTextbox.Designer.cs => ButtonsNumericTextbox.Designer.cs} (89%) rename Source/Core/Controls/{ClickableNumericTextbox.cs => ButtonsNumericTextbox.cs} (60%) rename Source/Core/Controls/{ClickableNumericTextbox.resx => ButtonsNumericTextbox.resx} (100%) diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 1919e443..3ecb70ca 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -231,11 +231,11 @@ CheckboxArrayControl.cs - + UserControl - - ClickableNumericTextbox.cs + + ButtonsNumericTextbox.cs UserControl @@ -833,9 +833,9 @@ Designer ArgumentBox.cs - + Designer - ClickableNumericTextbox.cs + ButtonsNumericTextbox.cs Designer diff --git a/Source/Core/Controls/ClickableNumericTextbox.Designer.cs b/Source/Core/Controls/ButtonsNumericTextbox.Designer.cs similarity index 89% rename from Source/Core/Controls/ClickableNumericTextbox.Designer.cs rename to Source/Core/Controls/ButtonsNumericTextbox.Designer.cs index 6f08c2d1..7e80a8bb 100644 --- a/Source/Core/Controls/ClickableNumericTextbox.Designer.cs +++ b/Source/Core/Controls/ButtonsNumericTextbox.Designer.cs @@ -1,6 +1,6 @@ namespace CodeImp.DoomBuilder.Controls { - partial class ClickableNumericTextbox + partial class ButtonsNumericTextbox { /// /// Required designer variable. @@ -35,12 +35,10 @@ namespace CodeImp.DoomBuilder.Controls // buttons // this.buttons.Location = new System.Drawing.Point(163, 0); - this.buttons.Maximum = 200; - this.buttons.Minimum = 1; + this.buttons.Minimum = -100; this.buttons.Name = "buttons"; this.buttons.Size = new System.Drawing.Size(18, 24); this.buttons.TabIndex = 1; - this.buttons.Value = 1; this.buttons.ValueChanged += new System.EventHandler(this.buttons_ValueChanged); // // textbox @@ -54,7 +52,6 @@ namespace CodeImp.DoomBuilder.Controls this.textbox.Size = new System.Drawing.Size(160, 20); this.textbox.TabIndex = 0; this.textbox.TextChanged += new System.EventHandler(this.textbox_TextChanged); - this.textbox.Leave += new System.EventHandler(this.textbox_Leave); // // ClickableNumericTextbox // diff --git a/Source/Core/Controls/ClickableNumericTextbox.cs b/Source/Core/Controls/ButtonsNumericTextbox.cs similarity index 60% rename from Source/Core/Controls/ClickableNumericTextbox.cs rename to Source/Core/Controls/ButtonsNumericTextbox.cs index d1107c2d..a1f06004 100644 --- a/Source/Core/Controls/ClickableNumericTextbox.cs +++ b/Source/Core/Controls/ButtonsNumericTextbox.cs @@ -32,29 +32,35 @@ using CodeImp.DoomBuilder.Editing; namespace CodeImp.DoomBuilder.Controls { - public partial class ClickableNumericTextbox : UserControl + public partial class ButtonsNumericTextbox : UserControl { #region ================== Events - public event EventHandler ValueChanged; + public event EventHandler TextChanged; #endregion - - #region ================== Properties - public int Minimum { get { return buttons.Minimum; } set { buttons.Minimum = value; } } - public int Maximum { get { return buttons.Maximum; } set { buttons.Maximum = value; } } + #region ================== Variables + + private bool ignorebuttonchange = false; + + #endregion + + #region ================== Properties + public bool AllowNegative { get { return textbox.AllowNegative; } set { textbox.AllowNegative = value; } } - public int Value { get { return buttons.Value; } set { buttons.Value = value; } } + public bool AllowRelative { get { return textbox.AllowRelative; } set { textbox.AllowRelative = value; } } + public string Text { get { return textbox.Text; } set { textbox.Text = value; } } #endregion #region ================== Constructor / Disposer // Constructor - public ClickableNumericTextbox() + public ButtonsNumericTextbox() { InitializeComponent(); + buttons.Value = 0; } #endregion @@ -82,31 +88,52 @@ namespace CodeImp.DoomBuilder.Controls buttons.Left = textbox.Width + 2; this.Height = buttons.Height; } - - #endregion - #region ================== Control - // Text in textbox changes private void textbox_TextChanged(object sender, EventArgs e) { - int result = textbox.GetResult(buttons.Value); - if((result >= buttons.Minimum) && (result <= buttons.Maximum)) buttons.Value = result; + if(TextChanged != null) TextChanged(sender, e); + buttons.Enabled = !textbox.CheckIsRelative(); } - - // Textbox loses focus - private void textbox_Leave(object sender, EventArgs e) - { - textbox.Text = buttons.Value.ToString(); - } - + // Buttons changed private void buttons_ValueChanged(object sender, EventArgs e) { - textbox.Text = buttons.Value.ToString(); - if(ValueChanged != null) ValueChanged(this, e); + if(!ignorebuttonchange) + { + ignorebuttonchange = true; + if(!textbox.CheckIsRelative()) + { + int newvalue = textbox.GetResult(0) - buttons.Value; + textbox.Text = newvalue.ToString(); + } + buttons.Value = 0; + ignorebuttonchange = false; + } } #endregion + + #region ================== Methods + + // This checks if the number is relative + public bool CheckIsRelative() + { + return textbox.CheckIsRelative(); + } + + // This determines the result value + public int GetResult(int original) + { + return textbox.GetResult(original); + } + + // This determines the result value + public float GetResultFloat(float original) + { + return textbox.GetResultFloat(original); + } + + #endregion } } diff --git a/Source/Core/Controls/ClickableNumericTextbox.resx b/Source/Core/Controls/ButtonsNumericTextbox.resx similarity index 100% rename from Source/Core/Controls/ClickableNumericTextbox.resx rename to Source/Core/Controls/ButtonsNumericTextbox.resx diff --git a/Source/Core/Controls/NumericTextbox.cs b/Source/Core/Controls/NumericTextbox.cs index ab532393..610dfb2d 100644 --- a/Source/Core/Controls/NumericTextbox.cs +++ b/Source/Core/Controls/NumericTextbox.cs @@ -185,6 +185,13 @@ namespace CodeImp.DoomBuilder.Controls base.OnValidating(e); } + // This checks if the number is relative + public bool CheckIsRelative() + { + // Prefixed with ++ or --? + return (this.Text.StartsWith("++") || this.Text.StartsWith("--")); + } + // This determines the result value public int GetResult(int original) { diff --git a/Source/Core/Editing/CopyPasteManager.cs b/Source/Core/Editing/CopyPasteManager.cs index b7f12b72..799c45bb 100644 --- a/Source/Core/Editing/CopyPasteManager.cs +++ b/Source/Core/Editing/CopyPasteManager.cs @@ -227,7 +227,7 @@ namespace CodeImp.DoomBuilder.Editing if(Clipboard.ContainsData(CLIPBOARD_DATA_FORMAT)) { // Cancel volatile mode - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Let the plugins know if(General.Plugins.OnPasteBegin(options)) @@ -391,7 +391,7 @@ namespace CodeImp.DoomBuilder.Editing PasteOptions options = General.Settings.PasteOptions.Copy(); // Cancel volatile mode - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Let the plugins know if(General.Plugins.OnPasteBegin(options)) @@ -452,7 +452,7 @@ namespace CodeImp.DoomBuilder.Editing if(File.Exists(lastprefabfile)) { // Cancel volatile mode - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Let the plugins know if(General.Plugins.OnPasteBegin(options)) diff --git a/Source/Core/Editing/EditModeInfo.cs b/Source/Core/Editing/EditModeInfo.cs index 01f52fae..8681283a 100644 --- a/Source/Core/Editing/EditModeInfo.cs +++ b/Source/Core/Editing/EditModeInfo.cs @@ -149,7 +149,7 @@ namespace CodeImp.DoomBuilder.Editing if((General.Editing.Mode != null) && General.Editing.Mode.Attributes.Volatile && this.attribs.Volatile) { // First cancel previous volatile mode - General.CancelVolatileMode(); + General.Editing.CancelVolatileMode(); } // When in VisualMode and switching to the same VisualMode, then we switch back to the previous classic mode diff --git a/Source/Core/Editing/EditingManager.cs b/Source/Core/Editing/EditingManager.cs index fd38eddd..83506995 100644 --- a/Source/Core/Editing/EditingManager.cs +++ b/Source/Core/Editing/EditingManager.cs @@ -61,6 +61,7 @@ namespace CodeImp.DoomBuilder.Editing private Type prevmode; private Type prevstablemode; private Type prevclassicmode; + private bool disengaging; // Disposing private bool isdisposed = false; @@ -178,7 +179,43 @@ namespace CodeImp.DoomBuilder.Editing #endregion #region ================== Methods - + + // This cancels a volatile mode, as if the user presses cancel + public bool CancelVolatileMode() + { + // Volatile mode? + if((General.Map != null) & (mode != null) && mode.Attributes.Volatile && !disengaging) + { + // Cancel + disengaging = true; + mode.OnCancel(); + return true; + } + else + { + // Mode is not volatile + return false; + } + } + + // This disengages a volatile mode, leaving the choice to cancel or accept to the editing mode + public bool DisengageVolatileMode() + { + // Volatile mode? + if((General.Map != null) && (mode != null) && mode.Attributes.Volatile && !disengaging) + { + // Change back to normal mode + disengaging = true; + ChangeMode(prevstablemode.Name); + return true; + } + else + { + // Mode is not volatile + return false; + } + } + // This returns specific editing mode info by name internal EditModeInfo GetEditModeInfo(string editmodename) { @@ -317,6 +354,7 @@ namespace CodeImp.DoomBuilder.Editing if(General.Plugins.ModeChanges(oldmode, newmode)) { // Disenagage old mode + disengaging = true; if(oldmode != null) oldmode.OnDisengage(); // Reset cursor @@ -326,6 +364,7 @@ namespace CodeImp.DoomBuilder.Editing General.WriteLogLine("Editing mode changes from " + TypeNameOrNull(oldmode) + " to " + TypeNameOrNull(nextmode)); General.WriteLogLine("Previous stable mode is " + TypeNameOrNull(prevstablemode) + ", previous classic mode is " + TypeNameOrNull(prevclassicmode)); mode = newmode; + disengaging = false; // Engage new mode if(newmode != null) newmode.OnEngage(); diff --git a/Source/Core/Editing/UndoManager.cs b/Source/Core/Editing/UndoManager.cs index 5cacb00b..954f831e 100644 --- a/Source/Core/Editing/UndoManager.cs +++ b/Source/Core/Editing/UndoManager.cs @@ -222,6 +222,14 @@ namespace CodeImp.DoomBuilder.Editing // Dispose all redos foreach(UndoSnapshot u in redos) u.Dispose(); redos.Clear(); + + // If the current snapshot is meant for redo, trash it also + if(isundosnapshot && (snapshot != null)) + { + FinishRecording(); + isundosnapshot = false; + snapshot = null; + } } } @@ -233,6 +241,14 @@ namespace CodeImp.DoomBuilder.Editing // Dispose all undos foreach(UndoSnapshot u in undos) u.Dispose(); undos.Clear(); + + // If the current snapshot is meant for undo, trash it also + if(!isundosnapshot && (snapshot != null)) + { + FinishRecording(); + isundosnapshot = false; + snapshot = null; + } } } @@ -549,34 +565,38 @@ namespace CodeImp.DoomBuilder.Editing } // This removes a previously made undo - public void WithdrawUndo(int ticket) + public void WithdrawUndo() { + // Previously, withdrawing an undo level was possible, because each undo level contained + // an entire snapshot of the map. With the new progressive undo system, you cannot ignore + // any changes, so we have to actually perform the undo and trash the redo it creates. + PerformUndo(1); + ClearAllRedos(); + + /* // Anything to undo? - if(undos.Count > 0) + if((undos.Count > 0) || ((snapshot != null) && !isundosnapshot)) { - // Check if the ticket id matches - if(ticket == undos[0].TicketID) + if(snapshot != null) { - General.WriteLogLine("Withdrawing undo snapshot \"" + undos[0].Description + "\", Ticket ID " + ticket + "..."); + General.WriteLogLine("Withdrawing undo snapshot \"" + snapshot.Description + "\", Ticket ID " + snapshot.TicketID + "..."); - if(snapshot != null) - { - // Just trash this recording - // You must call CreateUndo first before making any more changes - FinishRecording(); - isundosnapshot = false; - snapshot = null; - } - else - { - throw new Exception("No undo is recording that can be withdrawn"); - } - - // Update - dobackgroundwork = true; - General.MainWindow.UpdateInterface(); + // Just trash this recording + // You must call CreateUndo first before making any more changes + FinishRecording(); + isundosnapshot = false; + snapshot = null; } + else + { + throw new Exception("No undo is recording that can be withdrawn"); + } + + // Update + dobackgroundwork = true; + General.MainWindow.UpdateInterface(); } + */ } // This performs an undo @@ -605,7 +625,7 @@ namespace CodeImp.DoomBuilder.Editing { // Cancel volatile mode, if any // This returns false when mode was not volatile - if(!General.CancelVolatileMode()) + if(!General.Editing.CancelVolatileMode()) { // Go for all levels to undo for(int lvl = 0; lvl < levels; lvl++) @@ -736,7 +756,7 @@ namespace CodeImp.DoomBuilder.Editing { // Cancel volatile mode, if any // This returns false when mode was not volatile - if(!General.CancelVolatileMode()) + if(!General.Editing.CancelVolatileMode()) { // Go for all levels to undo for(int lvl = 0; lvl < levels; lvl++) diff --git a/Source/Core/General/General.cs b/Source/Core/General/General.cs index 84b9580f..58a78c5f 100644 --- a/Source/Core/General/General.cs +++ b/Source/Core/General/General.cs @@ -891,40 +891,6 @@ namespace CodeImp.DoomBuilder #endregion #region ================== Management - - // This cancels a volatile mode, as if the user presses cancel - public static bool CancelVolatileMode() - { - // Volatile mode? - if((map != null) & (editing.Mode != null) && editing.Mode.Attributes.Volatile) - { - // Cancel - editing.Mode.OnCancel(); - return true; - } - else - { - // Mode is not volatile - return false; - } - } - - // This disengages a volatile mode, leaving the choice to cancel or accept to the editing mode - public static bool DisengageVolatileMode() - { - // Volatile mode? - if((map != null) && (editing.Mode != null) && editing.Mode.Attributes.Volatile) - { - // Change back to normal mode - editing.ChangeMode(editing.PreviousStableMode.Name); - return true; - } - else - { - // Mode is not volatile - return false; - } - } // This creates a new map [BeginAction("newmap")] @@ -934,7 +900,7 @@ namespace CodeImp.DoomBuilder MapOptionsForm optionswindow; // Cancel volatile mode, if any - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Ask the user to save changes (if any) if(General.AskSaveMap()) @@ -1005,7 +971,7 @@ namespace CodeImp.DoomBuilder internal static bool CloseMap() { // Cancel volatile mode, if any - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Ask the user to save changes (if any) if(General.AskSaveMap()) @@ -1050,7 +1016,7 @@ namespace CodeImp.DoomBuilder OpenFileDialog openfile; // Cancel volatile mode, if any - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Open map file dialog openfile = new OpenFileDialog(); @@ -1078,7 +1044,7 @@ namespace CodeImp.DoomBuilder OpenMapOptionsForm openmapwindow; // Cancel volatile mode, if any - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Ask the user to save changes (if any) if(General.AskSaveMap()) @@ -1156,7 +1122,7 @@ namespace CodeImp.DoomBuilder bool result = false; // Cancel volatile mode, if any - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Check if a wad file is known if(map.FilePathName == "") @@ -1210,7 +1176,7 @@ namespace CodeImp.DoomBuilder bool result = false; // Cancel volatile mode, if any - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Show save as dialog savefile = new SaveFileDialog(); @@ -1267,7 +1233,7 @@ namespace CodeImp.DoomBuilder bool result = false; // Cancel volatile mode, if any - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Show save as dialog savefile = new SaveFileDialog(); diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index 82a90a15..000e50dc 100644 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -1549,7 +1549,7 @@ namespace CodeImp.DoomBuilder internal void ShowMapOptions() { // Cancel volatile mode, if any - General.DisengageVolatileMode(); + General.Editing.DisengageVolatileMode(); // Show map options dialog MapOptionsForm optionsform = new MapOptionsForm(options); diff --git a/Source/Plugins/BuilderModes/ClassicModes/BrightnessMode.cs b/Source/Plugins/BuilderModes/ClassicModes/BrightnessMode.cs index 2c3fefbd..bd0166b5 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/BrightnessMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/BrightnessMode.cs @@ -729,9 +729,13 @@ namespace CodeImp.DoomBuilder.BuilderModes mode = ModifyMode.None; sectorbrightness = null; - // Nothing changed? Then writhdraw the undo + // Nothing changed? Then withdraw the undo if(editstartpos.Y == Cursor.Position.Y) - General.Map.UndoRedo.WithdrawUndo(undoticket); + { + if((General.Map.UndoRedo.NextUndo != null) && + (General.Map.UndoRedo.NextUndo.TicketID == undoticket)) + General.Map.UndoRedo.WithdrawUndo(); + } // Update General.Map.Map.Update(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs index b019fec9..ae491a22 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs @@ -829,6 +829,10 @@ namespace CodeImp.DoomBuilder.BuilderModes index = 0; foreach(Thing t in selectedthings) t.Dispose(); + + // Withdraw the undo + if(General.Map.UndoRedo.NextUndo != null) + General.Map.UndoRedo.WithdrawUndo(); } else { diff --git a/Source/Plugins/BuilderModes/Interface/FindReplaceForm.cs b/Source/Plugins/BuilderModes/Interface/FindReplaceForm.cs index 2a03356c..5cad2443 100644 --- a/Source/Plugins/BuilderModes/Interface/FindReplaceForm.cs +++ b/Source/Plugins/BuilderModes/Interface/FindReplaceForm.cs @@ -176,9 +176,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Withdraw the undo step if nothing was replaced if (resultslist.Items.Count <= 0) - { - General.Map.UndoRedo.WithdrawUndo(ticket); - } + General.Map.UndoRedo.WithdrawUndo(); } else {