*
* This demo demonstrates the use of editable cells in a GtkTreeView. If
* you're new to the GtkTreeView widgets and associates, look into
- * the GtkListStore example first.
+ * the GtkListStore example first. It also shows how to use the
+ * GtkCellRenderer::editing-started signal to do custom setup of the
+ * editable widget.
*
+ * The cell renderers used in this demo are GtkCellRendererText,
+ * GtkCellRendererCombo and GtkCellRendererProgress.
*/
#include <gtk/gtk.h>
typedef struct
{
- gint number;
- gchar *product;
- gboolean editable;
+ gint number;
+ gchar *product;
+ gint yummy;
}
Item;
enum
{
- COLUMN_NUMBER,
- COLUMN_PRODUCT,
- COLUMN_EDITABLE,
- NUM_COLUMNS
+ COLUMN_ITEM_NUMBER,
+ COLUMN_ITEM_PRODUCT,
+ COLUMN_ITEM_YUMMY,
+ NUM_ITEM_COLUMNS
+};
+
+enum
+{
+ COLUMN_NUMBER_TEXT,
+ NUM_NUMBER_COLUMNS
};
static GArray *articles = NULL;
foo.number = 3;
foo.product = g_strdup ("bottles of coke");
- foo.editable = TRUE;
+ foo.yummy = 20;
g_array_append_vals (articles, &foo, 1);
foo.number = 5;
foo.product = g_strdup ("packages of noodles");
- foo.editable = TRUE;
+ foo.yummy = 50;
g_array_append_vals (articles, &foo, 1);
foo.number = 2;
foo.product = g_strdup ("packages of chocolate chip cookies");
- foo.editable = TRUE;
+ foo.yummy = 90;
g_array_append_vals (articles, &foo, 1);
foo.number = 1;
foo.product = g_strdup ("can vanilla ice cream");
- foo.editable = TRUE;
+ foo.yummy = 60;
g_array_append_vals (articles, &foo, 1);
foo.number = 6;
foo.product = g_strdup ("eggs");
- foo.editable = TRUE;
+ foo.yummy = 10;
g_array_append_vals (articles, &foo, 1);
}
static GtkTreeModel *
-create_model (void)
+create_items_model (void)
{
gint i = 0;
GtkListStore *model;
add_items ();
/* create list store */
- model = gtk_list_store_new (NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING,
- G_TYPE_BOOLEAN);
+ model = gtk_list_store_new (NUM_ITEM_COLUMNS, G_TYPE_INT, G_TYPE_STRING,
+ G_TYPE_INT, G_TYPE_BOOLEAN);
/* add items */
for (i = 0; i < articles->len; i++)
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter,
- COLUMN_NUMBER,
- g_array_index (articles, Item, i).number,
- COLUMN_PRODUCT,
- g_array_index (articles, Item, i).product,
- COLUMN_EDITABLE,
- g_array_index (articles, Item, i).editable,
- -1);
+ COLUMN_ITEM_NUMBER,
+ g_array_index (articles, Item, i).number,
+ COLUMN_ITEM_PRODUCT,
+ g_array_index (articles, Item, i).product,
+ COLUMN_ITEM_YUMMY,
+ g_array_index (articles, Item, i).yummy,
+ -1);
}
return GTK_TREE_MODEL (model);
}
+static GtkTreeModel *
+create_numbers_model (void)
+{
+#define N_NUMBERS 10
+ gint i = 0;
+ GtkListStore *model;
+ GtkTreeIter iter;
+
+ /* create list store */
+ model = gtk_list_store_new (NUM_NUMBER_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
+
+ /* add numbers */
+ for (i = 0; i < N_NUMBERS; i++)
+ {
+ char str[2];
+
+ str[0] = '0' + i;
+ str[1] = '\0';
+
+ gtk_list_store_append (model, &iter);
+
+ gtk_list_store_set (model, &iter,
+ COLUMN_NUMBER_TEXT, str,
+ -1);
+ }
+
+ return GTK_TREE_MODEL (model);
+
+#undef N_NUMBERS
+}
+
static void
add_item (GtkWidget *button, gpointer data)
{
foo.number = 0;
foo.product = g_strdup ("Description here");
- foo.editable = TRUE;
+ foo.yummy = 50;
g_array_append_vals (articles, &foo, 1);
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
- COLUMN_NUMBER, foo.number,
- COLUMN_PRODUCT, foo.product,
- COLUMN_EDITABLE, foo.editable,
- -1);
+ COLUMN_ITEM_NUMBER, foo.number,
+ COLUMN_ITEM_PRODUCT, foo.product,
+ COLUMN_ITEM_YUMMY, foo.yummy,
+ -1);
}
static void
}
}
+static gboolean
+separator_row (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GtkTreePath *path;
+ gint idx;
+
+ path = gtk_tree_model_get_path (model, iter);
+ idx = gtk_tree_path_get_indices (path)[0];
+
+ gtk_tree_path_free (path);
+
+ return idx == 5;
+}
+
+static void
+editing_started (GtkCellRenderer *cell,
+ GtkCellEditable *editable,
+ const gchar *path,
+ gpointer data)
+{
+ gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (editable),
+ separator_row, NULL, NULL);
+}
+
static void
cell_edited (GtkCellRendererText *cell,
- gchar *path_string,
- gchar *new_text,
- gpointer data)
+ const gchar *path_string,
+ const gchar *new_text,
+ gpointer data)
{
GtkTreeModel *model = (GtkTreeModel *)data;
GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
GtkTreeIter iter;
- gint *column;
-
- column = g_object_get_data (G_OBJECT (cell), "column");
+ gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));
gtk_tree_model_get_iter (model, &iter, path);
- switch ((gint) column)
+ switch (column)
{
- case COLUMN_NUMBER:
+ case COLUMN_ITEM_NUMBER:
{
- gint i;
+ gint i;
- i = gtk_tree_path_get_indices (path)[0];
- g_array_index (articles, Item, i).number = atoi (new_text);
+ i = gtk_tree_path_get_indices (path)[0];
+ g_array_index (articles, Item, i).number = atoi (new_text);
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
- g_array_index (articles, Item, i).number, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
+ g_array_index (articles, Item, i).number, -1);
}
break;
- case COLUMN_PRODUCT:
+ case COLUMN_ITEM_PRODUCT:
{
- gint i;
- gchar *old_text;
+ gint i;
+ gchar *old_text;
gtk_tree_model_get (model, &iter, column, &old_text, -1);
- g_free (old_text);
+ g_free (old_text);
- i = gtk_tree_path_get_indices (path)[0];
- g_free (g_array_index (articles, Item, i).product);
- g_array_index (articles, Item, i).product = g_strdup (new_text);
+ i = gtk_tree_path_get_indices (path)[0];
+ g_free (g_array_index (articles, Item, i).product);
+ g_array_index (articles, Item, i).product = g_strdup (new_text);
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
g_array_index (articles, Item, i).product, -1);
}
break;
}
static void
-add_columns (GtkTreeView *treeview)
+add_columns (GtkTreeView *treeview,
+ GtkTreeModel *items_model,
+ GtkTreeModel *numbers_model)
{
GtkCellRenderer *renderer;
- GtkTreeModel *model = gtk_tree_view_get_model (treeview);
/* number column */
- renderer = gtk_cell_renderer_text_new ();
- g_signal_connect (G_OBJECT (renderer), "edited",
- G_CALLBACK (cell_edited), model);
- g_object_set_data (G_OBJECT (renderer), "column", (gint *)COLUMN_NUMBER);
+ renderer = gtk_cell_renderer_combo_new ();
+ g_object_set (renderer,
+ "model", numbers_model,
+ "text-column", COLUMN_NUMBER_TEXT,
+ "has-entry", FALSE,
+ "editable", TRUE,
+ NULL);
+ g_signal_connect (renderer, "edited",
+ G_CALLBACK (cell_edited), items_model);
+ g_signal_connect (renderer, "editing-started",
+ G_CALLBACK (editing_started), NULL);
+ g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_NUMBER));
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
- -1, "Number", renderer,
- "text", COLUMN_NUMBER,
- "editable", COLUMN_EDITABLE,
- NULL);
+ -1, "Number", renderer,
+ "text", COLUMN_ITEM_NUMBER,
+ NULL);
/* product column */
renderer = gtk_cell_renderer_text_new ();
- g_signal_connect (G_OBJECT (renderer), "edited",
- G_CALLBACK (cell_edited), model);
- g_object_set_data (G_OBJECT (renderer), "column", (gint *)COLUMN_PRODUCT);
+ g_object_set (renderer,
+ "editable", TRUE,
+ NULL);
+ g_signal_connect (renderer, "edited",
+ G_CALLBACK (cell_edited), items_model);
+ g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_PRODUCT));
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
- -1, "Product", renderer,
- "text", COLUMN_PRODUCT,
- "editable", COLUMN_EDITABLE,
- NULL);
+ -1, "Product", renderer,
+ "text", COLUMN_ITEM_PRODUCT,
+ NULL);
+
+ /* yummy column */
+ renderer = gtk_cell_renderer_progress_new ();
+ g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_YUMMY));
+
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
+ -1, "Yummy", renderer,
+ "value", COLUMN_ITEM_YUMMY,
+ NULL);
+
+
}
GtkWidget *
-do_editable_cells (void)
+do_editable_cells (GtkWidget *do_widget)
{
if (!window)
{
GtkWidget *sw;
GtkWidget *treeview;
GtkWidget *button;
- GtkTreeModel *model;
+ GtkTreeModel *items_model;
+ GtkTreeModel *numbers_model;
/* create window, etc */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_screen (GTK_WINDOW (window),
+ gtk_widget_get_screen (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Shopping list");
gtk_container_set_border_width (GTK_CONTAINER (window), 5);
- g_signal_connect (G_OBJECT (window), "destroy",
- G_CALLBACK (gtk_widget_destroyed), &window);
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_widget_destroyed), &window);
- vbox = gtk_vbox_new (FALSE, 5);
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_box_pack_start (GTK_BOX (vbox),
- gtk_label_new ("Shopping list (you can edit the cells!)"),
- FALSE, FALSE, 0);
+ gtk_label_new ("Shopping list (you can edit the cells!)"),
+ FALSE, FALSE, 0);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
- GTK_SHADOW_ETCHED_IN);
+ GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
- /* create model */
- model = create_model ();
+ /* create models */
+ items_model = create_items_model ();
+ numbers_model = create_numbers_model ();
/* create tree view */
- treeview = gtk_tree_view_new_with_model (model);
- g_object_unref (G_OBJECT (model));
+ treeview = gtk_tree_view_new_with_model (items_model);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
- GTK_SELECTION_SINGLE);
+ GTK_SELECTION_SINGLE);
+
+ add_columns (GTK_TREE_VIEW (treeview), items_model, numbers_model);
- add_columns (GTK_TREE_VIEW (treeview));
+ g_object_unref (numbers_model);
+ g_object_unref (items_model);
gtk_container_add (GTK_CONTAINER (sw), treeview);
/* some buttons */
- hbox = gtk_hbox_new (TRUE, 4);
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
+ gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
button = gtk_button_new_with_label ("Add item");
- g_signal_connect (G_OBJECT (button), "clicked",
- G_CALLBACK (add_item), model);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (add_item), items_model);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
button = gtk_button_new_with_label ("Remove item");
- g_signal_connect (G_OBJECT (button), "clicked",
- G_CALLBACK (remove_item), treeview);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (remove_item), treeview);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_window_set_default_size (GTK_WINDOW (window), 320, 200);
}
- if (!GTK_WIDGET_VISIBLE (window))
+ if (!gtk_widget_get_visible (window))
gtk_widget_show_all (window);
else
{