📄 stock_browser.c
字号:
/* Stock Item and Icon Browser * * This source code for this demo doesn't demonstrate anything * particularly useful in applications. The purpose of the "demo" is * just to provide a handy place to browse the available stock icons * and stock items. */#include <string.h>#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 voidstock_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 (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 (info->small_icon); return info;}static GTypestock_item_info_get_type (void){ static GType our_type = 0; if (our_type == 0) our_type = g_boxed_type_register_static ("StockItemInfo", (GBoxedCopyFunc) stock_item_info_copy, (GBoxedFreeFunc) stock_item_info_free); 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;};static gchar*id_to_macro (const gchar *id){ GString *macro = NULL; const gchar *cp; /* gtk-foo-bar -> GTK_STOCK_FOO_BAR */ macro = g_string_new (NULL); cp = id; if (strncmp (cp, "gtk-", 4) == 0) { g_string_append (macro, "GTK_STOCK_"); cp += 4; } while (*cp) { if (*cp == '-') g_string_append_c (macro, '_'); else if (g_ascii_islower (*cp)) g_string_append_c (macro, g_ascii_toupper (*cp)); else g_string_append_c (macro, *cp); cp++; } return g_string_free (macro, FALSE);}static GtkTreeModel*create_model (void){ GtkListStore *store; GSList *ids; GSList *tmp_list; store = gtk_list_store_new (2, STOCK_ITEM_INFO_TYPE, G_TYPE_STRING); ids = gtk_stock_list_ids (); ids = g_slist_sort (ids, (GCompareFunc) strcmp); 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 (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, info.id, -1); g_free (info.macro); g_free (info.accel_str); if (info.small_icon) g_object_unref (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);}/* Finds the largest size at which the given image stock id is * available. This would not be useful for a normal application */static GtkIconSizeget_largest_size (const char *id){ GtkIconSet *set = gtk_icon_factory_lookup_default (id); GtkIconSize *sizes; gint n_sizes, i; GtkIconSize best_size = GTK_ICON_SIZE_INVALID; gint best_pixels = 0; gtk_icon_set_get_sizes (set, &sizes, &n_sizes); for (i = 0; i < n_sizes; i++) { gint width, height; gtk_icon_size_lookup (sizes[i], &width, &height); if (width * height > best_pixels) { best_size = sizes[i]; best_pixels = width * height; } } g_free (sizes); return best_size;}static voidselection_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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -