[gnome-control-center] region: Make full widget for input rows
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] region: Make full widget for input rows
- Date: Mon, 10 Sep 2018 22:45:37 +0000 (UTC)
commit 66981da2751648eab0365ee4892738fdd0d10d04
Author: Robert Ancell <robert ancell canonical com>
Date: Fri Jun 29 15:55:59 2018 +1200
region: Make full widget for input rows
The row widgets are not full GtkWidgets. This means they are harder
to understand, use g_object_set_data which looses type safety and
cause the one .c file to be overly large.
Update this code to use a CcInputRow widget that uses GTK+ best
practice.
panels/region/cc-input-row.c | 117 +++++++++++++++++++++++++++++++++
panels/region/cc-input-row.h | 44 +++++++++++++
panels/region/cc-input-row.ui | 32 +++++++++
panels/region/cc-region-panel.c | 129 +++++++++++++------------------------
panels/region/meson.build | 3 +-
panels/region/region.gresource.xml | 1 +
6 files changed, 239 insertions(+), 87 deletions(-)
---
diff --git a/panels/region/cc-input-row.c b/panels/region/cc-input-row.c
new file mode 100644
index 000000000..86b452dee
--- /dev/null
+++ b/panels/region/cc-input-row.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "cc-input-row.h"
+
+struct _CcInputRow
+{
+ GtkListBoxRow parent_instance;
+
+ gchar *type;
+ gchar *id;
+ GDesktopAppInfo *app_info;
+
+ GtkWidget *name_label;
+ GtkWidget *icon_image;
+};
+
+G_DEFINE_TYPE (CcInputRow, cc_input_row, GTK_TYPE_LIST_BOX_ROW)
+
+static void
+cc_input_row_dispose (GObject *object)
+{
+ CcInputRow *self = CC_INPUT_ROW (object);
+
+ g_clear_pointer (&self->type, g_free);
+ g_clear_pointer (&self->id, g_free);
+ g_clear_object (&self->app_info);
+
+ G_OBJECT_CLASS (cc_input_row_parent_class)->dispose (object);
+}
+
+void
+cc_input_row_class_init (CcInputRowClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->dispose = cc_input_row_dispose;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/region/cc-input-row.ui");
+ gtk_widget_class_bind_template_child (widget_class, CcInputRow, name_label);
+ gtk_widget_class_bind_template_child (widget_class, CcInputRow, icon_image);
+}
+
+void
+cc_input_row_init (CcInputRow *row)
+{
+ gtk_widget_init_template (GTK_WIDGET (row));
+}
+
+CcInputRow *
+cc_input_row_new (const gchar *type,
+ const gchar *id,
+ GDesktopAppInfo *app_info)
+{
+ CcInputRow *row;
+
+ row = g_object_new (CC_TYPE_INPUT_ROW, NULL);
+ row->type = g_strdup (type);
+ row->id = g_strdup (id);
+ if (app_info != NULL)
+ row->app_info = g_object_ref (app_info);
+
+ return row;
+}
+
+const gchar *
+cc_input_row_get_input_type (CcInputRow *row)
+{
+ g_return_val_if_fail (CC_IS_INPUT_ROW (row), NULL);
+ return row->type;
+}
+
+const gchar *
+cc_input_row_get_id (CcInputRow *row)
+{
+ g_return_val_if_fail (CC_IS_INPUT_ROW (row), NULL);
+ return row->id;
+}
+
+GDesktopAppInfo *
+cc_input_row_get_app_info (CcInputRow *row)
+{
+ g_return_val_if_fail (CC_IS_INPUT_ROW (row), NULL);
+ return row->app_info;
+}
+
+void
+cc_input_row_set_label (CcInputRow *row,
+ const gchar *text)
+{
+ g_return_if_fail (CC_IS_INPUT_ROW (row));
+ gtk_label_set_text (GTK_LABEL (row->name_label), text);
+}
+
+void
+cc_input_row_set_is_input_method (CcInputRow *row,
+ gboolean is_input_method)
+{
+ g_return_if_fail (CC_IS_INPUT_ROW (row));
+ gtk_widget_set_visible (row->icon_image, is_input_method);
+}
diff --git a/panels/region/cc-input-row.h b/panels/region/cc-input-row.h
new file mode 100644
index 000000000..dba8b6158
--- /dev/null
+++ b/panels/region/cc-input-row.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+#include <gio/gdesktopappinfo.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_INPUT_ROW (cc_input_row_get_type ())
+G_DECLARE_FINAL_TYPE (CcInputRow, cc_input_row, CC, INPUT_ROW, GtkListBoxRow)
+
+CcInputRow *cc_input_row_new (const gchar *type,
+ const gchar *id,
+ GDesktopAppInfo *app_info);
+
+const gchar *cc_input_row_get_input_type (CcInputRow *row);
+
+const gchar *cc_input_row_get_id (CcInputRow *row);
+
+GDesktopAppInfo *cc_input_row_get_app_info (CcInputRow *row);
+
+void cc_input_row_set_label (CcInputRow *row,
+ const gchar *text);
+
+void cc_input_row_set_is_input_method (CcInputRow *row,
+ gboolean is_input_method);
+
+G_END_DECLS
diff --git a/panels/region/cc-input-row.ui b/panels/region/cc-input-row.ui
new file mode 100644
index 000000000..ad8212b08
--- /dev/null
+++ b/panels/region/cc-input-row.ui
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+
+ <template class="CcInputRow" parent="GtkListBoxRow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="activatable">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="border-width">18</property>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="xalign">0.0</property>
+ <property name="hexpand">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="icon_image">
+ <property name="visible">True</property>
+ <property name="icon_name">system-run-symbolic</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c
index b20106d09..c733592e8 100644
--- a/panels/region/cc-region-panel.c
+++ b/panels/region/cc-region-panel.c
@@ -33,6 +33,7 @@
#include "cc-format-chooser.h"
#include "cc-input-chooser.h"
#include "cc-input-options.h"
+#include "cc-input-row.h"
#include "cc-common-language.h"
@@ -629,25 +630,19 @@ update_ibus_active_sources (CcRegionPanel *self)
{
g_autoptr(GList) rows = NULL;
GList *l;
- GtkWidget *row;
- const gchar *type;
- const gchar *id;
- IBusEngineDesc *engine_desc;
- GtkWidget *label;
rows = gtk_container_get_children (GTK_CONTAINER (self->input_list));
for (l = rows; l; l = l->next) {
- row = l->data;
- type = g_object_get_data (G_OBJECT (row), "type");
- id = g_object_get_data (G_OBJECT (row), "id");
- if (g_strcmp0 (type, INPUT_SOURCE_TYPE_IBUS) != 0)
+ CcInputRow *row = CC_INPUT_ROW (l->data);
+ IBusEngineDesc *engine_desc;
+
+ if (g_strcmp0 (cc_input_row_get_input_type (row), INPUT_SOURCE_TYPE_IBUS) != 0)
continue;
- engine_desc = g_hash_table_lookup (self->ibus_engines, id);
+ engine_desc = g_hash_table_lookup (self->ibus_engines, cc_input_row_get_id (row));
if (engine_desc) {
g_autofree gchar *display_name = engine_get_display_name (engine_desc);
- label = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "label"));
- gtk_label_set_text (GTK_LABEL (label), display_name);
+ cc_input_row_set_label (row, display_name);
}
}
}
@@ -749,58 +744,28 @@ remove_no_input_row (GtkContainer *list)
return;
if (l->next != NULL)
return;
- if (g_strcmp0 (g_object_get_data (G_OBJECT (l->data), "type"), "none") == 0)
+ if (g_strcmp0 (cc_input_row_get_input_type (CC_INPUT_ROW (l->data)), "none") == 0)
gtk_container_remove (list, GTK_WIDGET (l->data));
}
-static GtkWidget *
+static void
add_input_row (CcRegionPanel *self,
const gchar *type,
const gchar *id,
const gchar *name,
GDesktopAppInfo *app_info)
{
- GtkWidget *row;
- GtkWidget *box;
- GtkWidget *label;
- GtkWidget *image;
+ CcInputRow *row;
remove_no_input_row (GTK_CONTAINER (self->input_list));
- row = gtk_list_box_row_new ();
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_container_add (GTK_CONTAINER (row), box);
- label = gtk_label_new (name);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
- gtk_widget_set_margin_start (label, 20);
- gtk_widget_set_margin_end (label, 20);
- gtk_widget_set_margin_top (label, 18);
- gtk_widget_set_margin_bottom (label, 18);
- gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
-
- if (strcmp (type, INPUT_SOURCE_TYPE_IBUS) == 0) {
- image = gtk_image_new_from_icon_name ("system-run-symbolic", GTK_ICON_SIZE_BUTTON);
- gtk_widget_set_margin_start (image, 20);
- gtk_widget_set_margin_end (image, 20);
- gtk_widget_set_margin_top (image, 6);
- gtk_widget_set_margin_bottom (image, 6);
- gtk_style_context_add_class (gtk_widget_get_style_context (image), "dim-label");
- gtk_box_pack_start (GTK_BOX (box), image, FALSE, TRUE, 0);
- }
-
- gtk_widget_show_all (row);
- gtk_container_add (GTK_CONTAINER (self->input_list), row);
-
- g_object_set_data (G_OBJECT (row), "label", label);
- g_object_set_data (G_OBJECT (row), "type", (gpointer)type);
- g_object_set_data_full (G_OBJECT (row), "id", g_strdup (id), g_free);
- if (app_info) {
- g_object_set_data_full (G_OBJECT (row), "app-info", g_object_ref (app_info), g_object_unref);
- }
+ row = cc_input_row_new (type, id, app_info);
+ gtk_widget_show (GTK_WIDGET (row));
+ cc_input_row_set_label (row, name);
+ cc_input_row_set_is_input_method (row, strcmp (type, INPUT_SOURCE_TYPE_IBUS) == 0);
+ gtk_container_add (GTK_CONTAINER (self->input_list), GTK_WIDGET (row));
cc_list_box_adjust_scrolling (GTK_LIST_BOX (self->input_list));
-
- return row;
}
static void
@@ -884,10 +849,8 @@ select_by_id (GtkWidget *row,
gpointer data)
{
const gchar *id = data;
- const gchar *row_id;
- row_id = (const gchar *)g_object_get_data (G_OBJECT (row), "id");
- if (g_strcmp0 (row_id, id) == 0)
+ if (g_strcmp0 (cc_input_row_get_id (CC_INPUT_ROW (row)), id) == 0)
gtk_list_box_select_row (GTK_LIST_BOX (gtk_widget_get_parent (row)), GTK_LIST_BOX_ROW (row));
}
@@ -904,12 +867,12 @@ input_sources_changed (GSettings *settings,
const gchar *key,
CcRegionPanel *self)
{
- GtkListBoxRow *selected;
+ CcInputRow *selected;
g_autofree gchar *id = NULL;
- selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (self->input_list));
+ selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (GTK_LIST_BOX (self->input_list)));
if (selected)
- id = g_strdup (g_object_get_data (G_OBJECT (selected), "id"));
+ id = g_strdup (cc_input_row_get_id (selected));
clear_input_sources (self);
add_input_sources_from_settings (self);
if (id)
@@ -920,14 +883,14 @@ input_sources_changed (GSettings *settings,
static void
update_buttons (CcRegionPanel *self)
{
- GtkListBoxRow *selected;
+ CcInputRow *selected;
g_autoptr(GList) children = NULL;
guint n_rows;
children = gtk_container_get_children (GTK_CONTAINER (self->input_list));
n_rows = g_list_length (children);
- selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (self->input_list));
+ selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (GTK_LIST_BOX (self->input_list)));
if (selected == NULL) {
gtk_widget_set_visible (self->show_config, FALSE);
gtk_widget_set_sensitive (self->remove_input, FALSE);
@@ -936,14 +899,16 @@ update_buttons (CcRegionPanel *self)
gtk_widget_set_sensitive (self->move_down_input, FALSE);
} else {
GDesktopAppInfo *app_info;
+ gint index;
- app_info = (GDesktopAppInfo *)g_object_get_data (G_OBJECT (selected), "app-info");
+ app_info = cc_input_row_get_app_info (selected);
+ index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (selected));
gtk_widget_set_visible (self->show_config, app_info != NULL);
gtk_widget_set_sensitive (self->show_layout, TRUE);
gtk_widget_set_sensitive (self->remove_input, n_rows > 1);
- gtk_widget_set_sensitive (self->move_up_input, gtk_list_box_row_get_index (selected) > 0);
- gtk_widget_set_sensitive (self->move_down_input, gtk_list_box_row_get_index (selected) <
n_rows - 1);
+ gtk_widget_set_sensitive (self->move_up_input, index > 0);
+ gtk_widget_set_sensitive (self->move_down_input, index < n_rows - 1);
}
gtk_widget_set_visible (self->options_button,
@@ -953,8 +918,6 @@ update_buttons (CcRegionPanel *self)
static void
set_input_settings (CcRegionPanel *self)
{
- const gchar *type;
- const gchar *id;
GVariantBuilder builder;
g_autoptr(GList) list = NULL;
GList *l;
@@ -962,9 +925,8 @@ set_input_settings (CcRegionPanel *self)
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)"));
list = gtk_container_get_children (GTK_CONTAINER (self->input_list));
for (l = list; l; l = l->next) {
- type = (const gchar *)g_object_get_data (G_OBJECT (l->data), "type");
- id = (const gchar *)g_object_get_data (G_OBJECT (l->data), "id");
- g_variant_builder_add (&builder, "(ss)", type, id);
+ CcInputRow *row = CC_INPUT_ROW (l->data);
+ g_variant_builder_add (&builder, "(ss)", cc_input_row_get_input_type (row),
cc_input_row_get_id (row));
}
g_settings_set_value (self->input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
@@ -994,7 +956,7 @@ input_source_already_added (CcRegionPanel *self,
list = gtk_container_get_children (GTK_CONTAINER (self->input_list));
for (l = list; l; l = l->next)
- if (g_str_equal (id, (const gchar *) g_object_get_data (G_OBJECT (l->data), "id"))) {
+ if (g_str_equal (id, cc_input_row_get_id (CC_INPUT_ROW (l->data)))) {
return TRUE;
}
@@ -1201,26 +1163,24 @@ move_selected_input_down (CcRegionPanel *self)
static void
show_selected_settings (CcRegionPanel *self)
{
- GtkListBoxRow *selected;
+ CcInputRow *selected;
g_autoptr(GdkAppLaunchContext) ctx = NULL;
GDesktopAppInfo *app_info;
- const gchar *id;
g_autoptr(GError) error = NULL;
- selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (self->input_list));
+ selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (GTK_LIST_BOX (self->input_list)));
if (selected == NULL)
return;
- app_info = (GDesktopAppInfo *)g_object_get_data (G_OBJECT (selected), "app-info");
+ app_info = cc_input_row_get_app_info (selected);
if (app_info == NULL)
return;
ctx = gdk_display_get_app_launch_context (gdk_display_get_default ());
gdk_app_launch_context_set_timestamp (ctx, gtk_get_current_event_time ());
- id = (const gchar *)g_object_get_data (G_OBJECT (selected), "id");
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (ctx),
- "IBUS_ENGINE_NAME", id);
+ "IBUS_ENGINE_NAME", cc_input_row_get_id (selected));
if (!g_app_info_launch (G_APP_INFO (app_info), NULL, G_APP_LAUNCH_CONTEXT (ctx), &error))
g_warning ("Failed to launch input source setup: %s", error->message);
@@ -1229,20 +1189,18 @@ show_selected_settings (CcRegionPanel *self)
static void
show_selected_layout (CcRegionPanel *self)
{
- GtkListBoxRow *selected;
- const gchar *type;
- const gchar *id;
+ CcInputRow *selected;
+ const gchar *type, *id;
const gchar *layout;
const gchar *variant;
g_autofree gchar *commandline = NULL;
- selected = gtk_list_box_get_selected_row (GTK_LIST_BOX (self->input_list));
+ selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (GTK_LIST_BOX (self->input_list)));
if (selected == NULL)
return;
- type = (const gchar *)g_object_get_data (G_OBJECT (selected), "type");
- id = (const gchar *)g_object_get_data (G_OBJECT (selected), "id");
-
+ type = cc_input_row_get_input_type (selected);
+ id = cc_input_row_get_id (selected);
if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) {
gnome_xkb_info_get_layout_info (self->xkb_info,
id, NULL, NULL,
@@ -1475,22 +1433,21 @@ set_localed_input (CcRegionPanel *self)
{
g_autoptr(GString) layouts = NULL;
g_autoptr(GString) variants = NULL;
- const gchar *type, *id;
g_autoptr(GList) list = NULL;
GList *li;
- const gchar *l, *v;
layouts = g_string_new ("");
variants = g_string_new ("");
list = gtk_container_get_children (GTK_CONTAINER (self->input_list));
for (li = list; li; li = li->next) {
- type = (const gchar *)g_object_get_data (G_OBJECT (li->data), "type");
- id = (const gchar *)g_object_get_data (G_OBJECT (li->data), "id");
- if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS))
+ CcInputRow *row = CC_INPUT_ROW (li->data);
+ const gchar *l, *v;
+
+ if (g_str_equal (cc_input_row_get_input_type (row), INPUT_SOURCE_TYPE_IBUS))
continue;
- if (gnome_xkb_info_get_layout_info (self->xkb_info, id, NULL, NULL, &l, &v)) {
+ if (gnome_xkb_info_get_layout_info (self->xkb_info, cc_input_row_get_id (row), NULL, NULL,
&l, &v)) {
if (layouts->str[0]) {
g_string_append_c (layouts, ',');
g_string_append_c (variants, ',');
diff --git a/panels/region/meson.build b/panels/region/meson.build
index 5c0a6f5db..1ab0019d5 100644
--- a/panels/region/meson.build
+++ b/panels/region/meson.build
@@ -22,7 +22,8 @@ sources = files(
'cc-format-chooser.c',
'cc-ibus-utils.c',
'cc-input-chooser.c',
- 'cc-input-options.c'
+ 'cc-input-options.c',
+ 'cc-input-row.c',
)
resource_data = files(
diff --git a/panels/region/region.gresource.xml b/panels/region/region.gresource.xml
index 73ce4c167..b896bd701 100644
--- a/panels/region/region.gresource.xml
+++ b/panels/region/region.gresource.xml
@@ -3,6 +3,7 @@
<gresource prefix="/org/gnome/control-center/region">
<file preprocess="xml-stripblanks">region.ui</file>
<file preprocess="xml-stripblanks">cc-format-chooser.ui</file>
+ <file preprocess="xml-stripblanks">cc-input-row.ui</file>
<file preprocess="xml-stripblanks">input-options.ui</file>
<file preprocess="xml-stripblanks">input-chooser.ui</file>
</gresource>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]