diff options
author | Havoc Pennington <hp@src.gnome.org> | 2001-05-25 21:56:34 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2001-05-25 21:56:34 +0000 |
commit | fe14698f7fcd99426cf1a1b4e0e07404430e9b37 (patch) | |
tree | 92f58a1d6f174f2e93161c78fcc9af9ec477c96c | |
parent | 87684f9549a8ea4e2fa7b4c6ab69ded73b34b991 (diff) | |
download | gdk-pixbuf-fe14698f7fcd99426cf1a1b4e0e07404430e9b37.tar.gz |
forgot to add stock_browser.c
-rw-r--r-- | demos/gtk-demo/stock_browser.c | 516 |
1 files changed, 516 insertions, 0 deletions
diff --git a/demos/gtk-demo/stock_browser.c b/demos/gtk-demo/stock_browser.c new file mode 100644 index 000000000..e48c21611 --- /dev/null +++ b/demos/gtk-demo/stock_browser.c @@ -0,0 +1,516 @@ +/* Stock Item/Icon Browser + * + * This source code for this demo doesn't demonstrate anything + * particularly useful in applications, it just lets you scan the + * available stock icons and stock items. + */ + +#include <gtk/gtk.h> + +static GtkWidget *window = NULL; + +typedef struct _StockItemInfo StockItemInfo; +struct _StockItemInfo +{ + gchar *id; + GtkStockItem item; + GdkPixbuf *small_icon; + gchar *macro; + gchar *accel_str; +}; + +/* Make StockItemInfo a boxed type so we can automatically + * manage memory + */ +#define STOCK_ITEM_INFO_TYPE stock_item_info_get_type () + +static void +stock_item_info_free (StockItemInfo *info) +{ + g_free (info->id); + g_free (info->macro); + g_free (info->accel_str); + if (info->small_icon) + g_object_unref (G_OBJECT (info->small_icon)); + + g_free (info); +} + +static StockItemInfo* +stock_item_info_copy (StockItemInfo *src) +{ + StockItemInfo *info; + + info = g_new (StockItemInfo, 1); + info->id = g_strdup (src->id); + info->macro = g_strdup (src->macro); + info->accel_str = g_strdup (src->accel_str); + + info->item = src->item; + + info->small_icon = src->small_icon; + if (info->small_icon) + g_object_ref (G_OBJECT (info->small_icon)); + + return info; +} + +static GType +stock_item_info_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static ("StockItemInfo", + NULL, + (GBoxedCopyFunc) stock_item_info_copy, + (GBoxedFreeFunc) stock_item_info_free, + FALSE); + + return our_type; +} + +typedef struct _StockItemDisplay StockItemDisplay; +struct _StockItemDisplay +{ + GtkWidget *type_label; + GtkWidget *macro_label; + GtkWidget *id_label; + GtkWidget *label_accel_label; + GtkWidget *icon_image; +}; + +/* columns in the tree model */ +enum { + COLUMN_ICON_MACRO, + COLUMN_LABEL, + COLUMN_ACCEL, + COLUMN_ID +}; + +static gchar* +id_to_macro (const gchar *id) +{ + GString *macro; + const gchar *cp; + gchar *p; + + /* gtk-foo -> GTK_STOCK_FOO */ + + cp = id; + while (*cp && *cp != '-') + ++cp; + + if (*cp == '\0') + return g_strdup ("??UNKNOWN??"); + + macro = g_string_new (NULL); + + g_string_append_len (macro, id, cp - id); + + g_string_append (macro, "_STOCK"); + g_string_append (macro, cp); + + p = macro->str; + while (*p) + { + if (*p == '-') + *p = '_'; + ++p; + } + + g_strup (macro->str); + + return g_string_free (macro, FALSE); +} + +static GtkTreeModel* +create_model (void) +{ + GtkListStore *store; + GSList *ids; + GSList *tmp_list; + + store = gtk_list_store_new_with_types (1, STOCK_ITEM_INFO_TYPE); + + ids = gtk_stock_list_ids (); + tmp_list = ids; + while (tmp_list != NULL) + { + StockItemInfo info; + GtkStockItem item; + GtkTreeIter iter; + GtkIconSet *icon_set; + + info.id = tmp_list->data; + + if (gtk_stock_lookup (info.id, &item)) + { + info.item = item; + } + else + { + info.item.label = NULL; + info.item.stock_id = NULL; + info.item.modifier = 0; + info.item.keyval = 0; + info.item.translation_domain = NULL; + } + + /* only show icons for stock IDs that have default icons */ + icon_set = gtk_icon_factory_lookup_default (info.id); + if (icon_set) + { + GtkIconSize *sizes = NULL; + gint n_sizes = 0; + gint i; + GtkIconSize size; + + /* See what sizes this stock icon really exists at */ + gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes); + + /* Use menu size if it exists, otherwise first size found */ + size = sizes[0]; + i = 0; + while (i < n_sizes) + { + if (sizes[i] == GTK_ICON_SIZE_MENU) + { + size = GTK_ICON_SIZE_MENU; + break; + } + ++i; + } + g_free (sizes); + + info.small_icon = gtk_widget_render_icon (window, info.id, + size, + NULL); + + if (size != GTK_ICON_SIZE_MENU) + { + /* Make the result the proper size for our thumbnail */ + gint w, h; + GdkPixbuf *scaled; + + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h); + + scaled = gdk_pixbuf_scale_simple (info.small_icon, + w, h, + GDK_INTERP_BILINEAR); + + g_object_unref (G_OBJECT (info.small_icon)); + info.small_icon = scaled; + } + } + else + info.small_icon = NULL; + + if (info.item.keyval != 0) + { + info.accel_str = gtk_accelerator_name (info.item.keyval, + info.item.modifier); + } + else + { + info.accel_str = g_strdup (""); + } + + info.macro = id_to_macro (info.id); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, &info, -1); + + g_free (info.macro); + g_free (info.accel_str); + if (info.small_icon) + g_object_unref (G_OBJECT (info.small_icon)); + + tmp_list = g_slist_next (tmp_list); + } + + g_slist_foreach (ids, (GFunc)g_free, NULL); + g_slist_free (ids); + + return GTK_TREE_MODEL (store); +} + +static void +selection_changed (GtkTreeSelection *selection) +{ + GtkTreeView *treeview; + StockItemDisplay *display; + GtkTreeModel *model; + GtkTreeIter iter; + + treeview = gtk_tree_selection_get_tree_view (selection); + display = g_object_get_data (G_OBJECT (treeview), "stock-display"); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + StockItemInfo *info; + gchar *str; + + gtk_tree_model_get (model, &iter, + 0, &info, + -1); + + if (info->small_icon && info->item.label) + gtk_label_set_text (GTK_LABEL (display->type_label), "Icon and Item"); + else if (info->small_icon) + gtk_label_set_text (GTK_LABEL (display->type_label), "Icon Only"); + else if (info->item.label) + gtk_label_set_text (GTK_LABEL (display->type_label), "Item Only"); + else + gtk_label_set_text (GTK_LABEL (display->type_label), "???????"); + + gtk_label_set_text (GTK_LABEL (display->macro_label), info->macro); + gtk_label_set_text (GTK_LABEL (display->id_label), info->id); + + if (info->item.label) + { + str = g_strdup_printf ("%s %s", info->item.label, info->accel_str); + gtk_label_set_text_with_mnemonic (GTK_LABEL (display->label_accel_label), str); + g_free (str); + } + else + { + gtk_label_set_text (GTK_LABEL (display->label_accel_label), ""); + } + + /* The problem here is that some icons don't have SIZE_LARGE_TOOLBAR, + * so we get a "missing image" icon... + */ + if (info->small_icon) + gtk_image_set_from_stock (GTK_IMAGE (display->icon_image), info->id, + GTK_ICON_SIZE_LARGE_TOOLBAR); + else + gtk_image_set_from_pixbuf (GTK_IMAGE (display->icon_image), NULL); + + stock_item_info_free (info); + } + else + { + gtk_label_set_text (GTK_LABEL (display->type_label), "No selected item"); + gtk_label_set_text (GTK_LABEL (display->macro_label), ""); + gtk_label_set_text (GTK_LABEL (display->id_label), ""); + gtk_label_set_text (GTK_LABEL (display->label_accel_label), ""); + gtk_image_set_from_pixbuf (GTK_IMAGE (display->icon_image), NULL); + } +} + +static void +macro_set_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + StockItemInfo *info; + + gtk_tree_model_get (model, iter, + 0, &info, + -1); + + g_object_set (GTK_CELL_RENDERER (cell), + "text", info->macro, + "pixbuf", info->small_icon, + NULL); + + stock_item_info_free (info); +} + +static void +id_set_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + StockItemInfo *info; + + gtk_tree_model_get (model, iter, + 0, &info, + -1); + + g_object_set (GTK_CELL_RENDERER (cell), + "text", info->id, + NULL); + + stock_item_info_free (info); +} + +static void +accel_set_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + StockItemInfo *info; + + gtk_tree_model_get (model, iter, + 0, &info, + -1); + + g_object_set (GTK_CELL_RENDERER (cell), + "text", info->accel_str, + NULL); + + stock_item_info_free (info); +} + +static void +label_set_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + StockItemInfo *info; + + gtk_tree_model_get (model, iter, + 0, &info, + -1); + + g_object_set (GTK_CELL_RENDERER (cell), + "text", info->item.label, + NULL); + + stock_item_info_free (info); +} + +GtkWidget * +do_stock_browser (void) +{ + if (!window) + { + GtkWidget *frame; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *sw; + GtkWidget *treeview; + GtkWidget *align; + GtkTreeModel *model; + GtkCellRenderer *cell_renderer; + StockItemDisplay *display; + GtkTreeSelection *selection; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "Stock Icons and Items"); + + gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window); + gtk_container_set_border_width (GTK_CONTAINER (window), 8); + + hbox = gtk_hbox_new (FALSE, 8); + gtk_container_add (GTK_CONTAINER (window), hbox); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (hbox), sw, FALSE, FALSE, 0); + + model = create_model (); + + treeview = gtk_tree_view_new_with_model (model); + + g_object_unref (G_OBJECT (model)); + + gtk_container_add (GTK_CONTAINER (sw), treeview); + + cell_renderer = gtk_cell_renderer_text_pixbuf_new (); + + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview), + -1, + "Macro", + cell_renderer, + macro_set_func, + NULL, + NULL); + g_object_unref (G_OBJECT (cell_renderer)); + + cell_renderer = gtk_cell_renderer_text_new (); + + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview), + -1, + "Label", + cell_renderer, + label_set_func, + NULL, + NULL); + + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview), + -1, + "Accel", + cell_renderer, + accel_set_func, + NULL, + NULL); + + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview), + -1, + "ID", + cell_renderer, + id_set_func, + NULL, + NULL); + + g_object_unref (G_OBJECT (cell_renderer)); + + align = gtk_alignment_new (0.5, 0.0, 0.0, 0.0); + gtk_box_pack_end (GTK_BOX (hbox), align, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Selected Item"); + gtk_container_add (GTK_CONTAINER (align), frame); + + vbox = gtk_vbox_new (FALSE, 8); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_container_add (GTK_CONTAINER (frame), vbox); + + display = g_new (StockItemDisplay, 1); + g_object_set_data_full (G_OBJECT (treeview), + "stock-display", + display, + g_free); /* free display with treeview */ + + display->type_label = gtk_label_new (NULL); + display->macro_label = gtk_label_new (NULL); + display->id_label = gtk_label_new (NULL); + display->label_accel_label = gtk_label_new (NULL); + display->icon_image = gtk_image_new_from_pixbuf (NULL); /* empty image */ + + gtk_box_pack_start (GTK_BOX (vbox), display->type_label, + FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (vbox), display->icon_image, + FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (vbox), display->label_accel_label, + FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), display->macro_label, + FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), display->id_label, + FALSE, FALSE, 0); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_set_mode (selection, GTK_TREE_SELECTION_SINGLE); + + g_signal_connect_data (G_OBJECT (selection), + "selection_changed", + G_CALLBACK (selection_changed), + NULL, NULL, FALSE, FALSE); + } + + if (!GTK_WIDGET_VISIBLE (window)) + { + gtk_widget_show_all (window); + } + else + { + gtk_widget_destroy (window); + window = NULL; + } + + return window; +} |