1 /* Stock Item and Icon Browser
3 * This source code for this demo doesn't demonstrate anything
4 * particularly useful in applications. The purpose of the "demo" is
5 * just to provide a handy place to browse the available stock icons
13 static GtkWidget *window = NULL;
15 typedef struct _StockItemInfo StockItemInfo;
20 GdkPixbuf *small_icon;
25 /* Make StockItemInfo a boxed type so we can automatically
28 #define STOCK_ITEM_INFO_TYPE stock_item_info_get_type ()
31 stock_item_info_free (StockItemInfo *info)
35 g_free (info->accel_str);
37 g_object_unref (info->small_icon);
43 stock_item_info_copy (StockItemInfo *src)
47 info = g_new (StockItemInfo, 1);
48 info->id = g_strdup (src->id);
49 info->macro = g_strdup (src->macro);
50 info->accel_str = g_strdup (src->accel_str);
52 info->item = src->item;
54 info->small_icon = src->small_icon;
56 g_object_ref (info->small_icon);
62 G_DEFINE_BOXED_TYPE (StockItemInfo, stock_item_info,
66 typedef struct _StockItemDisplay StockItemDisplay;
67 struct _StockItemDisplay
69 GtkWidget *type_label;
70 GtkWidget *macro_label;
72 GtkWidget *label_accel_label;
73 GtkWidget *icon_image;
77 id_to_macro (const gchar *id)
79 GString *macro = NULL;
82 /* gtk-foo-bar -> GTK_STOCK_FOO_BAR */
84 macro = g_string_new (NULL);
88 if (strncmp (cp, "gtk-", 4) == 0)
90 g_string_append (macro, "GTK_STOCK_");
97 g_string_append_c (macro, '_');
98 else if (g_ascii_islower (*cp))
99 g_string_append_c (macro, g_ascii_toupper (*cp));
101 g_string_append_c (macro, *cp);
106 return g_string_free (macro, FALSE);
116 store = gtk_list_store_new (2, STOCK_ITEM_INFO_TYPE, G_TYPE_STRING);
118 ids = gtk_stock_list_ids ();
119 ids = g_slist_sort (ids, (GCompareFunc) strcmp);
121 while (tmp_list != NULL)
126 GtkIconSet *icon_set;
128 info.id = tmp_list->data;
130 if (gtk_stock_lookup (info.id, &item))
136 info.item.label = NULL;
137 info.item.stock_id = NULL;
138 info.item.modifier = 0;
139 info.item.keyval = 0;
140 info.item.translation_domain = NULL;
143 /* only show icons for stock IDs that have default icons */
144 icon_set = gtk_icon_factory_lookup_default (info.id);
147 GtkIconSize *sizes = NULL;
152 /* See what sizes this stock icon really exists at */
153 gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
155 /* Use menu size if it exists, otherwise first size found */
160 if (sizes[i] == GTK_ICON_SIZE_MENU)
162 size = GTK_ICON_SIZE_MENU;
169 info.small_icon = gtk_widget_render_icon (window, info.id,
173 if (size != GTK_ICON_SIZE_MENU)
175 /* Make the result the proper size for our thumbnail */
179 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
181 scaled = gdk_pixbuf_scale_simple (info.small_icon,
183 GDK_INTERP_BILINEAR);
185 g_object_unref (info.small_icon);
186 info.small_icon = scaled;
190 info.small_icon = NULL;
192 if (info.item.keyval != 0)
194 info.accel_str = gtk_accelerator_name (info.item.keyval,
199 info.accel_str = g_strdup ("");
202 info.macro = id_to_macro (info.id);
204 gtk_list_store_append (store, &iter);
205 gtk_list_store_set (store, &iter, 0, &info, 1, info.id, -1);
208 g_free (info.accel_str);
210 g_object_unref (info.small_icon);
212 tmp_list = g_slist_next (tmp_list);
215 g_slist_foreach (ids, (GFunc)g_free, NULL);
218 return GTK_TREE_MODEL (store);
221 /* Finds the largest size at which the given image stock id is
222 * available. This would not be useful for a normal application
225 get_largest_size (const char *id)
227 GtkIconSet *set = gtk_icon_factory_lookup_default (id);
230 GtkIconSize best_size = GTK_ICON_SIZE_INVALID;
231 gint best_pixels = 0;
233 gtk_icon_set_get_sizes (set, &sizes, &n_sizes);
235 for (i = 0; i < n_sizes; i++)
239 gtk_icon_size_lookup (sizes[i], &width, &height);
241 if (width * height > best_pixels)
243 best_size = sizes[i];
244 best_pixels = width * height;
254 selection_changed (GtkTreeSelection *selection)
256 GtkTreeView *treeview;
257 StockItemDisplay *display;
261 treeview = gtk_tree_selection_get_tree_view (selection);
262 display = g_object_get_data (G_OBJECT (treeview), "stock-display");
264 if (gtk_tree_selection_get_selected (selection, &model, &iter))
269 gtk_tree_model_get (model, &iter,
273 if (info->small_icon && info->item.label)
274 gtk_label_set_text (GTK_LABEL (display->type_label), "Icon and Item");
275 else if (info->small_icon)
276 gtk_label_set_text (GTK_LABEL (display->type_label), "Icon Only");
277 else if (info->item.label)
278 gtk_label_set_text (GTK_LABEL (display->type_label), "Item Only");
280 gtk_label_set_text (GTK_LABEL (display->type_label), "???????");
282 gtk_label_set_text (GTK_LABEL (display->macro_label), info->macro);
283 gtk_label_set_text (GTK_LABEL (display->id_label), info->id);
285 if (info->item.label)
287 str = g_strdup_printf ("%s %s", info->item.label, info->accel_str);
288 gtk_label_set_text_with_mnemonic (GTK_LABEL (display->label_accel_label), str);
293 gtk_label_set_text (GTK_LABEL (display->label_accel_label), "");
296 if (info->small_icon)
297 gtk_image_set_from_stock (GTK_IMAGE (display->icon_image), info->id,
298 get_largest_size (info->id));
300 gtk_image_set_from_pixbuf (GTK_IMAGE (display->icon_image), NULL);
302 stock_item_info_free (info);
306 gtk_label_set_text (GTK_LABEL (display->type_label), "No selected item");
307 gtk_label_set_text (GTK_LABEL (display->macro_label), "");
308 gtk_label_set_text (GTK_LABEL (display->id_label), "");
309 gtk_label_set_text (GTK_LABEL (display->label_accel_label), "");
310 gtk_image_set_from_pixbuf (GTK_IMAGE (display->icon_image), NULL);
315 macro_set_func_text (GtkTreeViewColumn *tree_column,
316 GtkCellRenderer *cell,
323 gtk_tree_model_get (model, iter,
327 g_object_set (GTK_CELL_RENDERER (cell),
331 stock_item_info_free (info);
335 id_set_func (GtkTreeViewColumn *tree_column,
336 GtkCellRenderer *cell,
343 gtk_tree_model_get (model, iter,
347 g_object_set (GTK_CELL_RENDERER (cell),
351 stock_item_info_free (info);
355 accel_set_func (GtkTreeViewColumn *tree_column,
356 GtkCellRenderer *cell,
363 gtk_tree_model_get (model, iter,
367 g_object_set (GTK_CELL_RENDERER (cell),
368 "text", info->accel_str,
371 stock_item_info_free (info);
375 label_set_func (GtkTreeViewColumn *tree_column,
376 GtkCellRenderer *cell,
383 gtk_tree_model_get (model, iter,
387 g_object_set (GTK_CELL_RENDERER (cell),
388 "text", info->item.label,
391 stock_item_info_free (info);
395 do_stock_browser (GtkWidget *do_widget)
406 GtkCellRenderer *cell_renderer;
407 StockItemDisplay *display;
408 GtkTreeSelection *selection;
409 GtkTreeViewColumn *column;
411 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
412 gtk_window_set_screen (GTK_WINDOW (window),
413 gtk_widget_get_screen (do_widget));
414 gtk_window_set_title (GTK_WINDOW (window), "Stock Icons and Items");
415 gtk_window_set_default_size (GTK_WINDOW (window), -1, 500);
417 g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
418 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
420 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 8);
421 gtk_container_add (GTK_CONTAINER (window), hbox);
423 sw = gtk_scrolled_window_new (NULL, NULL);
424 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
426 GTK_POLICY_AUTOMATIC);
427 gtk_box_pack_start (GTK_BOX (hbox), sw, FALSE, FALSE, 0);
429 model = create_model ();
431 treeview = gtk_tree_view_new_with_model (model);
433 g_object_unref (model);
435 gtk_container_add (GTK_CONTAINER (sw), treeview);
437 column = gtk_tree_view_column_new ();
438 gtk_tree_view_column_set_title (column, "Macro");
440 cell_renderer = gtk_cell_renderer_pixbuf_new ();
441 gtk_tree_view_column_pack_start (column,
444 gtk_tree_view_column_set_attributes (column, cell_renderer,
445 "stock_id", 1, NULL);
446 cell_renderer = gtk_cell_renderer_text_new ();
447 gtk_tree_view_column_pack_start (column,
450 gtk_tree_view_column_set_cell_data_func (column, cell_renderer,
451 macro_set_func_text, NULL, NULL);
453 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview),
456 cell_renderer = gtk_cell_renderer_text_new ();
457 gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
465 cell_renderer = gtk_cell_renderer_text_new ();
466 gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
474 cell_renderer = gtk_cell_renderer_text_new ();
475 gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
483 align = gtk_alignment_new (0.5, 0.0, 0.0, 0.0);
484 gtk_box_pack_end (GTK_BOX (hbox), align, FALSE, FALSE, 0);
486 frame = gtk_frame_new ("Selected Item");
487 gtk_container_add (GTK_CONTAINER (align), frame);
489 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 8);
490 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
491 gtk_container_add (GTK_CONTAINER (frame), vbox);
493 display = g_new (StockItemDisplay, 1);
494 g_object_set_data_full (G_OBJECT (treeview),
497 g_free); /* free display with treeview */
499 display->type_label = gtk_label_new (NULL);
500 display->macro_label = gtk_label_new (NULL);
501 display->id_label = gtk_label_new (NULL);
502 display->label_accel_label = gtk_label_new (NULL);
503 display->icon_image = gtk_image_new_from_pixbuf (NULL); /* empty image */
505 gtk_box_pack_start (GTK_BOX (vbox), display->type_label,
508 gtk_box_pack_start (GTK_BOX (vbox), display->icon_image,
511 gtk_box_pack_start (GTK_BOX (vbox), display->label_accel_label,
513 gtk_box_pack_start (GTK_BOX (vbox), display->macro_label,
515 gtk_box_pack_start (GTK_BOX (vbox), display->id_label,
518 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
519 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
521 g_signal_connect (selection,
523 G_CALLBACK (selection_changed),
527 if (!gtk_widget_get_visible (window))
529 gtk_widget_show_all (window);
533 gtk_widget_destroy (window);