[gnome-mines] Add a mines percentage slider for custom games



commit 98df3bd4cad9a167e0b1216aed1fe3dcca829105
Author: Isaac Lenton <isaac isuniversal com>
Date:   Sun Feb 10 02:32:47 2013 +1000

    Add a mines percentage slider for custom games
    
    Limit on minimum number of mines set to one percent
    
    https://bugzilla.gnome.org/show_bug.cgi?id=693423

 src/gnome-mines.vala |   57 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 54 insertions(+), 3 deletions(-)
---
diff --git a/src/gnome-mines.vala b/src/gnome-mines.vala
index e71ba03..8fb04b6 100644
--- a/src/gnome-mines.vala
+++ b/src/gnome-mines.vala
@@ -59,6 +59,7 @@ public class Mines : Gtk.Application
 
     private Gtk.Dialog? pref_dialog = null;
     private Gtk.SpinButton n_mines_spin;
+    private Gtk.SpinButton p_mines_spin;
     private SimpleAction new_game_action;
     private SimpleAction pause_action;
     private SimpleAction hint_action;
@@ -310,10 +311,20 @@ public class Mines : Gtk.Application
         set_n_mines_limit ();
         label.set_mnemonic_widget (n_mines_spin);
 
+        label = new Gtk.Label.with_mnemonic (_("_Percentage of mines:"));
+        label.set_alignment (0, 0.5f);
+        custom_game_grid.attach (label, 0, 3, 1, 1);
+
+        p_mines_spin = new Gtk.SpinButton.with_range (1, 100, 1);
+        p_mines_spin.value_changed.connect (p_mines_spin_cb);
+        custom_game_grid.attach (p_mines_spin, 1, 3, 1, 1);
+        set_p_mines_limit ();
+        label.set_mnemonic_widget (p_mines_spin);
+
         var button_grid = new Gtk.Grid ();
         button_grid.column_homogeneous = false;
         button_grid.column_spacing = 5;
-        custom_game_grid.attach (button_grid, 0, 3, 2, 1);
+        custom_game_grid.attach (button_grid, 0, 4, 2, 1);
 
         var button = new Gtk.Button.with_mnemonic (_("_Cancel"));
         button.valign = Gtk.Align.CENTER;
@@ -692,17 +703,42 @@ public class Mines : Gtk.Application
 
     private void set_n_mines_limit ()
     {
+        var size = settings.get_int (KEY_XSIZE) * settings.get_int (KEY_YSIZE);
+
         /* Fix up the maximum number of mines so that there is always at least
          * ten free spaces. Nine are so we can clear at least the immediate
          * eight neighbours at the start and one more so the game isn't over
          * immediately. */
-        var max_mines = settings.get_int (KEY_XSIZE) * settings.get_int (KEY_YSIZE) - 10;
+        var max_mines = size - 10;
         if (settings.get_int (KEY_NMINES) > max_mines)
         {
             settings.set_int (KEY_NMINES, max_mines);
             n_mines_spin.set_value (max_mines);
         }
-        n_mines_spin.set_range (1, max_mines);
+
+        /* On large minefields, require a minimum of 1% mines */
+        var min_mines = int.max ((int) Math.round (0.01f * size), 1);
+        if (settings.get_int (KEY_NMINES) < min_mines)
+        {
+            settings.set_int (KEY_NMINES, min_mines);
+            n_mines_spin.set_value (min_mines);
+        }
+
+        n_mines_spin.set_range (min_mines, max_mines);
+    }
+
+    private float p_mines
+    {
+        get { return 100.0f * (float) settings.get_int (KEY_NMINES) / (settings.get_int (KEY_XSIZE) * 
settings.get_int (KEY_YSIZE)); }
+    }
+
+    private void set_p_mines_limit ()
+    {
+        var size = settings.get_int (KEY_XSIZE) * settings.get_int (KEY_YSIZE);
+        var max_mines = (int) Math.round (100.0f * (float) (size - 10) / size);
+        var min_mines = int.max (1, (int) Math.round (100.0f / size));
+        p_mines_spin.set_range (min_mines, max_mines);
+        p_mines_spin.set_value ((int) Math.round (p_mines));
     }
 
     private void xsize_spin_cb (Gtk.SpinButton spin)
@@ -713,6 +749,7 @@ public class Mines : Gtk.Application
 
         settings.set_int (KEY_XSIZE, xsize);
         set_n_mines_limit ();
+        set_p_mines_limit ();
     }
 
     private void ysize_spin_cb (Gtk.SpinButton spin)
@@ -723,6 +760,7 @@ public class Mines : Gtk.Application
 
         settings.set_int (KEY_YSIZE, ysize);
         set_n_mines_limit ();
+        set_p_mines_limit ();
     }
 
     private void n_mines_spin_cb (Gtk.SpinButton spin)
@@ -732,6 +770,19 @@ public class Mines : Gtk.Application
             return;
 
         settings.set_int (KEY_NMINES, n_mines);
+
+        if (Math.fabs (p_mines - p_mines_spin.get_value ()) <= 100.0f * 0.5f / (settings.get_int (KEY_XSIZE) 
* settings.get_int (KEY_YSIZE)))
+            return;
+
+        p_mines_spin.set_value ((int) Math.round (p_mines));
+    }
+
+    private void p_mines_spin_cb (Gtk.SpinButton spin)
+    {
+        if (Math.fabs (p_mines - spin.get_value ()) <= 0.5f)
+            return;
+
+        n_mines_spin.set_value ((int) Math.round (spin.get_value () * (settings.get_int (KEY_XSIZE) * 
settings.get_int (KEY_YSIZE)) / 100.0f));
     }
 
     private void use_question_toggle_cb (Gtk.ToggleButton button)


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