summaryrefslogtreecommitdiff
path: root/demos
diff options
context:
space:
mode:
authorKristian Rietveld <kristian@planet.nl>2001-10-02 18:54:05 +0000
committerKristian Rietveld <kristian@src.gnome.org>2001-10-02 18:54:05 +0000
commitced4124efe73184a02b012a7e5e9fa173dcdc90f (patch)
tree5c43cee8ce99e355b211b74d9cbae6fa6cc26851 /demos
parentace5a03b9f2029f567a75be54936ea69e856fa65 (diff)
downloadgtk+-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.am3
-rw-r--r--demos/gtk-demo/appwindow.c16
-rw-r--r--demos/gtk-demo/editable_cells.c298
-rwxr-xr-xdemos/gtk-demo/geninclude.pl143
-rwxr-xr-xdemos/gtk-demo/geninclude.pl.in143
-rw-r--r--demos/gtk-demo/list_store.c220
-rw-r--r--demos/gtk-demo/main.c128
-rw-r--r--demos/gtk-demo/stock_browser.c2
-rw-r--r--demos/gtk-demo/tree_store.c446
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;
+}