gtk-demo: Add a filter model example

This shows computed columns.
This commit is contained in:
Matthias Clasen 2015-07-22 10:56:56 -04:00
parent 31191d5566
commit 6a5586a416
3 changed files with 162 additions and 0 deletions

View File

@ -25,6 +25,7 @@ demos_base = \
entry_completion.c \
event_axes.c \
expander.c \
filtermodel.c \
font_features.c \
gestures.c \
glarea.c \

View File

@ -131,6 +131,7 @@
<file>entry_completion.c</file>
<file>event_axes.c</file>
<file>expander.c</file>
<file>filtermodel.c</file>
<file>flowbox.c</file>
<file>font_features.c</file>
<file>gestures.c</file>

View File

@ -0,0 +1,160 @@
/* Tree View/Filter Model
*
* This example demonstrates how GtkTreeModelFilter can be used
* to compute columns that are not actually present in the underlying
* model.
*/
#include <gtk/gtk.h>
enum {
WIDTH_COLUMN,
HEIGHT_COLUMN,
AREA_COLUMN,
SQUARE_COLUMN
};
static void
format_number (GtkTreeViewColumn *col,
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
gint num;
gchar *text;
gtk_tree_model_get (model, iter, GPOINTER_TO_INT (data), &num, -1);
text = g_strdup_printf ("%d", num);
g_object_set (cell, "text", text, NULL);
g_free (text);
}
static void
filter_modify_func (GtkTreeModel *model,
GtkTreeIter *iter,
GValue *value,
gint column,
gpointer data)
{
GtkTreeModelFilter *filter_model = GTK_TREE_MODEL_FILTER (model);
gint width, height;
GtkTreeModel *child_model;
GtkTreeIter child_iter;
child_model = gtk_tree_model_filter_get_model (filter_model);
gtk_tree_model_filter_convert_iter_to_child_iter (filter_model, &child_iter, iter);
gtk_tree_model_get (child_model, &child_iter,
WIDTH_COLUMN, &width,
HEIGHT_COLUMN, &height,
-1);
switch (column)
{
case WIDTH_COLUMN:
g_value_set_int (value, width);
break;
case HEIGHT_COLUMN:
g_value_set_int (value, height);
break;
case AREA_COLUMN:
g_value_set_int (value, width * height);
break;
case SQUARE_COLUMN:
g_value_set_boolean (value, width == height);
break;
default:
g_assert_not_reached ();
}
}
GtkWidget *
do_filtermodel (GtkWidget *do_widget)
{
static GtkWidget *window;
GtkWidget *tree;
GtkListStore *store;
GtkTreeModel *model;
GtkTreeViewColumn *column;
GtkCellRenderer *cell;
GType types[4];
if (!window)
{
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), "Filter Model");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
tree = gtk_tree_view_new ();
gtk_container_add (GTK_CONTAINER (window), tree);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, "Width");
cell = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, cell, FALSE);
gtk_tree_view_column_set_cell_data_func (column, cell,
format_number, GINT_TO_POINTER (WIDTH_COLUMN), NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, "Height");
cell = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, cell, FALSE);
gtk_tree_view_column_set_cell_data_func (column, cell,
format_number, GINT_TO_POINTER (HEIGHT_COLUMN), NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, "Area");
cell = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, cell, FALSE);
gtk_tree_view_column_set_cell_data_func (column, cell,
format_number, GINT_TO_POINTER (AREA_COLUMN), NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, "Square");
cell = gtk_cell_renderer_pixbuf_new ();
g_object_set (cell, "icon-name", "object-select-symbolic", NULL);
gtk_tree_view_column_pack_start (column, cell, FALSE);
gtk_tree_view_column_add_attribute (column, cell, "visible", SQUARE_COLUMN);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_INT);
store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_INT);
gtk_list_store_insert_with_values (store, NULL, -1,
WIDTH_COLUMN, 10,
HEIGHT_COLUMN, 20,
-1);
gtk_list_store_insert_with_values (store, NULL, -1,
WIDTH_COLUMN, 5,
HEIGHT_COLUMN, 25,
-1);
gtk_list_store_insert_with_values (store, NULL, -1,
WIDTH_COLUMN, 15,
HEIGHT_COLUMN, 15,
-1);
types[WIDTH_COLUMN] = G_TYPE_INT;
types[HEIGHT_COLUMN] = G_TYPE_INT;
types[AREA_COLUMN] = G_TYPE_INT;
types[SQUARE_COLUMN] = G_TYPE_BOOLEAN;
model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
gtk_tree_model_filter_set_modify_func (GTK_TREE_MODEL_FILTER (model),
G_N_ELEMENTS (types), types,
filter_modify_func, NULL, NULL);
gtk_tree_view_set_model (GTK_TREE_VIEW (tree), model);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show_all (window);
else
gtk_widget_destroy (window);
return window;
}