diff --git a/McBitFont/ChangeHistory.cs b/McBitFont/ChangeHistory.cs index 23d90a0..d96713c 100644 --- a/McBitFont/ChangeHistory.cs +++ b/McBitFont/ChangeHistory.cs @@ -6,19 +6,18 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; -using static McBitFont.ChangeHistory; using static McBitFont.MainForm; namespace McBitFont { internal class ChangeHistory { private MainForm mainForm; - private List timeline = []; + private List timeline = []; private List canvasChanges = []; private List> fontChanges = []; - private List selFrameChanges = []; + private List selectionChanges = []; private int canvasIndex = 0; private int fontIndex = 0; - private int selFrameIndex = 0; + private int selectionIndex = 0; public int Depth { get; set; } public int Index { get; set; } = -1; public int Count { @@ -30,7 +29,6 @@ namespace McBitFont { public int Redos { get { return Index < 0 ? Count : Count - Index - 1; } } - public bool HistoryAction { get; set; } = false; public bool Doing { get; set; } = false; // Constructor @@ -38,32 +36,34 @@ namespace McBitFont { timeline = []; canvasChanges = []; fontChanges = []; - selFrameChanges = []; + selectionChanges = []; mainForm = form; Depth = depth; ResetIndices(); Add(); - HistoryAction = false; Doing = false; } + + private void ResetIndices() { Index = -1; canvasIndex = 0; fontIndex = 0; - selFrameIndex = 0; + selectionIndex = 0; } public enum ChangeType { None = 0, - Canvas = 1, // Changes made to canvas - Font = 2, // Symbol width has been changed - Frame = 3 // Selected another frame + Canvas = 1, // Changes made to canvas + Font = 2, // Symbol width has been changed + Selection = 3 // Selected another frame + } + + public class ChangeEvent(ChangeType type, FrameMiniature? canvas = null) { + public ChangeType Type { get; set; } = type; + public FrameMiniature? Canvas { get; set; } = canvas; } - //public class ChangeEvent(ChangeType type, int index) { - // public ChangeType Type { get; set; } = type; - // public int Index { get; set; } = index; - //} private static FrameMiniature CopyFrameSimple(FrameMiniature f) { FrameMiniature newf = new(f.code, f.width, f.height); @@ -75,14 +75,14 @@ namespace McBitFont { timeline.Clear(); canvasChanges.Clear(); fontChanges.Clear(); - selFrameChanges.Clear(); + selectionChanges.Clear(); ResetIndices(); Add(); } // Remove from a proper list by change type - private bool RemoveByType(ChangeType ct, bool first = true) { - switch (ct) { + private bool RemoveByType(ChangeEvent ce, bool first = true) { + switch (ce.Type) { case ChangeType.Canvas: if (canvasChanges.Count <= 1) return false; if ((first && canvasIndex > 0) || (!first && canvasIndex == canvasChanges.Count - 1)) canvasIndex--; @@ -91,12 +91,20 @@ namespace McBitFont { case ChangeType.Font: if (fontChanges.Count <= 1) return false; if ((first && fontIndex > 0) || (!first && fontIndex == fontChanges.Count - 1)) fontIndex--; + if (ce.Canvas != null) { + if ((first && canvasIndex > 0) || (!first && canvasIndex == canvasChanges.Count - 1)) canvasIndex--; + canvasChanges.Remove((FrameMiniature)ce.Canvas); + } fontChanges.RemoveAt(first ? 0 : fontChanges.Count - 1); break; - case ChangeType.Frame: - if (selFrameChanges.Count <= 1) return false; - if ((first && selFrameIndex > 0) || (!first && selFrameIndex == selFrameChanges.Count - 1)) selFrameIndex--; - selFrameChanges.RemoveAt(first ? 0 : selFrameChanges.Count - 1); + case ChangeType.Selection: + if (selectionChanges.Count <= 1) return false; + if ((first && selectionIndex > 0) || (!first && selectionIndex == selectionChanges.Count - 1)) selectionIndex--; + if (ce.Canvas != null) { + if ((first && canvasIndex > 0) || (!first && canvasIndex == canvasChanges.Count - 1)) canvasIndex--; + canvasChanges.Remove((FrameMiniature)ce.Canvas); + } + selectionChanges.RemoveAt(first ? 0 : selectionChanges.Count - 1); break; default: return false; @@ -111,8 +119,8 @@ namespace McBitFont { // Remove oldest event private bool RemoveOldest() { if (Count == 0) return false; - ChangeType ct = timeline.First(); - RemoveByType(ct); + ChangeEvent ce = timeline.First(); + RemoveByType(ce); return true; } @@ -120,8 +128,8 @@ namespace McBitFont { // Remove last event public bool RemoveLast() { if (Count == 0) return false; - var ct = timeline.Last(); - RemoveByType(ct, false); + var ce = timeline.Last(); + RemoveByType(ce, false); return true; } @@ -134,17 +142,7 @@ namespace McBitFont { timeline.RemoveRange( Index + 1, Count - Index - 1); canvasChanges.RemoveRange( canvasIndex + 1, canvasChanges.Count - canvasIndex - 1); fontChanges.RemoveRange( fontIndex + 1, fontChanges.Count - fontIndex - 1); - selFrameChanges.RemoveRange(selFrameIndex + 1, selFrameChanges.Count - selFrameIndex - 1); - } - } - - // Checks and resets HistoryAction property to abort Add action - private bool CheckHistoryAction() { - if (HistoryAction) { - HistoryAction = false; - return true; - } else { - return false; + selectionChanges.RemoveRange(selectionIndex + 1, selectionChanges.Count - selectionIndex - 1); } } @@ -158,24 +156,23 @@ namespace McBitFont { } // Add canvas change - public void Add(FrameMiniature f, bool useIndex = true) { - if (Doing) return; - if (useIndex && CheckHistoryAction()) return; + public FrameMiniature? Add(FrameMiniature f, bool useIndex = true) { + if (Doing) return null ; TruncateTail(); - if (Count > Depth) RemoveOldest(); + if (Count >= Depth) RemoveOldest(); canvasChanges.Add(CopyFrameSimple(f)); if (useIndex) { - timeline.Add(ChangeType.Canvas); + timeline.Add(new ChangeEvent(ChangeType.Canvas)); Index++; canvasIndex++; } + return canvasChanges.Last(); } // Add Font change public void Add(List ff, bool useIndex = true) { if (Doing) return; - if (useIndex && CheckHistoryAction()) return; TruncateTail(); var l = new List(); @@ -183,44 +180,52 @@ namespace McBitFont { l.Add(CopyFrameSimple(f)); } - if (Count > Depth) RemoveOldest(); + if (Count >= Depth) RemoveOldest(); fontChanges.Add(l); if (useIndex) { - timeline.Add(ChangeType.Font); + var canv = Add(mainForm.f, false); + canvasIndex++; + timeline.Add(new ChangeEvent(ChangeType.Font, canv)); Index++; fontIndex++; - Add(mainForm.f); } } // Add Frame selection change public void Add(int code, bool useIndex = true) { if (Doing) return; - if (useIndex && CheckHistoryAction()) return; - if (useIndex) { - Add(mainForm.frames.Find(x => x.code == code)); - //Add(mainForm.f); - } TruncateTail(); - if (Count > Depth) RemoveOldest(); - selFrameChanges.Add(code); + if (Count >= Depth) RemoveOldest(); + selectionChanges.Add(code); if (useIndex) { - timeline.Add(ChangeType.Frame); + var canv = Add(mainForm.f, false); + canvasIndex++; + timeline.Add(new ChangeEvent(ChangeType.Selection, canv)); Index++; - selFrameIndex++; + selectionIndex++; } } private void Do(bool undo = true) { + if (!undo && Index >= Count - 1) return; Doing = true; - var ct = timeline.ElementAt(Index + (undo ? 0 : 1)); + var ce = timeline.ElementAt(Index + (undo ? 0 : 1)); int dIndex = undo ? -1 : 1; - switch (ct) { + FrameMiniature fff; + switch (ce.Type) { case ChangeType.Canvas: canvasIndex += dIndex; mainForm.f = CopyFrameSimple(canvasChanges[canvasIndex]); + mainForm.SetModified(); + mainForm.nudX.ValueChanged -= mainForm.nudX_ValueChanged; + mainForm.nudY.ValueChanged -= mainForm.nudY_ValueChanged; + mainForm.nudY.Value = mainForm.dotHeight = canvasChanges[canvasIndex].height; + mainForm.nudX.Value = mainForm.dotWidth = canvasChanges[canvasIndex].width; + mainForm.SetNewWH(); + mainForm.nudX.ValueChanged += mainForm.nudX_ValueChanged; + mainForm.nudY.ValueChanged += mainForm.nudY_ValueChanged; break; case ChangeType.Font: Cursor.Current = Cursors.WaitCursor; @@ -231,6 +236,7 @@ namespace McBitFont { selCode = Convert.ToInt32(selItem); } fontIndex += dIndex; + canvasIndex += dIndex; mainForm.frames.Clear(); mainForm.miniList.Clear(); mainForm.ilMiniatures.Images.Clear(); @@ -238,7 +244,7 @@ namespace McBitFont { mainForm.frames.Add(CopyFrameSimple(f)); } mainForm.FillFrameLists(); - FrameMiniature fff; + if (selItem != "") { var selection = mainForm.miniList.Items.Find(selItem, false); if (selection.Length > 0) selection[0].Selected = true; @@ -248,44 +254,38 @@ namespace McBitFont { fff = mainForm.frames[0]; } mainForm.f = mainForm.CopyFrame(fff); + mainForm.nudX.ValueChanged -= mainForm.nudX_ValueChanged; + mainForm.nudY.ValueChanged -= mainForm.nudY_ValueChanged; mainForm.nudY.Value = mainForm.dotHeight = fff.height; mainForm.nudX.Value = mainForm.dotWidth = fff.width; + mainForm.SetNewWH(); + mainForm.nudX.ValueChanged += mainForm.nudX_ValueChanged; + mainForm.nudY.ValueChanged += mainForm.nudY_ValueChanged; + Cursor.Current = Cursors.Default; break; - case ChangeType.Frame: - HistoryAction = true; - selFrameIndex += dIndex; - var s = selFrameChanges[selFrameIndex].ToString().PadLeft(3, '0'); + case ChangeType.Selection: + selectionIndex += dIndex; + canvasIndex += dIndex; + var s = selectionChanges[selectionIndex].ToString().PadLeft(3, '0'); var sel = mainForm.miniList.Items.Find(s, false); if (sel.Length > 0) sel[0].Selected = true; + fff = mainForm.frames.Find(x => x.code == selectionChanges[selectionIndex]); + mainForm.f = CopyFrameSimple(fff); + mainForm.nudX.ValueChanged -= mainForm.nudX_ValueChanged; + mainForm.nudY.ValueChanged -= mainForm.nudY_ValueChanged; + mainForm.nudY.Value = mainForm.dotHeight = fff.height; + mainForm.nudX.Value = mainForm.dotWidth = fff.width; + mainForm.SetNewWH(); + mainForm.nudX.ValueChanged += mainForm.nudX_ValueChanged; + mainForm.nudY.ValueChanged += mainForm.nudY_ValueChanged; break; default: break; } Index += dIndex; Doing = false; - // Frame select change + Canvas change workarounds - if (ct == ChangeType.Frame && undo) { - Undo(); - return; - } - if (Index < Count - 1) { - var nextctframe = timeline.ElementAt(Index + 1) == ChangeType.Frame; - if (ct == ChangeType.Canvas && !undo && nextctframe) { - Redo(); - return; - } - } - //Font change + Canvas change workarounds - if (Index >= 0) { - var prevctfont = timeline.ElementAt(Index) == ChangeType.Font; - if (ct == ChangeType.Canvas && undo && prevctfont) { - Undo(); - return; - } - } - if (!undo && ct == ChangeType.Font) - Redo(); + } // Undo last change diff --git a/McBitFont/Form1.cs b/McBitFont/Form1.cs index 2543232..407f9e7 100644 --- a/McBitFont/Form1.cs +++ b/McBitFont/Form1.cs @@ -76,7 +76,7 @@ namespace McBitFont { this.dotPanel.MouseWheel += new MouseEventHandler(this.DotPanel_MouseWheel); } - private void SetNewWH() { + public void SetNewWH() { w = pixelOffset + dotWidth * (cellSize + gap); h = pixelOffset + dotHeight * (cellSize + gap); } @@ -85,7 +85,7 @@ namespace McBitFont { lblSelection.Text = width.ToString() + ',' + height.ToString(); } - private void SetModified(bool modif = true, bool prj = false) { + public void SetModified(bool modif = true, bool prj = false) { string suffix = ""; if (prj) { prjModified = modif; @@ -197,7 +197,7 @@ namespace McBitFont { } } - private void nudX_ValueChanged(object sender, EventArgs e) { + public void nudX_ValueChanged(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; if (monospaced) { Bitmap bmp; @@ -216,10 +216,13 @@ namespace McBitFont { } DotResize((int)nudX.Value, dotHeight); + if (monospaced) history.Add(frames); + else history.Add(f); + Cursor.Current = Cursors.Default; } - private void nudY_ValueChanged(object sender, EventArgs e) { + public void nudY_ValueChanged(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; Bitmap bmp; for (int i = 0; i < frames.Count; i++) { diff --git a/TODO.txt b/TODO.txt index f1f8932..239e159 100644 --- a/TODO.txt +++ b/TODO.txt @@ -3,9 +3,9 @@ Application: V Copy-Paste now uses System clipboard and it is possible to copy-paste from/to different instances of running program Functionality: -- Rewrite history class so it tracks all changes, not only a canvas changes +V Rewrite history class so it tracks all changes, not only a canvas changes Bugs: -- In some cases after switching to a symbol dotPanel mouse move causes "Out of range" exception (history.Pre after width change?) +V In some cases after switching to a symbol dotPanel mouse move causes "Out of range" exception (history.Pre after width change?) V Switching between symbols while select tool is active and small area selected trows an error V Full frame Copy in Clipboard does not respect selection on Paste operation \ No newline at end of file