[Gtk-sharp-list] TreeView & Glade on win32 via .NET

McP mariano.cano@hispalinux.es
20 Apr 2003 21:02:15 +0200


Before answer, I have a question about getting the cursor in a TreeView.

In gtk+ we have in GtkTreeView this
(http://developer.gnome.org/doc/API/2.2/gtk/GtkTreeView.html#gtk-tree-view-get-cursor):
void gtk_tree_view_get_cursor(
	GtkTreeView *tree_view,
	GtkTreePath **path,
	GtkTreeViewColumn **focus_column);
Fills in path and focus_column with the current path and focus column.
If the cursor isn't currently set, then *path will be NULL. 
If no column currently has focus, then *focus_column will be NULL.

In gtk# gapi traduces it with:
public void GetCursor(Gtk.TreePath path, 
	Gtk.TreeViewColumn focus_column) 
{
   gtk_tree_view_get_cursor(Handle,path.Handle,focus_column.Handle);
}

Is this the correct traduction for pointers to pointers (**)?
With this code I have to create new TreePath and a new TreeViewColumn,
which will point to another path and column after the funcion (see
code).
Why don't use references ?

If I use GetCursor I have a System.NullReferenceException:
System.NullReferenceException: A null value was found where an object
instance was required
in (unmanaged) 06 Gtk.ListStore:gtk_tree_model_get_iter
(intptr,Gtk.TreeIter&,intptr)
in <0x00004> 06 Gtk.ListStore:gtk_tree_model_get_iter
(intptr,Gtk.TreeIter&,intptr)
in <0x00042> 00 Gtk.ListStore:GetIter (Gtk.TreeIter&,Gtk.TreePath)
in <0x0012c> 00 .MultimediaTagger:TabPressed
(object,GtkSharp.KeyPressEventArgs)

This is the code
void TabPressed(object o, KeyPressEventArgs args)
{
	Gdk.EventKey key = args.Event;
	if(key.keyval == ((uint)Gdk.Key.Tab))
	{
		TreeIter iter;
		TreeView tree = (TreeView) o;
		// I have to create new objects
		TreePath path = new TreePath();
		TreeViewColumn col = new TreeViewColumn();

		tree.GetCursor(path,col);
		try{
			tree.Model.GetIter(out iter,path);
		}
		catch(System.Exception e)
		{
			Console.WriteLine(e);
			return;
		}
		......
	
	--------------------- THE ANSWER ----------------------

If you want to have two columns (one with a pixbuf and a label and the
other with a label), you have to do this:

note: columnId.Icon == ColumnId.Name

//Don't use Pixbuf type !!!
store = new TreeStore((int)TypeFundamentals.TypeString,
	(int)TypeFundamentals.TypeString);
tvFriendsLists = new TreeView(store); // Or tvFriendLists.Model = store, as you like

//the first column
TreeViewColumn labelColumn = new TreeViewColumn();
labelColumn.Title = "Friends";

CellRenderer iconRenderer = new CellRendererPixbuf();
labelColumn.PackStart(iconRenderer, false);
//Don't use this, if you use it, it will display a warning.
//labelColumn.AddAttribute(iconRenderer, "pixbuf", (int)ColumnId.Icon);

CellRenderer labelRenderer = new CellRendererText();
labelColumn.PackStart(labelRenderer, true);
labelColumn.AddAttribute(labelRenderer, "text", (int)ColumnId.Name);

//Add the SetCellDataFunc (see down)
labelColumn.SetCellDataFunc(pixbuf_renderer,SetPixbufDelegate,IntPtr.Zero,null);

tvFriendsList.AppendColumn(labelColumn);

// let's build the column that stores the JIDs
TreeViewColumn labelColumn2 = new TreeViewColumn();
labelColumn2.Title = "JID";

CellRenderer labelRenderer2 = new CellRendererText();
labelColumn2.PackStart(labelRenderer2, true);
labelColumn2.AddAttribute(labelRenderer2, "text", (int)ColumnId.JID);

tvFriendsList.AppendColumn(labelColumn2);


//Now you can add a node
TreeModel model;
TreeIter parent = TreeIter.Zero, iter;
TreeSelection selection = tvFriendsList.Selection;

if (null != selection && selection.GetSelected(out model, ref parent))
{
	store.Append(out iter, parent);
}
else
{
	store.Append(out iter);
}

//Only add the text
//store.SetValue(iter, (int)ColumnId.Icon, 
//	new Value(new Gdk.Pixbuf("test.png")));
store.SetValue(iter, (int)ColumnId.Name, new Value("Simon"));
store.SetValue(iter, (int)ColumnId.JID, new Value("simon@wherever.com"));


Now we have to add the correct pixbuf to each cell. You have to use
SetCellDataFunc. 
I'm working on a MP3-Ogg 'Tagger', and solved it with something like
this:

1) Declare a delegate function
TreeCellDataFunc SetPixbufDelegate = new TreeCellDataFunc(SetPixbuf);

2) Asign this function to the TreeViewColumn
col1.SetCellDataFunc(pixbuf_renderer,SetPixbufDelegate,IntPtr.Zero,null);

3) The function (this is the function I use)
static void SetPixbuf(TreeViewColumn tree_column, CellRenderer cell,
	TreeModel tree_model, TreeIter iter)
{
	GLib.Value mime;
	Gdk.Pixbuf pixbuf;
	
	tree_model.GetValue(iter,9,out mime);
	pixbuf=(Gdk.Pixbuf)pixbufHash[(string)mime];
	if(pixbuf!=null)
		cell.SetProperty("pixbuf", new Value(pixbuf));
}

-- 
McP <mariano.cano@hispalinux.es>