[gnome-nibbles/arnaudb/kill-preferences-dialog: 4/4] Warn when a key is assigned to multiple controls.



commit a361a870786264b344f8edabea5dd8b10a5397b6
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Fri Jun 12 15:49:00 2020 +0200

    Warn when a key is assigned to multiple controls.

 data/nibbles.css            |  4 +++
 src/controls.vala           | 61 +++++++++++++++++++++++++++++++++++++++++++--
 src/preferences-dialog.vala | 11 +++++---
 3 files changed, 70 insertions(+), 6 deletions(-)
---
diff --git a/data/nibbles.css b/data/nibbles.css
index 7101123..aadaa31 100644
--- a/data/nibbles.css
+++ b/data/nibbles.css
@@ -132,6 +132,10 @@ button.controls-box:hover {
   font-size:175%;
 }
 
+label.duplicate {
+  color:red;
+}
+
 /*\
 * * game screen
 \*/
diff --git a/src/controls.vala b/src/controls.vala
index c14a0db..a1ec9ae 100644
--- a/src/controls.vala
+++ b/src/controls.vala
@@ -39,21 +39,62 @@ private class Controls : Box
         foreach (var grid in grids_box.get_children ())
             grid.destroy ();
 
+        GenericSet<uint> duplicate_keys     = new GenericSet<uint> (direct_hash, direct_equal);
+        GenericSet<uint> encountered_keys   = new GenericSet<uint> (direct_hash, direct_equal);
         foreach (var worm in worms)
         {
             if (worm.is_human)
             {
-                var grid = new ControlsGrid (worm.id, worm_props.@get (worm), arrow_pixbuf, 
arrow_key_pixbuf);
+                WormProperties worm_prop = worm_props.@get (worm);
+
+                var grid = new ControlsGrid (worm.id, worm_prop, arrow_pixbuf, arrow_key_pixbuf);
                 grids_box.add (grid);
                 grids.add (grid);
+
+                check_for_duplicates (worm_prop.up,     ref encountered_keys, ref duplicate_keys);
+                check_for_duplicates (worm_prop.down,   ref encountered_keys, ref duplicate_keys);
+                check_for_duplicates (worm_prop.left,   ref encountered_keys, ref duplicate_keys);
+                check_for_duplicates (worm_prop.right,  ref encountered_keys, ref duplicate_keys);
             }
         }
+        foreach (ControlsGrid grid in grids)
+        {
+            grid.external_handler = grid.worm_props.notify.connect (() => {
+                    GenericSet<uint> _duplicate_keys    = new GenericSet<uint> (direct_hash, direct_equal);
+                    GenericSet<uint> _encountered_keys  = new GenericSet<uint> (direct_hash, direct_equal);
+                    foreach (var worm in worms)
+                    {
+                        if (worm.is_human)
+                        {
+                            WormProperties worm_prop = worm_props.@get (worm);
+
+                            check_for_duplicates (worm_prop.up,     ref _encountered_keys, ref 
_duplicate_keys);
+                            check_for_duplicates (worm_prop.down,   ref _encountered_keys, ref 
_duplicate_keys);
+                            check_for_duplicates (worm_prop.left,   ref _encountered_keys, ref 
_duplicate_keys);
+                            check_for_duplicates (worm_prop.right,  ref _encountered_keys, ref 
_duplicate_keys);
+                        }
+                    }
+                    foreach (ControlsGrid _grid in grids)
+                        _grid.mark_duplicated_keys (_duplicate_keys);
+                });
+            grid.mark_duplicated_keys (duplicate_keys);
+        }
+    }
+    private void check_for_duplicates (uint key, ref GenericSet<uint> encountered_keys, ref GenericSet<uint> 
duplicate_keys)
+    {
+        if (encountered_keys.contains (key))
+            duplicate_keys.add (key);
+        else
+            encountered_keys.add (key);
     }
 
     internal void clean ()
     {
         foreach (ControlsGrid grid in grids)
+        {
+            grid.worm_props.disconnect (grid.external_handler);
             grid.disconnect_stuff ();
+        }
         grids.clear ();
     }
 }
@@ -71,7 +112,8 @@ private class ControlsGrid : Button
     [GtkChild] private Label move_left_label;
     [GtkChild] private Label move_right_label;
 
-    private WormProperties worm_props;
+    internal WormProperties worm_props;
+    internal ulong external_handler;
     private ulong    up_handler;
     private ulong  down_handler;
     private ulong  left_handler;
@@ -111,6 +153,21 @@ private class ControlsGrid : Button
         configure_label (Gdk.keyval_name (worm_props.right), ref move_right_label);
     }
 
+    internal void mark_duplicated_keys (GenericSet<uint> duplicate_keys)
+    {
+        set_duplicate_class (worm_props.up    in duplicate_keys, ref move_up_label);
+        set_duplicate_class (worm_props.down  in duplicate_keys, ref move_down_label);
+        set_duplicate_class (worm_props.left  in duplicate_keys, ref move_left_label);
+        set_duplicate_class (worm_props.right in duplicate_keys, ref move_right_label);
+    }
+    private static void set_duplicate_class (bool new_value, ref Label label)
+    {
+        if (new_value)
+            label.get_style_context ().add_class ("duplicate");
+        else
+            label.get_style_context ().remove_class ("duplicate");
+    }
+
     internal void disconnect_stuff ()
     {
         worm_props.disconnect (   up_handler);
diff --git a/src/preferences-dialog.vala b/src/preferences-dialog.vala
index d21354c..859b1a4 100644
--- a/src/preferences-dialog.vala
+++ b/src/preferences-dialog.vala
@@ -187,17 +187,20 @@ private class PreferencesDialog : Window
              || keyval == worm_settings [i].get_int ("key-left")
              || keyval == worm_settings [i].get_int ("key-right"))
             {
-                valid = false;
-
                 var dialog = new MessageDialog (window,
                                                 DialogFlags.DESTROY_WITH_PARENT,
                                                 MessageType.WARNING,
-                                                ButtonsType.OK,
+                                                ButtonsType.CANCEL,
                                                 /* Translators: label of a MessageDialog that appears when 
one tries to assign an already assigned key */
                                                 _("The key you selected is already assigned!"));
 
-                dialog.run ();
+                /* Translators: label of one of the buttons of a MessageDialog that appears when one tries 
to assign an already assigned key (with a mnemonic that appears when pressing Alt) */
+                dialog.add_button (_("_Set anyway"), 42);
+
+                int response = dialog.run ();
                 dialog.destroy ();
+                if (response != 42)
+                    valid = false;
                 break;
             }
         }


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