[Xfce4-commits] <xfce4-appfinder:master> Add icon view mode and add preferences to set icon sizes.

Nick Schermer noreply at xfce.org
Tue Dec 27 14:10:01 CET 2011


Updating branch refs/heads/master
         to 09306d37f8b0ef1c32e118dd432b93127c8356fa (commit)
       from 74e51f72b05cb1917b58f8c191f01a7b4bdf65af (commit)

commit 09306d37f8b0ef1c32e118dd432b93127c8356fa
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Dec 27 14:08:08 2011 +0100

    Add icon view mode and add preferences to set icon sizes.

 src/appfinder-category-model.c  |   89 +++++++++-
 src/appfinder-model.c           |  183 +++++++++++++++-----
 src/appfinder-model.h           |   21 ++-
 src/appfinder-preferences.c     |   35 ++++
 src/appfinder-preferences.glade |  200 +++++++++++++++++++--
 src/appfinder-private.h         |    3 -
 src/appfinder-window.c          |  380 ++++++++++++++++++++++++++++++---------
 7 files changed, 760 insertions(+), 151 deletions(-)

diff --git a/src/appfinder-category-model.c b/src/appfinder-category-model.c
index f7860d9..07613b9 100644
--- a/src/appfinder-category-model.c
+++ b/src/appfinder-category-model.c
@@ -33,6 +33,14 @@
 
 
 static void               xfce_appfinder_category_model_tree_model_init       (GtkTreeModelIface        *iface);
+static void               xfce_appfinder_category_model_get_property          (GObject                  *object,
+                                                                               guint                     prop_id,
+                                                                               GValue                   *value,
+                                                                               GParamSpec               *pspec);
+static void               xfce_appfinder_category_model_set_property          (GObject                  *object,
+                                                                               guint                     prop_id,
+                                                                               const GValue             *value,
+                                                                               GParamSpec               *pspec);
 static void               xfce_appfinder_category_model_finalize              (GObject                  *object);
 static GtkTreeModelFlags  xfce_appfinder_category_model_get_flags             (GtkTreeModel             *tree_model);
 static gint               xfce_appfinder_category_model_get_n_columns         (GtkTreeModel             *tree_model);
@@ -73,12 +81,20 @@ struct _XfceAppfinderCategoryModelClass
 
 struct _XfceAppfinderCategoryModel
 {
-  GObject              __parent__;
-  gint                 stamp;
+  GObject                __parent__;
+  gint                   stamp;
 
-  GSList              *categories;
+  GSList                *categories;
 
-  GarconMenuDirectory *all_applications;
+  GarconMenuDirectory   *all_applications;
+
+  XfceAppfinderIconSize  icon_size;
+};
+
+enum
+{
+  PROP_0,
+  PROP_ICON_SIZE
 };
 
 
@@ -94,7 +110,17 @@ xfce_appfinder_category_model_class_init (XfceAppfinderCategoryModelClass *klass
   GObjectClass *gobject_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->get_property = xfce_appfinder_category_model_get_property;
+  gobject_class->set_property = xfce_appfinder_category_model_set_property;
   gobject_class->finalize = xfce_appfinder_category_model_finalize;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_ICON_SIZE,
+                                   g_param_spec_uint ("icon-size", NULL, NULL,
+                                                      XFCE_APPFINDER_ICON_SIZE_SMALLEST,
+                                                      XFCE_APPFINDER_ICON_SIZE_LARGEST,
+                                                      XFCE_APPFINDER_ICON_SIZE_DEFAULT_CATEGORY,
+                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 
@@ -104,6 +130,7 @@ xfce_appfinder_category_model_init (XfceAppfinderCategoryModel *model)
 {
   /* generate a unique stamp */
   model->stamp = g_random_int ();
+  model->icon_size = XFCE_APPFINDER_ICON_SIZE_DEFAULT_CATEGORY;
   model->all_applications = g_object_new (GARCON_TYPE_MENU_DIRECTORY,
                                           "name", _("All Applications"),
                                           "icon-name", "applications-other", NULL);
@@ -131,6 +158,58 @@ xfce_appfinder_category_model_tree_model_init (GtkTreeModelIface *iface)
 
 
 static void
+xfce_appfinder_category_model_get_property (GObject      *object,
+                                            guint         prop_id,
+                                            GValue       *value,
+                                            GParamSpec   *pspec)
+{
+  XfceAppfinderCategoryModel *model = XFCE_APPFINDER_CATEGORY_MODEL (object);
+
+  switch (prop_id)
+    {
+    case PROP_ICON_SIZE:
+      g_value_set_uint (value, model->icon_size);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+xfce_appfinder_category_model_set_property (GObject      *object,
+                                            guint         prop_id,
+                                            const GValue *value,
+                                            GParamSpec   *pspec)
+{
+  XfceAppfinderCategoryModel *model = XFCE_APPFINDER_CATEGORY_MODEL (object);
+  XfceAppfinderIconSize       icon_size;
+
+  switch (prop_id)
+    {
+    case PROP_ICON_SIZE:
+      icon_size = g_value_get_uint (value);
+      if (model->icon_size != icon_size)
+        {
+          model->icon_size = icon_size;
+
+          /* trigger a theme change to reload icons */
+          xfce_appfinder_category_model_icon_theme_changed (model);
+        }
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
 xfce_appfinder_category_model_finalize (GObject *object)
 {
   XfceAppfinderCategoryModel *model = XFCE_APPFINDER_CATEGORY_MODEL (object);
@@ -257,7 +336,7 @@ xfce_appfinder_category_model_get_value (GtkTreeModel *tree_model,
           && item->directory != NULL)
         {
           icon_name = garcon_menu_directory_get_icon_name (item->directory);
-          item->pixbuf = xfce_appfinder_model_load_pixbuf (icon_name, 24);
+          item->pixbuf = xfce_appfinder_model_load_pixbuf (icon_name, model->icon_size);
         }
 
       g_value_init (value, GDK_TYPE_PIXBUF);
diff --git a/src/appfinder-model.c b/src/appfinder-model.c
index 2f8e4cc..1259fda 100644
--- a/src/appfinder-model.c
+++ b/src/appfinder-model.c
@@ -38,6 +38,14 @@
 
 
 static void               xfce_appfinder_model_tree_model_init       (GtkTreeModelIface        *iface);
+static void               xfce_appfinder_model_get_property          (GObject                  *object,
+                                                                      guint                     prop_id,
+                                                                      GValue                   *value,
+                                                                      GParamSpec               *pspec);
+static void               xfce_appfinder_model_set_property          (GObject                  *object,
+                                                                      guint                     prop_id,
+                                                                      const GValue             *value,
+                                                                      GParamSpec               *pspec);
 static void               xfce_appfinder_model_finalize              (GObject                  *object);
 static GtkTreeModelFlags  xfce_appfinder_model_get_flags             (GtkTreeModel             *tree_model);
 static gint               xfce_appfinder_model_get_n_columns         (GtkTreeModel             *tree_model);
@@ -93,29 +101,31 @@ struct _XfceAppfinderModelClass
 
 struct _XfceAppfinderModel
 {
-  GObject              __parent__;
-  gint                 stamp;
+  GObject                __parent__;
+  gint                   stamp;
 
-  GSList              *items;
-  GHashTable          *items_hash;
+  GSList                *items;
+  GHashTable            *items_hash;
+
+  GarconMenu            *menu;
 
-  GarconMenu          *menu;
+  GdkPixbuf             *command_icon;
+  GdkPixbuf             *command_icon_large;
+  GarconMenuDirectory   *command_category;
 
-  GdkPixbuf           *command_icon_small;
-  GdkPixbuf           *command_icon_large;
-  GarconMenuDirectory *command_category;
+  GSList                *categories;
 
-  GSList              *categories;
+  guint                  collect_idle_id;
+  GSList                *collect_items;
+  GSList                *collect_categories;
+  GThread               *collect_thread;
+  GCancellable          *collect_cancelled;
 
-  guint                collect_idle_id;
-  GSList              *collect_items;
-  GSList              *collect_categories;
-  GThread             *collect_thread;
-  GCancellable        *collect_cancelled;
+  GFileMonitor          *history_monitor;
+  GFile                 *history_file;
+  guint64                history_mtime;
 
-  GFileMonitor        *history_monitor;
-  GFile               *history_file;
-  guint64              history_mtime;
+  XfceAppfinderIconSize  icon_size;
 };
 
 typedef struct
@@ -128,7 +138,7 @@ typedef struct
   gchar          *tooltip;
   guint           not_visible : 1;
 
-  GdkPixbuf      *icon_small;
+  GdkPixbuf      *icon;
   GdkPixbuf      *icon_large;
 }
 ModelItem;
@@ -147,6 +157,12 @@ enum
   LAST_SIGNAL
 };
 
+enum
+{
+  PROP_0,
+  PROP_ICON_SIZE
+};
+
 
 
 static guint model_signals[LAST_SIGNAL];
@@ -164,8 +180,18 @@ xfce_appfinder_model_class_init (XfceAppfinderModelClass *klass)
   GObjectClass *gobject_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->get_property = xfce_appfinder_model_get_property;
+  gobject_class->set_property = xfce_appfinder_model_set_property;
   gobject_class->finalize = xfce_appfinder_model_finalize;
 
+  g_object_class_install_property (gobject_class,
+                                   PROP_ICON_SIZE,
+                                   g_param_spec_uint ("icon-size", NULL, NULL,
+                                                      XFCE_APPFINDER_ICON_SIZE_SMALLEST,
+                                                      XFCE_APPFINDER_ICON_SIZE_LARGEST,
+                                                      XFCE_APPFINDER_ICON_SIZE_DEFAULT_ITEM,
+                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   model_signals[CATEGORIES_CHANGED] =
     g_signal_new (g_intern_static_string ("categories-changed"),
                   G_TYPE_FROM_CLASS (gobject_class),
@@ -183,8 +209,9 @@ xfce_appfinder_model_init (XfceAppfinderModel *model)
   /* generate a unique stamp */
   model->stamp = g_random_int ();
   model->items_hash = g_hash_table_new (g_str_hash, g_str_equal);
-  model->command_icon_small = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, ICON_SMALL);
-  model->command_icon_large = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, ICON_LARGE);
+  model->icon_size = XFCE_APPFINDER_ICON_SIZE_DEFAULT_ITEM;
+  model->command_icon = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, model->icon_size);
+  model->command_icon_large = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, XFCE_APPFINDER_ICON_SIZE_48);
   model->command_category = xfce_appfinder_model_get_command_category ();
   model->collect_cancelled = g_cancellable_new ();
 
@@ -212,6 +239,57 @@ xfce_appfinder_model_tree_model_init (GtkTreeModelIface *iface)
 }
 
 
+static void
+xfce_appfinder_model_get_property (GObject      *object,
+                                   guint         prop_id,
+                                   GValue       *value,
+                                   GParamSpec   *pspec)
+{
+  XfceAppfinderModel *model = XFCE_APPFINDER_MODEL (object);
+
+  switch (prop_id)
+    {
+    case PROP_ICON_SIZE:
+      g_value_set_uint (value, model->icon_size);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+xfce_appfinder_model_set_property (GObject      *object,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  XfceAppfinderModel    *model = XFCE_APPFINDER_MODEL (object);
+  XfceAppfinderIconSize  icon_size;
+
+  switch (prop_id)
+    {
+    case PROP_ICON_SIZE:
+      icon_size = g_value_get_uint (value);
+      if (model->icon_size != icon_size)
+        {
+          model->icon_size = icon_size;
+
+          /* trigger a theme change to reload icons */
+          xfce_appfinder_model_icon_theme_changed (model);
+        }
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
 
 static void
 xfce_appfinder_model_finalize (GObject *object)
@@ -248,7 +326,7 @@ xfce_appfinder_model_finalize (GObject *object)
   g_hash_table_destroy (model->items_hash);
 
   g_object_unref (G_OBJECT (model->command_icon_large));
-  g_object_unref (G_OBJECT (model->command_icon_small));
+  g_object_unref (G_OBJECT (model->command_icon));
   g_object_unref (G_OBJECT (model->command_category));
 
   APPFINDER_DEBUG ("model finalized");
@@ -281,12 +359,13 @@ xfce_appfinder_model_get_column_type (GtkTreeModel *tree_model,
   switch (column)
     {
     case XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT:
+    case XFCE_APPFINDER_MODEL_COLUMN_TITLE:
     case XFCE_APPFINDER_MODEL_COLUMN_URI:
     case XFCE_APPFINDER_MODEL_COLUMN_COMMAND:
     case XFCE_APPFINDER_MODEL_COLUMN_TOOLTIP:
       return G_TYPE_STRING;
 
-    case XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL:
+    case XFCE_APPFINDER_MODEL_COLUMN_ICON:
     case XFCE_APPFINDER_MODEL_COLUMN_ICON_LARGE:
       return GDK_TYPE_PIXBUF;
 
@@ -385,21 +464,29 @@ xfce_appfinder_model_get_value (GtkTreeModel *tree_model,
       g_value_set_static_string (value, item->abstract);
       break;
 
+    case XFCE_APPFINDER_MODEL_COLUMN_TITLE:
+      g_value_init (value, G_TYPE_STRING);
+      if (item->item != NULL)
+        g_value_set_static_string (value, garcon_menu_item_get_name (item->item));
+      else if (item->command != NULL)
+        g_value_set_static_string (value, item->command);
+      break;
+
     case XFCE_APPFINDER_MODEL_COLUMN_COMMAND:
       g_value_init (value, G_TYPE_STRING);
       g_value_set_static_string (value, item->command);
       break;
 
-    case XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL:
-      if (item->icon_small == NULL
+    case XFCE_APPFINDER_MODEL_COLUMN_ICON:
+      if (item->icon == NULL
           && item->item != NULL)
         {
           name = garcon_menu_item_get_icon_name (item->item);
-          item->icon_small = xfce_appfinder_model_load_pixbuf (name, ICON_SMALL);
+          item->icon = xfce_appfinder_model_load_pixbuf (name, model->icon_size);
         }
 
       g_value_init (value, GDK_TYPE_PIXBUF);
-      g_value_set_object (value, item->icon_small);
+      g_value_set_object (value, item->icon);
       break;
 
     case XFCE_APPFINDER_MODEL_COLUMN_ICON_LARGE:
@@ -407,7 +494,7 @@ xfce_appfinder_model_get_value (GtkTreeModel *tree_model,
           && item->item != NULL)
         {
           name = garcon_menu_item_get_icon_name (item->item);
-          item->icon_large = xfce_appfinder_model_load_pixbuf (name, ICON_LARGE);
+          item->icon_large = xfce_appfinder_model_load_pixbuf (name, XFCE_APPFINDER_ICON_SIZE_48);
         }
 
       g_value_init (value, GDK_TYPE_PIXBUF);
@@ -790,8 +877,8 @@ xfce_appfinder_model_item_free (gpointer            data,
     }
   if (model != NULL && item->command != NULL)
     g_hash_table_remove (model->items_hash, item->command);
-  if (item->icon_small != NULL)
-    g_object_unref (G_OBJECT (item->icon_small));
+  if (item->icon != NULL)
+    g_object_unref (G_OBJECT (item->icon));
   if (item->icon_large != NULL)
     g_object_unref (G_OBJECT (item->icon_large));
   if (item->categories != NULL)
@@ -879,7 +966,7 @@ xfce_appfinder_model_history_insert (XfceAppfinderModel *model,
   /* add new command */
   item = g_slice_new0 (ModelItem);
   item->command = g_strdup (command);
-  item->icon_small = g_object_ref (G_OBJECT (model->command_icon_small));
+  item->icon = g_object_ref (G_OBJECT (model->command_icon));
   item->icon_large = g_object_ref (G_OBJECT (model->command_icon_large));
   model->items = g_slist_insert_sorted (model->items, item, xfce_appfinder_model_item_compare);
 
@@ -1104,7 +1191,7 @@ xfce_appfinder_model_collect_history (XfceAppfinderModel *model,
         {
           item = g_slice_new0 (ModelItem);
           item->command = g_strndup (contents, end - contents);
-          item->icon_small = g_object_ref (G_OBJECT (model->command_icon_small));
+          item->icon = g_object_ref (G_OBJECT (model->command_icon));
           item->icon_large = g_object_ref (G_OBJECT (model->command_icon_large));
           model->collect_items = g_slist_prepend (model->collect_items, item);
         }
@@ -1644,13 +1731,25 @@ xfce_appfinder_model_execute (XfceAppfinderModel  *model,
 
 
 GdkPixbuf *
-xfce_appfinder_model_load_pixbuf (const gchar *icon_name,
-                                  gint         size)
+xfce_appfinder_model_load_pixbuf (const gchar           *icon_name,
+                                  XfceAppfinderIconSize  icon_size)
 {
   GdkPixbuf    *pixbuf = NULL;
   GdkPixbuf    *scaled;
   gchar        *p, *name;
   GtkIconTheme *icon_theme;
+  gint          size;
+
+  switch (icon_size)
+    {
+    case XFCE_APPFINDER_ICON_SIZE_SMALLEST: size = 16;  break;
+    case XFCE_APPFINDER_ICON_SIZE_SMALLER:  size = 24;  break;
+    case XFCE_APPFINDER_ICON_SIZE_SMALL:    size = 36;  break;
+    case XFCE_APPFINDER_ICON_SIZE_NORMAL:   size = 48;  break;
+    case XFCE_APPFINDER_ICON_SIZE_LARGE:    size = 64;  break;
+    case XFCE_APPFINDER_ICON_SIZE_LARGER:   size = 96;  break;
+    case XFCE_APPFINDER_ICON_SIZE_LARGEST:  size = 128; break;
+    }
 
   APPFINDER_DEBUG ("load icon %s at %dpx", icon_name, size);
 
@@ -1794,7 +1893,7 @@ xfce_appfinder_model_get_icon_for_command (XfceAppfinderModel *model,
               && item->item != NULL)
             {
               icon_name = garcon_menu_item_get_icon_name (item->item);
-              item->icon_large = xfce_appfinder_model_load_pixbuf (icon_name, ICON_LARGE);
+              item->icon_large = xfce_appfinder_model_load_pixbuf (icon_name, XFCE_APPFINDER_ICON_SIZE_48);
             }
 
           return g_object_ref (G_OBJECT (item->icon_large));
@@ -1821,13 +1920,13 @@ xfce_appfinder_model_icon_theme_changed (XfceAppfinderModel *model)
   APPFINDER_DEBUG ("icon theme changed");
 
   /* reload the command icons */
-  if (model->command_icon_small != NULL)
-    g_object_unref (G_OBJECT (model->command_icon_small));
-  model->command_icon_small = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, ICON_SMALL);
+  if (model->command_icon != NULL)
+    g_object_unref (G_OBJECT (model->command_icon));
+  model->command_icon = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, model->icon_size);
 
   if (model->command_icon_large != NULL)
     g_object_unref (G_OBJECT (model->command_icon_large));
-  model->command_icon_large = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, ICON_LARGE);
+  model->command_icon_large = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, XFCE_APPFINDER_ICON_SIZE_48);
 
   /* update the model items */
   for (li = model->items, idx = 0; li != NULL; li = li->next, idx++)
@@ -1835,10 +1934,10 @@ xfce_appfinder_model_icon_theme_changed (XfceAppfinderModel *model)
       item = li->data;
       item_changed = FALSE;
 
-      if (item->icon_small != NULL)
+      if (item->icon != NULL)
         {
-          g_object_unref (G_OBJECT (item->icon_small));
-          item->icon_small = NULL;
+          g_object_unref (G_OBJECT (item->icon));
+          item->icon = NULL;
           item_changed = TRUE;
         }
       if (item->icon_large != NULL)
@@ -1850,7 +1949,7 @@ xfce_appfinder_model_icon_theme_changed (XfceAppfinderModel *model)
 
       if (item->item == NULL)
         {
-          item->icon_small = g_object_ref (G_OBJECT (model->command_icon_small));
+          item->icon = g_object_ref (G_OBJECT (model->command_icon));
           item->icon_large = g_object_ref (G_OBJECT (model->command_icon_large));
         }
 
diff --git a/src/appfinder-model.h b/src/appfinder-model.h
index 1cc43ec..480f03f 100644
--- a/src/appfinder-model.h
+++ b/src/appfinder-model.h
@@ -37,7 +37,8 @@ typedef struct _XfceAppfinderModel      XfceAppfinderModel;
 enum
 {
   XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT,
-  XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL,
+  XFCE_APPFINDER_MODEL_COLUMN_TITLE,
+  XFCE_APPFINDER_MODEL_COLUMN_ICON,
   XFCE_APPFINDER_MODEL_COLUMN_ICON_LARGE,
   XFCE_APPFINDER_MODEL_COLUMN_COMMAND,
   XFCE_APPFINDER_MODEL_COLUMN_URI,
@@ -45,6 +46,22 @@ enum
   XFCE_APPFINDER_MODEL_N_COLUMNS,
 };
 
+typedef enum
+{
+  XFCE_APPFINDER_ICON_SIZE_SMALLEST, /* 16 */
+  XFCE_APPFINDER_ICON_SIZE_SMALLER,  /* 24 */
+  XFCE_APPFINDER_ICON_SIZE_SMALL,    /* 36 */
+  XFCE_APPFINDER_ICON_SIZE_NORMAL,   /* 48 */
+  XFCE_APPFINDER_ICON_SIZE_LARGE,    /* 64 */
+  XFCE_APPFINDER_ICON_SIZE_LARGER,   /* 96 */
+  XFCE_APPFINDER_ICON_SIZE_LARGEST   /* 128 */
+}
+XfceAppfinderIconSize;
+
+#define XFCE_APPFINDER_ICON_SIZE_DEFAULT_CATEGORY XFCE_APPFINDER_ICON_SIZE_SMALLER
+#define XFCE_APPFINDER_ICON_SIZE_DEFAULT_ITEM     XFCE_APPFINDER_ICON_SIZE_SMALL
+#define XFCE_APPFINDER_ICON_SIZE_48               XFCE_APPFINDER_ICON_SIZE_NORMAL
+
 typedef struct
 {
   GarconMenuDirectory *directory;
@@ -76,7 +93,7 @@ gboolean             xfce_appfinder_model_execute              (XfceAppfinderMod
                                                                 GError                   **error);
 
 GdkPixbuf           *xfce_appfinder_model_load_pixbuf          (const gchar               *icon_name,
-                                                                gint                       size) G_GNUC_MALLOC;
+                                                                XfceAppfinderIconSize      icon_size) G_GNUC_MALLOC;
 
 gboolean             xfce_appfinder_model_save_command         (XfceAppfinderModel        *model,
                                                                 const gchar               *command,
diff --git a/src/appfinder-preferences.c b/src/appfinder-preferences.c
index 6934b0f..03cfda1 100644
--- a/src/appfinder-preferences.c
+++ b/src/appfinder-preferences.c
@@ -39,6 +39,8 @@
 static void xfce_appfinder_preferences_response          (GtkWidget                *window,
                                                           gint                      response_id,
                                                           XfceAppfinderPreferences *preferences);
+static void xfce_appfinder_preferences_beside_sensitive  (GtkWidget                *show_icons,
+                                                          GtkWidget                *text_beside_icon);
 static void xfce_appfinder_preferences_clear_history     (XfceAppfinderPreferences *preferences);
 static void xfce_appfinder_preferences_action_add        (XfceAppfinderPreferences *preferences);
 static void xfce_appfinder_preferences_action_remove     (GtkWidget                *button,
@@ -96,6 +98,7 @@ xfce_appfinder_preferences_init (XfceAppfinderPreferences *preferences)
 {
   GObject     *object;
   GtkTreePath *path;
+  GObject     *icons;
 
   preferences->channel = xfconf_channel_get ("xfce4-appfinder");
 
@@ -116,6 +119,28 @@ xfce_appfinder_preferences_init (XfceAppfinderPreferences *preferences)
   xfconf_g_property_bind (preferences->channel, "/always-center", G_TYPE_BOOLEAN,
                           G_OBJECT (object), "active");
 
+  icons = gtk_builder_get_object (GTK_BUILDER (preferences), "icon-view");
+  xfconf_g_property_bind (preferences->channel, "/icon-view", G_TYPE_BOOLEAN,
+                          G_OBJECT (icons), "active");
+
+  object = gtk_builder_get_object (GTK_BUILDER (preferences), "text-beside-icons");
+  xfconf_g_property_bind (preferences->channel, "/text-beside-icons", G_TYPE_BOOLEAN,
+                          G_OBJECT (object), "active");
+
+  g_signal_connect (G_OBJECT (icons), "toggled",
+      G_CALLBACK (xfce_appfinder_preferences_beside_sensitive), object);
+  xfce_appfinder_preferences_beside_sensitive (GTK_WIDGET (icons), GTK_WIDGET (object));
+
+  object = gtk_builder_get_object (GTK_BUILDER (preferences), "item-icon-size");
+  gtk_combo_box_set_active (GTK_COMBO_BOX (object), XFCE_APPFINDER_ICON_SIZE_DEFAULT_ITEM);
+  xfconf_g_property_bind (preferences->channel, "/item-icon-size", G_TYPE_UINT,
+                          G_OBJECT (object), "active");
+
+  object = gtk_builder_get_object (GTK_BUILDER (preferences), "category-icon-size");
+  gtk_combo_box_set_active (GTK_COMBO_BOX (object), XFCE_APPFINDER_ICON_SIZE_DEFAULT_CATEGORY);
+  xfconf_g_property_bind (preferences->channel, "/category-icon-size", G_TYPE_UINT,
+                          G_OBJECT (object), "active");
+
   object = gtk_builder_get_object (GTK_BUILDER (preferences), "button-clear");
   g_signal_connect_swapped (G_OBJECT (object), "clicked",
       G_CALLBACK (xfce_appfinder_preferences_clear_history), preferences);
@@ -166,6 +191,16 @@ xfce_appfinder_preferences_response (GtkWidget                *window,
 
 
 static void
+xfce_appfinder_preferences_beside_sensitive (GtkWidget *show_icons,
+                                             GtkWidget *text_beside_icon)
+{
+  gtk_widget_set_sensitive (text_beside_icon,
+      gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_icons)));
+}
+
+
+
+static void
 xfce_appfinder_preferences_clear_history (XfceAppfinderPreferences *preferences)
 {
   XfceAppfinderModel *model;
diff --git a/src/appfinder-preferences.glade b/src/appfinder-preferences.glade
index f9a5b7a..3b5ea4a 100644
--- a/src/appfinder-preferences.glade
+++ b/src/appfinder-preferences.glade
@@ -25,6 +25,40 @@
       <column type="gint"/>
     </columns>
   </object>
+  <object class="GtkListStore" id="icon-sizes">
+    <columns>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Very Small</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Smaller</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Small</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Normal</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Large</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Larger</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Very Large</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkImage" id="image3">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-clear</property>
+  </object>
   <object class="XfceTitledDialog" id="dialog">
     <property name="can_focus">False</property>
     <property name="title" translatable="yes">Application Finder</property>
@@ -45,10 +79,10 @@
             <child>
               <object class="GtkButton" id="button-close">
                 <property name="label">gtk-close</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="use_stock">True</property>
               </object>
               <packing>
@@ -96,10 +130,10 @@
                             <child>
                               <object class="GtkCheckButton" id="remember-category">
                                 <property name="label" translatable="yes">Remember last _selected category</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
-                                <property name="use_action_appearance">False</property>
                                 <property name="use_underline">True</property>
                                 <property name="draw_indicator">True</property>
                               </object>
@@ -112,11 +146,11 @@
                             <child>
                               <object class="GtkCheckButton" id="always-center">
                                 <property name="label" translatable="yes">Always c_enter the window</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="tooltip_text" translatable="yes">Center the window on startup.</property>
-                                <property name="use_action_appearance">False</property>
                                 <property name="use_underline">True</property>
                                 <property name="draw_indicator">True</property>
                               </object>
@@ -148,6 +182,145 @@
                   </packing>
                 </child>
                 <child>
+                  <object class="GtkFrame" id="frame3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
+                    <child>
+                      <object class="GtkAlignment" id="alignment5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkTable" id="table2">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="border_width">6</property>
+                            <property name="n_rows">4</property>
+                            <property name="n_columns">2</property>
+                            <property name="column_spacing">12</property>
+                            <property name="row_spacing">6</property>
+                            <child>
+                              <object class="GtkCheckButton" id="icon-view">
+                                <property name="label" translatable="yes">Show items in an icon _view</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="right_attach">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="text-beside-icons">
+                                <property name="label" translatable="yes">Text besi_de icons</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label9">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Ite_m icon size:</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">item-icon-size</property>
+                              </object>
+                              <packing>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
+                                <property name="x_options">GTK_FILL</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label10">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Categ_ory icon size:</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">category-icon-size</property>
+                              </object>
+                              <packing>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                                <property name="x_options">GTK_FILL</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkComboBox" id="item-icon-size">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="model">icon-sizes</property>
+                                <child>
+                                  <object class="GtkCellRendererText" id="cellrenderertext4"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkComboBox" id="category-icon-size">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="model">icon-sizes</property>
+                                <child>
+                                  <object class="GtkCellRendererText" id="cellrenderertext2"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Appearance</property>
+                        <property name="use_markup">True</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
                   <object class="GtkFrame" id="frame2">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
@@ -165,10 +338,10 @@
                         <child>
                           <object class="GtkButton" id="button-clear">
                             <property name="label" translatable="yes">C_lear Custom Command History</property>
+                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
-                            <property name="use_action_appearance">False</property>
                             <property name="image">image3</property>
                             <property name="use_underline">True</property>
                           </object>
@@ -189,7 +362,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">1</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
               </object>
@@ -266,11 +439,11 @@
                             <property name="spacing">6</property>
                             <child>
                               <object class="GtkButton" id="button-add">
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
                                 <property name="tooltip_text" translatable="yes">Add a new custom action.</property>
-                                <property name="use_action_appearance">False</property>
                                 <child>
                                   <object class="GtkImage" id="image1">
                                     <property name="visible">True</property>
@@ -287,11 +460,11 @@
                             </child>
                             <child>
                               <object class="GtkButton" id="button-remove">
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
                                 <property name="tooltip_text" translatable="yes">Remove the currently selected action.</property>
-                                <property name="use_action_appearance">False</property>
                                 <child>
                                   <object class="GtkImage" id="image2">
                                     <property name="visible">True</property>
@@ -436,15 +609,12 @@
                       </packing>
                     </child>
                     <child>
-                      <placeholder/>
-                    </child>
-                    <child>
                       <object class="GtkCheckButton" id="save">
                         <property name="label" translatable="yes">_Save match in command history</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="draw_indicator">True</property>
                       </object>
@@ -455,6 +625,9 @@
                         <property name="bottom_attach">4</property>
                       </packing>
                     </child>
+                    <child>
+                      <placeholder/>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -492,9 +665,4 @@
       <action-widget response="0">button-close</action-widget>
     </action-widgets>
   </object>
-  <object class="GtkImage" id="image3">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="stock">gtk-clear</property>
-  </object>
 </interface>
diff --git a/src/appfinder-private.h b/src/appfinder-private.h
index 5b0b5af..7b3cb54 100644
--- a/src/appfinder-private.h
+++ b/src/appfinder-private.h
@@ -19,9 +19,6 @@
 #ifndef __XFCE_APPFINDER_PRIVATE_H__
 #define __XFCE_APPFINDER_PRIVATE_H__
 
-#define ICON_SMALL   32
-#define ICON_LARGE   48
-
 #define ITER_GET_DATA(iter)          (((GSList *) (iter)->user_data)->data)
 #define ITER_INIT(iter, iter_stamp, iter_data) \
 G_STMT_START { \
diff --git a/src/appfinder-window.c b/src/appfinder-window.c
index 351b4d2..5738237 100644
--- a/src/appfinder-window.c
+++ b/src/appfinder-window.c
@@ -48,6 +48,7 @@ static void       xfce_appfinder_window_finalize                      (GObject
 static void       xfce_appfinder_window_unmap                         (GtkWidget                   *widget);
 static gboolean   xfce_appfinder_window_key_press_event               (GtkWidget                   *widget,
                                                                        GdkEventKey                 *event);
+static void       xfce_appfinder_window_view                          (XfceAppfinderWindow         *window);
 static void       xfce_appfinder_window_set_padding                   (GtkWidget                   *entry,
                                                                        GtkWidget                   *align);
 static gboolean   xfce_appfinder_window_completion_match_func         (GtkEntryCompletion          *completion,
@@ -81,6 +82,10 @@ static void       xfce_appfinder_window_category_changed              (GtkTreeSe
 static void       xfce_appfinder_window_category_set_categories       (XfceAppfinderWindow         *window);
 static void       xfce_appfinder_window_preferences                   (GtkWidget                   *button,
                                                                        XfceAppfinderWindow         *window);
+static void       xfce_appfinder_window_property_changed              (XfconfChannel               *channel,
+                                                                       const gchar                 *prop,
+                                                                       const GValue                *value,
+                                                                       XfceAppfinderWindow         *window);
 static gboolean   xfce_appfinder_window_item_visible                  (GtkTreeModel                *model,
                                                                        GtkTreeIter                 *iter,
                                                                        gpointer                     data);
@@ -113,7 +118,8 @@ struct _XfceAppfinderWindow
   GtkWidget                  *paned;
   GtkWidget                  *entry;
   GtkWidget                  *image;
-  GtkWidget                  *treeview;
+  GtkWidget                  *view;
+  GtkWidget                  *viewscroll;
   GtkWidget                  *sidepane;
 
   GdkPixbuf                  *icon_find;
@@ -130,6 +136,8 @@ struct _XfceAppfinderWindow
   guint                       idle_entry_changed_id;
 
   gint                        last_window_height;
+
+  gulong                      property_watch_id;
 };
 
 static const GtkTargetEntry target_list[] =
@@ -167,13 +175,11 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
   GtkWidget          *pane;
   GtkWidget          *scroll;
   GtkWidget          *sidepane;
-  GtkWidget          *treeview;
   GtkWidget          *image;
   GtkWidget          *hbox;
   GtkWidget          *align;
   GtkTreeViewColumn  *column;
   GtkCellRenderer    *renderer;
-  GtkTreeModel       *filter_model;
   GtkTreeSelection   *selection;
   GtkWidget          *bbox;
   GtkWidget          *button;
@@ -185,7 +191,12 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
   window->last_window_height = xfconf_channel_get_int (window->channel, "/last/window-height", DEFAULT_WINDOW_HEIGHT);
 
   window->category_model = xfce_appfinder_category_model_new ();
+  xfconf_g_property_bind (window->channel, "/category-icon-size", G_TYPE_UINT,
+                          G_OBJECT (window->category_model), "icon-size");
+
   window->model = xfce_appfinder_model_get ();
+  xfconf_g_property_bind (window->channel, "/item-icon-size", G_TYPE_UINT,
+                          G_OBJECT (window->model), "icon-size");
 
   gtk_window_set_title (GTK_WINDOW (window), _("Application Finder"));
   integer = xfconf_channel_get_int (window->channel, "/last/window-width", DEFAULT_WINDOW_WIDTH);
@@ -208,7 +219,7 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
   gtk_box_pack_start (GTK_BOX (hbox), align, FALSE, FALSE, 0);
   gtk_widget_show (align);
 
-  window->icon_find = xfce_appfinder_model_load_pixbuf (GTK_STOCK_FIND, ICON_LARGE);
+  window->icon_find = xfce_appfinder_model_load_pixbuf (GTK_STOCK_FIND, XFCE_APPFINDER_ICON_SIZE_48);
   window->image = image = gtk_image_new_from_pixbuf (window->icon_find);
   gtk_container_add (GTK_CONTAINER (align), image);
   gtk_widget_show (image);
@@ -271,7 +282,7 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
       G_CALLBACK (xfce_appfinder_window_category_changed), window);
 
   column = gtk_tree_view_column_new ();
-  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
   gtk_tree_view_append_column (GTK_TREE_VIEW (sidepane), GTK_TREE_VIEW_COLUMN (column));
 
   renderer = gtk_cell_renderer_pixbuf_new ();
@@ -285,50 +296,14 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
   gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer,
                                        "text", XFCE_APPFINDER_CATEGORY_MODEL_COLUMN_NAME, NULL);
 
-  scroll = gtk_scrolled_window_new (NULL, NULL);
+  window->viewscroll = scroll = gtk_scrolled_window_new (NULL, NULL);
   gtk_paned_add2 (GTK_PANED (pane), scroll);
   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_ETCHED_IN);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
   gtk_widget_show (scroll);
 
-  filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (window->model), NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model), xfce_appfinder_window_item_visible, window, NULL);
-
-  window->treeview = treeview = gtk_tree_view_new_with_model (filter_model);
-  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
-  gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE);
-  gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (treeview), TRUE);
-  gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), XFCE_APPFINDER_MODEL_COLUMN_TOOLTIP);
-  g_signal_connect_swapped (GTK_TREE_VIEW (treeview), "row-activated", G_CALLBACK (xfce_appfinder_window_row_activated), window);
-  g_signal_connect_swapped (GTK_TREE_VIEW (treeview), "start-interactive-search", G_CALLBACK (gtk_widget_grab_focus), entry);
-  gtk_drag_source_set (treeview, GDK_BUTTON1_MASK, target_list, G_N_ELEMENTS (target_list), GDK_ACTION_COPY);
-  g_signal_connect (G_OBJECT (treeview), "drag-begin", G_CALLBACK (xfce_appfinder_window_drag_begin), window);
-  g_signal_connect (G_OBJECT (treeview), "drag-data-get", G_CALLBACK (xfce_appfinder_window_drag_data_get), window);
-  g_signal_connect (G_OBJECT (treeview), "key-press-event", G_CALLBACK (xfce_appfinder_window_treeview_key_press_event), window);
-  gtk_container_add (GTK_CONTAINER (scroll), treeview);
-  gtk_widget_show (treeview);
-  g_object_unref (G_OBJECT (filter_model));
-
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
-  gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-  g_signal_connect_swapped (G_OBJECT (selection), "changed",
-      G_CALLBACK (xfce_appfinder_window_item_changed), window);
-
-  column = gtk_tree_view_column_new ();
-  gtk_tree_view_column_set_spacing (column, 2);
-  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), GTK_TREE_VIEW_COLUMN (column));
-
-  renderer = gtk_cell_renderer_pixbuf_new ();
-  gtk_tree_view_column_pack_start (GTK_TREE_VIEW_COLUMN (column), renderer, FALSE);
-  gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer,
-                                       "pixbuf", XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL, NULL);
-
-  renderer = gtk_cell_renderer_text_new ();
-  g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-  gtk_tree_view_column_pack_start (GTK_TREE_VIEW_COLUMN (column), renderer, TRUE);
-  gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer,
-                                       "markup", XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT, NULL);
+  /* set the icon or tree view */
+  xfce_appfinder_window_view (window);
 
   window->bin_expanded = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
   gtk_box_pack_start (GTK_BOX (vbox), window->bin_expanded, FALSE, TRUE, 0);
@@ -372,6 +347,11 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
                             G_CALLBACK (xfce_appfinder_window_category_set_categories),
                             window);
 
+  /* monitor xfconf property changes */
+  window->property_watch_id =
+    g_signal_connect (G_OBJECT (window->channel), "property-changed",
+        G_CALLBACK (xfce_appfinder_window_property_changed), window);
+
   APPFINDER_DEBUG ("constructed window");
 }
 
@@ -385,6 +365,8 @@ xfce_appfinder_window_finalize (GObject *object)
   if (window->idle_entry_changed_id != 0)
     g_source_remove (window->idle_entry_changed_id);
 
+  g_signal_handler_disconnect (window->channel, window->property_watch_id);
+
   g_object_unref (G_OBJECT (window->model));
   g_object_unref (G_OBJECT (window->category_model));
   g_object_unref (G_OBJECT (window->completion));
@@ -451,6 +433,201 @@ xfce_appfinder_window_key_press_event (GtkWidget   *widget,
 
 
 static void
+xfce_appfinder_window_set_item_width (XfceAppfinderWindow *window)
+{
+  gint                   width;
+  XfceAppfinderIconSize  icon_size;
+  GtkOrientation         item_orientation = GTK_ORIENTATION_VERTICAL;
+  GList                 *renderers;
+  GList                 *li;
+
+  appfinder_return_if_fail (GTK_IS_ICON_VIEW (window->view));
+
+  g_object_get (G_OBJECT (window->model), "icon-size", &icon_size, NULL);
+
+  /* some hard-coded values for the cell size that seem to work fine */
+  switch (icon_size)
+    {
+    case XFCE_APPFINDER_ICON_SIZE_SMALLEST:
+      width = 16 * 3.75;
+      break;
+
+    case XFCE_APPFINDER_ICON_SIZE_SMALLER:
+      width = 24 * 3;
+      break;
+
+    case XFCE_APPFINDER_ICON_SIZE_SMALL:
+      width = 36 * 2.5;
+      break;
+
+    case XFCE_APPFINDER_ICON_SIZE_NORMAL:
+      width = 48 * 2;
+      break;
+
+    case XFCE_APPFINDER_ICON_SIZE_LARGE:
+      width = 64 * 1.5;
+      break;
+
+    case XFCE_APPFINDER_ICON_SIZE_LARGER:
+      width = 96 * 1.75;
+      break;
+
+    case XFCE_APPFINDER_ICON_SIZE_LARGEST:
+      width = 128 * 1.25;
+      break;
+    }
+
+  if (xfconf_channel_get_bool (window->channel, "/text-beside-icons", FALSE))
+    {
+      item_orientation = GTK_ORIENTATION_HORIZONTAL;
+      width *= 2;
+    }
+
+#if GTK_CHECK_VERSION (2, 22, 0)
+  gtk_icon_view_set_item_orientation (GTK_ICON_VIEW (window->view), item_orientation);
+#else
+  gtk_icon_view_set_orientation (GTK_ICON_VIEW (window->view), item_orientation);
+#endif
+  gtk_icon_view_set_item_width (GTK_ICON_VIEW (window->view), width);
+
+  if (item_orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      /* work around the yalign = 0.0 gtk uses */
+      renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (window->view));
+      for (li = renderers; li != NULL; li = li->next)
+        g_object_set (li->data, "yalign", 0.5, NULL);
+      g_list_free (renderers);
+    }
+}
+
+
+
+static void
+xfce_appfinder_window_view (XfceAppfinderWindow *window)
+{
+  GtkTreeViewColumn *column;
+  GtkCellRenderer   *renderer;
+  GtkTreeModel      *filter_model;
+  GtkTreeSelection  *selection;
+  GtkWidget         *view;
+  gboolean           icon_view;
+
+  icon_view = xfconf_channel_get_bool (window->channel, "/icon-view", FALSE);
+  if (window->view != NULL)
+    {
+      if (icon_view && GTK_IS_ICON_VIEW (window->view))
+        return;
+      gtk_widget_destroy (window->view);
+    }
+
+  filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (window->model), NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model), xfce_appfinder_window_item_visible, window, NULL);
+
+  if (icon_view)
+    {
+      window->view = view = gtk_icon_view_new_with_model (filter_model);
+      gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (view), GTK_SELECTION_BROWSE);
+      gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (view), XFCE_APPFINDER_MODEL_COLUMN_ICON);
+      gtk_icon_view_set_text_column (GTK_ICON_VIEW (view), XFCE_APPFINDER_MODEL_COLUMN_TITLE);
+      gtk_icon_view_set_tooltip_column (GTK_ICON_VIEW (view), XFCE_APPFINDER_MODEL_COLUMN_TOOLTIP);
+      xfce_appfinder_window_set_item_width (window);
+
+      g_signal_connect_swapped (G_OBJECT (view), "selection-changed",
+          G_CALLBACK (xfce_appfinder_window_item_changed), window);
+      g_signal_connect_swapped (G_OBJECT (view), "item-activated",
+          G_CALLBACK (xfce_appfinder_window_row_activated), window);
+    }
+  else
+    {
+      window->view = view = gtk_tree_view_new_with_model (filter_model);
+      gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
+      gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE);
+      gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (view), XFCE_APPFINDER_MODEL_COLUMN_TOOLTIP);
+      g_signal_connect_swapped (G_OBJECT (view), "row-activated",
+          G_CALLBACK (xfce_appfinder_window_row_activated), window);
+      g_signal_connect_swapped (G_OBJECT (view), "start-interactive-search",
+          G_CALLBACK (gtk_widget_grab_focus), window->entry);
+      g_signal_connect (G_OBJECT (view), "key-press-event",
+           G_CALLBACK (xfce_appfinder_window_treeview_key_press_event), window);
+
+      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+      gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+      g_signal_connect_swapped (G_OBJECT (selection), "changed",
+          G_CALLBACK (xfce_appfinder_window_item_changed), window);
+
+      column = gtk_tree_view_column_new ();
+      gtk_tree_view_column_set_spacing (column, 2);
+      gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+      gtk_tree_view_append_column (GTK_TREE_VIEW (view), GTK_TREE_VIEW_COLUMN (column));
+
+      renderer = gtk_cell_renderer_pixbuf_new ();
+      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, FALSE);
+      gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer,
+                                      "pixbuf", XFCE_APPFINDER_MODEL_COLUMN_ICON, NULL);
+
+      renderer = gtk_cell_renderer_text_new ();
+      g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
+      gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer,
+                                      "markup", XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT, NULL);
+    }
+
+  gtk_drag_source_set (view, GDK_BUTTON1_MASK, target_list,
+                       G_N_ELEMENTS (target_list), GDK_ACTION_COPY);
+  g_signal_connect (G_OBJECT (view), "drag-begin",
+      G_CALLBACK (xfce_appfinder_window_drag_begin), window);
+  g_signal_connect (G_OBJECT (view), "drag-data-get",
+      G_CALLBACK (xfce_appfinder_window_drag_data_get), window);
+  gtk_container_add (GTK_CONTAINER (window->viewscroll), view);
+  gtk_widget_show (view);
+
+  g_object_unref (G_OBJECT (filter_model));
+}
+
+
+
+static gboolean
+xfce_appfinder_window_view_get_selected (XfceAppfinderWindow  *window,
+                                         GtkTreeModel        **model,
+                                         GtkTreeIter          *iter)
+{
+  GtkTreeSelection *selection;
+  gboolean          have_iter;
+  GList            *items;
+
+  appfinder_return_val_if_fail (XFCE_IS_APPFINDER_WINDOW (window), FALSE);
+  appfinder_return_val_if_fail (model != NULL, FALSE);
+  appfinder_return_val_if_fail (iter != NULL, FALSE);
+
+  if (GTK_IS_TREE_VIEW (window->view))
+    {
+      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->view));
+      have_iter = gtk_tree_selection_get_selected (selection, model, iter);
+    }
+  else
+    {
+      items = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (window->view));
+      appfinder_assert (g_list_length (items) <= 1);
+      if (items != NULL)
+        {
+          *model = gtk_icon_view_get_model (GTK_ICON_VIEW (window->view));
+          have_iter = gtk_tree_model_get_iter (*model, iter, items->data);
+
+          gtk_tree_path_free (items->data);
+          g_list_free (items);
+        }
+      else
+        {
+          have_iter = FALSE;
+        }
+    }
+
+  return have_iter;
+}
+
+
+
+static void
 xfce_appfinder_window_update_image (XfceAppfinderWindow *window,
                                     GdkPixbuf           *pixbuf)
 {
@@ -470,7 +647,8 @@ xfce_appfinder_window_set_padding (GtkWidget *entry,
 {
   gint padding;
 
-  padding = (ICON_LARGE - entry->allocation.height) / 2;
+  /* 48 is the icon size of XFCE_APPFINDER_ICON_SIZE_48 */
+  padding = (48 - entry->allocation.height) / 2;
   gtk_alignment_set_padding (GTK_ALIGNMENT (align), MAX (0, padding), 0, 0, 0);
 }
 
@@ -527,8 +705,11 @@ xfce_appfinder_window_entry_changed_idle (gpointer data)
           window->filter_text = NULL;
         }
 
-      model = gtk_tree_view_get_model (GTK_TREE_VIEW (window->treeview));
       APPFINDER_DEBUG ("refilter entry");
+      if (GTK_IS_TREE_VIEW (window->view))
+        model = gtk_tree_view_get_model (GTK_TREE_VIEW (window->view));
+      else
+        model = gtk_icon_view_get_model (GTK_ICON_VIEW (window->view));
       gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
     }
   else
@@ -577,13 +758,22 @@ xfce_appfinder_window_entry_activate (GtkEditable         *entry,
 
   if (gtk_widget_get_visible (window->paned))
     {
-      if (gtk_tree_view_get_visible_range (GTK_TREE_VIEW (window->treeview), &path, NULL))
+      if (GTK_IS_TREE_VIEW (window->view))
         {
-          gtk_tree_view_set_cursor (GTK_TREE_VIEW (window->treeview), path, NULL, FALSE);
+          if (gtk_tree_view_get_visible_range (GTK_TREE_VIEW (window->view), &path, NULL))
+            {
+              gtk_tree_view_set_cursor (GTK_TREE_VIEW (window->view), path, NULL, FALSE);
+              gtk_tree_path_free (path);
+            }
+        }
+      else if (gtk_icon_view_get_visible_range (GTK_ICON_VIEW (window->view), &path, NULL))
+        {
+          gtk_icon_view_select_path (GTK_ICON_VIEW (window->view), path);
+          gtk_icon_view_set_cursor (GTK_ICON_VIEW (window->view), path, NULL, FALSE);
           gtk_tree_path_free (path);
         }
 
-      gtk_widget_grab_focus (window->treeview);
+      gtk_widget_grab_focus (window->view);
     }
   else if (gtk_widget_get_sensitive (window->button_launch))
     {
@@ -626,15 +816,13 @@ xfce_appfinder_window_drag_begin (GtkWidget           *widget,
                                   GdkDragContext      *drag_context,
                                   XfceAppfinderWindow *window)
 {
-  GtkTreeSelection *selection;
-  GtkTreeModel     *model;
-  GtkTreeIter       iter;
-  GdkPixbuf        *pixbuf;
+  GtkTreeModel *model;
+  GtkTreeIter   iter;
+  GdkPixbuf    *pixbuf;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter))
+  if (xfce_appfinder_window_view_get_selected (window, &model, &iter))
     {
-      gtk_tree_model_get (model, &iter, XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL, &pixbuf, -1);
+      gtk_tree_model_get (model, &iter, XFCE_APPFINDER_MODEL_COLUMN_ICON_LARGE, &pixbuf, -1);
       if (G_LIKELY (pixbuf != NULL))
         {
           gtk_drag_set_icon_pixbuf (drag_context, pixbuf, 0, 0);
@@ -657,13 +845,11 @@ xfce_appfinder_window_drag_data_get (GtkWidget           *widget,
                                      guint                drag_time,
                                      XfceAppfinderWindow *window)
 {
-  GtkTreeSelection *selection;
-  GtkTreeModel     *model;
-  GtkTreeIter       iter;
-  gchar            *uris[2];
+  GtkTreeModel *model;
+  GtkTreeIter   iter;
+  gchar        *uris[2];
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter))
+  if (xfce_appfinder_window_view_get_selected (window, &model, &iter))
     {
       uris[1] = NULL;
       gtk_tree_model_get (model, &iter, XFCE_APPFINDER_MODEL_COLUMN_URI, &uris[0], -1);
@@ -679,7 +865,7 @@ xfce_appfinder_window_treeview_key_press_event (GtkWidget           *widget,
                                                 GdkEventKey         *event,
                                                 XfceAppfinderWindow *window)
 {
-  if (widget == window->treeview)
+  if (widget == window->view)
     {
       if (event->keyval == GDK_Left)
         {
@@ -691,7 +877,7 @@ xfce_appfinder_window_treeview_key_press_event (GtkWidget           *widget,
     {
       if (event->keyval == GDK_Right)
         {
-          gtk_widget_grab_focus (window->treeview);
+          gtk_widget_grab_focus (window->view);
           return TRUE;
         }
     }
@@ -741,7 +927,10 @@ xfce_appfinder_window_category_changed (GtkTreeSelection    *selection,
           APPFINDER_DEBUG ("refilter category");
 
           /* update visible items */
-          model = gtk_tree_view_get_model (GTK_TREE_VIEW (window->treeview));
+          if (GTK_IS_TREE_VIEW (window->view))
+            model = gtk_tree_view_get_model (GTK_TREE_VIEW (window->view));
+          else
+            model = gtk_icon_view_get_model (GTK_ICON_VIEW (window->view));
           gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
 
           /* store last category */
@@ -776,8 +965,11 @@ xfce_appfinder_window_category_set_categories (XfceAppfinderWindow *window)
     name = NULL;
 
   path = xfce_appfinder_category_model_find_category (window->category_model, name);
-  gtk_tree_view_set_cursor (GTK_TREE_VIEW (window->sidepane), path, NULL, FALSE);
-  gtk_tree_path_free (path);
+  if (path != NULL)
+    {
+      gtk_tree_view_set_cursor (GTK_TREE_VIEW (window->sidepane), path, NULL, FALSE);
+      gtk_tree_path_free (path);
+    }
   g_free (name);
 }
 
@@ -798,6 +990,32 @@ xfce_appfinder_window_preferences (GtkWidget           *button,
 
 
 
+static void
+xfce_appfinder_window_property_changed (XfconfChannel       *channel,
+                                        const gchar         *prop,
+                                        const GValue        *value,
+                                        XfceAppfinderWindow *window)
+{
+  appfinder_return_if_fail (XFCE_IS_APPFINDER_WINDOW (window));
+  appfinder_return_if_fail (window->channel == channel);
+
+  if (g_strcmp0 (prop, "/icon-view") == 0)
+    {
+      xfce_appfinder_window_view (window);
+    }
+  else if (g_strcmp0 (prop, "/item-icon-size") == 0)
+    {
+      if (GTK_IS_ICON_VIEW (window->view))
+        xfce_appfinder_window_set_item_width (window);
+    }
+  else if (g_strcmp0 (prop, "/text-beside-icons") == 0)
+    {
+      xfce_appfinder_window_set_item_width (window);
+    }
+}
+
+
+
 static gboolean
 xfce_appfinder_window_item_visible (GtkTreeModel *model,
                                     GtkTreeIter  *iter,
@@ -817,13 +1035,11 @@ xfce_appfinder_window_item_changed (XfceAppfinderWindow *window)
   GtkTreeIter       iter;
   GtkTreeModel     *model;
   gboolean          can_launch;
-  GtkTreeSelection *selection;
   GdkPixbuf        *pixbuf;
 
   if (gtk_widget_get_visible (window->paned))
     {
-      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
-      can_launch = gtk_tree_selection_get_selected (selection, &model, &iter);
+      can_launch = xfce_appfinder_window_view_get_selected (window, &model, &iter);
       gtk_widget_set_sensitive (window->button_launch, can_launch);
 
       if (can_launch)
@@ -858,7 +1074,7 @@ xfce_appfinder_window_icon_theme_changed (XfceAppfinderWindow *window)
 {
   if (window->icon_find != NULL)
     g_object_unref (G_OBJECT (window->icon_find));
-  window->icon_find = xfce_appfinder_model_load_pixbuf (GTK_STOCK_FIND, ICON_LARGE);
+  window->icon_find = xfce_appfinder_model_load_pixbuf (GTK_STOCK_FIND, XFCE_APPFINDER_ICON_SIZE_48);
 
   /* drop cached pixbufs */
   xfce_appfinder_model_icon_theme_changed (window->model);
@@ -919,16 +1135,15 @@ xfce_appfinder_window_execute_command (const gchar          *text,
 static void
 xfce_appfinder_window_execute (XfceAppfinderWindow *window)
 {
-  GtkTreeSelection *selection;
-  GtkTreeModel     *model;
-  GtkTreeIter       iter, orig;
-  GError           *error = NULL;
-  gboolean          result = FALSE;
-  GdkScreen        *screen;
-  const gchar      *text;
-  gchar            *cmd = NULL;
-  gboolean          regular_command = FALSE;
-  gboolean          save_cmd;
+  GtkTreeModel *model;
+  GtkTreeIter   iter, orig;
+  GError       *error = NULL;
+  gboolean      result = FALSE;
+  GdkScreen    *screen;
+  const gchar  *text;
+  gchar        *cmd = NULL;
+  gboolean      regular_command = FALSE;
+  gboolean      save_cmd;
 
   if (!gtk_widget_get_sensitive (window->button_launch))
     return;
@@ -936,8 +1151,7 @@ xfce_appfinder_window_execute (XfceAppfinderWindow *window)
   screen = gtk_window_get_screen (GTK_WINDOW (window));
   if (gtk_widget_get_visible (window->paned))
     {
-      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
-      if (gtk_tree_selection_get_selected (selection, &model, &iter))
+      if (xfce_appfinder_window_view_get_selected (window, &model, &iter))
         {
           gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &orig, &iter);
           result = xfce_appfinder_model_execute (window->model, &orig, screen, &regular_command, &error);


More information about the Xfce4-commits mailing list