a long question for a quick answer



All,
This is a long one, sorry.  I have been trying to learn the GtkCTree widget
for a couple of days now, and stumbled across this example in the back of
the "GNOME / GTK+ Programming Bible."
Unfortunately, it had no comments in it (why would you write a book for
beginners and then not comment your example code?), so this morning I
grabbed my copy of the GTK tutorial and 
decided to comment every line until I figured it out.  If you read the
program below, you'll see how screwed up I was and exactly where I
understood what was going on.  My question is this:
I understand how the widget is populated with a tree, but this widget has
two columns, and I'm not seeing where data is told which column to go to.  

Any help would be appreciated.  
Thanks,
Shane

/** shanetree.c **/
#include <gnome.h>

gint eventDelete(GtkWidget *widget,
        GdkEvent *event,gpointer data);
gint eventDestroy(GtkWidget *widget,
        GdkEvent *event,gpointer data);
static GtkWidget *makeWidget();
static GtkCTreeNode *makeNode(GtkWidget *widget,
        GtkCTreeNode *parent,GtkCTreeNode *sibling,
        gint level,gint count);

int main(int argc,char *argv[])
{
    GtkWidget *app;
    GtkWidget *widget;

    gnome_init("xgtkctree","1.0",argc,argv);
    app = gnome_app_new("xgtkctree","GtkCTree");
    gtk_container_set_border_width(GTK_CONTAINER(app),20);
    gtk_signal_connect(GTK_OBJECT(app),"delete_event",
            GTK_SIGNAL_FUNC(eventDelete),NULL);
    gtk_signal_connect(GTK_OBJECT(app),"destroy",
            GTK_SIGNAL_FUNC(eventDestroy),NULL);

    widget = makeWidget();

    gnome_app_set_contents(GNOME_APP(app),widget);
    gtk_widget_show_all(app);
    gtk_main();
    exit(0);
}
gint eventDelete(GtkWidget *widget,
        GdkEvent *event,gpointer data) {
    return(FALSE);
}
gint eventDestroy(GtkWidget *widget,
        GdkEvent *event,gpointer data) {
    gtk_main_quit();
    return(0);
}
static GtkWidget *makeWidget()
{
    GtkCTreeNode *node1_1;
    GtkCTreeNode *node1_3;
    GtkWidget *widget;
    static gchar *titles[] = {
        "First Column",
        "Second Column"
    };

    /* create the ctree.  2 -> number of columns. 0 -> starting column to
stick the titles in,
       columns start from the number 0. titles -> the titles to stick in
those columns. */
    widget = gtk_ctree_new_with_titles(2,0,titles);
    /* make a node to stick in the ctree.  widget -> the ctree we are
currently manipulating.
       NULL -> the parent node of the one we are inserting; NULL means that
this is a root
       level or initial node.  NULL -> a sibling of the node we are
inserting; NULL means that
       there are no siblings to this node. 1 -> the textual contents of this
node; this is pointing
       to the text array  in the next function (line1 -- i think). 1 -> this
has to be the pointer 
       to the second array in the text function, because in the final
product the the 'level' value 
       only uses the numbers one and two, while the count value uses numbers
from one to four, i 
       just don't know how it's getting in there */
    node1_1 = makeNode(widget,NULL,NULL,1,1);
    /* this statement makes a node that is a sibling of node1_1, and calls
those screwy text arrays
       again. */
    makeNode(widget,NULL,node1_1,1,2);
    /* this statement makes a node that is also a sibling of node1_1, still
calling those damn arrays */
    node1_3 = makeNode(widget,NULL,node1_1,1,3);
    /* this statement makes another node that is a sibling of node1_1.
hmmm... four top level nodes --
       the final product has four lines all the way to the left (root level)
-- i may be catching on to 
       something here... */
    makeNode(widget,NULL,node1_1,1,4);
    /* the next four lines make children nodes.  two for node1_1 and two for
node1_3.  the final product
       has four lines that are indented and are shown when you click on the
little arrow thingy  -- yeah,
       i definitely think i'm on to something here. */
    makeNode(widget,node1_1,NULL,2,1);  // this is the line I use for my
example comments
    makeNode(widget,node1_1,NULL,2,2);
    makeNode(widget,node1_3,NULL,2,1);
    makeNode(widget,node1_3,NULL,2,2);
    return(widget);
}
static GtkCTreeNode *makeNode(GtkWidget *widget,
        GtkCTreeNode *parent,GtkCTreeNode *sibling,
        gint level,gint count)
{
	/* ok, now i know that this function populates the nodes we built in
the last function, but i'm having
	   issues with how exactly this is done.  this first line declares a
widget to eventually be packed into
	   the widget named 'widget' -- how original. */
    GtkCTreeNode *node;
    gchar *text[2];  // here's that damn array everybody's talking about
    gchar line1[20]; // declaration for the sprintf statement a few lines
down
    gchar line2[20]; // declaration for the sprintf statement a few lines
down
    text[0] = line1; // definition of the first array variable
    text[1] = line2; // definition of the second array variable

    /* ok, this is the part where we put the text together with the
numbers...  hold on a second -- i've got it! all those statements
       in the first function were not standard gtk calls that i just didn't
understand, they were calls to this function!  everything
       in the parenthesis was not in correct order because they weren't
actually making the nodes up there, they were just passing 
       variables to this piece of crap gtk_ctree_insert_node statement down
here. i finally understand! i am the smartest man alive! */
    sprintf(line1,"Level %d",level);
    sprintf(line2,"Number %d",count);

    /* i'm going to comment the bejesus out of this statement, using line 76
as an example, so that i can avoid more embarrassing 
       questions to the real code slingers later.  the next line here is the
actual gtk statement i thought i was dealing with above. */
    node = gtk_ctree_insert_node(GTK_CTREE(widget),
            parent, // the widget 'node1_1' is the parent of this node.
            sibling, // this node has no sibling.
            text, // here is where we insert the junk from the sprinf
statements above.
            0, // this is the spacing between the nodes pixmap and the text
elements.
            NULL,NULL,NULL,NULL, // if you want to use pixmaps for showing
the status of a node, they are specified here; we aren't using any.
            FALSE,TRUE); /* the first variable here is wheather or not this
is a leaf or a branch node, i honestly don't know which one FALSE
            				indicates, but at this point, i'm
just happy to know what the variable is for.  the second variable indicates
            				wheather or not the a branch node is
initially expanded, in this case, when i execute the final product, the 
            				children nodes are expanded, so i'm
figuring that's what TRUE indicates.  you know, after typing that last
sentance,
            				it occurred to me that the branch
node could not be expanded by default if it were in fact a leaf node, so the

            				first variable in this line (FALSE)
must mean that it is a branch node rather than a leaf node. */
    return(node); // here we send our finished product back up to the first
function.
}




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]