[gnome-software] Improve the category pages
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Improve the category pages
- Date: Wed, 4 Sep 2013 04:02:36 +0000 (UTC)
commit 9d4149a67cb858e9f66ea76bde8d875545887045
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Sep 4 00:00:58 2013 -0400
Improve the category pages
Make it so that the filter list doesn't scroll with the
content. To do so, we take the filter list out of the grid,
and instead use a simple custom container which allocates
its children with fixed relative sizes, to allocate the
filter list and the content at a ratio of 1:2.
src/Makefile.am | 2 +
src/gnome-software.ui | 96 +++++++++-------
src/gs-application.c | 3 +
src/gs-box.c | 289 +++++++++++++++++++++++++++++++++++++++++++++++
src/gs-box.h | 48 ++++++++
src/gs-shell-category.c | 58 ++++------
6 files changed, 418 insertions(+), 78 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 4b74eab..f34b7e4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,8 @@ gnome_software_SOURCES = \
gs-category.h \
gs-app-widget.c \
gs-app-widget.h \
+ gs-box.h \
+ gs-box.c \
gs-plugin.c \
gs-plugin.h \
gs-shell.c \
diff --git a/src/gnome-software.ui b/src/gnome-software.ui
index a026e90..65b133c 100644
--- a/src/gnome-software.ui
+++ b/src/gnome-software.ui
@@ -795,62 +795,70 @@ with multi-level undo.
</object>
</child>
<child>
- <object class="GtkScrolledWindow" id="scrolledwindow_category">
+ <object class="GsBox" id="box_category">
<property name="visible">True</property>
- <property name="shadow_type">none</property>
- <property name="can_focus">False</property>
- <property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
- <style>
- <class name="main-scrolled-software"/>
- </style>
<child>
- <object class="GtkViewport" id="viewport3">
+ <object class="GtkFrame" id="frame_filter">
+ <property name="visible">True</property>
+ <property name="margin-top">18</property>
+ <property name="margin-bottom">18</property>
+ <property name="margin-left">12</property>
+ <property name="margin-right">12</property>
+ <property name="shadow_type">in</property>
+ <property name="halign">fill</property>
+ <property name="valign">start</property>
+ <style>
+ <class name="view"/>
+ </style>
+ <child>
+ <object class="GtkListBox" id="listbox_filter">
+ <property name="visible">True</property>
+ <property name="selection_mode">browse</property>
+ <property name="halign">fill</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="relative_size">1.0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow_category">
<property name="visible">True</property>
+ <property name="shadow_type">none</property>
<property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <style>
+ <class name="main-scrolled-software"/>
+ </style>
<child>
- <object class="GtkGrid" id="category_detail_grid">
+ <object class="GtkViewport" id="viewport3">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="margin_left">12</property>
- <property name="margin_right">12</property>
- <property name="margin_top">12</property>
- <property name="margin_bottom">12</property>
- <property name="row_spacing">12</property>
- <property name="column_spacing">12</property>
- <property name="row_homogeneous">True</property>
- <property name="column_homogeneous">True</property>
- <property name="hexpand">True</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
<child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
+ <object class="GtkGrid" id="category_detail_grid">
+ <property name="margin_left">12</property>
+ <property name="margin_right">12</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">12</property>
+ <property name="halign">fill</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <property name="row_homogeneous">True</property>
+ <property name="column_homogeneous">True</property>
+ <property name="hexpand">True</property>
+ <property name="valign">start</property>
+ </object>
</child>
</object>
</child>
</object>
+ <packing>
+ <property name="relative_size">2.0</property>
+ </packing>
</child>
</object>
</child>
diff --git a/src/gs-application.c b/src/gs-application.c
index 885f2a6..4026f78 100644
--- a/src/gs-application.c
+++ b/src/gs-application.c
@@ -28,6 +28,7 @@
#include <gtk/gtk.h>
#include <packagekit-glib2/packagekit.h>
+#include "gs-box.h"
#include "gs-shell.h"
#include "gs-plugin-loader.h"
@@ -120,6 +121,8 @@ gs_application_startup (GApplication *application)
G_APPLICATION_CLASS (gs_application_parent_class)->startup (application);
+ g_type_ensure (GS_TYPE_BOX);
+
/* set up the app menu */
g_action_map_add_action_entries (G_ACTION_MAP (app),
actions, G_N_ELEMENTS (actions),
diff --git a/src/gs-box.c b/src/gs-box.c
new file mode 100644
index 0000000..2eb7199
--- /dev/null
+++ b/src/gs-box.c
@@ -0,0 +1,289 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012-2013 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "gs-box.h"
+
+typedef struct {
+ GtkWidget *widget;
+ gdouble relative_size;
+} GsBoxChild;
+
+struct _GsBox {
+ GtkContainer parent;
+ GList *children;
+ gdouble total;
+};
+
+struct _GsBoxClass {
+ GtkContainerClass parent_class;
+};
+
+G_DEFINE_TYPE (GsBox, gs_box, GTK_TYPE_CONTAINER)
+
+enum {
+ CHILD_PROP_0,
+ CHILD_PROP_RELATIVE_SIZE
+};
+
+static void
+gs_box_real_add (GtkContainer *container, GtkWidget *widget)
+{
+ gs_box_add (GS_BOX (container), widget, 1.0);
+}
+
+static void
+gs_box_remove (GtkContainer *container, GtkWidget *widget)
+{
+ GsBox *box = GS_BOX (container);
+ GList *l;
+
+ for (l = box->children; l; l = l->next) {
+ GsBoxChild *child = l->data;
+ if (child->widget == widget) {
+ gtk_widget_unparent (child->widget);
+ box->children = g_list_delete_link (box->children, l);
+ box->total -= child->relative_size;
+ g_free (child);
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ break;
+ }
+ }
+}
+
+static void
+gs_box_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GsBox *box = GS_BOX (container);
+ GsBoxChild *child;
+ GList *children;
+
+ children = box->children;
+ while (children) {
+ child = children->data;
+ children = children->next;
+ (* callback) (child->widget, callback_data);
+ }
+}
+
+static void
+gs_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+ GsBox *box = GS_BOX (widget);
+ GsBoxChild *child;
+ GtkAllocation child_allocation;
+ gint x;
+ GList *l;
+ gboolean rtl;
+
+ rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ x = allocation->x;
+ for (l = box->children; l; l = l->next) {
+ child = l->data;
+ child_allocation.x = x;
+ child_allocation.y = allocation->y;
+ child_allocation.width = allocation->width * (child->relative_size / box->total);
+ child_allocation.height = allocation->height;
+ if (rtl) {
+ child_allocation.x = allocation->x + allocation->width - child_allocation.x -
child_allocation.width;
+ }
+ gtk_widget_size_allocate (child->widget, &child_allocation);
+ x += child_allocation.width;
+ }
+}
+
+static void
+gs_box_get_preferred_width (GtkWidget *widget, gint *min, gint *nat)
+{
+ GsBox *box = GS_BOX (widget);
+ GsBoxChild *child;
+ gint cm, *cn;
+ gint n_children;
+ gint ms, m, n;
+ GList *l;
+ gint i;
+
+ n_children = g_list_length (box->children);
+
+ cn = g_new0 (gint, n_children);
+
+ ms = 0;
+ for (l = box->children, i = 0; l; l = l->next, i++) {
+ child = l->data;
+ gtk_widget_get_preferred_width (child->widget, &cm, cn + i);
+ ms = MAX (ms, cm / child->relative_size);
+ }
+
+ m = n = 0;
+ for (l = box->children, i = 0; l; l = l->next, i++) {
+ cm = ms * child->relative_size;
+ m += cm;
+ n += MAX (cn[i], cm);
+ }
+
+ g_free (cn);
+
+ if (min)
+ *min = m;
+ if (nat)
+ *nat = n;
+}
+
+static void
+gs_box_get_preferred_height (GtkWidget *widget, gint *min, gint *nat)
+{
+ GsBox *box = GS_BOX (widget);
+ gint m, n;
+ gint cm, cn;
+ GsBoxChild *child;
+ GList *l;
+
+ m = n = 0;
+ for (l = box->children; l; l = l->next) {
+ child = l->data;
+ gtk_widget_get_preferred_height (child->widget, &cm, &cn);
+ m = MAX (m, cm);
+ n = MAX (n, cn);
+ }
+ if (min)
+ *min = m;
+ if (nat)
+ *nat = n;
+}
+
+static void
+gs_box_get_child_property (GtkContainer *container,
+ GtkWidget *widget,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsBox *box = GS_BOX (container);
+ GList *l;
+ GsBoxChild *child;
+
+ child = NULL;
+ for (l = box->children; l; l = l->next) {
+ child = l->data;
+ if (child->widget == widget) {
+ break;
+ }
+ }
+
+ switch (property_id) {
+ case CHILD_PROP_RELATIVE_SIZE:
+ g_value_set_double (value, child->relative_size);
+ break;
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ }
+}
+
+static void
+gs_box_set_child_property (GtkContainer *container,
+ GtkWidget *widget,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GsBox *box = GS_BOX (container);
+ GList *l;
+ GsBoxChild *child;
+
+ child = NULL;
+ for (l = box->children; l; l = l->next) {
+ child = l->data;
+ if (child->widget == widget) {
+ break;
+ }
+ }
+
+ switch (property_id) {
+ case CHILD_PROP_RELATIVE_SIZE:
+ box->total -= child->relative_size;
+ child->relative_size = g_value_get_double (value);
+ box->total += child->relative_size;
+ break;
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ }
+}
+
+static void
+gs_box_init (GsBox *box)
+{
+ gtk_widget_set_has_window (GTK_WIDGET (box), FALSE);
+}
+
+static void
+gs_box_class_init (GsBoxClass *class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
+
+ widget_class->size_allocate = gs_box_size_allocate;
+ widget_class->get_preferred_width = gs_box_get_preferred_width;
+ widget_class->get_preferred_height = gs_box_get_preferred_height;
+
+ container_class->add = gs_box_real_add;
+ container_class->remove = gs_box_remove;
+ container_class->forall = gs_box_forall;
+ container_class->get_child_property = gs_box_get_child_property;
+ container_class->set_child_property = gs_box_set_child_property;
+
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_RELATIVE_SIZE,
+ g_param_spec_double ("relative-size", NULL, NULL,
+ 0.0, G_MAXDOUBLE, 1.0,
+ G_PARAM_READWRITE));
+}
+
+GtkWidget *
+gs_box_new (void)
+{
+ return g_object_new (GS_TYPE_BOX, NULL);
+}
+
+void
+gs_box_add (GsBox *box, GtkWidget *widget, gdouble relative_size)
+{
+ GsBoxChild *child;
+
+ child = g_new (GsBoxChild, 1);
+
+ child->widget = widget;
+ child->relative_size = relative_size;
+
+ box->total += relative_size;
+
+ box->children = g_list_append (box->children, child);
+ gtk_widget_set_parent (widget, GTK_WIDGET (box));
+}
diff --git a/src/gs-box.h b/src/gs-box.h
new file mode 100644
index 0000000..d318156
--- /dev/null
+++ b/src/gs-box.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef GS_BOX_H
+#define GS_BOX_H
+
+#include <gtk/gtk.h>
+
+#define GS_TYPE_BOX (gs_box_get_type())
+#define GS_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GS_TYPE_BOX, GsBox))
+#define GS_BOX_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), GS_TYPE_BOX, GsBoxClass))
+#define GS_IS_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GS_TYPE_BOX))
+#define GS_IS_BOX_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), GS_TYPE_BOX))
+#define GS_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GS_TYPE_BOX, GsBoxClass))
+
+G_BEGIN_DECLS
+
+typedef struct _GsBox GsBox;
+typedef struct _GsBoxClass GsBoxClass;
+
+GType gs_box_get_type (void);
+GtkWidget *gs_box_new (void);
+void gs_box_add (GsBox *box,
+ GtkWidget *child,
+ gdouble relative_size);
+
+G_END_DECLS
+
+#endif /* GS_BOX_H */
+
diff --git a/src/gs-shell-category.c b/src/gs-shell-category.c
index 8f9ce96..dbce924 100644
--- a/src/gs-shell-category.c
+++ b/src/gs-shell-category.c
@@ -33,8 +33,8 @@ struct GsShellCategoryPrivate {
GCancellable *cancellable;
GsShell *shell;
GsCategory *category;
+ GtkWidget *col0_placeholder;
GtkWidget *col1_placeholder;
- GtkWidget *col2_placeholder;
};
G_DEFINE_TYPE (GsShellCategory, gs_shell_category, G_TYPE_OBJECT)
@@ -75,6 +75,7 @@ create_app_tile (GsShellCategory *shell, GsApp *app)
PangoAttrList *attrs;
button = gtk_button_new ();
+ gtk_widget_set_hexpand (button, TRUE);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (button), frame);
@@ -86,6 +87,7 @@ create_app_tile (GsShellCategory *shell, GsApp *app)
image = gtk_image_new_from_pixbuf (gs_app_get_pixbuf (app));
gtk_grid_attach (GTK_GRID (grid), image, 0, 0, 1, 2);
label = gtk_label_new (gs_app_get_name (app));
+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
@@ -138,20 +140,17 @@ gs_shell_category_get_apps_cb (GObject *source_object,
goto out;
}
grid = GTK_WIDGET (gtk_builder_get_object (priv->builder, "category_detail_grid"));
- gtk_grid_remove_column (GTK_GRID (grid), 2);
gtk_grid_remove_column (GTK_GRID (grid), 1);
+ gtk_grid_remove_column (GTK_GRID (grid), 0);
for (l = list, i = 0; l != NULL; l = l->next, i++) {
app = GS_APP (l->data);
tile = create_app_tile (shell, app);
- if (gs_category_get_parent (priv->category) != NULL)
- gtk_grid_attach (GTK_GRID (grid), tile, 1 + (i % 2), i / 2, 1, 1);
- else
- gtk_grid_attach (GTK_GRID (grid), tile, i % 3, i / 3, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), tile, (i % 2), i / 2, 1, 1);
}
if (i == 1)
- gtk_grid_attach (GTK_GRID (grid), priv->col2_placeholder, 2, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), priv->col1_placeholder, 1, 0, 1, 1);
out:
g_list_free (list);
@@ -178,15 +177,12 @@ gs_shell_category_populate_filtered (GsShellCategory *shell)
gs_category_get_id (priv->category));
}
- /* Remove old content. Be careful not to remove the
- * subcategories and put placeholders there to keep
- * the subcategory list from growing
- */
grid = GTK_WIDGET (gtk_builder_get_object (priv->builder, "category_detail_grid"));
- gtk_grid_remove_column (GTK_GRID (grid), 2);
gtk_grid_remove_column (GTK_GRID (grid), 1);
+ gtk_grid_remove_column (GTK_GRID (grid), 0);
+
+ gtk_grid_attach (GTK_GRID (grid), priv->col0_placeholder, 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), priv->col1_placeholder, 1, 0, 1, 1);
- gtk_grid_attach (GTK_GRID (grid), priv->col2_placeholder, 2, 0, 1, 1);
gs_plugin_loader_get_category_apps_async (priv->plugin_loader,
priv->category,
@@ -227,8 +223,6 @@ gs_shell_category_create_filter_list (GsShellCategory *shell, GsCategory *catego
GtkWidget *grid;
GtkWidget *list_box;
GtkWidget *row;
- GtkWidget *frame;
- guint i;
GList *list, *l;
GsCategory *s;
@@ -239,32 +233,23 @@ gs_shell_category_create_filter_list (GsShellCategory *shell, GsCategory *catego
if (!list)
return;
+ gtk_grid_attach (GTK_GRID (grid), priv->col0_placeholder, 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), priv->col1_placeholder, 1, 0, 1, 1);
- gtk_grid_attach (GTK_GRID (grid), priv->col2_placeholder, 2, 0, 1, 1);
- list_box = gtk_list_box_new ();
- gtk_list_box_set_selection_mode (GTK_LIST_BOX (list_box), GTK_SELECTION_BROWSE);
- g_signal_connect (list_box, "row-selected", G_CALLBACK (filter_selected), shell);
- gtk_list_box_set_header_func (GTK_LIST_BOX (list_box), add_separator, NULL, NULL);
- for (l = list, i = 0; l; l = l->next, i++) {
+ list_box = GTK_WIDGET (gtk_builder_get_object (priv->builder, "listbox_filter"));
+ gs_container_remove_all (GTK_CONTAINER (list_box));
+
+ for (l = list; l; l = l->next) {
s = l->data;
row = gtk_label_new (gs_category_get_name (s));
g_object_set_data_full (G_OBJECT (row), "category", g_object_ref (s), g_object_unref);
g_object_set (row, "xalign", 0.0, "margin", 6, NULL);
- gtk_list_box_insert (GTK_LIST_BOX (list_box), row, i);
+ gtk_widget_show (row);
+ gtk_list_box_insert (GTK_LIST_BOX (list_box), row, -1);
if (subcategory == s)
gtk_list_box_select_row (GTK_LIST_BOX (list_box), GTK_LIST_BOX_ROW
(gtk_widget_get_parent (row)));
}
g_list_free (list);
-
- frame = gtk_frame_new (NULL);
- g_object_set (frame, "margin", 6, NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- gtk_style_context_add_class (gtk_widget_get_style_context (frame), "view");
- gtk_container_add (GTK_CONTAINER (frame), list_box);
- gtk_widget_show_all (frame);
- gtk_widget_set_valign (frame, GTK_ALIGN_START);
- gtk_grid_attach (GTK_GRID (grid), frame, 0, 0, 1, 20);
}
void
@@ -317,11 +302,11 @@ gs_shell_category_init (GsShellCategory *shell)
priv = G_TYPE_INSTANCE_GET_PRIVATE (shell, GS_TYPE_SHELL_CATEGORY, GsShellCategoryPrivate);
shell->priv = priv;
+ priv->col0_placeholder = g_object_ref_sink (gtk_label_new (""));
priv->col1_placeholder = g_object_ref_sink (gtk_label_new (""));
- priv->col2_placeholder = g_object_ref_sink (gtk_label_new (""));
+ gtk_widget_show (priv->col0_placeholder);
gtk_widget_show (priv->col1_placeholder);
- gtk_widget_show (priv->col2_placeholder);
}
static void
@@ -334,8 +319,8 @@ gs_shell_category_finalize (GObject *object)
g_clear_object (&priv->category);
g_clear_object (&priv->plugin_loader);
g_clear_object (&priv->cancellable);
+ g_clear_object (&priv->col0_placeholder);
g_clear_object (&priv->col1_placeholder);
- g_clear_object (&priv->col2_placeholder);
G_OBJECT_CLASS (gs_shell_category_parent_class)->finalize (object);
}
@@ -358,11 +343,16 @@ gs_shell_category_setup (GsShellCategory *shell_category,
GCancellable *cancellable)
{
GsShellCategoryPrivate *priv = shell_category->priv;
+ GtkWidget *list_box;
priv->plugin_loader = g_object_ref (plugin_loader);
priv->builder = g_object_ref (builder);
priv->cancellable = g_cancellable_new ();
priv->shell = shell;
+
+ list_box = GTK_WIDGET (gtk_builder_get_object (priv->builder, "listbox_filter"));
+ g_signal_connect (list_box, "row-selected", G_CALLBACK (filter_selected), shell_category);
+ gtk_list_box_set_header_func (GTK_LIST_BOX (list_box), add_separator, NULL, NULL);
}
GsShellCategory *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]