[gnome-sudoku] Handle earmarks properly in undo/redo



commit 89e7bc1fa67d96b3e1741314b3e8e2046cd4ff3b
Author: shak-mar <shakmar openmailbox org>
Date:   Tue Jul 9 22:24:40 2019 +0200

    Handle earmarks properly in undo/redo
    
    Before this commit, undo/redo didn't know anything about earmarks.  This
    can lead to annoyances in real-world usage of the application:  Imagine
    you set some earmarks on a cell and then think some of those numbers
    should be the real value.  So you set the value to be what you want, but
    shortly afterwards notice that it was nonsense actually.  So you undo,
    but now the earmarks you set before are lost!  This is not what undo
    should be like.
    
    In addition to the value a cell has, we now simply also save the
    earmarks.  Whenever you change something, the value and earmarks the
    cell had before the change are saved onto the undo stack.  Whenever you
    undo/redo, the earmarks are set appropriately.

 lib/sudoku-board.vala |  8 ++++++++
 lib/sudoku-game.vala  | 46 ++++++++++++++++++++++++++++++++++++++--------
 src/sudoku-view.vala  |  4 ++--
 3 files changed, 48 insertions(+), 10 deletions(-)
---
diff --git a/lib/sudoku-board.vala b/lib/sudoku-board.vala
index 8b30f7f..3b61700 100644
--- a/lib/sudoku-board.vala
+++ b/lib/sudoku-board.vala
@@ -504,6 +504,14 @@ public class SudokuBoard : Object
         return file.query_exists ();
     }
 
+    public bool[] get_earmarks (int row, int col)
+    {
+        bool[] the_earmarks = new bool[max_val];
+        for (var i = 1; i <= max_val; i++)
+            the_earmarks[i-1] = earmarks[row, col, i-1];
+        return the_earmarks;
+    }
+
     public string get_earmarks_string (int row, int col)
     {
         string s = "";
diff --git a/lib/sudoku-game.vala b/lib/sudoku-game.vala
index 99b2faf..0583de9 100644
--- a/lib/sudoku-game.vala
+++ b/lib/sudoku-game.vala
@@ -47,6 +47,7 @@ public class SudokuGame : Object
         public int row;
         public int col;
         public int val;
+        public bool[] earmarks;
     }
 
     public signal void cell_changed (int row, int col, int old_val, int new_val);
@@ -73,10 +74,29 @@ public class SudokuGame : Object
         redostack = new ArrayList<UndoItem?> ();
     }
 
+    public void enable_earmark (int row, int col, int k_no)
+    {
+        var old_val = board[row, col];
+        var old_earmarks = board.get_earmarks(row, col);
+        update_undo (row, col, old_val, old_earmarks);
+
+        board.enable_earmark (row, col, k_no);
+    }
+
+    public void disable_earmark (int row, int col, int k_no)
+    {
+        var old_val = board[row, col];
+        var old_earmarks = board.get_earmarks(row, col);
+        update_undo (row, col, old_val, old_earmarks);
+
+        board.disable_earmark (row, col, k_no);
+    }
+
     public void insert (int row, int col, int val)
     {
         var old_val = board[row, col];
-        update_undo (row, col, old_val);
+        var old_earmarks = board.get_earmarks(row, col);
+        update_undo (row, col, old_val, old_earmarks);
 
         if (mode == GameMode.CREATE)
         {
@@ -91,8 +111,9 @@ public class SudokuGame : Object
 
     public void remove (int row, int col)
     {
-        int old_val = board[row, col];
-        update_undo (row, col, old_val);
+        var old_val = board[row, col];
+        var old_earmarks = board.get_earmarks(row, col);
+        update_undo (row, col, old_val, old_earmarks);
 
         if (mode == GameMode.CREATE)
         {
@@ -149,15 +170,15 @@ public class SudokuGame : Object
         cell_changed (row, col, old_val, new_val);
     }
 
-    public void update_undo (int row, int col, int old_val)
+    public void update_undo (int row, int col, int old_val, bool[] old_earmarks)
     {
-        add_to_stack (undostack, row, col, old_val);
+        add_to_stack (undostack, row, col, old_val, old_earmarks);
         redostack.clear ();
     }
 
-    private void add_to_stack (Gee.List<UndoItem?> stack, int r, int c, int v)
+    private void add_to_stack (Gee.List<UndoItem?> stack, int r, int c, int v, bool[] e)
     {
-        UndoItem step = { r, c, v };
+        UndoItem step = { r, c, v, e };
         stack.add (step);
     }
 
@@ -168,7 +189,8 @@ public class SudokuGame : Object
 
         var top = from.remove_at (from.size - 1);
         int old_val = board [top.row, top.col];
-        add_to_stack (to, top.row, top.col, old_val);
+        bool[] old_earmarks = board.get_earmarks (top.row, top.col);
+        add_to_stack (to, top.row, top.col, old_val, old_earmarks);
 
         if (mode == GameMode.CREATE)
         {
@@ -189,6 +211,14 @@ public class SudokuGame : Object
                 board.insert (top.row, top.col, top.val);
         }
 
+        for (var i = 1; i <= top.earmarks.length; i++)
+        {
+            if (top.earmarks[i-1])
+                board.enable_earmark (top.row, top.col, i);
+            else
+                board.disable_earmark (top.row, top.col, i);
+        }
+
         cell_changed (top.row, top.col, old_val, top.val);
     }
 
diff --git a/src/sudoku-view.vala b/src/sudoku-view.vala
index 885b3c5..88a4d18 100644
--- a/src/sudoku-view.vala
+++ b/src/sudoku-view.vala
@@ -159,9 +159,9 @@ private class SudokuCellView : Gtk.DrawingArea
         earmark_picker = new NumberPicker (ref game.board, true);
         earmark_picker.earmark_state_changed.connect ((number, state) => {
             if (state)
-                this.game.board.enable_earmark (row, col, number);
+                this.game.enable_earmark (row, col, number);
             else
-                this.game.board.disable_earmark (row, col, number);
+                this.game.disable_earmark (row, col, number);
             this.game.cell_changed (row, col, value, value);
             queue_draw ();
         });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]