[gnome-sudoku/vala-port] Use Popover for number picker and earmarking



commit 4baa0572431ce018bea574f7d4cff611da6eebc0
Author: Parin Porecha <parinporecha gmail com>
Date:   Tue May 27 15:13:22 2014 +0530

    Use Popover for number picker and earmarking
    
    https://bugzilla.gnome.org/show_bug.cgi?id=633464

 src/number-picker.vala |   58 ++++++++++++++------
 src/sudoku-board.vala  |    3 +
 src/sudoku-saver.vala  |   34 ++++++++++--
 src/sudoku-view.vala   |  142 ++++++++++++++----------------------------------
 4 files changed, 112 insertions(+), 125 deletions(-)
---
diff --git a/src/number-picker.vala b/src/number-picker.vala
index c39417e..761ca1a 100644
--- a/src/number-picker.vala
+++ b/src/number-picker.vala
@@ -1,14 +1,17 @@
 /* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 
+using Gtk;
+
 private class NumberPicker : Gtk.Grid
 {
     private SudokuBoard board;
 
     public signal void number_picked (int number);
+    public signal void earmark_state_changed (int number, bool active);
 
-    private Gtk.Button clear_button;
+    private Button clear_button;
 
-    public NumberPicker (ref SudokuBoard board) {
+    public NumberPicker (ref SudokuBoard board, bool earmark = false) {
         this.board = board;
 
         for (var col = 0; col < board.block_cols; col++)
@@ -17,18 +20,26 @@ private class NumberPicker : Gtk.Grid
             {
                 int n = col + row * board.block_cols + 1;
 
-                var button = new Gtk.Button ();
+                var button = earmark ? new ToggleButton () : new Button ();
                 button.focus_on_click = false;
                 this.attach (button, col, row, 1, 1);
 
-                var label = new Gtk.Label ("<big>%d</big>".printf (n));
+                var label = new Label ("<big>%d</big>".printf (n));
                 label.use_markup = true;
                 button.add (label);
                 label.show ();
 
-                button.clicked.connect (() => {
-                    number_picked(n);
-                });
+                if (!earmark)
+                    button.clicked.connect (() => {
+                        number_picked (n);
+                    });
+                else
+                {
+                    var toggle_button = (ToggleButton) button;
+                    toggle_button.toggled.connect (() => {
+                        earmark_state_changed (n, toggle_button.get_active ());
+                    });
+                }
 
                 if (n == 5)
                     button.grab_focus ();
@@ -37,18 +48,21 @@ private class NumberPicker : Gtk.Grid
             }
         }
 
-        clear_button = new Gtk.Button ();
-        clear_button.focus_on_click = false;
-        this.attach (clear_button, 0, 4, 3, 1);
+        if (!earmark)
+        {
+            clear_button = new Button ();
+            clear_button.focus_on_click = false;
+            this.attach (clear_button, 0, 4, 3, 1);
 
-        var label = new Gtk.Label ("<big>Clear</big>");
-        label.use_markup = true;
-        clear_button.add (label);
-        label.show ();
+            var label = new Label ("<big>Clear</big>");
+            label.use_markup = true;
+            clear_button.add (label);
+            label.show ();
 
-        clear_button.clicked.connect (() => {
-            number_picked(0);
-        });
+            clear_button.clicked.connect (() => {
+                number_picked(0);
+            });
+        }
 
         this.show ();
     }
@@ -60,4 +74,14 @@ private class NumberPicker : Gtk.Grid
         else
             clear_button.hide ();
     }
+
+    public void set_earmarks (int row, int col)
+    {
+        for (var i = 0; i < board.max_val; i++)
+            if (board.earmarks[row, col, i])
+            {
+                var button = (ToggleButton) this.get_child_at (i % board.block_cols, i / board.block_rows);
+                button.set_active (board.earmarks[row, col, i]);
+            }
+    }
 }
diff --git a/src/sudoku-board.vala b/src/sudoku-board.vala
index f909b75..2c2dcaf 100644
--- a/src/sudoku-board.vala
+++ b/src/sudoku-board.vala
@@ -12,6 +12,8 @@ public class SudokuBoard
     private bool[,] possible_in_col;            /* if specific value is possible in specific col */
     private bool[,,] possible_in_block;         /* if specific value is possible in specific block */
 
+    public bool[,,] earmarks;                  /* Earmarks set by the user */
+
     public double previous_played_time { set; get; default = 0; }
 
     /* Number of rows in one block */
@@ -110,6 +112,7 @@ public class SudokuBoard
         possible_in_row = new bool[_rows, _cols];
         possible_in_col = new bool[_cols, _rows];
         possible_in_block = new bool[_block_rows, _block_cols, _block_rows * _block_cols];
+        earmarks = new bool[_rows, _cols, max_val];
 
         for (var l1 = 0; l1 < _rows; l1++)
         {
diff --git a/src/sudoku-saver.vala b/src/sudoku-saver.vala
index 08ff4c4..cba3396 100644
--- a/src/sudoku-saver.vala
+++ b/src/sudoku-saver.vala
@@ -90,7 +90,12 @@ public class SudokuSaver
         {
             for (var j = 0; j < board.cols; j++)
             {
-                if (board_cells[i, j] == 0)
+                int[] earmarks = {};
+                for (var k = 0; k < board.max_val; k++)
+                    if (board.earmarks[i, j, k])
+                        earmarks += k;
+
+                if (board_cells[i, j] == 0 && earmarks.length == 0)
                     continue;
 
                 builder.begin_object ();
@@ -104,8 +109,13 @@ public class SudokuSaver
                 builder.add_int_value (board_cells[i, j]);
                 builder.set_member_name ("fixed");
                 builder.add_boolean_value (board.is_fixed[i, j]);
-                builder.set_member_name ("notes");
-                builder.add_string_value ("");
+                builder.set_member_name ("earmarks");
+                builder.begin_array ();
+
+                foreach (int k in earmarks)
+                    builder.add_int_value (k);
+
+                builder.end_array ();
 
                 builder.end_object ();
             }
@@ -135,7 +145,7 @@ public class SudokuSaver
         Json.Node node = parser.get_root ();
         Json.Reader reader = new Json.Reader (node);
         reader.read_member ("cells");
-        assert (reader.is_array ());
+        return_val_if_fail (reader.is_array (), null);
 
         for (var i = 0; i < reader.count_elements (); i++)
         {
@@ -165,9 +175,21 @@ public class SudokuSaver
             var is_fixed = reader.get_boolean_value ();
             reader.end_member ();
 
-            reader.end_element ();
+            if (val != 0)
+                board.insert (row, col, val, is_fixed);
 
-            board.insert (row, col, val, is_fixed);
+            reader.read_member ("earmarks");
+            return_val_if_fail (reader.is_array (), null);
+            for (var k = 0; k < reader.count_elements (); k++)
+            {
+                reader.read_element (k);
+                return_val_if_fail (reader.is_value (), null);
+                board.earmarks[row, col, (int) reader.get_int_value ()] = true;
+                reader.end_element ();
+            }
+            reader.end_member ();
+
+            reader.end_element ();
         }
         reader.end_member ();
 
diff --git a/src/sudoku-view.vala b/src/sudoku-view.vala
index 27cf25b..9a2962d 100644
--- a/src/sudoku-view.vala
+++ b/src/sudoku-view.vala
@@ -10,6 +10,7 @@ private class SudokuCellView : Gtk.DrawingArea
     private double size_ratio = 2;
 
     private Gtk.Popover popover;
+    private Gtk.Popover earmark_popover;
 
     private SudokuGame game;
 
@@ -70,9 +71,6 @@ private class SudokuCellView : Gtk.DrawingArea
         }
     }
 
-    public string top_notes { set; get; default = ""; }
-    public string bottom_notes { set; get; default = ""; }
-
     private bool _show_possibilities;
     public bool show_possibilities
     {
@@ -125,6 +123,7 @@ private class SudokuCellView : Gtk.DrawingArea
     }
 
     private NumberPicker number_picker;
+    private NumberPicker earmark_picker;
 
     public SudokuCellView (int row, int col, ref SudokuGame game, bool small = false)
     {
@@ -148,6 +147,18 @@ private class SudokuCellView : Gtk.DrawingArea
         popover.position = PositionType.BOTTOM;
         popover.focus_out_event.connect (() => { popover.hide (); return true; });
 
+        earmark_picker = new NumberPicker(ref game.board, true);
+        earmark_picker.earmark_state_changed.connect ((number, state) => {
+            this.game.board.earmarks[row, col, number-1] = state;
+            queue_draw ();
+        });
+
+        earmark_popover = new Popover (this);
+        earmark_popover.add (earmark_picker);
+        earmark_popover.modal = false;
+        earmark_popover.position = PositionType.BOTTOM;
+        earmark_popover.focus_out_event.connect (() => { earmark_popover.hide (); return true; });
+
         // background_color is set in the SudokuView, as it manages the color of the cells
 
         can_focus = true;
@@ -192,24 +203,11 @@ private class SudokuCellView : Gtk.DrawingArea
             return false;
         }
 
-        if (event.y / get_allocated_height () < 0.25)
-        {
-            show_note_editor (0);
-        }
+        var event_height = event.y / get_allocated_height ();
+        if (!_show_possibilities && (event_height < 0.25 || event_height > 0.75))
+            show_earmark_picker ();
         else
-        {
-            if (event.y / get_allocated_height () > 0.75)
-            {
-                if (!_show_possibilities)
-                {
-                    show_note_editor (1);
-                }
-            }
-            else
-            {
-                show_number_picker ();
-            }
-        }
+            show_number_picker ();
 
         return false;
     }
@@ -219,46 +217,25 @@ private class SudokuCellView : Gtk.DrawingArea
         if (!is_fixed)
         {
             number_picker.set_clear_button_visibility (value != 0);
+            earmark_popover.hide ();
             popover.show ();
         }
     }
 
-    private void show_note_editor (int top)
-    {
-        if (is_fixed)
-            return;
-
-/*  TODO - reimplement as earmarks
-
-        var entry = new Gtk.Entry ();
-        entry.has_frame = false;
-        if (top == 0)
-            entry.set_text (top_notes);
-        else
-            entry.set_text (bottom_notes);
-        popover.add (entry);
-
-        entry.focus_out_event.connect (() => {
-            hide_note_editor (entry, top);
-            return true;
-        });
-
-        entry.activate.connect (() => { hide_note_editor (entry, top); });
-*/
-    }
-
-    private void hide_note_editor (Gtk.Entry entry, int top)
+    private void show_earmark_picker ()
     {
-        if (top == 0)
-            top_notes = entry.get_text ();
-        else
-            bottom_notes = entry.get_text ();
-        // TODO - need to hide a thing
+        if (!is_fixed)
+        {
+            earmark_picker.set_earmarks (_row, _col);
+            popover.hide ();
+            earmark_popover.show ();
+        }
     }
 
     private bool focus_out_cb (Gtk.Widget widget, Gdk.EventFocus event)
     {
         popover.hide ();
+        earmark_popover.hide ();
         return false;
     }
 
@@ -365,45 +342,30 @@ private class SudokuCellView : Gtk.DrawingArea
             Pango.cairo_show_layout (c, layout);
             c.restore ();
         }
-        else if (_show_possibilities)
-        {
-            double possibility_size = get_allocated_height () / (size_ratio * 2);
-            c.set_font_size (possibility_size);
-            c.set_source_rgb (0.0, 0.0, 0.0);
 
-            bool[] possibilities = game.board.get_possibilities_as_bool_array(row, col);
+        double earmark_size = get_allocated_height () / (size_ratio * 2);
+        c.set_font_size (earmark_size);
+        c.set_source_rgb (0.0, 0.0, 0.0);
 
-            int height = get_allocated_height () / game.board.block_cols;
-            int width = get_allocated_height () / game.board.block_rows;
+        int height = get_allocated_height () / game.board.block_cols;
+        int width = get_allocated_height () / game.board.block_rows;
 
-            int num = 0;
-            for (int row = 0; row < game.board.block_rows; row++)
+        int num = 0;
+        for (int row = 0; row < game.board.block_rows; row++)
+            for (int col = 0; col < game.board.block_cols; col++)
             {
-                for (int col = 0; col < game.board.block_cols; col++)
-                {
-                    num++;
+                num++;
 
-                    if (possibilities[num - 1])
-                    {
-                        c.move_to (col * width, (row * height) + possibility_size);
-                        c.show_text ("%d".printf(num));
-                    }
+                if (game.board.earmarks[_row, _col, num-1] || (_show_possibilities && game.board.is_possible 
(_row, _col, num)))
+                {
+                    c.move_to (col * width, (row * height) + earmark_size);
+                    c.show_text ("%d".printf(num));
                 }
             }
-        }
 
         if (is_fixed)
             return false;
 
-        // Draw the notes
-        double note_size = get_allocated_height () / (size_ratio * 2);
-        c.set_font_size (note_size);
-
-        c.move_to (0, note_size);
-
-        c.set_source_rgb (0.0, 0.0, 0.0);
-        c.show_text (top_notes);
-
         c.move_to (0, (get_allocated_height () - 3));
         if (_warn_about_unfillable_squares)
         {
@@ -413,14 +375,6 @@ private class SudokuCellView : Gtk.DrawingArea
         else
         {
             c.set_source_rgb (0.0, 0.0, 0.0);
-            //if (_show_possibilities)
-            //{
-            //    c.show_text (get_possibility_string (game.board.get_possibilities(_row, _col)));
-            //}
-            //else
-            //{
-                c.show_text (bottom_notes);
-            //}
         }
 
         return false;
@@ -704,22 +658,6 @@ public class SudokuView : Gtk.AspectFrame
         return dance_colors[Random.int_range(0, dance_colors.length)];
     }
 
-    public void clear_top_notes ()
-    {
-        for (var i = 0; i < game.board.rows; i++)
-            for (var j = 0; j < game.board.cols; j++)
-                cells[i,j].top_notes = "";
-        queue_draw ();
-    }
-
-    public void clear_bottom_notes ()
-    {
-        for (var i = 0; i < game.board.rows; i++)
-            for (var j = 0; j < game.board.cols; j++)
-                cells[i,j].bottom_notes = "";
-        queue_draw ();
-    }
-
     public void cell_grab_focus(int row, int col)
     {
         cells[row, col].grab_focus ();


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