With GTree.cell_render_text you can not only display text, but you can also allow the user to edit a single cell's text right in the tree view by double-clicking on a cell.
To make this work you need to tell the cell renderer that a cell is editable, which you can do by setting the `EDITABLE property of the text cell renderer in question to true. You can either do this on a per-row basis (which allows you to set each single cell either editable or not) by connecting the "editable" property to a boolean type column in your tree model using attributes; or you can just do a ...
let renderer = GTree.cell_renderer_text [`EDITABLE true; ...] in
... when you create the renderer, which sets all rows in that particular renderer column to be editable.
Now that our cells are editable, we also want to be notified when a cell has been edited. This can be achieved by connecting to the cell renderer's "edited" signal like this:
renderer#connect#edited ~callback:cell_edited_callback;
This callback is then called whenever a cell has been edited. We can pass a model as a parameter of the callback function, as we probably want to store the new value in the model.
The "edited" signal callback looks like this:
method edited : callback:(Gtk.tree_path -> string -> unit) -> GtkSignal.id
The tree path is passed to the "edited" signal callback. You can convert this into an iter with GTree.model#get_iter.
Note that the cell renderer will not change the data for you in the store. After a cell has been edited, you will only receive an "edited" signal. If you do not change the data in the store, the old text will be rendered again as if nothing had happened.
If you have multiple (renderer) columns with editable cells, it is not necessary to have a different callback for each renderer, you can use the same callback for all renderers, and attach some data to each renderer, which you can later retrieve again in the callback to know which renderer/column has been edited. This is done like this, for example:
... let cols = new GTree.column_list let col_name = cols#add Gobject.Data.string let col_age = cols#add Gobject.Data.int ... let cell_edited_callback index path str = ... let create_view () = ... let renderer = GTree.cell_renderer_text [`EDITABLE true] in renderer#connect#edited ~callback:(cell_edited_callback col_name.index); ... let renderer = GTree.cell_renderer_text [`EDITABLE true] in renderer#connect#edited ~callback:(cell_edited_callback col_age.index); ...
The column such as col_name and col_age has a field called index which is unique in a GTree.column_list.
You can move the cursor to a specific cell in a tree view with GTree.view#set_cursor (gtk_tree_view_set_cursor), and start editing the cell if you want to. Similarly, you can get the current row and focus column with GTree.view#get_cursor (gtk_tree_view_get_cursor). Use misc#grab_focus method (gtk_widget_grab_focus(treeview)) will make sure that the tree view has the keyboard focus.
As the API reference points out, the tree view needs to be realised for cell editing to happen. In other words: If you want to start editing a specific cell right at program startup, you need to set up an idle timeout with GMain.Idle.add (g_idle_add) that does this for you as soon as the window and everything else has been realised (return false in the timeout to make it run only once).
Connect to the tree view's "cursor-changed" and/or "move-cursor" signals to keep track of the current position of the cursor.