]> Pileus Git - ~andy/gtk/commitdiff
Add a simple file browser based on the icon view.
authorAnders Carlsson <andersca@gnome.org>
Sun, 4 Jul 2004 20:35:35 +0000 (20:35 +0000)
committerAnders Carlsson <andersca@src.gnome.org>
Sun, 4 Jul 2004 20:35:35 +0000 (20:35 +0000)
2004-07-04  Anders Carlsson  <andersca@gnome.org>

* demos/gtk-demo/Makefile.am:
* demos/gtk-demo/gnome-fs-directory.png:
* demos/gtk-demo/gnome-fs-regular.png:
* demos/gtk-demo/iconview.c: (load_pixbufs), (fill_store),
(sort_func), (create_store), (item_activated), (up_clicked),
(home_clicked), (do_iconview):
Add a simple file browser based on the icon view.

* gtk/gtk.h:
Add gtk/gtkiconview.h

* gtk/gtkiconview.c: (gtk_icon_view_layout),
(gtk_icon_view_item_new), (gtk_icon_view_item_activated):
Fix a few bugs discovered while writing the demo.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
demos/gtk-demo/Makefile.am
demos/gtk-demo/gnome-fs-directory.png [new file with mode: 0644]
demos/gtk-demo/gnome-fs-regular.png [new file with mode: 0644]
demos/gtk-demo/iconview.c [new file with mode: 0644]
gtk/gtk.h
gtk/gtkiconview.c

index 68a94576a34a7198fb809775201d8a15f0e9cba9..e2550590743c750401fc2f18776304c9f96999b6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2004-07-04  Anders Carlsson  <andersca@gnome.org>
+
+       * demos/gtk-demo/Makefile.am:
+       * demos/gtk-demo/gnome-fs-directory.png:
+       * demos/gtk-demo/gnome-fs-regular.png:
+       * demos/gtk-demo/iconview.c: (load_pixbufs), (fill_store),
+       (sort_func), (create_store), (item_activated), (up_clicked),
+       (home_clicked), (do_iconview):
+       Add a simple file browser based on the icon view.
+       
+       * gtk/gtk.h:
+       Add gtk/gtkiconview.h
+       
+       * gtk/gtkiconview.c: (gtk_icon_view_layout),
+       (gtk_icon_view_item_new), (gtk_icon_view_item_activated):
+       Fix a few bugs discovered while writing the demo.
+       
 2004-07-04  Anders Carlsson  <andersca@gnome.org>
 
        * gtk/Makefile.am:
index 68a94576a34a7198fb809775201d8a15f0e9cba9..e2550590743c750401fc2f18776304c9f96999b6 100644 (file)
@@ -1,3 +1,20 @@
+2004-07-04  Anders Carlsson  <andersca@gnome.org>
+
+       * demos/gtk-demo/Makefile.am:
+       * demos/gtk-demo/gnome-fs-directory.png:
+       * demos/gtk-demo/gnome-fs-regular.png:
+       * demos/gtk-demo/iconview.c: (load_pixbufs), (fill_store),
+       (sort_func), (create_store), (item_activated), (up_clicked),
+       (home_clicked), (do_iconview):
+       Add a simple file browser based on the icon view.
+       
+       * gtk/gtk.h:
+       Add gtk/gtkiconview.h
+       
+       * gtk/gtkiconview.c: (gtk_icon_view_layout),
+       (gtk_icon_view_item_new), (gtk_icon_view_item_activated):
+       Fix a few bugs discovered while writing the demo.
+       
 2004-07-04  Anders Carlsson  <andersca@gnome.org>
 
        * gtk/Makefile.am:
index 68a94576a34a7198fb809775201d8a15f0e9cba9..e2550590743c750401fc2f18776304c9f96999b6 100644 (file)
@@ -1,3 +1,20 @@
+2004-07-04  Anders Carlsson  <andersca@gnome.org>
+
+       * demos/gtk-demo/Makefile.am:
+       * demos/gtk-demo/gnome-fs-directory.png:
+       * demos/gtk-demo/gnome-fs-regular.png:
+       * demos/gtk-demo/iconview.c: (load_pixbufs), (fill_store),
+       (sort_func), (create_store), (item_activated), (up_clicked),
+       (home_clicked), (do_iconview):
+       Add a simple file browser based on the icon view.
+       
+       * gtk/gtk.h:
+       Add gtk/gtkiconview.h
+       
+       * gtk/gtkiconview.c: (gtk_icon_view_layout),
+       (gtk_icon_view_item_new), (gtk_icon_view_item_activated):
+       Fix a few bugs discovered while writing the demo.
+       
 2004-07-04  Anders Carlsson  <andersca@gnome.org>
 
        * gtk/Makefile.am:
index 68a94576a34a7198fb809775201d8a15f0e9cba9..e2550590743c750401fc2f18776304c9f96999b6 100644 (file)
@@ -1,3 +1,20 @@
+2004-07-04  Anders Carlsson  <andersca@gnome.org>
+
+       * demos/gtk-demo/Makefile.am:
+       * demos/gtk-demo/gnome-fs-directory.png:
+       * demos/gtk-demo/gnome-fs-regular.png:
+       * demos/gtk-demo/iconview.c: (load_pixbufs), (fill_store),
+       (sort_func), (create_store), (item_activated), (up_clicked),
+       (home_clicked), (do_iconview):
+       Add a simple file browser based on the icon view.
+       
+       * gtk/gtk.h:
+       Add gtk/gtkiconview.h
+       
+       * gtk/gtkiconview.c: (gtk_icon_view_layout),
+       (gtk_icon_view_item_new), (gtk_icon_view_item_activated):
+       Fix a few bugs discovered while writing the demo.
+       
 2004-07-04  Anders Carlsson  <andersca@gnome.org>
 
        * gtk/Makefile.am:
index c139feb3dadf9405f5c3149570e095b099dbc6b2..7557fb91bb7c70d487fb210d5dad8fa8fcf916ff 100644 (file)
@@ -15,6 +15,7 @@ demos =                                               \
        entry_completion.c                      \
        expander.c                              \
        hypertext.c                             \
+       iconview.c                              \
        images.c                                \
        list_store.c                            \
        menus.c                                 \
@@ -72,12 +73,14 @@ IMAGEFILES= alphatest.png           \
                floppybuddy.gif         \
                gnome-applets.png       \
                gnome-calendar.png      \
+               gnome-fs-directory.png  \
+               gnome-fs-regular.png    \
                gnome-foot.png          \
                gnome-gimp.png          \
                gnome-gmush.png         \
                gnome-gsame.png         \
                gnu-keys.png            \
-               gtk-logo-rgb.gif
+               gtk-logo-rgb.gif                
 
 democode_DATA = $(demos) $(IMAGEFILES)
 
diff --git a/demos/gtk-demo/gnome-fs-directory.png b/demos/gtk-demo/gnome-fs-directory.png
new file mode 100644 (file)
index 0000000..05921a6
Binary files /dev/null and b/demos/gtk-demo/gnome-fs-directory.png differ
diff --git a/demos/gtk-demo/gnome-fs-regular.png b/demos/gtk-demo/gnome-fs-regular.png
new file mode 100644 (file)
index 0000000..0f5019c
Binary files /dev/null and b/demos/gtk-demo/gnome-fs-regular.png differ
diff --git a/demos/gtk-demo/iconview.c b/demos/gtk-demo/iconview.c
new file mode 100644 (file)
index 0000000..56e74da
--- /dev/null
@@ -0,0 +1,358 @@
+/* Icon View
+ *
+ * The GtkIconView widget is used to display and manipulate icons.  It
+ * uses a GtkTreeModel for data storage, so the list store example
+ * might be helpful.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include "demo-common.h"
+
+static GtkWidget *window = NULL;
+
+#define FOLDER_NAME "gnome-fs-directory.png"
+#define FILE_NAME "gnome-fs-regular.png"
+
+enum
+{
+  COL_PATH,
+  COL_DISPLAY_NAME,
+  COL_PIXBUF,
+  COL_IS_DIRECTORY,
+  NUM_COLS
+};
+
+
+static GdkPixbuf *file_pixbuf, *folder_pixbuf;
+gchar *parent;
+GtkToolItem *up_button;
+
+/* Loads the images for the demo and returns whether the operation succeeded */
+static gboolean
+load_pixbufs (GError **error)
+{
+  char *filename;
+
+  if (file_pixbuf)
+    return TRUE; /* already loaded earlier */
+
+  /* demo_find_file() looks in the the current directory first,
+   * so you can run gtk-demo without installing GTK, then looks
+   * in the location where the file is installed.
+   */
+  filename = demo_find_file (FILE_NAME, error);
+  if (!filename)
+    return FALSE; /* note that "error" was filled in and returned */
+
+  file_pixbuf = gdk_pixbuf_new_from_file (filename, error);
+  g_free (filename);
+  
+  if (!file_pixbuf)
+    return FALSE; /* Note that "error" was filled with a GError */
+  
+  filename = demo_find_file (FOLDER_NAME, error);
+  if (!filename)
+    return FALSE; /* note that "error" was filled in and returned */
+
+  folder_pixbuf = gdk_pixbuf_new_from_file (filename, error);
+  g_free (filename);
+
+  return TRUE;
+}
+
+static void
+fill_store (GtkListStore *store)
+{
+  GDir *dir;
+  const gchar *name;
+  GtkTreeIter iter;
+  
+  /* First clear the store */
+  gtk_list_store_clear (store);
+
+  /* Now go through the directory and extract all the file
+   * information */
+  dir = g_dir_open (parent, 0, NULL);
+  if (!dir)
+    return;
+
+  name = g_dir_read_name (dir);
+  while (name != NULL)
+    {
+      gchar *path, *display_name;
+      gboolean is_dir;
+      
+      /* We ignore hidden files that start with a '.' */
+      if (name[0] != '.')
+       {
+         path = g_build_filename (parent, name, NULL);
+
+         is_dir = g_file_test (path, G_FILE_TEST_IS_DIR);
+         
+         display_name = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
+
+         gtk_list_store_append (store, &iter);
+         gtk_list_store_set (store, &iter,
+                             COL_PATH, path,
+                             COL_DISPLAY_NAME, display_name,
+                             COL_IS_DIRECTORY, is_dir,
+                             COL_PIXBUF, is_dir ? folder_pixbuf : file_pixbuf,
+                             -1);
+         g_free (path);
+         g_free (display_name);
+       }
+
+      name = g_dir_read_name (dir);      
+    }
+}
+
+static gint
+sort_func (GtkTreeModel *model,
+          GtkTreeIter  *a,
+          GtkTreeIter  *b,
+          gpointer      user_data)
+{
+  gboolean is_dir_a, is_dir_b;
+  gchar *name_a, *name_b;
+  int ret;
+
+  /* We need this function because we want to sort
+   * folders before files.
+   */
+
+  
+  gtk_tree_model_get (model, a,
+                     COL_IS_DIRECTORY, &is_dir_a,
+                     COL_DISPLAY_NAME, &name_a,
+                     -1);
+
+  gtk_tree_model_get (model, b,
+                     COL_IS_DIRECTORY, &is_dir_b,
+                     COL_DISPLAY_NAME, &name_b,
+                     -1);
+
+  if (!is_dir_a && is_dir_b)
+    ret = 1;
+  else if (is_dir_a && !is_dir_b)
+    ret = -1;
+  else
+    {
+      ret = g_utf8_collate (name_a, name_b);
+    }
+
+  g_free (name_a);
+  g_free (name_b);
+
+  return ret;
+}
+
+GtkListStore *
+create_store (void)
+{
+  GtkListStore *store;
+
+  store = gtk_list_store_new (NUM_COLS,
+                             G_TYPE_STRING, 
+                             G_TYPE_STRING, 
+                             GDK_TYPE_PIXBUF,
+                             G_TYPE_BOOLEAN);
+
+  /* Set sort column and function */ 
+  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store),
+                                          sort_func,
+                                          NULL, NULL);
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
+                                       GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+                                       GTK_SORT_ASCENDING);
+
+  return store;
+}
+
+static void
+item_activated (GtkIconView *icon_view,
+               GtkTreePath *tree_path,
+               gpointer     user_data)
+{
+  GtkListStore *store;
+  gchar *path;
+  GtkTreeIter iter;
+  gboolean is_dir;
+  
+  store = GTK_LIST_STORE (user_data);
+
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (store),
+                          &iter, tree_path);
+  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+                     COL_PATH, &path,
+                     COL_IS_DIRECTORY, &is_dir,
+                     -1);
+
+  if (!is_dir)
+    {
+      g_free (path);
+      return;
+    }
+  
+  /* Replace parent with path and re-fill the model*/
+  g_free (parent);
+  parent = path;
+
+  fill_store (store);
+
+  /* Sensitize the up button */
+  gtk_widget_set_sensitive (GTK_WIDGET (up_button), TRUE);
+}
+
+static void
+up_clicked (GtkToolItem *item,
+           gpointer     user_data)
+{
+  GtkListStore *store;
+  gchar *dir_name;
+
+  store = GTK_LIST_STORE (user_data);
+
+  dir_name = g_path_get_dirname (parent);
+  g_free (parent);
+  
+  parent = dir_name;
+
+  fill_store (store);
+
+  /* Maybe de-sensitize the up button */
+  gtk_widget_set_sensitive (GTK_WIDGET (up_button),
+                           strcmp (parent, "/") != 0);
+}
+
+static void
+home_clicked (GtkToolItem *item,
+             gpointer     user_data)
+{
+  GtkListStore *store;
+
+  store = GTK_LIST_STORE (user_data);
+
+  g_free (parent);
+  parent = g_strdup (g_get_home_dir ());
+
+  fill_store (store);
+
+  /* Sensitize the up button */
+  gtk_widget_set_sensitive (GTK_WIDGET (up_button),
+                           TRUE);
+}
+
+GtkWidget *
+do_iconview (GtkWidget *do_widget)
+{
+  if (!window)
+    {
+      GError *error;
+            
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_window_set_default_size (GTK_WINDOW (window), 650, 400);
+      
+      gtk_window_set_screen (GTK_WINDOW (window),
+                            gtk_widget_get_screen (do_widget));
+      gtk_window_set_title (GTK_WINDOW (window), "GtkIconView demo");
+
+      g_signal_connect (window, "destroy",
+                       G_CALLBACK (gtk_widget_destroyed), &window);
+
+      error = NULL;
+      if (!load_pixbufs (&error))
+       {
+         GtkWidget *dialog;
+
+         dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                          GTK_DIALOG_DESTROY_WITH_PARENT,
+                                          GTK_MESSAGE_ERROR,
+                                          GTK_BUTTONS_CLOSE,
+                                          "Failed to load an image: %s",
+                                          error->message);
+
+         g_error_free (error);
+
+         g_signal_connect (dialog, "response",
+                           G_CALLBACK (gtk_widget_destroy), NULL);
+
+         gtk_widget_show (dialog);
+       }
+      else
+       {
+         GtkWidget *sw;
+         GtkWidget *icon_view;
+         GtkListStore *store;
+         GtkWidget *vbox;
+         GtkWidget *tool_bar;
+         GtkToolItem *home_button;
+         
+         vbox = gtk_vbox_new (FALSE, 0);
+         gtk_container_add (GTK_CONTAINER (window), vbox);
+
+         tool_bar = gtk_toolbar_new ();
+         gtk_box_pack_start (GTK_BOX (vbox), tool_bar, FALSE, FALSE, 0);
+         
+         up_button = gtk_tool_button_new_from_stock (GTK_STOCK_GO_UP);
+         gtk_tool_item_set_is_important (up_button, TRUE);
+         gtk_widget_set_sensitive (GTK_WIDGET (up_button), FALSE);
+         gtk_toolbar_insert (GTK_TOOLBAR (tool_bar), up_button, -1);
+
+         home_button = gtk_tool_button_new_from_stock (GTK_STOCK_HOME);
+         gtk_tool_item_set_is_important (home_button, TRUE);
+         gtk_toolbar_insert (GTK_TOOLBAR (tool_bar), home_button, -1);
+         
+         
+         sw = gtk_scrolled_window_new (NULL, NULL);
+         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
+                                              GTK_SHADOW_ETCHED_IN);
+         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+                                         GTK_POLICY_AUTOMATIC,
+                                         GTK_POLICY_AUTOMATIC);
+         
+         gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
+         
+         /* Create the store and fill it with the contents of '/' */
+         parent = g_strdup ("/");
+         store = create_store ();
+         fill_store (store);
+
+         icon_view = gtk_icon_view_new_with_model (GTK_TREE_MODEL (store));
+         g_object_unref (store);
+         
+         /* Connect to the "clicked" signal of the "Up" tool button */
+         g_signal_connect (up_button, "clicked",
+                           G_CALLBACK (up_clicked), store);
+
+         /* Connect to the "clicked" signal of the "Home" tool button */
+         g_signal_connect (home_button, "clicked",
+                           G_CALLBACK (home_clicked), store);
+         
+         /* We now set which model columns that correspont to the text
+          * and pixbuf of each item
+          */
+         gtk_icon_view_set_text_column (GTK_ICON_VIEW (icon_view), COL_DISPLAY_NAME);
+         gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icon_view), COL_PIXBUF);
+
+         /* Connect to the "item_activated" signal */
+         g_signal_connect (icon_view, "item_activated",
+                           G_CALLBACK (item_activated), store);
+         gtk_container_add (GTK_CONTAINER (sw), icon_view);
+
+         gtk_widget_grab_focus (icon_view);
+       }
+    }
+  
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show_all (window);
+  else
+    {
+      gtk_widget_destroy (window);
+      window = NULL;
+    }
+
+  return window;
+}
+
index b8482520147a3f216401cd73f9df7e32efbffac3..5b7dcfb3e1898e881bde15998934a60d6753833a 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -92,6 +92,7 @@
 #include <gtk/gtkhseparator.h>
 #include <gtk/gtkiconfactory.h>
 #include <gtk/gtkicontheme.h>
+#include <gtk/gtkiconview.h>
 #include <gtk/gtkimage.h>
 #include <gtk/gtkimagemenuitem.h>
 #include <gtk/gtkimcontext.h>
index 8ac72d48bf8320f87028534801556711fef3a283..a7b83b052c4535d13ba88dc08167cf0cda2dcbf0 100644 (file)
@@ -47,8 +47,6 @@
 
 typedef struct 
 {
-  gint ref_count;
-
   GtkTreeIter iter;
   int index;
   
@@ -1476,7 +1474,10 @@ gtk_icon_view_layout (GtkIconView *icon_view)
   GList *icons;
   GtkWidget *widget;
   gint row;
-  
+
+  if (!VALID_MODEL_AND_COLUMNS (icon_view))
+    return;
+
   widget = GTK_WIDGET (icon_view);
   icons = icon_view->priv->items;
 
@@ -1824,7 +1825,6 @@ gtk_icon_view_item_new (void)
 
   item = g_new0 (GtkIconViewItem, 1);
 
-  item->ref_count = 1;
   item->width = -1;
   item->height = -1;
   
@@ -3146,6 +3146,8 @@ gtk_icon_view_get_selected_items (GtkIconView *icon_view)
  * 
  * Selects all the icons. @icon_view must has its selection mode set
  * to #GTK_SELECTION_MULTIPLE.
+ *
+ * Since: 2.6
  **/
 void
 gtk_icon_view_select_all (GtkIconView *icon_view)
@@ -3179,6 +3181,8 @@ gtk_icon_view_select_all (GtkIconView *icon_view)
  * @icon_view: A #GtkIconView.
  * 
  * Unselects all the icons.
+ *
+ * Since: 2.6
  **/
 void
 gtk_icon_view_unselect_all (GtkIconView *icon_view)
@@ -3202,6 +3206,8 @@ gtk_icon_view_unselect_all (GtkIconView *icon_view)
  * selected. If @icon does not point to a valid location, %FALSE is returned.
  * 
  * Return value: %TRUE if @path is selected.
+ *
+ * Since: 2.6
  **/
 gboolean
 gtk_icon_view_path_is_selected (GtkIconView *icon_view,
@@ -3228,10 +3234,15 @@ gtk_icon_view_path_is_selected (GtkIconView *icon_view,
  * @path: The #GtkTreePath to be activated
  * 
  * Activates the item determined by @path.
+ *
+ * Since: 2.6
  **/
 void
 gtk_icon_view_item_activated (GtkIconView      *icon_view,
                              GtkTreePath      *path)
 {
+  g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
+  g_return_if_fail (path != NULL);
+  
   g_signal_emit (G_OBJECT (icon_view), icon_view_signals[ITEM_ACTIVATED], 0, path);
 }