diff options
author | Kristian Rietveld <kristian@planet.nl> | 2001-10-02 18:54:05 +0000 |
---|---|---|
committer | Kristian Rietveld <kristian@src.gnome.org> | 2001-10-02 18:54:05 +0000 |
commit | ced4124efe73184a02b012a7e5e9fa173dcdc90f (patch) | |
tree | 5c43cee8ce99e355b211b74d9cbae6fa6cc26851 /demos | |
parent | ace5a03b9f2029f567a75be54936ea69e856fa65 (diff) | |
download | gtk+-ced4124efe73184a02b012a7e5e9fa173dcdc90f.tar.gz |
add editable_cells.c, list_store.c and tree_store.c
Tue Oct 2 20:18:32 2001 Kristian Rietveld <kristian@planet.nl>
* demos/gtk-demo/Makefile.am: add editable_cells.c,
list_store.c and tree_store.c
* demos/gtk-demo/appwindow.c: remove tearoff item from
File menu, put menubar and toolbar in handle boxes.
* demos/gtk-demo/genincude.pl: various changes to support trees
* demos/gtk-demo/main.c: various changes to support trees
* demos/gtk-demo/stock_browser.c: changed name of demo
to Stock Item and Icon Browser, so geninclude.pl doesn't see
it as child
* demos/gtk-demo/editable_cells.c: new file/demo
* demos/gtk-demo/list_store.c: new file/demo
* demos/gtk-demo/tree_store.c: new file/demo
Diffstat (limited to 'demos')
-rw-r--r-- | demos/gtk-demo/Makefile.am | 3 | ||||
-rw-r--r-- | demos/gtk-demo/appwindow.c | 16 | ||||
-rw-r--r-- | demos/gtk-demo/editable_cells.c | 298 | ||||
-rwxr-xr-x | demos/gtk-demo/geninclude.pl | 143 | ||||
-rwxr-xr-x | demos/gtk-demo/geninclude.pl.in | 143 | ||||
-rw-r--r-- | demos/gtk-demo/list_store.c | 220 | ||||
-rw-r--r-- | demos/gtk-demo/main.c | 128 | ||||
-rw-r--r-- | demos/gtk-demo/stock_browser.c | 2 | ||||
-rw-r--r-- | demos/gtk-demo/tree_store.c | 446 |
9 files changed, 1332 insertions, 67 deletions
diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index b1dc020598..cd92264c28 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -10,14 +10,17 @@ demos = @STRIP_BEGIN@ \ colorsel.c \ dialog.c \ drawingarea.c \ + editable_cells.c \ images.c \ item_factory.c \ + list_store.c \ menus.c \ panes.c \ pixbufs.c \ sizegroup.c \ stock_browser.c \ textview.c \ + tree_store.c \ @STRIP_END@ INCLUDES = @STRIP_BEGIN@ \ diff --git a/demos/gtk-demo/appwindow.c b/demos/gtk-demo/appwindow.c index cb88dc7fe8..b1befcbe69 100644 --- a/demos/gtk-demo/appwindow.c +++ b/demos/gtk-demo/appwindow.c @@ -35,7 +35,6 @@ menuitem_cb (gpointer callback_data, static GtkItemFactoryEntry menu_items[] = { { "/_File", NULL, 0, 0, "<Branch>" }, - { "/File/tearoff1", NULL, menuitem_cb, 0, "<Tearoff>" }, { "/File/_New", "<control>N", menuitem_cb, 0, "<StockItem>", GTK_STOCK_NEW }, { "/File/_Open", "<control>O", menuitem_cb, 0, "<StockItem>", GTK_STOCK_OPEN }, { "/File/_Save", "<control>S", menuitem_cb, 0, "<StockItem>", GTK_STOCK_SAVE }, @@ -182,6 +181,8 @@ do_appwindow (void) if (!window) { GtkWidget *table; + GtkWidget *menubar_handle; + GtkWidget *toolbar_handle; GtkWidget *toolbar; GtkWidget *statusbar; GtkWidget *contents; @@ -214,6 +215,8 @@ do_appwindow (void) gtk_accel_group_attach (accel_group, G_OBJECT (window)); gtk_accel_group_unref (accel_group); + menubar_handle = gtk_handle_box_new (); + item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group); /* Set up item factory to go away with the window */ @@ -228,8 +231,11 @@ do_appwindow (void) gtk_item_factory_create_items (item_factory, G_N_ELEMENTS (menu_items), menu_items, window); + gtk_container_add (GTK_CONTAINER (menubar_handle), + gtk_item_factory_get_widget (item_factory, "<main>")); + gtk_table_attach (GTK_TABLE (table), - gtk_item_factory_get_widget (item_factory, "<main>"), + menubar_handle, /* X direction */ /* Y direction */ 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, @@ -237,6 +243,8 @@ do_appwindow (void) /* Create the toolbar */ + toolbar_handle = gtk_handle_box_new (); + toolbar = gtk_toolbar_new (); gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), @@ -265,8 +273,10 @@ do_appwindow (void) window, /* user data for callback */ -1); /* -1 means "append" */ + gtk_container_add (GTK_CONTAINER (toolbar_handle), toolbar); + gtk_table_attach (GTK_TABLE (table), - toolbar, + toolbar_handle, /* X direction */ /* Y direction */ 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0, diff --git a/demos/gtk-demo/editable_cells.c b/demos/gtk-demo/editable_cells.c new file mode 100644 index 0000000000..7157f60c14 --- /dev/null +++ b/demos/gtk-demo/editable_cells.c @@ -0,0 +1,298 @@ +/* Tree View/Editable Cells + * + * This demo demostrates the use of editable cells in a GtkTreeView. If + * you're new to the GtkTreeView widgets and associates, look into + * the GtkListStore example first. + * + */ + +#include <gtk/gtk.h> +#include <string.h> +#include <stdlib.h> + +static GtkWidget *window = NULL; + +typedef struct +{ + gint number; + gchar *product; + gboolean editable; +} +Item; + +enum +{ + COLUMN_NUMBER, + COLUMN_PRODUCT, + COLUMN_EDITABLE, + NUM_COLUMNS +}; + +static GArray *articles = NULL; + +static void +add_items (void) +{ + Item foo; + + g_return_if_fail (articles != NULL); + + foo.number = 3; + foo.product = g_strdup ("bottles of coke"); + foo.editable = TRUE; + g_array_append_vals (articles, &foo, 1); + + foo.number = 5; + foo.product = g_strdup ("packages of noodles"); + foo.editable = TRUE; + g_array_append_vals (articles, &foo, 1); + + foo.number = 2; + foo.product = g_strdup ("packages of chocolate chip cookies"); + foo.editable = TRUE; + g_array_append_vals (articles, &foo, 1); + + foo.number = 1; + foo.product = g_strdup ("can vanilla ice cream"); + foo.editable = TRUE; + g_array_append_vals (articles, &foo, 1); + + foo.number = 6; + foo.product = g_strdup ("eggs"); + foo.editable = TRUE; + g_array_append_vals (articles, &foo, 1); +} + +static GtkTreeModel * +create_model (void) +{ + gint i = 0; + GtkListStore *model; + GtkTreeIter iter; + + /* create array */ + articles = g_array_sized_new (FALSE, FALSE, sizeof (Item), 1); + + add_items (); + + /* create list store */ + model = gtk_list_store_new (NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING, + 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); + } + + return GTK_TREE_MODEL (model); +} + +static void +add_item (GtkWidget *button, gpointer data) +{ + Item foo; + GtkTreeIter iter; + GtkTreeModel *model = (GtkTreeModel *)data; + + g_return_if_fail (articles != NULL); + + foo.number = 0; + foo.product = g_strdup ("Description here"); + foo.editable = TRUE; + 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); +} + +static void +remove_item (GtkWidget *widget, gpointer data) +{ + GtkTreeIter iter; + GtkTreeView *treeview = (GtkTreeView *)data; + GtkTreeModel *model = gtk_tree_view_get_model (treeview); + GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview); + + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + gint i; + GtkTreePath *path; + + path = gtk_tree_model_get_path (model, &iter); + i = gtk_tree_path_get_indices (path)[0]; + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + + g_array_remove_index (articles, i); + + gtk_tree_path_free (path); + } +} + +static void +cell_edited (GtkCellRendererText *cell, + gchar *path_string, + gchar *new_text, + gpointer data) +{ + GtkTreeModel *model = (GtkTreeModel *)data; + GtkTreePath *path = gtk_tree_path_new_from_string (path_string); + GtkTreeIter iter; + + gchar old_text[256]; /* ugly? */ + gint *column; + + column = g_object_get_data (G_OBJECT (cell), "column"); + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, column, old_text, -1); + + switch ((gint) column) + { + case COLUMN_NUMBER: + { + gint i; + + 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, + atoi (new_text), -1); + } + break; + + case COLUMN_PRODUCT: + { + gint i; + + 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, + new_text, -1); + } + break; + } + + gtk_tree_path_free (path); +} + +static void +add_columns (GtkTreeView *treeview) +{ + 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); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + -1, "Number", renderer, + "text", COLUMN_NUMBER, + "editable", COLUMN_EDITABLE, + 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); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + -1, "Product", renderer, + "text", COLUMN_PRODUCT, + "editable", COLUMN_EDITABLE, + NULL); +} + +GtkWidget * +do_editable_cells (void) +{ + if (!window) + { + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *sw; + GtkWidget *treeview; + GtkWidget *button; + GtkTreeModel *model; + + /* create window, etc */ + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + 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); + + vbox = gtk_vbox_new (FALSE, 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); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), + GTK_SHADOW_ETCHED_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0); + + /* create model */ + model = create_model (); + + /* create tree view */ + treeview = gtk_tree_view_new_with_model (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); + + add_columns (GTK_TREE_VIEW (treeview)); + + gtk_container_add (GTK_CONTAINER (sw), treeview); + + /* some buttons */ + hbox = gtk_hbox_new (TRUE, 4); + 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); + 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); + 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)) + gtk_widget_show_all (window); + else + { + gtk_widget_destroy (window); + window = NULL; + } + + return window; +} diff --git a/demos/gtk-demo/geninclude.pl b/demos/gtk-demo/geninclude.pl index df534bc46d..f5fcd3ff48 100755 --- a/demos/gtk-demo/geninclude.pl +++ b/demos/gtk-demo/geninclude.pl @@ -10,22 +10,16 @@ struct _Demo gchar *title; gchar *filename; GDoDemoFunc func; + Demo *children; }; EOT -$array = ""; -$first = 1; for $file (@ARGV) { + my %demo; ($basename = $file) =~ s/\.c$//; - if ($first) { - $first = 0; - } else { - $array .= ",\n"; - } - open INFO_FILE, $file or die "Cannot open '$file'\n"; $title = <INFO_FILE>; $title =~ s@^\s*/\*\s*@@; @@ -34,9 +28,136 @@ for $file (@ARGV) { close INFO_FILE; print "GtkWidget *do_$basename (void);\n"; - $array .= qq( { "$title", "$file", do_$basename }); + + push @demos, {"title" => $title, "file" => $file, + "func" => "do_$basename"}; +} + +# generate a list of 'parent names' +foreach $href (@demos) { + if ($href->{"title"} =~ m|^([\w\s]+)/[\w\s]+$|) { + my $parent_name = $1; + my $do_next = 0; + + # parent detected + if (defined @parents) { + foreach $foo (@parents) { + if ($foo eq $parent_name) { + $do_next = 1; + } + } + + if ($do_next) { + next; + } + } + + push @parents, $parent_name; + + $tmp = (defined @child_arrays)?($#child_arrays + 1):0; + push @child_arrays, "child$tmp"; + + push @demos, {"title" => $parent_name, "file" => "NULL", + "func" => "NULL"}; + } +} + +if (defined @parents) { + $i = 0; + for ($i = 0; $i <= $#parents; $i++) { + $first = 1; + + print "\nDemo ", $child_arrays[$i], "[] = {\n"; + + $j = 0; + for ($j = 0; $j <= $#demos; $j++) { + $href = $demos[$j]; + + if (!defined $demos[$j]) { + next; + } + + if ($demos[$j]{"title"} =~ m|^$parents[$i]/([\w\s]+)$|) { + if ($first) { + $first = 0; + } else { + print ",\n"; + } + + print qq ( { "$1", "$demos[$j]{file}", $demos[$j]{func}, NULL }); + + # hack ... ugly + $demos[$j]{"title"} = "foo"; + } + } + + print ",\n"; + print qq ( { NULL } ); + print "\n};\n"; + } +} + +# sort @demos +@demos_old = @demos; + +@demos = sort { + $a->{"title"} cmp $b->{"title"}; +} @demos_old; + +# sort the child arrays +if (defined @child_arrays) { + for ($i = 0; $i <= $#child_arrays; $i++) { + @foo_old = @{$child_arrays[$i]}; + + @{$child_arrays[$i]} = sort { + $a->{"title"} cmp $b->{"title"}; + } @foo_old; + } } -print "\nDemo testgtk_demos[] = {"; -print $array; +# toplevel +print "\nDemo testgtk_demos[] = {\n"; + +$first = 1; +foreach $href (@demos) { + $handled = 0; + + # ugly evil hack + if ($href->{title} eq "foo") { + next; + } + + if ($first) { + $first = 0; + } else { + print ", \n"; + } + + if (defined @parents) { + for ($i = 0; $i <= $#parents; $i++) { + if ($parents[$i] eq $href->{title}) { + + if ($href->{file} eq 'NULL') { + print qq ( { "$href->{title}", NULL, $href->{func}, $child_arrays[$i] }); + } else { + print qq ( { "$href->{title}", "$href->{file}", $href->{func}, $child_arrays[$i] }); + } + + $handled = 1; + last; + } + } + } + + if ($handled) { + next; + } + + print qq ( { "$href->{title}", "$href->{file}", $href->{func}, NULL }); +} + +print ",\n"; +print qq ( { NULL } ); print "\n};\n"; + +exit 0; diff --git a/demos/gtk-demo/geninclude.pl.in b/demos/gtk-demo/geninclude.pl.in index df534bc46d..f5fcd3ff48 100755 --- a/demos/gtk-demo/geninclude.pl.in +++ b/demos/gtk-demo/geninclude.pl.in @@ -10,22 +10,16 @@ struct _Demo gchar *title; gchar *filename; GDoDemoFunc func; + Demo *children; }; EOT -$array = ""; -$first = 1; for $file (@ARGV) { + my %demo; ($basename = $file) =~ s/\.c$//; - if ($first) { - $first = 0; - } else { - $array .= ",\n"; - } - open INFO_FILE, $file or die "Cannot open '$file'\n"; $title = <INFO_FILE>; $title =~ s@^\s*/\*\s*@@; @@ -34,9 +28,136 @@ for $file (@ARGV) { close INFO_FILE; print "GtkWidget *do_$basename (void);\n"; - $array .= qq( { "$title", "$file", do_$basename }); + + push @demos, {"title" => $title, "file" => $file, + "func" => "do_$basename"}; +} + +# generate a list of 'parent names' +foreach $href (@demos) { + if ($href->{"title"} =~ m|^([\w\s]+)/[\w\s]+$|) { + my $parent_name = $1; + my $do_next = 0; + + # parent detected + if (defined @parents) { + foreach $foo (@parents) { + if ($foo eq $parent_name) { + $do_next = 1; + } + } + + if ($do_next) { + next; + } + } + + push @parents, $parent_name; + + $tmp = (defined @child_arrays)?($#child_arrays + 1):0; + push @child_arrays, "child$tmp"; + + push @demos, {"title" => $parent_name, "file" => "NULL", + "func" => "NULL"}; + } +} + +if (defined @parents) { + $i = 0; + for ($i = 0; $i <= $#parents; $i++) { + $first = 1; + + print "\nDemo ", $child_arrays[$i], "[] = {\n"; + + $j = 0; + for ($j = 0; $j <= $#demos; $j++) { + $href = $demos[$j]; + + if (!defined $demos[$j]) { + next; + } + + if ($demos[$j]{"title"} =~ m|^$parents[$i]/([\w\s]+)$|) { + if ($first) { + $first = 0; + } else { + print ",\n"; + } + + print qq ( { "$1", "$demos[$j]{file}", $demos[$j]{func}, NULL }); + + # hack ... ugly + $demos[$j]{"title"} = "foo"; + } + } + + print ",\n"; + print qq ( { NULL } ); + print "\n};\n"; + } +} + +# sort @demos +@demos_old = @demos; + +@demos = sort { + $a->{"title"} cmp $b->{"title"}; +} @demos_old; + +# sort the child arrays +if (defined @child_arrays) { + for ($i = 0; $i <= $#child_arrays; $i++) { + @foo_old = @{$child_arrays[$i]}; + + @{$child_arrays[$i]} = sort { + $a->{"title"} cmp $b->{"title"}; + } @foo_old; + } } -print "\nDemo testgtk_demos[] = {"; -print $array; +# toplevel +print "\nDemo testgtk_demos[] = {\n"; + +$first = 1; +foreach $href (@demos) { + $handled = 0; + + # ugly evil hack + if ($href->{title} eq "foo") { + next; + } + + if ($first) { + $first = 0; + } else { + print ", \n"; + } + + if (defined @parents) { + for ($i = 0; $i <= $#parents; $i++) { + if ($parents[$i] eq $href->{title}) { + + if ($href->{file} eq 'NULL') { + print qq ( { "$href->{title}", NULL, $href->{func}, $child_arrays[$i] }); + } else { + print qq ( { "$href->{title}", "$href->{file}", $href->{func}, $child_arrays[$i] }); + } + + $handled = 1; + last; + } + } + } + + if ($handled) { + next; + } + + print qq ( { "$href->{title}", "$href->{file}", $href->{func}, NULL }); +} + +print ",\n"; +print qq ( { NULL } ); print "\n};\n"; + +exit 0; diff --git a/demos/gtk-demo/list_store.c b/demos/gtk-demo/list_store.c new file mode 100644 index 0000000000..590289544b --- /dev/null +++ b/demos/gtk-demo/list_store.c @@ -0,0 +1,220 @@ +/* Tree View/List Store + * + * The GtkListStore is used to store data in list form, to be used + * later on by a GtkTreeView to display it. This demo builds a + * simple GtkListStore and displays it. See the Stock Browser + * demo for a more advanced example. + * + */ + +#include <gtk/gtk.h> + +static GtkWidget *window = NULL; + +typedef struct +{ + const gboolean fixed; + const guint number; + const gchar *severity; + const gchar *description; +} +Bug; + +enum +{ + COLUMN_FIXED, + COLUMN_NUMBER, + COLUMN_SEVERITY, + COLUMN_DESCRIPTION, + NUM_COLUMNS +}; + +static Bug data[] = +{ + { FALSE, 60482, "Normal", "scrollable notebooks and hidden tabs" }, + { FALSE, 60620, "Critical", "gdk_window_clear_area (gdkwindow-win32.c) is not thread-safe" }, + { FALSE, 50214, "Major", "Xft support does not clean up correctly" }, + { TRUE, 52877, "Major", "GtkFileSelection needs a refresh method. " }, + { FALSE, 56070, "Normal", "Can't click button after setting in sensitive" }, + { TRUE, 56355, "Normal", "GtkLabel - Not all changes propagate correctly" }, + { FALSE, 50055, "Normal", "Rework width/height computations for TreeView" }, + { FALSE, 58278, "Normal", "gtk_dialog_set_response_sensitive () doesn't work" }, + { FALSE, 55767, "Normal", "Getters for all setters" }, + { FALSE, 56925, "Normal", "Gtkcalender size" }, + { FALSE, 56221, "Normal", "Selectable label needs right-click copy menu" }, + { TRUE, 50939, "Normal", "Add shift clicking to GtkTextView" }, + { FALSE, 6112, "Enhancement","netscape-like collapsable toolbars" }, + { FALSE, 1, "Normal", "First bug :=)" }, + { 0, 0, NULL, NULL } +}; + +static GtkTreeModel * +create_model (void) +{ + gint i = 0; + GtkListStore *store; + GtkTreeIter iter; + + /* create list store */ + store = gtk_list_store_new (NUM_COLUMNS, + G_TYPE_BOOLEAN, + G_TYPE_UINT, + G_TYPE_STRING, + G_TYPE_STRING); + + /* add data to the list store */ + while (data[i].number) + { + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + COLUMN_FIXED, data[i].fixed, + COLUMN_NUMBER, data[i].number, + COLUMN_SEVERITY, data[i].severity, + COLUMN_DESCRIPTION, data[i].description, + -1); + i++; + } + + return GTK_TREE_MODEL (store); +} + +static void +fixed_toggled (GtkCellRendererToggle *cell, + gchar *path_str, + gpointer data) +{ + GtkTreeModel *model = (GtkTreeModel *)data; + GtkTreeIter iter; + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + gboolean fixed; + + /* get toggled iter */ + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, COLUMN_FIXED, &fixed, -1); + + /* do something with the value */ + fixed ^= 1; + + /* set new value */ + gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_FIXED, fixed, -1); + + /* clean up */ + gtk_tree_path_free (path); +} + +static void +add_columns (GtkTreeView *treeview) +{ + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeModel *model = gtk_tree_view_get_model (treeview); + + /* column for fixed toggles */ + renderer = gtk_cell_renderer_toggle_new (); + g_signal_connect (G_OBJECT (renderer), "toggled", + G_CALLBACK (fixed_toggled), model); + + column = gtk_tree_view_column_new_with_attributes ("Fixed?", + renderer, + "active", COLUMN_FIXED, + NULL); + + /* set this column to a fixed sizing (of 50 pixels) */ + gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), + GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 50); + gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); + + gtk_tree_view_append_column (treeview, column); + + /* column for bug numbers */ + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Bug number", + renderer, + "text", + COLUMN_NUMBER, + NULL); + gtk_tree_view_append_column (treeview, column); + + /* column for severities */ + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Severity", + renderer, + "text", + COLUMN_SEVERITY, + NULL); + gtk_tree_view_append_column (treeview, column); + + /* column for description */ + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Description", + renderer, + "text", + COLUMN_DESCRIPTION, + NULL); + gtk_tree_view_append_column (treeview, column); +} + +GtkWidget * +do_list_store (void) +{ + if (!window) + { + GtkWidget *vbox; + GtkWidget *label; + GtkWidget *sw; + GtkTreeModel *model; + GtkWidget *treeview; + + /* create window, etc */ + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "GtkListStore demo"); + + g_signal_connect (G_OBJECT (window), "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + gtk_container_set_border_width (GTK_CONTAINER (window), 8); + + vbox = gtk_vbox_new (FALSE, 8); + gtk_container_add (GTK_CONTAINER (window), vbox); + + label = gtk_label_new ("This is the bug list (note: not based on real data, it would be nice to have a nice ODBC interface to bugzilla or so, though)."); + gtk_box_pack_start (GTK_BOX (vbox), label, 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_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0); + + /* create tree model */ + model = create_model (); + + /* create tree view */ + treeview = gtk_tree_view_new_with_model (model); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE); + gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview), + COLUMN_DESCRIPTION); + + g_object_unref (G_OBJECT (model)); + + gtk_container_add (GTK_CONTAINER (sw), treeview); + + /* add columns to the tree view */ + add_columns (GTK_TREE_VIEW (treeview)); + + /* finish & show */ + gtk_window_set_default_size (GTK_WINDOW (window), 280, 250); + } + + if (!GTK_WIDGET_VISIBLE (window)) + gtk_widget_show_all (window); + else + { + gtk_widget_destroy (window); + window = NULL; + } + + return window; +} diff --git a/demos/gtk-demo/main.c b/demos/gtk-demo/main.c index 00fabe74af..b40f6ec1ea 100644 --- a/demos/gtk-demo/main.c +++ b/demos/gtk-demo/main.c @@ -408,6 +408,7 @@ load_file (const gchar *filename) { gchar *p = buffer->str; gchar *q; + gchar *r; switch (state) { @@ -415,6 +416,11 @@ load_file (const gchar *filename) /* Reading title */ while (*p == '/' || *p == '*' || isspace (*p)) p++; + r = p; + while (*r != '/' && strlen (r)) + r++; + if (strlen (r) > 0) + p = r + 1; q = p + strlen (p); while (q > p && isspace (*(q - 1))) q--; @@ -532,28 +538,34 @@ button_press_event_cb (GtkTreeView *tree_view, FUNC_COLUMN, &func, ITALIC_COLUMN, &italic, -1); - gtk_tree_store_set (GTK_TREE_STORE (model), - &iter, - ITALIC_COLUMN, !italic, - -1); - window = (func) (); - if (window != NULL) - { - CallbackData *cbdata; - - cbdata = g_new (CallbackData, 1); - cbdata->model = model; - cbdata->path = path; - gtk_signal_connect (GTK_OBJECT (window), - "destroy", - GTK_SIGNAL_FUNC (window_closed_cb), - cbdata); - } - else + if (func) { - gtk_tree_path_free (path); + gtk_tree_store_set (GTK_TREE_STORE (model), + &iter, + ITALIC_COLUMN, !italic, + -1); + window = (func) (); + if (window != NULL) + { + CallbackData *cbdata; + + cbdata = g_new (CallbackData, 1); + cbdata->model = model; + cbdata->path = path; + + gtk_signal_connect (GTK_OBJECT (window), + "destroy", + GTK_SIGNAL_FUNC (window_closed_cb), + cbdata); + } + else + { + gtk_tree_path_free (path); + } } + else + gtk_tree_path_free (path); } gtk_signal_emit_stop_by_name (GTK_OBJECT (tree_view), @@ -583,24 +595,28 @@ row_activated_cb (GtkTreeView *tree_view, FUNC_COLUMN, &func, ITALIC_COLUMN, &italic, -1); - gtk_tree_store_set (GTK_TREE_STORE (model), - &iter, - ITALIC_COLUMN, !italic, - -1); - window = (func) (); - if (window != NULL) + if (func) { - CallbackData *cbdata; - - cbdata = g_new (CallbackData, 1); - cbdata->model = model; - cbdata->path = gtk_tree_path_copy (path); + gtk_tree_store_set (GTK_TREE_STORE (model), + &iter, + ITALIC_COLUMN, !italic, + -1); + window = (func) (); - gtk_signal_connect (GTK_OBJECT (window), - "destroy", - GTK_SIGNAL_FUNC (window_closed_cb), - cbdata); + if (window != NULL) + { + CallbackData *cbdata; + + cbdata = g_new (CallbackData, 1); + cbdata->model = model; + cbdata->path = gtk_tree_path_copy (path); + + gtk_signal_connect (GTK_OBJECT (window), + "destroy", + GTK_SIGNAL_FUNC (window_closed_cb), + cbdata); + } } } @@ -617,7 +633,8 @@ selection_cb (GtkTreeSelection *selection, gtk_tree_model_get_value (model, &iter, FILENAME_COLUMN, &value); - load_file (g_value_get_string (&value)); + if (g_value_get_string (&value)) + load_file (g_value_get_string (&value)); g_value_unset (&value); } @@ -668,7 +685,6 @@ create_text (GtkTextBuffer **buffer, return scrolled_window; } -/* Technically a list, but if we do go to 80 demos, we may want to move to a tree */ static GtkWidget * create_tree (void) { @@ -678,7 +694,8 @@ create_tree (void) GtkTreeViewColumn *column; GtkTreeStore *model; GtkTreeIter iter; - gint i; + + Demo *d = testgtk_demos; model = gtk_tree_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN); tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); @@ -688,17 +705,44 @@ create_tree (void) GTK_SELECTION_BROWSE); gtk_widget_set_size_request (tree_view, 200, -1); - for (i=0; i < G_N_ELEMENTS (testgtk_demos); i++) + /* this code only supports 1 level of children. If we + * want more we probably have to use a recursing function. + */ + while (d->title) { + Demo *children = d->children; + gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL); gtk_tree_store_set (GTK_TREE_STORE (model), &iter, - TITLE_COLUMN, testgtk_demos[i].title, - FILENAME_COLUMN, testgtk_demos[i].filename, - FUNC_COLUMN, testgtk_demos[i].func, + TITLE_COLUMN, d->title, + FILENAME_COLUMN, d->filename, + FUNC_COLUMN, d->func, ITALIC_COLUMN, FALSE, -1); + + d++; + + if (!children) + continue; + + while (children->title) + { + GtkTreeIter child_iter; + + gtk_tree_store_append (GTK_TREE_STORE (model), &child_iter, &iter); + + gtk_tree_store_set (GTK_TREE_STORE (model), + &child_iter, + TITLE_COLUMN, children->title, + FILENAME_COLUMN, children->filename, + FUNC_COLUMN, children->func, + ITALIC_COLUMN, FALSE, + -1); + + children++; + } } cell = gtk_cell_renderer_text_new (); @@ -719,6 +763,8 @@ create_tree (void) g_signal_connect (G_OBJECT (selection), "changed", GTK_SIGNAL_FUNC (selection_cb), model); g_signal_connect (G_OBJECT (tree_view), "row_activated", GTK_SIGNAL_FUNC (row_activated_cb), model); + gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view)); + return tree_view; } diff --git a/demos/gtk-demo/stock_browser.c b/demos/gtk-demo/stock_browser.c index 0622d40ec8..5594a423d6 100644 --- a/demos/gtk-demo/stock_browser.c +++ b/demos/gtk-demo/stock_browser.c @@ -1,4 +1,4 @@ -/* Stock Item/Icon Browser +/* 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 diff --git a/demos/gtk-demo/tree_store.c b/demos/gtk-demo/tree_store.c new file mode 100644 index 0000000000..92e68b6903 --- /dev/null +++ b/demos/gtk-demo/tree_store.c @@ -0,0 +1,446 @@ +/* Tree View/Tree Store + * + * The GtkTreeStore is used to store data in tree form, to be + * used later on by a GtkTreeView to display it. This demo builds + * a simple GtkTreeStore and displays it. If you're new to the + * GtkTreeView widgets and associates, look into the GtkListStore + * example first. + * + */ + +#include <gtk/gtk.h> + +static GtkWidget *window = NULL; + +/* TreeItem structure */ +typedef struct _TreeItem TreeItem; +struct _TreeItem +{ + const gchar *label; + gboolean alex; + gboolean havoc; + gboolean tim; + gboolean owen; + gboolean dave; + gboolean world_holiday; /* shared by the European hackers */ + TreeItem *children; +}; + +/* columns */ +enum +{ + HOLIDAY_NAME_COLUMN = 0, + ALEX_COLUMN, + HAVOC_COLUMN, + TIM_COLUMN, + OWEN_COLUMN, + DAVE_COLUMN, + + VISIBLE_COLUMN, + WORLD_COLUMN, + NUM_COLUMNS +}; + +/* tree data */ +static TreeItem january[] = +{ + {"New Years Day", TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + {"Presidential Inauguration", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL }, + {"Martin Luther King Jr. day", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL }, + { NULL } +}; + +static TreeItem february[] = +{ + { "Presidents' Day", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL }, + { "Groundhog Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Valentine's Day", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, NULL }, + { NULL } +}; + +static TreeItem march[] = +{ + { "National Tree Planting Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "St Patrick's Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL }, + { NULL } +}; +static TreeItem april[] = +{ + { "April Fools' Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL }, + { "Army Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Earth Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL }, + { "Administrative Professionals' Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { NULL } +}; + +static TreeItem may[] = +{ + { "Nurses' Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "National Day of Prayer", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Mothers' Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL }, + { "Armed Forces Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Memorial Day", TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + { NULL } +}; + +static TreeItem june[] = +{ + { "June Fathers' Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL }, + { "Juneteenth (Liberation of Slaves)", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Flag Day", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL }, + { NULL } +}; + +static TreeItem july[] = +{ + { "Parents' Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL }, + { "Independence Day", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL }, + { NULL } +}; + +static TreeItem august[] = +{ + { "Air Force Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Coast Guard Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Friendship Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { NULL } +}; + +static TreeItem september[] = +{ + { "Grandparents' Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL }, + { "Citizenship Day or Constitution Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Labor Day", TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + { NULL } +}; + +static TreeItem october[] = +{ + { "National Children's Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Bosses' Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Sweetest Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Mother-in-Law's Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Navy Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Columbus Day", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL }, + { "Halloween", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL }, + { NULL } +}; + +static TreeItem november[] = +{ + { "Marine Corps Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Veterans' Day", TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + { "Thanksgiving", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL }, + { NULL } +}; + +static TreeItem december[] = +{ + { "Pearl Harbor Remembrance Day", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { "Christmas", TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + { "Kwanzaa", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { NULL } +}; + + +static TreeItem toplevel[] = +{ + {"January", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, january}, + {"February", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, february}, + {"March", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, march}, + {"April", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, april}, + {"May", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, may}, + {"June", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, june}, + {"July", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, july}, + {"August", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, august}, + {"September", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, september}, + {"October", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, october}, + {"November", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, november}, + {"December", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, december}, + {NULL} +}; + + +static GtkTreeModel * +create_model (void) +{ + GtkTreeStore *model; + GtkTreeIter iter; + TreeItem *month = toplevel; + + /* create tree store */ + model = gtk_tree_store_new (NUM_COLUMNS, + G_TYPE_STRING, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN); + + /* add data to the tree store */ + while (month->label) + { + TreeItem *holiday = month->children; + + gtk_tree_store_append (model, &iter, NULL); + gtk_tree_store_set (model, &iter, + HOLIDAY_NAME_COLUMN, month->label, + ALEX_COLUMN, FALSE, + HAVOC_COLUMN, FALSE, + TIM_COLUMN, FALSE, + OWEN_COLUMN, FALSE, + DAVE_COLUMN, FALSE, + VISIBLE_COLUMN, FALSE, + WORLD_COLUMN, FALSE, + -1); + + /* add children */ + while (holiday->label) + { + GtkTreeIter child_iter; + + gtk_tree_store_append (model, &child_iter, &iter); + gtk_tree_store_set (model, &child_iter, + HOLIDAY_NAME_COLUMN, holiday->label, + ALEX_COLUMN, holiday->alex, + HAVOC_COLUMN, holiday->havoc, + TIM_COLUMN, holiday->tim, + OWEN_COLUMN, holiday->owen, + DAVE_COLUMN, holiday->dave, + VISIBLE_COLUMN, TRUE, + WORLD_COLUMN, holiday->world_holiday, + -1); + + holiday++; + } + + month++; + } + + return GTK_TREE_MODEL (model); +} + +static void +item_toggled (GtkCellRendererToggle *cell, + gchar *path_str, + gpointer data) +{ + GtkTreeModel *model = (GtkTreeModel *)data; + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + GtkTreeIter iter; + gboolean toggle_item; + + gint *column; + + column = g_object_get_data (G_OBJECT (cell), "column"); + + /* get toggled iter */ + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, column, &toggle_item, -1); + + /* do something with the value */ + toggle_item ^= 1; + + /* set new value */ + gtk_tree_store_set (GTK_TREE_STORE (model), &iter, column, + toggle_item, -1); + + /* clean up */ + gtk_tree_path_free (path); +} + +static void +add_columns (GtkTreeView *treeview) +{ + gint col_offset; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeModel *model = gtk_tree_view_get_model (treeview); + + /* column for holiday names */ + renderer = gtk_cell_renderer_text_new (); + g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL); + + col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + -1, "Holiday", + renderer, "text", + HOLIDAY_NAME_COLUMN, + NULL); + column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1); + gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); + + /* alex column */ + renderer = gtk_cell_renderer_toggle_new (); + g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL); + g_object_set_data (G_OBJECT (renderer), "column", (gint *)ALEX_COLUMN); + + g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (item_toggled), + model); + col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + -1, "Alex", + renderer, + "active", + ALEX_COLUMN, + "visible", + VISIBLE_COLUMN, + "activatable", + WORLD_COLUMN, NULL); + + column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1); + gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), + GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 50); + gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); + + /* havoc column */ + renderer = gtk_cell_renderer_toggle_new (); + g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL); + g_object_set_data (G_OBJECT (renderer), "column", (gint *)HAVOC_COLUMN); + + g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (item_toggled), + model); + col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + -1, "Havoc", + renderer, + "active", + HAVOC_COLUMN, + "visible", + VISIBLE_COLUMN, + NULL); + + column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1); + gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), + GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 50); + gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); + + /* tim column */ + renderer = gtk_cell_renderer_toggle_new (); + g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL); + g_object_set_data (G_OBJECT (renderer), "column", (gint *)TIM_COLUMN); + + g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (item_toggled), + model); + col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + -1, "Tim", + renderer, + "active", + TIM_COLUMN, + "visible", + VISIBLE_COLUMN, + "activatable", + WORLD_COLUMN, NULL); + + column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1); + gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), + GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 50); + gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); + + /* owen column */ + renderer = gtk_cell_renderer_toggle_new (); + g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL); + g_object_set_data (G_OBJECT (renderer), "column", (gint *)OWEN_COLUMN); + + g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (item_toggled), + model); + col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + -1, "Owen", + renderer, + "active", + OWEN_COLUMN, + "visible", + VISIBLE_COLUMN, + NULL); + + column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1); + gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), + GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 50); + gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); + + /* dave column */ + renderer = gtk_cell_renderer_toggle_new (); + g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL); + g_object_set_data (G_OBJECT (renderer), "column", (gint *)DAVE_COLUMN); + + g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (item_toggled), + model); + col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + -1, "Dave", + renderer, + "active", + DAVE_COLUMN, + "visible", + VISIBLE_COLUMN, + NULL); + + column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1); + gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), + GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 50); + gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); +} + +GtkWidget * +do_tree_store (void) +{ + if (!window) + { + GtkWidget *vbox; + GtkWidget *sw; + GtkWidget *treeview; + GtkTreeModel *model; + + /* create window, etc */ + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "Card planning sheet"); + g_signal_connect (G_OBJECT (window), "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + vbox = gtk_vbox_new (FALSE, 8); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 8); + gtk_container_add (GTK_CONTAINER (window), vbox); + + gtk_box_pack_start (GTK_BOX (vbox), + gtk_label_new ("Jonathan's Holiday Card Planning Sheet"), + 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_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0); + + /* create model */ + model = create_model (); + + /* create tree view */ + treeview = gtk_tree_view_new_with_model (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_MULTIPLE); + + add_columns (GTK_TREE_VIEW (treeview)); + + gtk_container_add (GTK_CONTAINER (sw), treeview); + + g_signal_connect (G_OBJECT (treeview), "realize", + G_CALLBACK (gtk_tree_view_expand_all), NULL); + gtk_window_set_default_size (GTK_WINDOW (window), 650, 400); + } + + if (!GTK_WIDGET_VISIBLE (window)) + gtk_widget_show_all (window); + else + { + gtk_widget_destroy (window); + window = NULL; + } + + return window; +} |