Commit aac3f2c8 authored by Chris Toshok's avatar Chris Toshok Committed by Chris Toshok

change things so we focus the cell and select the row, and also dispatch

2000-06-10  Chris Toshok  <toshok@helixcode.com>

	* e-table-item.c (eti_event): change things so we focus the cell
	and select the row, and also dispatch the event to that row/cell.
	This fixes the problem with the tree where you had to click twice
	to activate the tree controls.

	* Makefile.am (libetable_a_SOURCES): remove e-tree-gnode.* and add
	e-tree-simple.*
	(icons): add tree-expanded.xpm and tree-unexpanded.xpm

	* e-cell-tree.c (ect_enter_edit): defer to subcell's view.
	(ect_leave_edit): defer to subcell's view.
	(visible_depth_of_node): visual depth, taking into account that
	the root node of the model might not be displayed.
	(offset_of_node): return the offset used to shift the subcell
	over.
	(ect_draw): don't draw vertical lines if we're the leftmode node
	(a visual root node).  also, don't shift x2 by the subcell offset,
	so we get ellipses like we're supposed to.
	(ect_event): remove GDK_BUTTON_RELEASE from the list of events
	that we care about.

	* e-tree-example-1.c: lots of changes, a more dynamic UI so we can
	test tree model api stuff.

	* e-tree-gnode.c, e-tree-gnode.c: removed files, since their guts
	have been rolled into e-tree-model.c

	* e-tree-model.c, e-tree-model.h: substantially changed.  too much
	to really describe here.  this should really be considered the
	first revision of these files :)

	* e-tree-simple.c, e-tree-simple.h: analogous to e-table-simple, a
	subclass that allows the use of function pointers.

svn path=/trunk/; revision=3519
parent 835ec00d
2000-06-10 Chris Toshok <toshok@helixcode.com>
* e-table-item.c (eti_event): change things so we focus the cell
and select the row, and also dispatch the event to that row/cell.
This fixes the problem with the tree where you had to click twice
to activate the tree controls.
* Makefile.am (libetable_a_SOURCES): remove e-tree-gnode.* and add
e-tree-simple.*
(icons): add tree-expanded.xpm and tree-unexpanded.xpm
* e-cell-tree.c (ect_enter_edit): defer to subcell's view.
(ect_leave_edit): defer to subcell's view.
(visible_depth_of_node): visual depth, taking into account that
the root node of the model might not be displayed.
(offset_of_node): return the offset used to shift the subcell
over.
(ect_draw): don't draw vertical lines if we're the leftmode node
(a visual root node). also, don't shift x2 by the subcell offset,
so we get ellipses like we're supposed to.
(ect_event): remove GDK_BUTTON_RELEASE from the list of events
that we care about.
* e-tree-example-1.c: lots of changes, a more dynamic UI so we can
test tree model api stuff.
* e-tree-gnode.c, e-tree-gnode.c: removed files, since their guts
have been rolled into e-tree-model.c
* e-tree-model.c, e-tree-model.h: substantially changed. too much
to really describe here. this should really be considered the
first revision of these files :)
* e-tree-simple.c, e-tree-simple.h: analogous to e-table-simple, a
subclass that allows the use of function pointers.
2000-06-11 Christopher James Lahey <clahey@helixcode.com>
* e-table-model.c: Small syntactic changes.
......
......@@ -76,10 +76,10 @@ libetable_a_SOURCES = \
e-table-subset-variable.h \
e-table-text-model.c \
e-table-text-model.h \
e-tree-gnode.c \
e-tree-gnode.h \
e-tree-model.c \
e-tree-model.h
e-tree-model.h \
e-tree-simple.c \
e-tree-simple.h
noinst_PROGRAMS = \
table-test table-example-1 table-example-2 table-size-test tree-example-1
......@@ -159,7 +159,9 @@ icons = \
add-col.xpm \
check-empty.xpm \
check-filled.xpm \
remove-col.xpm
remove-col.xpm \
tree-expanded.xpm \
tree-unexpanded.xpm
EXTRA_DIST = \
sample.table \
......
......@@ -49,6 +49,21 @@ static ECellClass *parent_class;
static GdkPixbuf *tree_expanded_pixbuf, *tree_unexpanded_pixbuf;
#define INDENT_AMOUNT 16
static int
visible_depth_of_node (ETreeModel *tree_model, ETreePath *path)
{
return (e_tree_model_node_depth (tree_model, path)
- (e_tree_model_root_node_is_visible (tree_model) ? 0 : 1));
}
static gint
offset_of_node (ETreeModel *tree_model, ETreePath *path)
{
return (visible_depth_of_node(tree_model, path) + 1) * INDENT_AMOUNT;
}
static ETreePath*
e_cell_tree_get_node (ETreeModel *tree_model, int row)
{
......@@ -136,7 +151,6 @@ ect_unrealize (ECellView *ecv)
(* parent_class->unrealize) (ecv);
}
#define INDENT_AMOUNT 16
/*
* ECell::draw method
*/
......@@ -167,7 +181,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
*/
node = e_cell_tree_get_node (tree_model, row);
offset = (e_tree_model_node_depth (tree_model, node) + 1) * INDENT_AMOUNT;
offset = offset_of_node (tree_model, node);
expandable = e_tree_model_node_is_expandable (tree_model, node);
expanded = e_tree_model_node_is_expanded (tree_model, node);
subcell_offset = offset;
......@@ -196,15 +210,8 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
rect.x, rect.y, rect.width, rect.height);
gdk_gc_set_foreground (tree_view->gc, foreground);
/* draw our lines */
if (E_CELL_TREE(tree_view->cell_view.ecell)->draw_lines) {
/* draw our lines */
gdk_draw_line (drawable, tree_view->gc,
rect.x + offset - INDENT_AMOUNT / 2,
rect.y,
rect.x + offset - INDENT_AMOUNT / 2,
(e_tree_model_node_get_next (tree_model, node)
? rect.y + rect.height
: rect.y + rect.height / 2));
gdk_draw_line (drawable, tree_view->gc,
rect.x + offset - INDENT_AMOUNT / 2 + 1,
......@@ -212,12 +219,22 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
rect.x + offset,
rect.y + rect.height / 2);
if (visible_depth_of_node (tree_model, node) != 0) {
gdk_draw_line (drawable, tree_view->gc,
rect.x + offset - INDENT_AMOUNT / 2,
rect.y,
rect.x + offset - INDENT_AMOUNT / 2,
(e_tree_model_node_get_next (tree_model, node)
? rect.y + rect.height
: rect.y + rect.height / 2));
}
/* now traverse back up to the root of the tree, checking at
each level if the node has siblings, and drawing the
correct vertical pipe for it's configuration. */
node = e_tree_model_node_get_parent (tree_model, node);
offset -= INDENT_AMOUNT;
while (node && ! e_tree_model_node_is_root (tree_model, node)) {
while (node && visible_depth_of_node (tree_model, node) != 0) {
if (e_tree_model_node_get_next(tree_model, node)) {
gdk_draw_line (drawable, tree_view->gc,
rect.x + offset - INDENT_AMOUNT / 2,
......@@ -255,7 +272,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
subcell_offset pixels */
e_cell_draw (tree_view->subcell_view, drawable,
model_col, view_col, row, selected,
x1 + subcell_offset, y1, x2 + subcell_offset, y2);
x1 + subcell_offset, y1, x2, y2);
}
/*
......@@ -267,13 +284,12 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col,
ECellTreeView *tree_view = (ECellTreeView *) ecell_view;
switch (event->type) {
case GDK_BUTTON_PRESS:
case GDK_BUTTON_RELEASE: {
case GDK_BUTTON_PRESS: {
/* if the event happened in our area of control (and
we care about it), handle it. */
ETreeModel *tree_model = e_cell_tree_get_tree_model (ecell_view->e_table_model, row);
ETreePath *node = e_cell_tree_get_node (tree_model, row);
int offset = (e_tree_model_node_depth (tree_model, node) + 1) * INDENT_AMOUNT;
int offset = offset_of_node (tree_model, node);
/* only activate the tree control if the click/release happens in the icon's area. */
if (event->button.x > (offset - INDENT_AMOUNT) && event->button.x < offset) {
......@@ -284,6 +300,8 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col,
}
return TRUE;
}
else if (event->button.x < (offset - INDENT_AMOUNT))
return TRUE;
}
default:
/* otherwise, pass it off to our subcell_view */
......@@ -309,7 +327,10 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
static void *
ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return NULL;
/* just defer to our subcell's view */
ECellTreeView *tree_view = (ECellTreeView *) ecell_view;
return e_cell_enter_edit (tree_view->subcell_view, model_col, view_col, row);
}
/*
......@@ -318,6 +339,10 @@ ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
static void
ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
/* just defer to our subcell's view */
ECellTreeView *tree_view = (ECellTreeView *) ecell_view;
e_cell_leave_edit (tree_view->subcell_view, model_col, view_col, row, edit_context);
}
/*
......
......@@ -1197,6 +1197,14 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (!find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1))
return TRUE;
if (eti->cursor_row != row || eti->cursor_col != col){
/*
* Focus the cell, and select the row
*/
e_table_item_leave_edit (eti);
e_table_item_focus (eti, col, row);
}
if (eti->cursor_row == row && eti->cursor_col == col){
ecol = e_table_header_get_column (eti->header, col);
......@@ -1209,12 +1217,6 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e->button.y = y1;
e_cell_event (ecell_view, e, ecol->col_idx, col, row);
} else {
/*
* Focus the cell, and select the row
*/
e_table_item_leave_edit (eti);
e_table_item_focus (eti, col, row);
}
break;
case 3:
......
......@@ -4,7 +4,6 @@
#include <string.h>
#include <gnome.h>
#include "e-util/e-cursors.h"
#include "e-tree-gnode.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-item.h"
......@@ -12,6 +11,7 @@
#include "e-cell-tree.h"
#include "e-cell-checkbox.h"
#include "e-table.h"
#include "e-tree-simple.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
......@@ -56,6 +56,8 @@ char *headers [COLS] = {
"Date"
};
GtkWidget *e_table;
/*
* ETableSimple callbacks
* These are the callbacks that define the behavior of our custom model.
......@@ -73,12 +75,12 @@ my_col_count (ETableModel *etc, void *data)
return COLS;
}
/* This function returns the value at a particular point in our ETableModel. */
/* This function returns the value at a particular point in our ETreeModel. */
static void *
my_value_at (ETreeModel *etc, GNode *node, int col, void *data)
my_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data)
{
switch (col) {
case 0: return "Re: Two things";
case 0: return e_tree_model_node_get_data (etm, path);
case 1: return "Chris Toshok";
case 2: return "toshok@helixcode.com";
case 3: return "Jun 07 2000";
......@@ -86,67 +88,163 @@ my_value_at (ETreeModel *etc, GNode *node, int col, void *data)
}
}
/* This function sets the value at a particular point in our ETableModel. */
/* This function sets the value at a particular point in our ETreeModel. */
static void
my_set_value_at (ETableModel *etc, GNode *node, int col, const void *val, void *data)
my_set_value_at (ETreeModel *etm, ETreePath *path, int col, const void *val, void *model_data)
{
if (col == 0) {
char *str = e_tree_model_node_get_data (etm, path);
g_free (str);
e_tree_model_node_set_data (etm, path, g_strdup(val));
}
}
/* This function returns whether a particular cell is editable. */
static gboolean
my_is_editable (ETableModel *etc, GNode *node, int col, void *data)
my_is_editable (ETreeModel *etm, ETreePath *path, int col, void *model_data)
{
return FALSE;
if (col == 0)
return TRUE;
else
return FALSE;
}
/* This function duplicates the value passed to it. */
static void *
my_duplicate_value (ETableModel *etc, int col, const void *value, void *data)
static void
toggle_root (GtkButton *button, gpointer data)
{
ETreeModel *e_tree_model = (ETreeModel*)data;
e_tree_model_root_node_set_visible (e_tree_model, !e_tree_model_root_node_is_visible (e_tree_model));
}
static void
add_sibling (GtkButton *button, gpointer data)
{
ETreeModel *e_tree_model = E_TREE_MODEL (data);
int selected_row;
ETreePath *selected_node;
ETreePath *parent_node;
selected_row = e_table_get_selected_view_row (E_TABLE (e_table));
if (selected_row == -1)
return;
selected_node = e_tree_model_node_at_row (e_tree_model, selected_row);
g_assert (selected_node);
parent_node = e_tree_model_node_get_parent (e_tree_model, selected_node);
e_tree_model_node_insert_before (e_tree_model, parent_node,
selected_node, "User added sibling");
}
static void
add_child (GtkButton *button, gpointer data)
{
ETreeModel *e_tree_model = E_TREE_MODEL (data);
int selected_row;
ETreePath *selected_node;
selected_row = e_table_get_selected_view_row (E_TABLE (e_table));
if (selected_row == -1)
return;
selected_node = e_tree_model_node_at_row (e_tree_model, selected_row);
g_assert (selected_node);
e_tree_model_node_insert (e_tree_model, selected_node,
0, "User added child");
}
static void
remove_node (GtkButton *button, gpointer data)
{
return g_strdup (value);
ETreeModel *e_tree_model = E_TREE_MODEL (data);
int selected_row;
char *str;
ETreePath *selected_node;
selected_row = e_table_get_selected_view_row (E_TABLE (e_table));
if (selected_row == -1)
return;
selected_node = e_tree_model_node_at_row (e_tree_model, selected_row);
g_assert (selected_node);
if (e_tree_model_node_get_children (e_tree_model, selected_node, NULL) > 0)
return;
str = (char*)e_tree_model_node_remove (e_tree_model, selected_node);
printf ("removed node %s\n", str);
g_free (str);
}
/* This function frees the value passed to it. */
static void
my_free_value (ETableModel *etc, int col, void *value, void *data)
expand_all (GtkButton *button, gpointer data)
{
g_free (value);
ETreeModel *e_tree_model = E_TREE_MODEL (data);
int selected_row;
ETreePath *selected_node;
selected_row = e_table_get_selected_view_row (E_TABLE (e_table));
if (selected_row == -1)
return;
selected_node = e_tree_model_node_at_row (e_tree_model, selected_row);
g_assert (selected_node);
e_tree_model_node_set_expanded_recurse (e_tree_model, selected_node, TRUE);
}
/* This function is for when the model is unfrozen. This can mostly
be ignored for simple models. */
static void
my_thaw (ETableModel *etc, void *data)
collapse_all (GtkButton *button, gpointer data)
{
ETreeModel *e_tree_model = E_TREE_MODEL (data);
int selected_row;
ETreePath *selected_node;
selected_row = e_table_get_selected_view_row (E_TABLE (e_table));
if (selected_row == -1)
return;
selected_node = e_tree_model_node_at_row (e_tree_model, selected_row);
g_assert (selected_node);
e_tree_model_node_set_expanded_recurse (e_tree_model, selected_node, FALSE);
}
/* We create a window containing our new tree. */
static void
create_tree (void)
{
GtkWidget *e_table, *window, *frame;
GtkWidget *window, *frame, *button, *vbox;
ECell *cell_left_just;
ECell *cell_tree;
ETableHeader *e_table_header;
int i, j;
ETreeModel *e_tree_model = NULL;
GNode *root_node;
ETreePath *root_node;
/* here we create our model. This uses the functions we defined
earlier. */
e_tree_model = e_tree_simple_new (my_value_at,
my_set_value_at,
my_is_editable,
NULL);
/* create a root node with 5 children */
root_node = g_node_new (NULL);
root_node = e_tree_model_node_insert (e_tree_model, NULL,
0, g_strdup("Root Node"));
for (i = 0; i < 5; i++){
GNode *n = g_node_insert (root_node, 0, g_node_new(NULL));
ETreePath *n = e_tree_model_node_insert (e_tree_model,
root_node, 0, g_strdup("First level of children"));
for (j = 0; j < 5; j ++) {
g_node_insert (n, 0, g_node_new(NULL));
e_tree_model_node_insert (e_tree_model,
n, 0, g_strdup("Second level of children"));
}
}
/* Next we create our model. This uses the functions we defined
earlier. */
e_tree_model = e_tree_gnode_new (root_node,
my_value_at,
NULL);
/*
* Next we create a header. The ETableHeader is used in two
* different way. The first is the full_header. This is the
......@@ -200,6 +298,7 @@ create_tree (void)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* This frame is simply to get a bevel around our table. */
vbox = gtk_vbox_new (FALSE, 0);
frame = gtk_frame_new (NULL);
/*
......@@ -213,8 +312,34 @@ create_tree (void)
/* Build the gtk widget hierarchy. */
gtk_container_add (GTK_CONTAINER (frame), e_table);
gtk_container_add (GTK_CONTAINER (window), frame);
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
button = gtk_button_new_with_label ("Toggle Root Node");
gtk_signal_connect (GTK_OBJECT (button), "clicked", toggle_root, e_tree_model);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
button = gtk_button_new_with_label ("Add Sibling");
gtk_signal_connect (GTK_OBJECT (button), "clicked", add_sibling, e_tree_model);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
button = gtk_button_new_with_label ("Add Child");
gtk_signal_connect (GTK_OBJECT (button), "clicked", add_child, e_tree_model);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
button = gtk_button_new_with_label ("Remove Node");
gtk_signal_connect (GTK_OBJECT (button), "clicked", remove_node, e_tree_model);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
button = gtk_button_new_with_label ("Expand All Below");
gtk_signal_connect (GTK_OBJECT (button), "clicked", expand_all, e_tree_model);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
button = gtk_button_new_with_label ("Collapse All Below");
gtk_signal_connect (GTK_OBJECT (button), "clicked", collapse_all, e_tree_model);
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
/* Size the initial window. */
gtk_widget_set_usize (window, 200, 200);
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* e-tree-gnode.c: a Tree Model that reflects a GNode structure visually.
*
* Author:
* Chris Toshok (toshok@helixcode.com)
*
* (C) 2000 Helix Code, Inc.
*/
#include <config.h>
#include <gtk/gtksignal.h>
#include "e-util/e-util.h"
#include "e-tree-gnode.h"
#define PARENT_TYPE E_TREE_MODEL_TYPE
static ETreePath *
gnode_get_root (ETreeModel *etm)
{
ETreeGNode *etg = E_TREE_GNODE (etm);
ETreePath *path = NULL;
path = g_list_append(path, etg->root);
return path;
}
static ETreePath *
gnode_get_prev (ETreeModel *etm, ETreePath *node)
{
ETreePath *prev_path;
GNode *gnode;
GNode *prev_sibling;
g_return_val_if_fail (node && node->data, NULL);
gnode = (GNode*)node->data;
prev_sibling = g_node_prev_sibling(gnode);
if (!prev_sibling)
return NULL;
prev_path = g_list_copy (node->next);
prev_path = g_list_prepend (prev_path, prev_sibling);
return prev_path;
}
static ETreePath *
gnode_get_next (ETreeModel *etm, ETreePath *node)
{
ETreePath *next_path;
GNode *gnode;
GNode *next_sibling;
g_return_val_if_fail (node && node->data, NULL);
gnode = (GNode*)node->data;
next_sibling = g_node_next_sibling(gnode);
if (!next_sibling)
return NULL;
next_path = g_list_copy (node->next);
next_path = g_list_prepend (next_path, next_sibling);
return next_path;
}
static void *
gnode_value_at (ETreeModel *etm, ETreePath *node, int col)
{
ETreeGNode *etg = E_TREE_GNODE (etm);
GNode *gnode;
g_return_val_if_fail (node && node->data, NULL);
gnode = (GNode*)node->data;
return etg->value_at (etm, gnode, col, etg->data);
}
static void
gnode_set_value_at (ETreeModel *etm, ETreePath *node, int col, const void *val)
{
ETreeGNode *etg = E_TREE_GNODE (etm);
GNode *gnode;
g_return_if_fail (node && node->data);
gnode = (GNode*)node->data;
/* XXX */
}
static gboolean
gnode_is_editable (ETreeModel *etm, ETreePath *node, int col)
{
ETreeGNode *etg = E_TREE_GNODE (etm);
GNode *gnode;
g_return_val_if_fail (node && node->data, FALSE);
gnode = (GNode*)node->data;
/* XXX */
return FALSE;
}
static guint
gnode_get_children (ETreeModel *etm, ETreePath *node, ETreePath ***paths)
{
ETreeGNode *etg = E_TREE_GNODE (etm);
GNode *gnode;
guint n_children;
g_return_val_if_fail (node && node->data, 0);
gnode = (GNode*)node->data;
n_children = g_node_n_children (gnode);
if (paths)
{
int i;
(*paths) = g_malloc (sizeof (ETreePath*) * n_children);
for (i = 0; i < n_children; i ++) {
(*paths)[i] = g_list_copy (node);
(*paths)[i] = g_list_prepend ((*paths)[i], g_node_nth_child (gnode, i));
}
}
return n_children;
}
static void
gnode_release_paths (ETreeModel *etm, ETreePath **paths, guint num_paths)
{
guint i;
g_return_if_fail (paths);
for (i = 0; i < num_paths; i ++)
g_list_free (paths[i]);
g_free (paths);
}
static gboolean
gnode_is_expanded (ETreeModel *etm, ETreePath *node)
{
ETreeGNode *etg = E_TREE_GNODE (etm);
GNode *gnode;
g_return_val_if_fail (node && node->data, FALSE);
gnode = (GNode*)node->data;
return (gboolean)gnode->data;
}
static void
gnode_set_expanded (ETreeModel *etm, ETreePath *node, gboolean expanded)
{
ETreeGNode *etg = E_TREE_GNODE (etm);
GNode *gnode;
int num_descendents;
g_return_if_fail (node && node->data);
gnode = (GNode*)node->data;
/* XXX */
gnode->data = (gpointer)expanded;
e_table_model_changed (E_TABLE_MODEL(etm));
}
static void
e_tree_gnode_class_init (GtkObjectClass *object_class)
{
ETreeModelClass *model_class = (ETreeModelClass *) object_class;
model_class->get_root = gnode_get_root;
model_class->get_next = gnode_get_next;
model_class->get_prev = gnode_get_prev;
model_class->value_at = gnode_value_at;
model_class->set_value_at = gnode_set_value_at;
model_class->is_editable = gnode_is_editable;
model_class->get_children = gnode_get_children;
model_class->release_paths = gnode_release_paths;
model_class->is_expanded = gnode_is_expanded;
model_class->set_expanded = gnode_set_expanded;
}
E_MAKE_TYPE(e_tree_gnode, "ETreeGNode", ETreeGNode, e_tree_gnode_class_init, NULL, PARENT_TYPE)
ETreeModel *
e_tree_gnode_new (GNode *root_node,
ETreeGNodeValueAtFn value_at,
void *data)
{
ETreeGNode *etg;
etg = gtk_type_new (e_tree_gnode_get_type ());
etg->root = root_node;
etg->value_at = value_at;
etg->data = data;
return (ETreeModel*)etg;
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TREE_GNODE_H_
#define _E_TREE_GNODE_H_
#include "e-tree-model.h"
#define E_TREE_GNODE_TYPE (e_tree_gnode_get_type ())
#define E_TREE_GNODE(o) (GTK_CHECK_CAST ((o), E_TREE_GNODE_TYPE, ETreeGNode))