Published 2007-06-13 08:21:04

I'm still digging through the gtk api, checking it works as I go. (and still deciding on a name for the bindings). I've been looking at perhaps one of the two most complex widgets in Gtk, GtkTreeView. The tutorial for which looks like it weighs in at half the Full Gtk manual.

At present I've got through the first section, and got a roughed out GtkListStore to work with it. (TreeStore should come next).

For those who dont know GtkTreeView, it uses the concept of a Model, and a View.

The Model contains all the data (in rows or a tree) - GtkListStore is a model.

The View (eg. GtkTreeView and it's columns) describe how to render the view, and what columns to use from the model.

This API is pretty raw at present, Some of it can be tidied up in Javascript, others may need more work in the bindings

First part of using the tree is creating the Store.
var store = new Gtk.ListStore(
"gchararray",
"gfloat",
"gpointer",
"gboolean",
"GdkPixbuf");
At present I've used the Gtype names to define what is being stored where. - This may need simplifying, and integrating somehow with the writing mechanism as validating data types written to the tree is a bit haphazard at present.

Next, to add data, you must use what I think is the worst named Class in Gtk, Gtk.TreeIter. a better name would have probably been something like  GtkRowReaderAndWriter (bit of a mouthfull, but alot clearer.)

To use this Row reader/writer, we first have to create a blank version. Then call the append Method on the store (a bit ass backwards, but again this could be fixed with some Javascript prototype modifications.
var iter = new Gtk.TreeIter();
store.append(iter);
The append method loads the Row reader writer, so that it can access the new row.

Next we add data to the row. This is done via G.Values at present, although this may change in the future...

store.set(iter, 0, new G.Value("test"));
store.set(iter, 1, new G.Value(1.0));
store.set(iter, 2, new G.Value({ a: 1, c: 2}));
store.set(iter, 3, new G.Value(true) );
var pixbuf = Gdk.Pixbuf.newFromFile("gnome-logo-icon.png");
store.set(iter, 4, new G.Value(pixbuf) );

all this could easily be abstracted by defining a simple prototype

Gtk.ListStore.prototype.appendRow = function(rdata) {
var iter = new Gtk.TreeIter();
this.append(iter);
for(var i =0;i<rdata.length;i++) {
this.set(iter,i, new G.Value(rdata[i]));
}
}
.....
store.appendRow(["test", 1.0, {a: 1}, true, Gtk.Pixbuf.newFromFile(....)]);

Next step is to build the Widget. And the renderers (the classes that turn the data into visable data). Gtk comes with a few renderers, It will be interesting to see if creating them in Javascript is feasible.

var view = new Gtk.TreeView();
var renderer = new Gtk.CellRendererText ();
var pixrenderer = new Gtk.CellRendererPixbuf ();

Adding columns is again a little raw, as we cant use the varargs methods the C does, so we have to combine a few calls.


var col = new Gtk.TreeViewColumn();
col.setTitle("Name");
col.packStart(renderer, true);
col.addAttribute(renderer, "text", 0);
view.insertColumn( col, -1);
Again a nice wrapper could be written.

Gtk.TreeView.prototype.insertColumnAuto = function(config) {
var col = new Gtk.TreeViewColumn();
col.setTitle(config.title);
col.packStart(config.renderer, true);
col.addAttribute(config.renderer,
config.renderer.isPrototypeOf(GtkCellRenderText) ?
 "text" : "pixbuf", 0);
this.insertColumn( col, -1);
}
...
view.insertColumnAuto({
title: "text here",
renderer: new GtkCellRendererText(),
}

Merging the data and the view is done simply by setting the model.
view.setModel ( store );
window.add(view); // add it to a GtkWindow..
window.showAll();
Gtk.main();

I also had a few experiments with callbacks.

view.connect("row-activated", function(view, path, col) {
var model = view.getModel();
var iter = new Gtk.TreeIter();

if (model.getIter(iter, path)) {
var name = new G.Value();
var name2 = new G.Value();
model.getValue(iter, 0, name);
model.getValue(iter, 1, name2);
println (
"The row containing the name '"+
name.getString() +
"' has been double-clicked. holding" +
name2.getFloat()
);
model = new Gtk.ListStore(model);
model.remove(iter);
println ("removed?");
}


});
At present this is a little klunky, but again with some prototype modifications it should be pretty easy to solve.
Fetching values has to be done by creating an empty G.Value, them fetching and converting them.

The last line illustrates removing a line. - since we cant cast in Javascript, I've modified the ListStore constructor to accept either a list of strings (eg. creating it) or a store object which does effectively the same as casting.. enabling you to call the remove method on GtkListStore.

Anyway back to fighting fires with real work today...

Mentioned By:
google.com : april (84 referals)
google.com : december (55 referals)
google.com : prototype treeview (52 referals)
google.com : php treeview (33 referals)
google.com : treeview php (18 referals)
www.digitalmars.com : Digital Mars - digitalmars.D.announce - Gtk bindings to dmdscript (17 referals)
google.com : php tree view (11 referals)
google.com : treeview prototype (7 referals)
www.planet-php.net : Planet PHP (6 referals)
www.phpeye.com : gtkdjs updates - treeview liststore - Alan Knowles - PHP教程|PHP5|PEAR|框架 - Powered by HappyCMS (4 referals)
www.linuxpourtous.com : Linuxpourtous.com - gtkdjs updates - treeview liststore (4 referals)
google.com : gvalue pixbuf (4 referals)
google.com : prototype tree view (4 referals)
www.debian.org.hk : Debian HK | Debian @ Hong Kong (3 referals)
www.debian.org.hk : Planet DebianHK | Debian HK (3 referals)
google.com : insertcolumn gtk (3 referals)
google.com : javascript prototype treeview (3 referals)
google.com : javascript treeview list php (3 referals)
google.com : treeview in PHP (3 referals)
google.com : treeview php -bengtsson (3 referals)

Add Your Comment