[gnome-control-center/wip/gbsneto/new-keyboard-panel: 17/19] keyboard: support resetting keys from the list



commit fe2ed32583bf922f49f8325b590faec7429ac9bc
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Jul 18 21:48:47 2016 -0300

    keyboard: support resetting keys from the list
    
    Following the proposed mockups, the shortcut list must
    have the ability to reset modified right away.
    
    After adding the necessary API in CcKeyboardItem, adding
    the user-visible elements to enable that is easy.
    
    To make that happen, add a button that resets the
    keyboard shortcut.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769063

 panels/keyboard/cc-keyboard-manager.c         |   62 ++++++++++++++++
 panels/keyboard/cc-keyboard-manager.h         |    3 +
 panels/keyboard/cc-keyboard-panel.c           |   93 +++++++++++++++++++++++-
 panels/keyboard/cc-keyboard-shortcut-editor.c |   27 +++++++
 panels/keyboard/shortcut-editor.ui            |    1 +
 5 files changed, 182 insertions(+), 4 deletions(-)
---
diff --git a/panels/keyboard/cc-keyboard-manager.c b/panels/keyboard/cc-keyboard-manager.c
index 611eb77..d418e8a 100644
--- a/panels/keyboard/cc-keyboard-manager.c
+++ b/panels/keyboard/cc-keyboard-manager.c
@@ -82,6 +82,17 @@ free_key_array (GPtrArray *keys)
     }
 }
 
+static const gchar*
+get_binding_from_variant (GVariant *variant)
+{
+  if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING))
+    return g_variant_get_string (variant, NULL);
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING_ARRAY))
+    return g_variant_get_strv (variant, NULL)[0];
+
+  return NULL;
+}
+
 static gboolean
 compare_keys_for_uniqueness (CcKeyboardItem   *current_item,
                              CcUniquenessData *data)
@@ -965,3 +976,54 @@ cc_keyboard_manager_disable_shortcut (CcKeyboardManager *self,
 
   g_object_set (item, "binding", NULL, NULL);
 }
+
+/**
+ * cc_keyboard_manager_reset_shortcut:
+ * @self: a #CcKeyboardManager
+ * @item: a #CcKeyboardItem
+ *
+ * Resets the keyboard shortcut managed by @item, and eventually
+ * disables any collision detected.
+ */
+void
+cc_keyboard_manager_reset_shortcut (CcKeyboardManager *self,
+                                    CcKeyboardItem    *item)
+{
+  GVariant *default_value;
+  const gchar *default_binding;
+
+  g_return_if_fail (CC_IS_KEYBOARD_MANAGER (self));
+  g_return_if_fail (CC_IS_KEYBOARD_ITEM (item));
+
+  default_value = g_settings_get_default_value (item->settings, item->key);
+  default_binding = get_binding_from_variant (default_value);
+
+  /* Disables any eventual collision we find */
+  if (default_binding && default_binding[0] != '\0')
+    {
+      GdkModifierType mask;
+      CcKeyboardItem *collision;
+      guint *keycodes;
+      guint keyval;
+
+      gtk_accelerator_parse_with_keycode (default_binding, &keyval, &keycodes, &mask);
+
+      g_message ("default value for '%s' is '%s'", item->description, default_binding);
+
+      collision = cc_keyboard_manager_get_collision (self,
+                                                     NULL,
+                                                     keyval,
+                                                     mask,
+                                                     keycodes ? keycodes[0] : 0);
+
+      if (collision)
+        cc_keyboard_manager_disable_shortcut (self, collision);
+
+      g_free (keycodes);
+    }
+
+  /* Resets the current item */
+  cc_keyboard_item_reset (item);
+
+  g_variant_unref (default_value);
+}
diff --git a/panels/keyboard/cc-keyboard-manager.h b/panels/keyboard/cc-keyboard-manager.h
index c7c31b0..5df3aa7 100644
--- a/panels/keyboard/cc-keyboard-manager.h
+++ b/panels/keyboard/cc-keyboard-manager.h
@@ -52,6 +52,9 @@ CcKeyboardItem*      cc_keyboard_manager_get_collision           (CcKeyboardMana
 void                 cc_keyboard_manager_disable_shortcut        (CcKeyboardManager  *self,
                                                                   CcKeyboardItem     *item);
 
+void                 cc_keyboard_manager_reset_shortcut          (CcKeyboardManager  *self,
+                                                                  CcKeyboardItem     *item);
+
 G_END_DECLS
 
 #endif /* CC_KEYBOARD_MANAGER_H */
diff --git a/panels/keyboard/cc-keyboard-panel.c b/panels/keyboard/cc-keyboard-panel.c
index fc07ce2..06f94f2 100644
--- a/panels/keyboard/cc-keyboard-panel.c
+++ b/panels/keyboard/cc-keyboard-panel.c
@@ -62,6 +62,11 @@ enum {
   PROP_PARAMETERS
 };
 
+static const gchar* custom_css =
+"button.reset-shortcut-button {"
+"    padding: 0;"
+"}";
+
 /*
  * RowData functions
  */
@@ -103,7 +108,25 @@ transform_binding_to_accel (GBinding     *binding,
 
   item = CC_KEYBOARD_ITEM (g_binding_get_source (binding));
 
-  accelerator = convert_keysym_state_to_string (item->keyval, item->mask, item->keycode);
+  /* Bold the label when the shortcut is modified */
+  if (cc_keyboard_item_is_modified (item))
+    {
+      gchar *tmp;
+
+      tmp = convert_keysym_state_to_string (item->keyval,
+                                            item->mask,
+                                            item->keycode);
+
+      accelerator = g_strdup_printf ("<b>%s</b>", tmp);
+
+      g_free (tmp);
+    }
+  else
+    {
+      accelerator = convert_keysym_state_to_string (item->keyval,
+                                                    item->mask,
+                                                    item->keycode);
+    }
 
   g_value_set_string (to_value, accelerator);
 
@@ -113,16 +136,41 @@ transform_binding_to_accel (GBinding     *binding,
 }
 
 static void
+shortcut_modified_changed_cb (CcKeyboardItem *item,
+                              GParamSpec     *pspec,
+                              GtkWidget      *button)
+{
+  gtk_widget_set_child_visible (button, cc_keyboard_item_is_modified (item));
+}
+
+static void
+reset_shortcut_cb (GtkWidget      *reset_button,
+                   CcKeyboardItem *item)
+{
+  CcKeyboardPanel *self;
+
+  self = CC_KEYBOARD_PANEL (gtk_widget_get_ancestor (reset_button, CC_TYPE_KEYBOARD_PANEL));
+
+  cc_keyboard_manager_reset_shortcut (self->manager, item);
+}
+
+static void
 add_item (CcKeyboardPanel *self,
           CcKeyboardItem  *item,
           const gchar     *section_id,
           const gchar     *section_title)
 {
-  GtkWidget *row, *box, *label;
+  GtkWidget *row, *box, *label, *reset_button;
 
   /* Horizontal box */
-  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-  gtk_container_set_border_width (GTK_CONTAINER (box), 6);
+  box = g_object_new (GTK_TYPE_BOX,
+                      "orientation", GTK_ORIENTATION_HORIZONTAL,
+                      "spacing", 18,
+                      "margin-start", 6,
+                      "margin-end", 6,
+                      "margin-bottom", 4,
+                      "margin-top", 4,
+                      NULL);
 
   /* Shortcut title */
   label = gtk_label_new (item->description);
@@ -142,6 +190,7 @@ add_item (CcKeyboardPanel *self,
   /* Shortcut accelerator */
   label = gtk_label_new ("");
   gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
 
   gtk_size_group_add_widget (self->accelerator_sizegroup, label);
 
@@ -157,6 +206,31 @@ add_item (CcKeyboardPanel *self,
 
   gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
 
+  /* Reset shortcut button */
+  reset_button = gtk_button_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_BUTTON);
+  gtk_widget_set_valign (reset_button, GTK_ALIGN_CENTER);
+
+  gtk_button_set_relief (GTK_BUTTON (reset_button), GTK_RELIEF_NONE);
+  gtk_widget_set_child_visible (reset_button, cc_keyboard_item_is_modified (item));
+
+  gtk_widget_set_tooltip_text (reset_button, _("Reset the shortcut to its default value"));
+
+  gtk_container_add (GTK_CONTAINER (box), reset_button);
+
+  gtk_style_context_add_class (gtk_widget_get_style_context (reset_button), "flat");
+  gtk_style_context_add_class (gtk_widget_get_style_context (reset_button), "circular");
+  gtk_style_context_add_class (gtk_widget_get_style_context (reset_button), "reset-shortcut-button");
+
+  g_signal_connect (item,
+                    "notify::is-modified",
+                    G_CALLBACK (shortcut_modified_changed_cb),
+                    reset_button);
+
+  g_signal_connect (reset_button,
+                    "clicked",
+                    G_CALLBACK (reset_shortcut_cb),
+                    item);
+
   /* The row */
   row = gtk_list_box_row_new ();
   gtk_container_add (GTK_CONTAINER (row), box);
@@ -398,11 +472,22 @@ cc_keyboard_panel_class_init (CcKeyboardPanelClass *klass)
 static void
 cc_keyboard_panel_init (CcKeyboardPanel *self)
 {
+  GtkCssProvider *provider;
 
   g_resources_register (cc_keyboard_get_resource ());
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
+  /* Custom CSS */
+  provider = gtk_css_provider_new ();
+  gtk_css_provider_load_from_data (provider, custom_css, -1, NULL);
+
+  gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+                                             GTK_STYLE_PROVIDER (provider),
+                                             GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
+
+  g_object_unref (provider);
+
   /* Shortcut manager */
   self->manager = cc_keyboard_manager_new ();
 
diff --git a/panels/keyboard/cc-keyboard-shortcut-editor.c b/panels/keyboard/cc-keyboard-shortcut-editor.c
index e904991..e9d91fe 100644
--- a/panels/keyboard/cc-keyboard-shortcut-editor.c
+++ b/panels/keyboard/cc-keyboard-shortcut-editor.c
@@ -48,6 +48,7 @@ struct _CcKeyboardShortcutEditor
   GtkWidget          *new_shortcut_conflict_label;
   GtkWidget          *remove_button;
   GtkWidget          *replace_button;
+  GtkWidget          *reset_button;
   GtkWidget          *shortcut_accel_label;
   GtkWidget          *shortcut_conflict_label;
   GtkWidget          *stack;
@@ -59,6 +60,7 @@ struct _CcKeyboardShortcutEditor
 
   CcKeyboardManager  *manager;
   CcKeyboardItem     *item;
+  GBinding           *reset_item_binding;
 
   CcKeyboardItem     *collision_item;
 
@@ -411,6 +413,20 @@ replace_button_clicked_cb (CcKeyboardShortcutEditor *self)
 }
 
 static void
+reset_item_clicked_cb (CcKeyboardShortcutEditor *self)
+{
+  gchar *accel;
+
+  /* Reset first, then update the shortcut */
+  cc_keyboard_manager_reset_shortcut (self->manager, self->item);
+
+  accel = gtk_accelerator_name (self->item->keyval, self->item->mask);
+  cc_shortcut_label_set_accelerator (CC_SHORTCUT_LABEL (self->shortcut_accel_label), accel);
+
+  g_free (accel);
+}
+
+static void
 setup_keyboard_item (CcKeyboardShortcutEditor *self,
                      CcKeyboardItem           *item)
 {
@@ -441,6 +457,13 @@ setup_keyboard_item (CcKeyboardShortcutEditor *self,
   cc_shortcut_label_set_accelerator (CC_SHORTCUT_LABEL (self->shortcut_accel_label), accel);
   cc_shortcut_label_set_accelerator (CC_SHORTCUT_LABEL (self->custom_shortcut_accel_label), accel);
 
+  g_clear_pointer (&self->reset_item_binding, g_binding_unbind);
+  self->reset_item_binding = g_object_bind_property (item,
+                                                     "is-modified",
+                                                     self->reset_button,
+                                                     "visible",
+                                                     G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
   /* Setup the custom entries */
   if (is_custom)
     {
@@ -476,6 +499,8 @@ cc_keyboard_shortcut_editor_finalize (GObject *object)
   g_clear_object (&self->item);
   g_clear_object (&self->manager);
 
+  g_clear_pointer (&self->reset_item_binding, g_binding_unbind);
+
   G_OBJECT_CLASS (cc_keyboard_shortcut_editor_parent_class)->finalize (object);
 }
 
@@ -672,6 +697,7 @@ cc_keyboard_shortcut_editor_class_init (CcKeyboardShortcutEditorClass *klass)
   gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutEditor, new_shortcut_conflict_label);
   gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutEditor, remove_button);
   gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutEditor, replace_button);
+  gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutEditor, reset_button);
   gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutEditor, shortcut_accel_label);
   gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutEditor, shortcut_conflict_label);
   gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutEditor, stack);
@@ -684,6 +710,7 @@ cc_keyboard_shortcut_editor_class_init (CcKeyboardShortcutEditorClass *klass)
   gtk_widget_class_bind_template_callback (widget_class, name_entry_changed_cb);
   gtk_widget_class_bind_template_callback (widget_class, remove_button_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, replace_button_clicked_cb);
+  gtk_widget_class_bind_template_callback (widget_class, reset_item_clicked_cb);
 }
 
 static void
diff --git a/panels/keyboard/shortcut-editor.ui b/panels/keyboard/shortcut-editor.ui
index 8978461..3bca7e1 100644
--- a/panels/keyboard/shortcut-editor.ui
+++ b/panels/keyboard/shortcut-editor.ui
@@ -64,6 +64,7 @@
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="halign">end</property>
+                    <signal name="clicked" handler="reset_item_clicked_cb" object="CcKeyboardShortcutEditor" 
swapped="yes" />
                   </object>
                 </child>
               </object>


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