[Gtk-sharp-list] Heterogeneous Nodes In Gtk.NodeView / Gtk.NodeStore

Slug toddglodek at hotmail.com
Sun Apr 19 13:47:28 EDT 2009


I have a requirement to have a tree that contains different node types at
different levels.  I have gotten  this to work using the TreeView /
TreeStore data structures, but it was so cumbersome to support that I tried
the NodeView / NodeStore pattern as a test.  So following the example of
songs provided in the Tutorial
(http://mono-project.com/GtkSharpNodeViewTutorialExamples ), My requirement
would be to have tree something like this:

ARTIST                    SONG
-----------                     ----------
60s ROCK
  -  Beatles              Yesterday.
NOT 60s ROCK
  -  Peter Gabriel      In Your Eyes
  -  Rush                 Fly By Night

So I modified the example as follows, and I ran into a few issues/questions
that I thought I might share:

namespace NodeViewTutorial {
 		
     //  [Gtk.TreeNode (ListOnly=true)]    <<  COMMENT THAT OUT
    public class MyTreeNode : Gtk.TreeNode {
 
            string song_title;

            public MyTreeNode (string artist, string song_title)
            {
                    Artist = artist;
                    this.song_title = song_title;
            }

            [Gtk.TreeNodeValue (Column=0)]
            public string Artist;

            [Gtk.TreeNodeValue (Column=1)]
            public string SongTitle {get { return song_title; } }
    }
		 
        public class NodeViewExample : Gtk.Window {
 
                public NodeViewExample () : base ("NodeView")
                {
                        SetSizeRequest (200,150);
 
                        // Create our TreeView and add it as our child
widget
                        Gtk.NodeView view = new Gtk.NodeView (Store);
                        Add (view);
 
                        // Create a column with title Artist and bind its
renderer to model column 0
                        view.AppendColumn ("Artist", new
Gtk.CellRendererText (), "text", 0);
 
                        // Create a column with title 'Song Title' and bind
its renderer to model column 1
                        view.AppendColumn ("Song Title", new
Gtk.CellRendererText (), "text", 1);
                        view.ShowAll ();
                }
 
                protected override bool OnDeleteEvent (Gdk.Event ev)
                {
                        Gtk.Application.Quit ();
                        return true;
                }
 
                Gtk.NodeStore store;
                Gtk.NodeStore Store {
                        get {
                            if (store == null) {
                                    store = new Gtk.NodeStore (typeof
(MyTreeNode));					
				     MyTreeNode tParentNode = new MyTreeNode ("The Beatles",
"Yesterday");  
				     store.AddNode (tParentNode);
										
                                    tParentNode.AddChild (new MyTreeNode
("Peter Gabriel", "In Your Eyes")); // USE ADD CHILD
                                    tParentNode.AddChild (new MyTreeNode
("Rush", "Fly By Night"));             // USE ADD CHILD
                            }
                            return store;
                        }
                }
 
                public static void Main ()
                {
                        Gtk.Application.Init ();
                        NodeViewExample win = new NodeViewExample ();
                        win.Show ();
                        Gtk.Application.Run ();
                }
 
        }
}


Lesson Learned :  
1)    If you leave the  "    [Gtk.TreeNode (ListOnly=true)]    "  ON it will
only display the top level nodes 
       in the tree (never the child nodes ).   So comment that bit out, and
the tree will work !! 
2)    If you put in an abstract node type in the store constructor ( e.g.
Gtk.NodeStore (typeof (Gtk.TreeNode) )  ) - the
       whole thing loads, but crashes later when it tries to display the
tree.

This was important because I wanted to create a second class 

		public class GenreNode : Gtk.TreeNode {		
                        [Gtk.TreeNodeValue (Column=0)]		
			public string Genre {get; set; }
		}
		
and then change the way the store gets loaded to something like this 

		GenreNode t60sRock = new GenreNode() {Genre = "60s Rock" };
		store.AddNode( t60sRock );					
                t60sRock.AddChild (new MyTreeNode ("The Beatles",
"Yesterday"));
					
                GenreNode tNot60sRock = new GenreNode() {Genre = "Not 60s
Rock"};
		store.AddNode( tNot60sRock );
					
                tNot60sRock.AddChild (new MyTreeNode ("Peter Gabriel", "In
Your Eyes"));
                tNot60sRock.AddChild (new MyTreeNode ("Rush", "Fly By
Night"));

I would hope that it would produce the tree I drew above (which can be
acheived using the TreeView/TreeStore).  I was hopeful because NodeView
inherits from TreeView. But instead the approach just crashes too with now
exception thrown.

It seems hopeless because we need to pass the node's class type into the
store's constructor.  Its there some some hidden instantiation going on
behind the scenes that breaks it?   Why is it necessary to pass the type
anyway?  Why restrict the all the nodes in a tree to a single type ??  Would
it be possible to just capture the type of each individual node (
t60sRock.GetType() ) as it is added and track that inside the NodeStore
somewhere unseen?

So my question is..  has anybody gotten something like this this to work? 
If so I would really appreciate hearing about it.

thanks - SLUG
		
-- 
View this message in context: http://www.nabble.com/Heterogeneous-Nodes-In-Gtk.NodeView---Gtk.NodeStore-tp23125428p23125428.html
Sent from the Mono - Gtk# mailing list archive at Nabble.com.



More information about the Gtk-sharp-list mailing list