[gnome-control-center/extensible-shell] shell: split iconview behaviour and category views into separate objects
- From: Thomas Wood <thos src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/extensible-shell] shell: split iconview behaviour and category views into separate objects
- Date: Mon, 12 Apr 2010 22:21:01 +0000 (UTC)
commit 7f1303e4a2722cc943c2c6a1c1925710882db217
Author: Thomas Wood <thomas wood intel com>
Date: Mon Apr 12 23:20:50 2010 +0100
shell: split iconview behaviour and category views into separate objects
CcShellItemView is a GtkIconView derived object that modifies the the
item activation behaviour to that required by the shell. In particular,
items can be activated by a single click, and double or triple clicks are
ignored. It also expects a particular model to be set and emits a signal
containing relevant data when an item is activated.
CcShellCategoryView is a widget that provides the category groups for the
main overview of the shell. It consists of a title and a CcSehllItemView.
shell/Makefile.am | 15 ++
shell/cc-shell-category-view.c | 245 +++++++++++++++++++++++++++++++
shell/cc-shell-category-view.h | 76 ++++++++++
shell/cc-shell-item-view.c | 194 +++++++++++++++++++++++++
shell/cc-shell-item-view.h | 72 +++++++++
shell/cc-shell-marshal.list | 1 +
shell/control-center.c | 314 +++++++++++++++------------------------
shell/control-center.h | 32 ++++
shell/shell.ui | 12 +-
9 files changed, 759 insertions(+), 202 deletions(-)
---
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 7dbeeac..2ee976a 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -9,10 +9,25 @@ INCLUDES = \
bin_PROGRAMS = gnome-control-center
+MARSHAL_FILES = cc-shell-marshal.c cc-shell-marshal.h
+BUILT_SOURCES = $(MARSHAL_FILES)
+
+cc-shell-marshal.h: cc-shell-marshal.list
+ @GLIB_GENMARSHAL@ --prefix=cc_shell_marshal $< --header > $@
+
+cc-shell-marshal.c: cc-shell-marshal.list
+ @GLIB_GENMARSHAL@ --prefix=cc_shell_marshal $< --body --header > $@
+
gnome_control_center_SOURCES = \
control-center.c \
+ control-center.h \
shell-search-renderer.c \
shell-search-renderer.h \
+ cc-shell-category-view.c \
+ cc-shell-category-view.h \
+ cc-shell-item-view.c \
+ cc-shell-item-view.h \
+ $(MARSHAL_FILES) \
$(NULL)
gnome_control_center_LDADD = \
diff --git a/shell/cc-shell-category-view.c b/shell/cc-shell-category-view.c
new file mode 100644
index 0000000..9bcc3c7
--- /dev/null
+++ b/shell/cc-shell-category-view.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2010 Intel, Inc.
+ *
+ * The Control Center 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.
+ *
+ * The Control Center 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 the Control Center; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Thomas Wood <thos gnome org>
+ */
+
+#include "cc-shell-category-view.h"
+#include "cc-shell-item-view.h"
+#include "cc-shell.h"
+#include "control-center.h"
+
+G_DEFINE_TYPE (CcShellCategoryView, cc_shell_category_view, GTK_TYPE_FRAME)
+
+#define SHELL_CATEGORY_VIEW_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_SHELL_CATEGORY_VIEW, CcShellCategoryViewPrivate))
+
+enum
+{
+ PROP_NAME = 1,
+ PROP_MODEL
+};
+
+struct _CcShellCategoryViewPrivate
+{
+ gchar *name;
+ GtkTreeModel *model;
+
+ GtkWidget *header;
+ GtkWidget *iconview;
+};
+
+static void
+cc_shell_category_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv;
+
+ switch (property_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, priv->name);
+ break;
+
+ case PROP_MODEL:
+ g_value_set_object (value, priv->model);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+cc_shell_category_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv;
+
+ switch (property_id)
+ {
+ case PROP_NAME:
+ priv->name = g_value_dup_string (value);
+ break;
+
+ case PROP_MODEL:
+ priv->model = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+cc_shell_category_view_dispose (GObject *object)
+{
+ CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv;
+
+ if (priv->model)
+ {
+ g_object_unref (priv->model);
+ priv->model = NULL;
+ }
+
+ G_OBJECT_CLASS (cc_shell_category_view_parent_class)->dispose (object);
+}
+
+static void
+cc_shell_category_view_finalize (GObject *object)
+{
+ CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv;
+
+ if (priv->name)
+ {
+ g_free (priv->name);
+ priv->name = NULL;
+ }
+
+ G_OBJECT_CLASS (cc_shell_category_view_parent_class)->finalize (object);
+}
+
+static void
+cc_shell_category_view_constructed (GObject *object)
+{
+ CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv;
+ gchar *header_name;
+ GtkWidget *iconview, *vbox, *header, *self;
+
+ self = GTK_WIDGET (object);
+
+ iconview = cc_shell_item_view_new ();
+ gtk_icon_view_set_model (GTK_ICON_VIEW (iconview), priv->model);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+
+ gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (iconview), COL_PIXBUF);
+ gtk_icon_view_set_text_column (GTK_ICON_VIEW (iconview), COL_NAME);
+ gtk_icon_view_set_item_width (GTK_ICON_VIEW (iconview), 120);
+
+ /* create the header if required */
+ if (priv->name)
+ {
+ header_name = g_strdup_printf ("<b>%s</b>", priv->name);
+
+ header = g_object_new (GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_name,
+ "wrap", TRUE,
+ "xalign", 0.0,
+ "xpad", 6,
+ NULL);
+
+ g_free (header_name);
+ gtk_box_pack_start (GTK_BOX (vbox), header, FALSE, TRUE, 3);
+
+ priv->header = header;
+ }
+
+ /* add the iconview to the vbox */
+ gtk_box_pack_start (GTK_BOX (vbox), iconview, FALSE, TRUE, 0);
+
+ /* add the main vbox to the view */
+ gtk_container_add (GTK_CONTAINER (object), vbox);
+ gtk_widget_show_all (vbox);
+
+ priv->iconview = iconview;
+}
+
+static void
+cc_shell_category_view_style_set (GtkWidget *widget,
+ GtkStyle *old_style)
+{
+ CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (widget)->priv;
+
+ if (priv->header)
+ {
+ gtk_widget_modify_bg (priv->header, GTK_STATE_NORMAL,
+ &widget->style->base[GTK_STATE_NORMAL]);
+ gtk_widget_modify_fg (priv->header, GTK_STATE_NORMAL,
+ &widget->style->text[GTK_STATE_NORMAL]);
+ }
+
+ if (priv->iconview)
+ {
+ gtk_widget_modify_bg (priv->iconview, GTK_STATE_NORMAL,
+ &widget->style->base[GTK_STATE_NORMAL]);
+ gtk_widget_modify_fg (priv->iconview, GTK_STATE_NORMAL,
+ &widget->style->text[GTK_STATE_NORMAL]);
+ }
+}
+
+static void
+cc_shell_category_view_class_init (CcShellCategoryViewClass *klass)
+{
+ GParamSpec *pspec;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (CcShellCategoryViewPrivate));
+
+ object_class->get_property = cc_shell_category_view_get_property;
+ object_class->set_property = cc_shell_category_view_set_property;
+ object_class->dispose = cc_shell_category_view_dispose;
+ object_class->finalize = cc_shell_category_view_finalize;
+ object_class->constructed = cc_shell_category_view_constructed;
+
+ widget_class->style_set = cc_shell_category_view_style_set;
+
+ pspec = g_param_spec_string ("name",
+ "Name",
+ "Name of the category",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_NAME, pspec);
+
+ pspec = g_param_spec_object ("model",
+ "Model",
+ "Model of the category",
+ GTK_TYPE_TREE_MODEL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_MODEL, pspec);
+
+}
+
+static void
+cc_shell_category_view_init (CcShellCategoryView *self)
+{
+ self->priv = SHELL_CATEGORY_VIEW_PRIVATE (self);
+
+ gtk_frame_set_shadow_type (GTK_FRAME (self), GTK_SHADOW_NONE);
+}
+
+GtkWidget *
+cc_shell_category_view_new (const gchar *name,
+ GtkTreeModel *model)
+{
+ return g_object_new (CC_TYPE_SHELL_CATEGORY_VIEW,
+ "name", name,
+ "model", model, NULL);
+}
+
+CcShellItemView*
+cc_shell_category_view_get_item_view (CcShellCategoryView *self)
+{
+ return (CcShellItemView*) self->priv->iconview;
+}
diff --git a/shell/cc-shell-category-view.h b/shell/cc-shell-category-view.h
new file mode 100644
index 0000000..d434501
--- /dev/null
+++ b/shell/cc-shell-category-view.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 Intel, Inc.
+ *
+ * The Control Center 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.
+ *
+ * The Control Center 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 the Control Center; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Thomas Wood <thos gnome org>
+ */
+
+
+#ifndef _CC_SHELL_CATEGORY_VIEW_H
+#define _CC_SHELL_CATEGORY_VIEW_H
+
+#include <gtk/gtk.h>
+#include "cc-shell-item-view.h"
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_SHELL_CATEGORY_VIEW cc_shell_category_view_get_type()
+
+#define CC_SHELL_CATEGORY_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ CC_TYPE_SHELL_CATEGORY_VIEW, CcShellCategoryView))
+
+#define CC_SHELL_CATEGORY_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ CC_TYPE_SHELL_CATEGORY_VIEW, CcShellCategoryViewClass))
+
+#define CC_IS_SHELL_CATEGORY_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ CC_TYPE_SHELL_CATEGORY_VIEW))
+
+#define CC_IS_SHELL_CATEGORY_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ CC_TYPE_SHELL_CATEGORY_VIEW))
+
+#define CC_SHELL_CATEGORY_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ CC_TYPE_SHELL_CATEGORY_VIEW, CcShellCategoryViewClass))
+
+typedef struct _CcShellCategoryView CcShellCategoryView;
+typedef struct _CcShellCategoryViewClass CcShellCategoryViewClass;
+typedef struct _CcShellCategoryViewPrivate CcShellCategoryViewPrivate;
+
+struct _CcShellCategoryView
+{
+ GtkFrame parent;
+
+ CcShellCategoryViewPrivate *priv;
+};
+
+struct _CcShellCategoryViewClass
+{
+ GtkFrameClass parent_class;
+};
+
+GType cc_shell_category_view_get_type (void) G_GNUC_CONST;
+
+GtkWidget *cc_shell_category_view_new (const gchar *name,
+ GtkTreeModel *model);
+CcShellItemView* cc_shell_category_view_get_item_view (CcShellCategoryView *self);
+
+G_END_DECLS
+
+#endif /* _CC_SHELL_CATEGORY_VIEW_H */
diff --git a/shell/cc-shell-item-view.c b/shell/cc-shell-item-view.c
new file mode 100644
index 0000000..3f17aec
--- /dev/null
+++ b/shell/cc-shell-item-view.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2010 Intel, Inc.
+ *
+ * The Control Center 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.
+ *
+ * The Control Center 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 the Control Center; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Thomas Wood <thos gnome org>
+ */
+
+#include "cc-shell-item-view.h"
+#include "control-center.h"
+#include "cc-shell-marshal.h"
+
+G_DEFINE_TYPE (CcShellItemView, cc_shell_item_view, GTK_TYPE_ICON_VIEW)
+
+#define SHELL_ITEM_VIEW_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_SHELL_ITEM_VIEW, CcShellItemViewPrivate))
+
+struct _CcShellItemViewPrivate
+{
+ gboolean ignore_release;
+};
+
+
+enum
+{
+ DESKTOP_ITEM_ACTIVATED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0,};
+
+static void
+cc_shell_item_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+cc_shell_item_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+cc_shell_item_view_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (cc_shell_item_view_parent_class)->dispose (object);
+}
+
+static void
+cc_shell_item_view_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (cc_shell_item_view_parent_class)->finalize (object);
+}
+
+static gboolean
+iconview_button_press_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ CcShellItemView *cc_view)
+{
+ /* be sure to ignore double and triple clicks */
+ cc_view->priv->ignore_release = (event->type != GDK_BUTTON_PRESS);
+
+ return FALSE;
+}
+
+static gboolean
+iconview_button_release_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ CcShellItemView *cc_view)
+{
+ CcShellItemViewPrivate *priv = cc_view->priv;
+
+ if (event->button == 1 && !priv->ignore_release)
+ {
+ GList *selection;
+
+ selection =
+ gtk_icon_view_get_selected_items (GTK_ICON_VIEW (cc_view));
+
+ if (!selection)
+ return TRUE;
+
+ gtk_icon_view_item_activated (GTK_ICON_VIEW (cc_view),
+ (GtkTreePath*) selection->data);
+
+ g_list_free (selection);
+ }
+
+ return TRUE;
+}
+
+static void
+iconview_item_activated_cb (GtkIconView *icon_view,
+ GtkTreePath *path,
+ CcShellItemView *cc_view)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *name, *desktop_file, *id;
+
+ model = gtk_icon_view_get_model (icon_view);
+
+ gtk_icon_view_unselect_all (icon_view);
+
+ /* get the iter and ensure it is valid */
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return;
+
+ gtk_tree_model_get (model, &iter,
+ COL_NAME, &name,
+ COL_DESKTOP_FILE, &desktop_file,
+ COL_ID, &id,
+ -1);
+
+ g_signal_emit (cc_view, signals[DESKTOP_ITEM_ACTIVATED], 0,
+ name, id, desktop_file);
+
+ g_free (desktop_file);
+ g_free (name);
+ g_free (id);
+}
+
+static void
+cc_shell_item_view_class_init (CcShellItemViewClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (CcShellItemViewPrivate));
+
+ object_class->get_property = cc_shell_item_view_get_property;
+ object_class->set_property = cc_shell_item_view_set_property;
+ object_class->dispose = cc_shell_item_view_dispose;
+ object_class->finalize = cc_shell_item_view_finalize;
+
+ signals[DESKTOP_ITEM_ACTIVATED] = g_signal_new ("desktop-item-activated",
+ CC_TYPE_SHELL_ITEM_VIEW,
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL,
+ NULL,
+ cc_shell_marshal_VOID__STRING_STRING_STRING,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+}
+
+static void
+cc_shell_item_view_init (CcShellItemView *self)
+{
+ self->priv = SHELL_ITEM_VIEW_PRIVATE (self);
+
+ g_signal_connect (self, "item-activated",
+ G_CALLBACK (iconview_item_activated_cb), self);
+ g_signal_connect (self, "button-press-event",
+ G_CALLBACK (iconview_button_press_event_cb), self);
+ g_signal_connect (self, "button-release-event",
+ G_CALLBACK (iconview_button_release_event_cb), self);
+}
+
+GtkWidget *
+cc_shell_item_view_new (void)
+{
+ return g_object_new (CC_TYPE_SHELL_ITEM_VIEW, NULL);
+}
diff --git a/shell/cc-shell-item-view.h b/shell/cc-shell-item-view.h
new file mode 100644
index 0000000..ec27f14
--- /dev/null
+++ b/shell/cc-shell-item-view.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010 Intel, Inc.
+ *
+ * The Control Center 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.
+ *
+ * The Control Center 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 the Control Center; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Thomas Wood <thos gnome org>
+ */
+
+#ifndef _CC_SHELL_ITEM_VIEW_H
+#define _CC_SHELL_ITEM_VIEW_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_SHELL_ITEM_VIEW cc_shell_item_view_get_type()
+
+#define CC_SHELL_ITEM_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ CC_TYPE_SHELL_ITEM_VIEW, CcShellItemView))
+
+#define CC_SHELL_ITEM_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ CC_TYPE_SHELL_ITEM_VIEW, CcShellItemViewClass))
+
+#define CC_IS_SHELL_ITEM_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ CC_TYPE_SHELL_ITEM_VIEW))
+
+#define CC_IS_SHELL_ITEM_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ CC_TYPE_SHELL_ITEM_VIEW))
+
+#define CC_SHELL_ITEM_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ CC_TYPE_SHELL_ITEM_VIEW, CcShellItemViewClass))
+
+typedef struct _CcShellItemView CcShellItemView;
+typedef struct _CcShellItemViewClass CcShellItemViewClass;
+typedef struct _CcShellItemViewPrivate CcShellItemViewPrivate;
+
+struct _CcShellItemView
+{
+ GtkIconView parent;
+
+ CcShellItemViewPrivate *priv;
+};
+
+struct _CcShellItemViewClass
+{
+ GtkIconViewClass parent_class;
+};
+
+GType cc_shell_item_view_get_type (void) G_GNUC_CONST;
+
+GtkWidget *cc_shell_item_view_new (void);
+
+G_END_DECLS
+
+#endif /* _CC_SHELL_ITEM_VIEW_H */
diff --git a/shell/cc-shell-marshal.list b/shell/cc-shell-marshal.list
new file mode 100644
index 0000000..41e4027
--- /dev/null
+++ b/shell/cc-shell-marshal.list
@@ -0,0 +1 @@
+VOID:STRING,STRING,STRING
diff --git a/shell/control-center.c b/shell/control-center.c
index 3affb43..3675b1c 100644
--- a/shell/control-center.c
+++ b/shell/control-center.c
@@ -21,6 +21,8 @@
#include "config.h"
+#include "control-center.h"
+
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
@@ -33,6 +35,7 @@
#include "cc-panel.h"
#include "cc-shell.h"
#include "shell-search-renderer.h"
+#include "cc-shell-category-view.h"
#include <unique/unique.h>
@@ -50,12 +53,12 @@ typedef struct
GtkWidget *window;
GtkWidget *search_entry;
- GSList *icon_views;
-
gchar *current_title;
GtkListStore *store;
+
GtkTreeModel *search_filter;
+ GtkWidget *search_view;
GtkCellRenderer *search_renderer;
gchar *filter_string;
@@ -65,76 +68,73 @@ typedef struct
} ShellData;
-enum
-{
- COL_NAME,
- COL_DESKTOP_FILE,
- COL_ID,
- COL_PIXBUF,
- COL_CATEGORY,
- COL_SEARCH_TARGET,
-
- N_COLS
-};
-
-static void item_activated_cb (GtkIconView *icon_view, GtkTreePath *path, ShellData *data);
-
-static gboolean
-button_release_cb (GtkWidget *view,
- GdkEventButton *event,
- ShellData *data)
+static void
+activate_panel (const gchar *name,
+ const gchar *id,
+ const gchar *desktop_file,
+ ShellData *data)
{
- if (event->button == 1)
+ if (cc_shell_set_panel (CC_SHELL (data->builder), id))
+ {
+ gtk_label_set_text (GTK_LABEL (W (data->builder, "label-title")), name);
+ gtk_widget_show (W (data->builder, "title-alignment"));
+ }
+ else
{
- GList *selection;
+ /* start app directly */
+ g_debug ("Panel module not found for %s", id);
- selection = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (view));
+ GAppInfo *appinfo;
+ GError *err = NULL;
+ GdkAppLaunchContext *ctx;
+ GKeyFile *key_file;
- if (!selection)
- return FALSE;
+ key_file = g_key_file_new ();
+ g_key_file_load_from_file (key_file, desktop_file, 0, &err);
- data->last_time = event->time;
+ if (err)
+ {
+ g_warning ("Error starting \"%s\": %s", id, err->message);
- item_activated_cb (GTK_ICON_VIEW (view), selection->data, data);
+ g_error_free (err);
+ err = NULL;
+ return;
+ }
- g_list_free (selection);
- return TRUE;
- }
- return FALSE;
-}
+ appinfo = (GAppInfo*) g_desktop_app_info_new_from_keyfile (key_file);
-static void
-selection_changed_cb (GtkIconView *view,
- ShellData *data)
-{
- GSList *iconviews, *l;
- GList *selection;
+ g_key_file_free (key_file);
- /* don't clear other selections if this icon view does not have one */
- selection = gtk_icon_view_get_selected_items (view);
- if (!selection)
- return;
- else
- g_list_free (selection);
- iconviews = data->icon_views;
+ ctx = gdk_app_launch_context_new ();
+ gdk_app_launch_context_set_screen (ctx, gdk_screen_get_default ());
+ gdk_app_launch_context_set_timestamp (ctx, data->last_time);
- for (l = iconviews; l; l = l->next)
- {
- GtkIconView *iconview = l->data;
+ g_app_info_launch (appinfo, NULL, G_APP_LAUNCH_CONTEXT (ctx), &err);
- if (iconview != view)
+ g_object_unref (appinfo);
+ g_object_unref (ctx);
+
+ if (err)
{
- if ((selection = gtk_icon_view_get_selected_items (iconview)))
- {
- gtk_icon_view_unselect_all (iconview);
- g_list_free (selection);
- }
+ g_warning ("Error starting \"%s\": %s", id, err->message);
+ g_error_free (err);
+ err = NULL;
}
}
}
+static void
+item_activated_cb (CcShellCategoryView *view,
+ gchar *name,
+ gchar *id,
+ gchar *desktop_file,
+ ShellData *data)
+{
+ activate_panel (name, id, desktop_file, data);
+}
+
static gboolean
model_filter_func (GtkTreeModel *model,
GtkTreeIter *iter,
@@ -185,15 +185,65 @@ category_filter_func (GtkTreeModel *model,
}
static void
+setup_search (ShellData *data)
+{
+ GtkWidget *search_scrolled, *search_view;
+
+ g_return_if_fail (data->store != NULL);
+
+ /* create the search filter */
+ data->search_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (data->store),
+ NULL);
+
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (data->search_filter),
+ (GtkTreeModelFilterVisibleFunc)
+ model_filter_func,
+ data, NULL);
+
+ /* set up the search view */
+ data->search_view = search_view = cc_shell_item_view_new ();
+ gtk_icon_view_set_orientation (GTK_ICON_VIEW (search_view),
+ GTK_ORIENTATION_HORIZONTAL);
+ gtk_icon_view_set_spacing (GTK_ICON_VIEW (search_view), 6);
+ gtk_icon_view_set_model (GTK_ICON_VIEW (search_view),
+ GTK_TREE_MODEL (data->search_filter));
+ gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (search_view), COL_PIXBUF);
+
+ search_scrolled = W (data->builder, "search-scrolled-window");
+ gtk_container_add (GTK_CONTAINER (search_scrolled), search_view);
+
+
+ /* add the custom renderer */
+ data->search_renderer = (GtkCellRenderer*) shell_search_renderer_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (search_view),
+ data->search_renderer, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (search_view),
+ data->search_renderer,
+ "title", COL_NAME);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (search_view),
+ data->search_renderer,
+ "search-target", COL_SEARCH_TARGET);
+
+ /* connect the activated signal */
+ g_signal_connect (search_view, "desktop-item-activated",
+ G_CALLBACK (item_activated_cb), data);
+}
+
+static void
fill_model (ShellData *data)
{
GSList *list, *l;
GMenuTreeDirectory *d;
GMenuTree *tree;
- GtkWidget *vbox, *w;
+ GtkWidget *vbox;
vbox = W (data->builder, "main-vbox");
+ gtk_widget_modify_bg (vbox->parent, GTK_STATE_NORMAL,
+ &vbox->style->base[GTK_STATE_NORMAL]);
+ gtk_widget_modify_fg (vbox->parent, GTK_STATE_NORMAL,
+ &vbox->style->text[GTK_STATE_NORMAL]);
+
tree = gmenu_tree_lookup (MENUDIR "/gnomecc.menu", 0);
if (!tree)
@@ -210,82 +260,38 @@ fill_model (ShellData *data)
G_TYPE_STRING, GDK_TYPE_PIXBUF,
G_TYPE_STRING, G_TYPE_STRING);
- data->search_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (data->store), NULL);
-
- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (data->search_filter),
- (GtkTreeModelFilterVisibleFunc)
- model_filter_func,
- data, NULL);
-
- w = (GtkWidget *) gtk_builder_get_object (data->builder, "search-view");
- gtk_icon_view_set_model (GTK_ICON_VIEW (w), GTK_TREE_MODEL (data->search_filter));
- gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (w), COL_PIXBUF);
-
-
- data->search_renderer = (GtkCellRenderer*) shell_search_renderer_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), data->search_renderer, TRUE);
- gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (w), data->search_renderer,
- "title", COL_NAME);
- gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (w), data->search_renderer,
- "search-target", COL_SEARCH_TARGET);
-
- g_signal_connect (w, "item-activated",
- G_CALLBACK (item_activated_cb), data);
- g_signal_connect (w, "button-release-event",
- G_CALLBACK (button_release_cb), data);
- g_signal_connect (w, "selection-changed",
- G_CALLBACK (selection_changed_cb), data);
for (l = list; l; l = l->next)
{
GMenuTreeItemType type;
type = gmenu_tree_item_get_type (l->data);
+
if (type == GMENU_TREE_ITEM_DIRECTORY)
{
GtkTreeModel *filter;
- GtkWidget *header, *iconview;
- GSList *foo, *f;
+ GtkWidget *categoryview;
+ GSList *contents, *f;
const gchar *dir_name;
- gchar *header_name;
- foo = gmenu_tree_directory_get_contents (l->data);
+ contents = gmenu_tree_directory_get_contents (l->data);
dir_name = gmenu_tree_directory_get_name (l->data);
+ /* create new category view for this category */
filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (data->store), NULL);
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
(GtkTreeModelFilterVisibleFunc) category_filter_func,
g_strdup (dir_name), g_free);
- iconview = gtk_icon_view_new_with_model (GTK_TREE_MODEL (filter));
-
- gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (iconview), COL_PIXBUF);
- gtk_icon_view_set_text_column (GTK_ICON_VIEW (iconview), COL_NAME);
- gtk_icon_view_set_item_width (GTK_ICON_VIEW (iconview), 120);
- g_signal_connect (iconview, "item-activated",
+ categoryview = cc_shell_category_view_new (dir_name, filter);
+ gtk_box_pack_start (GTK_BOX (vbox), categoryview, FALSE, TRUE, 6);
+ g_signal_connect (cc_shell_category_view_get_item_view (CC_SHELL_CATEGORY_VIEW (categoryview)),
+ "desktop-item-activated",
G_CALLBACK (item_activated_cb), data);
- g_signal_connect (iconview, "button-release-event",
- G_CALLBACK (button_release_cb), data);
- g_signal_connect (iconview, "selection-changed",
- G_CALLBACK (selection_changed_cb), data);
-
- data->icon_views = g_slist_prepend (data->icon_views, iconview);
-
- header_name = g_strdup_printf ("<b>%s</b>", dir_name);
-
- header = g_object_new (GTK_TYPE_LABEL,
- "use-markup", TRUE,
- "label", header_name,
- "wrap", TRUE,
- "xalign", 0.0,
- "xpad", 6,
- NULL);
-
- gtk_box_pack_start (GTK_BOX (vbox), header, FALSE, TRUE, 3);
- gtk_box_pack_start (GTK_BOX (vbox), iconview, FALSE, TRUE, 0);
-
+ gtk_widget_show (categoryview);
- for (f = foo; f; f = f->next)
+ /* add the items from this category to the model */
+ for (f = contents; f; f = f->next)
{
if (gmenu_tree_item_get_type (f->data)
== GMENU_TREE_ITEM_ENTRY)
@@ -343,85 +349,7 @@ fill_model (ShellData *data)
}
-static void
-activate_panel (const gchar *id,
- const gchar *desktop_file,
- ShellData *data)
-{
- if (!cc_shell_set_panel (CC_SHELL (data->builder), id))
- {
- /* start app directly */
- g_debug ("Panel module not found for %s", id);
-
- GAppInfo *appinfo;
- GError *err = NULL;
- GdkAppLaunchContext *ctx;
- GKeyFile *key_file;
-
- key_file = g_key_file_new ();
- g_key_file_load_from_file (key_file, desktop_file, 0, &err);
-
- if (err)
- {
- g_warning ("Error starting \"%s\": %s", id, err->message);
-
- g_error_free (err);
- err = NULL;
- return;
- }
-
- appinfo = (GAppInfo*) g_desktop_app_info_new_from_keyfile (key_file);
-
- g_key_file_free (key_file);
-
-
- ctx = gdk_app_launch_context_new ();
- gdk_app_launch_context_set_screen (ctx, gdk_screen_get_default ());
- gdk_app_launch_context_set_timestamp (ctx, data->last_time);
-
- g_app_info_launch (appinfo, NULL, G_APP_LAUNCH_CONTEXT (ctx), &err);
-
- g_object_unref (appinfo);
- g_object_unref (ctx);
-
- if (err)
- {
- g_warning ("Error starting \"%s\": %s", id, err->message);
- g_error_free (err);
- err = NULL;
- }
- }
-
-}
-
-static void
-item_activated_cb (GtkIconView *icon_view,
- GtkTreePath *path,
- ShellData *data)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *name, *desktop_file, *id;
-
- model = gtk_icon_view_get_model (icon_view);
-
- /* get the iter and ensure it is valid */
- if (!gtk_tree_model_get_iter (model, &iter, path))
- return;
-
- gtk_tree_model_get (model, &iter, COL_NAME, &name,
- COL_DESKTOP_FILE, &desktop_file,
- COL_ID, &id, -1);
- g_debug ("activated id: '%s'", id);
-
- cc_shell_set_title (CC_SHELL (data->builder), name);
-
- activate_panel (id, desktop_file, data);
-
- g_free (id);
- g_free (desktop_file);
-}
static void
shell_show_overview_page (ShellData *data)
@@ -491,9 +419,8 @@ search_entry_key_press_event_cb (GtkEntry *entry,
data->last_time = event->time;
- item_activated_cb ((GtkIconView *) gtk_builder_get_object (data->builder,
- "search-view"),
- path, data);
+ gtk_icon_view_item_activated (GTK_ICON_VIEW (data->search_view), path);
+
gtk_tree_path_free (path);
return TRUE;
}
@@ -587,6 +514,7 @@ main (int argc, char **argv)
G_CALLBACK (notebook_switch_page_cb), data);
fill_model (data);
+ setup_search (data);
g_signal_connect (gtk_builder_get_object (data->builder, "home-button"),
@@ -650,7 +578,7 @@ main (int argc, char **argv)
g_free (data->current_title);
data->current_title = name;
- activate_panel (start_id, start_id, data);
+ activate_panel (name, start_id, NULL, data);
}
gtk_main ();
diff --git a/shell/control-center.h b/shell/control-center.h
new file mode 100644
index 0000000..88c1a27
--- /dev/null
+++ b/shell/control-center.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 Intel, Inc.
+ *
+ * The Control Center 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.
+ *
+ * The Control Center 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 the Control Center; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Thomas Wood <thos gnome org>
+ */
+
+
+enum
+{
+ COL_NAME,
+ COL_DESKTOP_FILE,
+ COL_ID,
+ COL_PIXBUF,
+ COL_CATEGORY,
+ COL_SEARCH_TARGET,
+
+ N_COLS
+};
diff --git a/shell/shell.ui b/shell/shell.ui
index f40dac0..e42a741 100644
--- a/shell/shell.ui
+++ b/shell/shell.ui
@@ -125,20 +125,14 @@
<placeholder/>
</child>
<child>
- <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <object class="GtkScrolledWindow" id="search-scrolled-window">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<child>
- <object class="GtkIconView" id="search-view">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="orientation">horizontal</property>
- <property name="model">liststore</property>
- <property name="spacing">6</property>
- </object>
+ <placeholder/>
</child>
</object>
<packing>
@@ -169,8 +163,8 @@
<object class="GtkSizeGroup" id="sizegroup">
<property name="mode">vertical</property>
<widgets>
- <widget name="entry-alignment"/>
<widget name="home-button"/>
+ <widget name="entry-alignment"/>
</widgets>
</object>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]