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 stock_item_info_get_type (void)
64 static GType our_type = 0;
67 our_type = g_boxed_type_register_static ("StockItemInfo",
68 (GBoxedCopyFunc) stock_item_info_copy,
69 (GBoxedFreeFunc) stock_item_info_free);
74 typedef struct _StockItemDisplay StockItemDisplay;
75 struct _StockItemDisplay
77 GtkWidget *type_label;
78 GtkWidget *macro_label;
80 GtkWidget *label_accel_label;
81 GtkWidget *icon_image;
85 id_to_macro (const gchar *id)
87 GString *macro = NULL;
90 /* gtk-foo-bar -> GTK_STOCK_FOO_BAR */
92 macro = g_string_new (NULL);
96 if (strncmp (cp, "gtk-", 4) == 0)
98 g_string_append (macro, "GTK_STOCK_");
105 g_string_append_c (macro, '_');
106 else if (g_ascii_islower (*cp))
107 g_string_append_c (macro, g_ascii_toupper (*cp));
109 g_string_append_c (macro, *cp);
114 return g_string_free (macro, FALSE);
124 store = gtk_list_store_new (2, STOCK_ITEM_INFO_TYPE, G_TYPE_STRING);
126 ids = gtk_stock_list_ids ();
127 ids = g_slist_sort (ids, (GCompareFunc) strcmp);
129 while (tmp_list != NULL)
134 GtkIconSet *icon_set;
136 info.id = tmp_list->data;
138 if (gtk_stock_lookup (info.id, &item))
144 info.item.label = NULL;
145 info.item.stock_id = NULL;
146 info.item.modifier = 0;
147 info.item.keyval = 0;
148 info.item.translation_domain = NULL;
151 /* only show icons for stock IDs that have default icons */
152 icon_set = gtk_icon_factory_lookup_default (info.id);
155 GtkIconSize *sizes = NULL;
160 /* See what sizes this stock icon really exists at */
161 gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
163 /* Use menu size if it exists, otherwise first size found */
168 if (sizes[i] == GTK_ICON_SIZE_MENU)
170 size = GTK_ICON_SIZE_MENU;
177 info.small_icon = gtk_widget_render_icon (window, info.id,
181 if (size != GTK_ICON_SIZE_MENU)
183 /* Make the result the proper size for our thumbnail */
187 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
189 scaled = gdk_pixbuf_scale_simple (info.small_icon,
191 GDK_INTERP_BILINEAR);
193 g_object_unref (info.small_icon);
194 info.small_icon = scaled;
198 info.small_icon = NULL;
200 if (info.item.keyval != 0)
202 info.accel_str = gtk_accelerator_name (info.item.keyval,
207 info.accel_str = g_strdup ("");
210 info.macro = id_to_macro (info.id);
212 gtk_list_store_append (store, &iter);
213 gtk_list_store_set (store, &iter, 0, &info, 1, info.id, -1);
216 g_free (info.accel_str);
218 g_object_unref (info.small_icon);
220 tmp_list = g_slist_next (tmp_list);
223 g_slist_foreach (ids, (GFunc)g_free, NULL);
226 return GTK_TREE_MODEL (store);
229 /* Finds the largest size at which the given image stock id is
230 * available. This would not be useful for a normal application
233 get_largest_size (const char *id)
235 GtkIconSet *set = gtk_icon_factory_lookup_default (id);
238 GtkIconSize best_size = GTK_ICON_SIZE_INVALID;
239 gint best_pixels = 0;
241 gtk_icon_set_get_sizes (set, &sizes, &n_sizes);
243 for (i = 0; i < n_sizes; i++)
247 gtk_icon_size_lookup (sizes[i], &width, &height);
249 if (width * height > best_pixels)
251 best_size = sizes[i];
252 best_pixels = width * height;
262 selection_changed (GtkTreeSelection *selection)
264 GtkTreeView *treeview;
265 StockItemDisplay *display;
269 treeview = gtk_tree_selection_get_tree_view (selection);
270 display = g_object_get_data (G_OBJECT (treeview), "stock-display");
272 if (gtk_tree_selection_get_selected (selection, &model, &iter))
277 gtk_tree_model_get (model, &iter,
281 if (info->small_icon && info->item.label)
282 gtk_label_set_text (GTK_LABEL (display->type_label), "Icon and Item");
283 else if (info->small_icon)
284 gtk_label_set_text (GTK_LABEL (display->type_label), "Icon Only");
285 else if (info->item.label)
286 gtk_label_set_text (GTK_LABEL (display->type_label), "Item Only");
288 gtk_label_set_text (GTK_LABEL (display->type_label), "???????");
290 gtk_label_set_text (GTK_LABEL (display->macro_label), info->macro);
291 gtk_label_set_text (GTK_LABEL (display->id_label), info->id);
293 if (info->item.label)
295 str = g_strdup_printf ("%s %s", info->item.label, info->accel_str);
296 gtk_label_set_text_with_mnemonic (GTK_LABEL (display->label_accel_label), str);
301 gtk_label_set_text (GTK_LABEL (display->label_accel_label), "");
304 if (info->small_icon)
305 gtk_image_set_from_stock (GTK_IMAGE (display->icon_image), info->id,
306 get_largest_size (info->id));
308 gtk_image_set_from_pixbuf (GTK_IMAGE (display->icon_image), NULL);
310 stock_item_info_free (info);
314 gtk_label_set_text (GTK_LABEL (display->type_label), "No selected item");
315 gtk_label_set_text (GTK_LABEL (display->macro_label), "");
316 gtk_label_set_text (GTK_LABEL (display->id_label), "");
317 gtk_label_set_text (GTK_LABEL (display->label_accel_label), "");
318 gtk_image_set_from_pixbuf (GTK_IMAGE (display->icon_image), NULL);
323 macro_set_func_text (GtkTreeViewColumn *tree_column,
324 GtkCellRenderer *cell,
331 gtk_tree_model_get (model, iter,
335 g_object_set (GTK_CELL_RENDERER (cell),
339 stock_item_info_free (info);
343 id_set_func (GtkTreeViewColumn *tree_column,
344 GtkCellRenderer *cell,
351 gtk_tree_model_get (model, iter,
355 g_object_set (GTK_CELL_RENDERER (cell),
359 stock_item_info_free (info);
363 accel_set_func (GtkTreeViewColumn *tree_column,
364 GtkCellRenderer *cell,
371 gtk_tree_model_get (model, iter,
375 g_object_set (GTK_CELL_RENDERER (cell),
376 "text", info->accel_str,
379 stock_item_info_free (info);
383 label_set_func (GtkTreeViewColumn *tree_column,
384 GtkCellRenderer *cell,
391 gtk_tree_model_get (model, iter,
395 g_object_set (GTK_CELL_RENDERER (cell),
396 "text", info->item.label,
399 stock_item_info_free (info);
403 do_stock_browser (void)
414 GtkCellRenderer *cell_renderer;
415 StockItemDisplay *display;
416 GtkTreeSelection *selection;
417 GtkTreeViewColumn *column;
419 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
420 gtk_window_set_title (GTK_WINDOW (window), "Stock Icons and Items");
421 gtk_window_set_default_size (GTK_WINDOW (window), -1, 500);
423 g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
424 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
426 hbox = gtk_hbox_new (FALSE, 8);
427 gtk_container_add (GTK_CONTAINER (window), hbox);
429 sw = gtk_scrolled_window_new (NULL, NULL);
430 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
432 GTK_POLICY_AUTOMATIC);
433 gtk_box_pack_start (GTK_BOX (hbox), sw, FALSE, FALSE, 0);
435 model = create_model ();
437 treeview = gtk_tree_view_new_with_model (model);
439 g_object_unref (model);
441 gtk_container_add (GTK_CONTAINER (sw), treeview);
443 column = gtk_tree_view_column_new ();
444 gtk_tree_view_column_set_title (column, "Macro");
446 cell_renderer = gtk_cell_renderer_pixbuf_new ();
447 gtk_tree_view_column_pack_start (column,
450 gtk_tree_view_column_set_attributes (column, cell_renderer,
451 "stock_id", 1, NULL);
452 cell_renderer = gtk_cell_renderer_text_new ();
453 gtk_tree_view_column_pack_start (column,
456 gtk_tree_view_column_set_cell_data_func (column, cell_renderer,
457 macro_set_func_text, NULL, NULL);
459 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview),
462 cell_renderer = gtk_cell_renderer_text_new ();
463 gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
471 cell_renderer = gtk_cell_renderer_text_new ();
472 gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
480 cell_renderer = gtk_cell_renderer_text_new ();
481 gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
489 align = gtk_alignment_new (0.5, 0.0, 0.0, 0.0);
490 gtk_box_pack_end (GTK_BOX (hbox), align, FALSE, FALSE, 0);
492 frame = gtk_frame_new ("Selected Item");
493 gtk_container_add (GTK_CONTAINER (align), frame);
495 vbox = gtk_vbox_new (FALSE, 8);
496 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
497 gtk_container_add (GTK_CONTAINER (frame), vbox);
499 display = g_new (StockItemDisplay, 1);
500 g_object_set_data_full (G_OBJECT (treeview),
503 g_free); /* free display with treeview */
505 display->type_label = gtk_label_new (NULL);
506 display->macro_label = gtk_label_new (NULL);
507 display->id_label = gtk_label_new (NULL);
508 display->label_accel_label = gtk_label_new (NULL);
509 display->icon_image = gtk_image_new_from_pixbuf (NULL); /* empty image */
511 gtk_box_pack_start (GTK_BOX (vbox), display->type_label,
514 gtk_box_pack_start (GTK_BOX (vbox), display->icon_image,
517 gtk_box_pack_start (GTK_BOX (vbox), display->label_accel_label,
519 gtk_box_pack_start (GTK_BOX (vbox), display->macro_label,
521 gtk_box_pack_start (GTK_BOX (vbox), display->id_label,
524 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
525 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
527 g_signal_connect (selection,
529 G_CALLBACK (selection_changed),
533 if (!GTK_WIDGET_VISIBLE (window))
535 gtk_widget_show_all (window);
539 gtk_widget_destroy (window);