[gnome-control-center/wip/gbsneto/new-keyboard-panel: 19/27] keyboard: show sortcuts in a listbox
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/gbsneto/new-keyboard-panel: 19/27] keyboard: show sortcuts in a listbox
- Date: Tue, 19 Jul 2016 16:03:39 +0000 (UTC)
commit a99db109ee14e3617425db5d3cbf72cc86dc9fc7
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Tue Jun 14 23:05:57 2016 -0300
keyboard: show sortcuts in a listbox
The new listbox will replace the current treeview. This
patch simply the listbox and add the initial add() and
remove() functions to manage the rows, and does not remove
the treeview yet.
panels/keyboard/cc-keyboard-panel.c | 281 ++++++++++++++++++++++++++++++-
panels/keyboard/gnome-keyboard-panel.ui | 43 +++++
panels/keyboard/keyboard-shortcuts.c | 25 +++
panels/keyboard/keyboard-shortcuts.h | 3 +
4 files changed, 343 insertions(+), 9 deletions(-)
---
diff --git a/panels/keyboard/cc-keyboard-panel.c b/panels/keyboard/cc-keyboard-panel.c
index d3530db..204b931 100644
--- a/panels/keyboard/cc-keyboard-panel.c
+++ b/panels/keyboard/cc-keyboard-panel.c
@@ -37,6 +37,13 @@
#define BINDINGS_SCHEMA "org.gnome.settings-daemon.plugins.media-keys"
#define CUSTOM_SHORTCUTS_ID "custom"
+typedef struct
+{
+ CcKeyboardItem *item;
+ gchar *section_title;
+ gchar *section_id;
+} RowData;
+
struct _CcKeyboardPanel
{
CcPanel parent;
@@ -45,6 +52,9 @@ struct _CcKeyboardPanel
GtkListStore *sections_store;
GtkTreeModel *sections_model;
GtkWidget *shortcut_treeview;
+ GtkWidget *listbox;
+ GtkListBoxRow *add_shortcut_row;
+ GtkSizeGroup *accelerator_sizegroup;
/* Toolbar widgets */
GtkWidget *add_toolbutton;
@@ -75,6 +85,243 @@ enum {
PROP_PARAMETERS
};
+/*
+ * RowData functions
+ */
+static RowData*
+row_data_new (CcKeyboardItem *item,
+ const gchar *section_id,
+ const gchar *section_title)
+{
+ RowData *data;
+
+ data = g_new0 (RowData, 1);
+ data->item = g_object_ref (item);
+ data->section_id = g_strdup (section_id);
+ data->section_title = g_strdup (section_title);
+
+ return data;
+}
+
+static void
+row_data_free (RowData *data)
+{
+ g_object_unref (data->item);
+ g_free (data->section_id);
+ g_free (data->section_title);
+ g_free (data);
+}
+
+/*
+ * Listbox-related functions
+ */
+static gboolean
+transform_binding_to_accel (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ CcKeyboardItem *item;
+ gchar *accelerator;
+
+ item = CC_KEYBOARD_ITEM (g_binding_get_source (binding));
+
+ accelerator = convert_keysym_state_to_string (item->keyval, item->mask, item->keycode);
+
+ g_value_set_string (to_value, accelerator);
+
+ g_free (accelerator);
+
+ return TRUE;
+}
+
+static void
+add_item (CcKeyboardPanel *self,
+ CcKeyboardItem *item,
+ const gchar *section_id,
+ const gchar *section_title)
+{
+ GtkWidget *row, *box, *label;
+
+ /* Horizontal box */
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 6);
+
+ /* Shortcut title */
+ label = gtk_label_new (item->description);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
+ gtk_widget_set_hexpand (label, TRUE);
+
+ g_object_bind_property (item,
+ "description",
+ label,
+ "label",
+ G_BINDING_DEFAULT);
+
+ gtk_container_add (GTK_CONTAINER (box), label);
+
+ /* Shortcut accelerator */
+ label = gtk_label_new ("");
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+
+ gtk_size_group_add_widget (self->accelerator_sizegroup, label);
+
+ g_object_bind_property_full (item,
+ "binding",
+ label,
+ "label",
+ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE,
+ transform_binding_to_accel,
+ NULL, NULL, NULL);
+
+ gtk_container_add (GTK_CONTAINER (box), label);
+
+ gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
+
+ /* The row */
+ row = gtk_list_box_row_new ();
+ gtk_container_add (GTK_CONTAINER (row), box);
+
+ gtk_widget_show_all (row);
+
+ g_object_set_data_full (G_OBJECT (row),
+ "data",
+ row_data_new (item, section_id, section_title),
+ (GDestroyNotify) row_data_free);
+
+ gtk_container_add (GTK_CONTAINER (self->listbox), row);
+}
+
+static void
+remove_item (CcKeyboardPanel *self,
+ CcKeyboardItem *item)
+{
+ GList *children, *l;
+
+ children = gtk_container_get_children (GTK_CONTAINER (self->listbox));
+
+ for (l = children; l != NULL; l = l->next)
+ {
+ RowData *row_data;
+
+ row_data = g_object_get_data (l->data, "data");
+
+ if (row_data->item == item)
+ {
+ gtk_container_remove (GTK_CONTAINER (self->listbox), l->data);
+ break;
+ }
+ }
+
+ g_list_free (children);
+}
+
+static gint
+sort_function (GtkListBoxRow *a,
+ GtkListBoxRow *b,
+ gpointer user_data)
+{
+ CcKeyboardPanel *self;
+ RowData *a_data, *b_data;
+ gint retval;
+
+ self = user_data;
+
+ if (a == self->add_shortcut_row)
+ return 1;
+
+ if (b == self->add_shortcut_row)
+ return -1;
+
+ a_data = g_object_get_data (G_OBJECT (a), "data");
+ b_data = g_object_get_data (G_OBJECT (b), "data");
+
+ /* Put custom shortcuts below everything else */
+ if (a_data->item->type == CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH)
+ return 1;
+ else if (b_data->item->type == CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH)
+ return -1;
+
+ retval = g_strcmp0 (a_data->section_title, b_data->section_title);
+
+ if (retval != 0)
+ return retval;
+
+ return g_strcmp0 (a_data->item->description, b_data->item->description);
+}
+
+static void
+header_function (GtkListBoxRow *row,
+ GtkListBoxRow *before,
+ gpointer user_data)
+{
+ CcKeyboardPanel *self;
+ gboolean add_header;
+ RowData *data;
+
+ self = user_data;
+ add_header = FALSE;
+
+ /* The + row always have a separator */
+ if (row == self->add_shortcut_row)
+ {
+ GtkWidget *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_widget_show (separator);
+
+ gtk_list_box_row_set_header (row, separator);
+
+ return;
+ }
+
+ data = g_object_get_data (G_OBJECT (row), "data");
+
+ if (before)
+ {
+ RowData *before_data = g_object_get_data (G_OBJECT (before), "data");
+
+ if (before_data)
+ add_header = g_strcmp0 (before_data->section_id, data->section_id) != 0;
+ }
+ else
+ {
+ add_header = TRUE;
+ }
+
+ if (add_header)
+ {
+ GtkWidget *box, *label;
+ gchar *markup;
+
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_widget_set_margin_top (box, before ? 18 : 6);
+
+ markup = g_strdup_printf ("<b>%s</b>", _(data->section_title));
+ label = g_object_new (GTK_TYPE_LABEL,
+ "label", markup,
+ "use-markup", TRUE,
+ "xalign", 0.0,
+ "margin-start", 6,
+ NULL);
+
+ gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
+
+ gtk_container_add (GTK_CONTAINER (box), label);
+ gtk_container_add (GTK_CONTAINER (box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
+
+ gtk_list_box_row_set_header (row, box);
+
+ gtk_widget_show_all (box);
+
+ g_free (markup);
+ }
+ else
+ {
+ gtk_list_box_row_set_header (row, NULL);
+ }
+}
+
static GHashTable*
get_hash_for_group (CcKeyboardPanel *self,
BindingGroupType group)
@@ -474,7 +721,6 @@ static void
reload_sections (CcKeyboardPanel *self)
{
GtkTreeModel *shortcut_model;
- GtkTreeIter iter;
GHashTable *loaded_files;
GDir *dir;
gchar *default_wm_keybindings[] = { "Mutter", "GNOME Shell", NULL };
@@ -557,14 +803,6 @@ reload_sections (CcKeyboardPanel *self)
g_hash_table_destroy (loaded_files);
g_strfreev (wm_keybindings);
- /* Add a separator */
- gtk_list_store_append (GTK_LIST_STORE (self->sections_store), &iter);
- gtk_list_store_set (GTK_LIST_STORE (self->sections_store),
- &iter,
- SECTION_DESCRIPTION_COLUMN, NULL,
- SECTION_GROUP_COLUMN, BINDING_GROUP_SEPARATOR,
- -1);
-
/* Load custom keybindings */
append_sections_from_gsettings (self);
}
@@ -649,10 +887,15 @@ add_shortcuts (CcKeyboardPanel *self)
DETAIL_KEYENTRY_COLUMN, item,
DETAIL_TYPE_COLUMN, SHORTCUT_TYPE_KEY_ENTRY,
-1);
+
+ add_item (self, item, id, title);
}
}
can_continue = gtk_tree_model_iter_next (self->sections_model, §ions_iter);
+
+ g_free (title);
+ g_free (id);
}
}
@@ -849,6 +1092,8 @@ remove_custom_shortcut (CcKeyboardPanel *self,
/* not a custom shortcut */
g_assert (item->type == CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH);
+ remove_item (self, item);
+
g_settings_delay (item->settings);
g_settings_reset (item->settings, "name");
g_settings_reset (item->settings, "command");
@@ -931,6 +1176,8 @@ add_custom_shortcut (CcKeyboardPanel *self,
gtk_tree_view_expand_to_path (tree_view, path);
gtk_tree_view_scroll_to_cell (tree_view, path, NULL, FALSE, 0, 0);
gtk_tree_path_free (path);
+
+ add_item (self, item, CUSTOM_SHORTCUTS_ID, _("Custom Shortcuts"));
}
else
{
@@ -1688,6 +1935,7 @@ cc_keyboard_panel_finalize (GObject *object)
g_clear_pointer (&self->pictures_regex, g_regex_unref);
g_clear_pointer (&self->wm_changed_id, wm_common_unregister_window_manager_change);
+ g_clear_object (&self->accelerator_sizegroup);
g_clear_object (&self->custom_shortcut_dialog);
g_clear_object (&self->binding_settings);
@@ -1739,11 +1987,13 @@ cc_keyboard_panel_class_init (CcKeyboardPanelClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/keyboard/gnome-keyboard-panel.ui");
+ gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, add_shortcut_row);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, add_toolbutton);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, custom_shortcut_command_entry);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, custom_shortcut_dialog);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, custom_shortcut_name_entry);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, custom_shortcut_ok_button);
+ gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, listbox);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, remove_toolbutton);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, shortcut_toolbar);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, shortcut_treeview);
@@ -1762,4 +2012,17 @@ cc_keyboard_panel_init (CcKeyboardPanel *self)
gtk_widget_init_template (GTK_WIDGET (self));
self->binding_settings = g_settings_new (BINDINGS_SCHEMA);
+
+ /* Use a sizegroup to make the accelerator labels the same width */
+ self->accelerator_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ gtk_list_box_set_sort_func (GTK_LIST_BOX (self->listbox),
+ sort_function,
+ self,
+ NULL);
+
+ gtk_list_box_set_header_func (GTK_LIST_BOX (self->listbox),
+ header_function,
+ self,
+ NULL);
}
diff --git a/panels/keyboard/gnome-keyboard-panel.ui b/panels/keyboard/gnome-keyboard-panel.ui
index 8ab194a..192b3a3 100644
--- a/panels/keyboard/gnome-keyboard-panel.ui
+++ b/panels/keyboard/gnome-keyboard-panel.ui
@@ -202,6 +202,49 @@
</packing>
</child>
<child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkListBox" id="listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="selection-mode">none</property>
+ <property name="width-request">100</property>
+ <child>
+ <object class="GtkListBoxRow" id="add_shortcut_row">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <child type="center">
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">list-add-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkToolbar" id="shortcut_toolbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
diff --git a/panels/keyboard/keyboard-shortcuts.c b/panels/keyboard/keyboard-shortcuts.c
index de09087..deef038 100644
--- a/panels/keyboard/keyboard-shortcuts.c
+++ b/panels/keyboard/keyboard-shortcuts.c
@@ -357,3 +357,28 @@ setup_keyboard_options (GtkListStore *store)
G_CALLBACK (xkb_option_changed), store);
}
+/* Stealed from GtkCellRendererAccel */
+gchar*
+convert_keysym_state_to_string (guint keysym,
+ GdkModifierType mask,
+ guint keycode)
+{
+ gchar *name;
+
+ if (keysym == 0 && keycode == 0)
+ {
+ /* This label is displayed in a treeview cell displaying
+ * a disabled accelerator key combination.
+ */
+ name = g_strdup (_("Disabled"));
+ }
+ else
+ {
+ name = gtk_accelerator_get_label_with_keycode (NULL, keysym, keycode, mask);
+
+ if (name == NULL)
+ name = gtk_accelerator_name_with_keycode (NULL, keysym, keycode, mask);
+ }
+
+ return name;
+}
diff --git a/panels/keyboard/keyboard-shortcuts.h b/panels/keyboard/keyboard-shortcuts.h
index bf53300..0f4c890 100644
--- a/panels/keyboard/keyboard-shortcuts.h
+++ b/panels/keyboard/keyboard-shortcuts.h
@@ -96,3 +96,6 @@ void parse_start_tag (GMarkupParseContext *ctx,
gpointer user_data,
GError **error);
+gchar* convert_keysym_state_to_string (guint keysym,
+ GdkModifierType mask,
+ guint keycode);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]