home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / share / gtk-2.0 / demo / combobox.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-25  |  9.2 KB  |  372 lines

  1. /* Combo boxes 
  2.  *
  3.  * The ComboBox widget allows to select one option out of a list.
  4.  * The ComboBoxEntry additionally allows the user to enter a value
  5.  * that is not in the list of options. 
  6.  *
  7.  * How the options are displayed is controlled by cell renderers.
  8.  */
  9.  
  10. #include <gtk/gtk.h>
  11.  
  12. enum 
  13. {
  14.   PIXBUF_COL,
  15.   TEXT_COL
  16. };
  17.  
  18. static gchar *
  19. strip_underscore (const gchar *text)
  20. {
  21.   gchar *p, *q;
  22.   gchar *result;
  23.   
  24.   result = g_strdup (text);
  25.   p = q = result;
  26.   while (*p) 
  27.     {
  28.       if (*p != '_')
  29.     {
  30.       *q = *p;
  31.       q++;
  32.     }
  33.       p++;
  34.     }
  35.   *q = '\0';
  36.  
  37.   return result;
  38. }
  39.  
  40. static GtkTreeModel *
  41. create_stock_icon_store (void)
  42. {
  43.   gchar *stock_id[6] = {
  44.     GTK_STOCK_DIALOG_WARNING,
  45.     GTK_STOCK_STOP,
  46.     GTK_STOCK_NEW,
  47.     GTK_STOCK_CLEAR,
  48.     NULL,
  49.     GTK_STOCK_OPEN    
  50.   };
  51.  
  52.   GtkStockItem item;
  53.   GdkPixbuf *pixbuf;
  54.   GtkWidget *cellview;
  55.   GtkTreeIter iter;
  56.   GtkListStore *store;
  57.   gchar *label;
  58.   gint i;
  59.  
  60.   cellview = gtk_cell_view_new ();
  61.   
  62.   store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
  63.  
  64.   for (i = 0; i < G_N_ELEMENTS (stock_id); i++)
  65.     {
  66.       if (stock_id[i])
  67.     {
  68.       pixbuf = gtk_widget_render_icon (cellview, stock_id[i],
  69.                        GTK_ICON_SIZE_BUTTON, NULL);
  70.       gtk_stock_lookup (stock_id[i], &item);
  71.       label = strip_underscore (item.label);
  72.       gtk_list_store_append (store, &iter);
  73.       gtk_list_store_set (store, &iter,
  74.                   PIXBUF_COL, pixbuf,
  75.                   TEXT_COL, label,
  76.                   -1);
  77.       g_free (label);
  78.     }
  79.       else
  80.     {
  81.       gtk_list_store_append (store, &iter);
  82.       gtk_list_store_set (store, &iter,
  83.                   PIXBUF_COL, NULL,
  84.                   TEXT_COL, "separator",
  85.                   -1);
  86.     }
  87.     }
  88.  
  89.   gtk_widget_destroy (cellview);
  90.   
  91.   return GTK_TREE_MODEL (store);
  92. }
  93.  
  94. /* A GtkCellLayoutDataFunc that demonstrates how one can control
  95.  * sensitivity of rows. This particular function does nothing 
  96.  * useful and just makes the second row insensitive.
  97.  */
  98. static void
  99. set_sensitive (GtkCellLayout   *cell_layout,
  100.            GtkCellRenderer *cell,
  101.            GtkTreeModel    *tree_model,
  102.            GtkTreeIter     *iter,
  103.            gpointer         data)
  104. {
  105.   GtkTreePath *path;
  106.   gint *indices;
  107.   gboolean sensitive;
  108.  
  109.   path = gtk_tree_model_get_path (tree_model, iter);
  110.   indices = gtk_tree_path_get_indices (path);
  111.   sensitive = indices[0] != 1;
  112.   gtk_tree_path_free (path);
  113.  
  114.   g_object_set (cell, "sensitive", sensitive, NULL);
  115. }
  116.  
  117. /* A GtkTreeViewRowSeparatorFunc that demonstrates how rows can be
  118.  * rendered as separators. This particular function does nothing 
  119.  * useful and just turns the fourth row into a separator.
  120.  */
  121. static gboolean
  122. is_separator (GtkTreeModel *model,
  123.           GtkTreeIter  *iter,
  124.           gpointer      data)
  125. {
  126.   GtkTreePath *path;
  127.   gboolean result;
  128.  
  129.   path = gtk_tree_model_get_path (model, iter);
  130.   result = gtk_tree_path_get_indices (path)[0] == 4;
  131.   gtk_tree_path_free (path);
  132.  
  133.   return result;
  134. }
  135.  
  136. static GtkTreeModel *
  137. create_capital_store (void)
  138. {
  139.   struct {
  140.     gchar *group;
  141.     gchar *capital;
  142.   } capitals[] = {
  143.     { "A - B", NULL }, 
  144.     { NULL, "Albany" },
  145.     { NULL, "Annapolis" },
  146.     { NULL, "Atlanta" },
  147.     { NULL, "Augusta" }, 
  148.     { NULL, "Austin" },
  149.     { NULL, "Baton Rouge" },
  150.     { NULL, "Bismarck" },
  151.     { NULL, "Boise" },
  152.     { NULL, "Boston" },
  153.     { "C - D", NULL },
  154.     { NULL, "Carson City" },
  155.     { NULL, "Charleston" },
  156.     { NULL, "Cheyenne" },
  157.     { NULL, "Columbia" },
  158.     { NULL, "Columbus" },
  159.     { NULL, "Concord" },
  160.     { NULL, "Denver" },
  161.     { NULL, "Des Moines" },
  162.     { NULL, "Dover" },
  163.     { "E - J", NULL },
  164.     { NULL, "Frankfort" },
  165.     { NULL, "Harrisburg" },
  166.     { NULL, "Hartford" },
  167.     { NULL, "Helena" },
  168.     { NULL, "Honolulu" },
  169.     { NULL, "Indianapolis" },
  170.     { NULL, "Jackson" },
  171.     { NULL, "Jefferson City" },
  172.     { NULL, "Juneau" },
  173.     { "K - O" },
  174.     { NULL, "Lansing" },
  175.     { NULL, "Lincoln" },
  176.     { NULL, "Little Rock" },
  177.     { NULL, "Madison" },
  178.     { NULL, "Montgomery" },
  179.     { NULL, "Montpelier" },
  180.     { NULL, "Nashville" },
  181.     { NULL, "Oklahoma City" },
  182.     { NULL, "Olympia" },
  183.     { NULL, "P - S" },
  184.     { NULL, "Phoenix" },
  185.     { NULL, "Pierre" },
  186.     { NULL, "Providence" },
  187.     { NULL, "Raleigh" },
  188.     { NULL, "Richmond" },
  189.     { NULL, "Sacramento" },
  190.     { NULL, "Salem" },
  191.     { NULL, "Salt Lake City" },
  192.     { NULL, "Santa Fe" },
  193.     { NULL, "Springfield" },
  194.     { NULL, "St. Paul" },
  195.     { "T - Z", NULL },
  196.     { NULL, "Tallahassee" },
  197.     { NULL, "Topeka" },
  198.     { NULL, "Trenton" },
  199.     { NULL, NULL }
  200.   };
  201.   
  202.   GtkTreeIter iter, iter2;
  203.   GtkTreeStore *store;
  204.   gint i;
  205.  
  206.   store = gtk_tree_store_new (1, G_TYPE_STRING);
  207.   
  208.   for (i = 0; capitals[i].group || capitals[i].capital; i++)
  209.     {
  210.       if (capitals[i].group)
  211.     {
  212.       gtk_tree_store_append (store, &iter, NULL);
  213.       gtk_tree_store_set (store, &iter, 0, capitals[i].group, -1);
  214.     }
  215.       else if (capitals[i].capital)
  216.     {
  217.       gtk_tree_store_append (store, &iter2, &iter);
  218.       gtk_tree_store_set (store, &iter2, 0, capitals[i].capital, -1);
  219.     }
  220.     }
  221.   
  222.   return GTK_TREE_MODEL (store);
  223. }
  224.  
  225. static void
  226. is_capital_sensitive (GtkCellLayout   *cell_layout,
  227.               GtkCellRenderer *cell,
  228.               GtkTreeModel    *tree_model,
  229.               GtkTreeIter     *iter,
  230.               gpointer         data)
  231. {
  232.   gboolean sensitive;
  233.  
  234.   sensitive = !gtk_tree_model_iter_has_child (tree_model, iter);
  235.  
  236.   g_object_set (cell, "sensitive", sensitive, NULL);
  237. }
  238.  
  239. static void
  240. fill_combo_entry (GtkWidget *entry)
  241. {
  242.   gtk_combo_box_append_text (GTK_COMBO_BOX (entry), "One");
  243.   gtk_combo_box_append_text (GTK_COMBO_BOX (entry), "Two");
  244.   gtk_combo_box_append_text (GTK_COMBO_BOX (entry), "2\302\275");
  245.   gtk_combo_box_append_text (GTK_COMBO_BOX (entry), "Three");
  246. }
  247.  
  248. GtkWidget *
  249. do_combobox (GtkWidget *do_widget)
  250. {
  251.   static GtkWidget *window = NULL;
  252.   GtkWidget *vbox, *frame, *box, *combo;
  253.   GtkTreeModel *model;
  254.   GtkCellRenderer *renderer;
  255.   GtkTreePath *path;
  256.   GtkTreeIter iter;
  257.  
  258.   if (!window)
  259.   {
  260.     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  261.     gtk_window_set_screen (GTK_WINDOW (window),
  262.                            gtk_widget_get_screen (do_widget));
  263.     gtk_window_set_title (GTK_WINDOW (window), "Combo boxes");
  264.    
  265.     g_signal_connect (window, "destroy",
  266.                       G_CALLBACK (gtk_widget_destroyed),
  267.                       &window);
  268.     
  269.     gtk_container_set_border_width (GTK_CONTAINER (window), 10);
  270.  
  271.     vbox = gtk_vbox_new (FALSE, 2);
  272.     gtk_container_add (GTK_CONTAINER (window), vbox);
  273.  
  274.     /* A combobox demonstrating cell renderers, separators and
  275.      *  insensitive rows 
  276.      */
  277.     frame = gtk_frame_new ("Some stock icons");
  278.     gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
  279.     
  280.     box = gtk_vbox_new (FALSE, 0);
  281.     gtk_container_set_border_width (GTK_CONTAINER (box), 5);
  282.     gtk_container_add (GTK_CONTAINER (frame), box);
  283.     
  284.     model = create_stock_icon_store ();
  285.     combo = gtk_combo_box_new_with_model (model);
  286.     g_object_unref (model);
  287.     gtk_container_add (GTK_CONTAINER (box), combo);
  288.     
  289.     renderer = gtk_cell_renderer_pixbuf_new ();
  290.     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
  291.     gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
  292.                     "pixbuf", PIXBUF_COL, 
  293.                     NULL);
  294.  
  295.     gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
  296.                     renderer,
  297.                     set_sensitive,
  298.                     NULL, NULL);
  299.     
  300.     renderer = gtk_cell_renderer_text_new ();
  301.     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
  302.     gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
  303.                     "text", TEXT_COL,
  304.                     NULL);
  305.  
  306.     gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
  307.                     renderer,
  308.                     set_sensitive,
  309.                     NULL, NULL);
  310.  
  311.     gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), 
  312.                       is_separator, NULL, NULL);
  313.     
  314.     gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
  315.     
  316.     /* A combobox demonstrating trees.
  317.      */
  318.     frame = gtk_frame_new ("Where are we ?");
  319.     gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
  320.  
  321.     box = gtk_vbox_new (FALSE, 0);
  322.     gtk_container_set_border_width (GTK_CONTAINER (box), 5);
  323.     gtk_container_add (GTK_CONTAINER (frame), box);
  324.     
  325.     model = create_capital_store ();
  326.     combo = gtk_combo_box_new_with_model (model);
  327.     g_object_unref (model);
  328.     gtk_container_add (GTK_CONTAINER (box), combo);
  329.  
  330.     renderer = gtk_cell_renderer_text_new ();
  331.     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
  332.     gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
  333.                     "text", 0,
  334.                     NULL);
  335.     gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
  336.                     renderer,
  337.                     is_capital_sensitive,
  338.                     NULL, NULL);
  339.  
  340.     path = gtk_tree_path_new_from_indices (0, 8, -1);
  341.     gtk_tree_model_get_iter (model, &iter, path);
  342.     gtk_tree_path_free (path);
  343.     gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);
  344.  
  345.     /* A GtkComboBoxEntry 
  346.      */
  347.     frame = gtk_frame_new ("Editable");
  348.     gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
  349.     
  350.     box = gtk_vbox_new (FALSE, 0);
  351.     gtk_container_set_border_width (GTK_CONTAINER (box), 5);
  352.     gtk_container_add (GTK_CONTAINER (frame), box);
  353.     
  354.     combo = gtk_combo_box_entry_new_text ();
  355.     fill_combo_entry (combo);
  356.     gtk_container_add (GTK_CONTAINER (box), combo);
  357.     
  358.   }
  359.  
  360.   if (!GTK_WIDGET_VISIBLE (window))
  361.     {
  362.       gtk_widget_show_all (window);
  363.     }
  364.   else
  365.     {    
  366.       gtk_widget_destroy (window);
  367.       window = NULL;
  368.     }
  369.  
  370.   return window;
  371. }
  372.