I have used "gintro" with a TreeView. There are some things that do not work
the way I want (for instance the impossibility in Gtk3 to use alternate colors
for rows if the theme doesn’t provide it), so I still use my previous version
in gtk2. But here is how I proceed using _gintro_.
To allocate the _ListStore_ , I use this code:
var types = [TYPE_STRING, TYPE_STRING]
let store = newListStore(2, addr(types))
Run
The types are missing in _gintro_ , so I have defined them in another file.
Here is the beginning of this file with the types:
import gintro/[gtk, gobject, glib]
import gintro/gdk except Window
const Lib* = "libgtk-3.so.0"
{.pragma: libprag, cdecl, dynlib: Lib.}
# GType values.
const
TYPE_NONE* = GType(1 shl TYPE_FUNDAMENTAL_SHIFT)
TYPE_CHAR* = GType(3 shl TYPE_FUNDAMENTAL_SHIFT)
TYPE_BOOLEAN* = GType(5 shl TYPE_FUNDAMENTAL_SHIFT)
TYPE_INT64* = GType(10 shl TYPE_FUNDAMENTAL_SHIFT)
TYPE_ENUM* = GType(12 shl TYPE_FUNDAMENTAL_SHIFT)
TYPE_STRING* = GType(16 shl TYPE_FUNDAMENTAL_SHIFT)
TYPE_OBJECT* = GType(20 shl TYPE_FUNDAMENTAL_SHIFT)
Run
I didn’t found the _typeFromName_ function, so there is a simpler way to do
what you want without using my types declaration. But, anyway, you need to
initialize an array and to pass its address to _newListStore_.
I have implemented a sort too but not when clicking on the header, so I cannot
tell you how to catch the event. To sort, you can use a selection sort or use
the reorder function of the Gtk3 API. I use the latter method. The selection
sort method is simpler but uses an algorithm which is not very efficient (but
it will be fine if you have not a lot of values to sort).
So, I build a list which contains tuples (value, position). In my case, the
values are always strings, so that is easy. Then, you sort the list and use
this sorted list to build a mapping from the new position to the old position.
Finally, you have to call the method _reorder_ of the _ListStore_ with the
address of the first element of the mapping as argument (not the address of the
sequence, of course).
Here is an excerpt of the code I use:
let store = app.store
let count = store.iterNChildren()
var sortlist = newSeqOfCap[tuple[val: string, pos: int32]](count)
var iter: TreeIter
# Build a list of tuples (value, position).
discard store.getIterFirst(iter)
var idx = 0'i32
while true:
var val: Value
store.getValue(iter, 0, val)
sortlist.add((val.getString().toUpper, idx))
if not store.iterNext(iter):
break # No more row.
idx += 1
# Sort the list.
sortlist.sort(system.cmp)
# Build the mapping new position -> old position.
var mapping = newSeq[int32](count)
var changed = false
for idx, item in sortlist:
changed = changed or idx != item.pos
mapping[idx] = item.pos
if not changed: return # Already sorted.
# Apply the reorder mapping.
app.store.reorder(addr(mapping[0]))
Run
When you click in a cell, you have the possibility to execute a callback which
gives you a path and a renderer. I think that it is possible to find the row
and column numbers from the path. In my case, as I only needed the column
number, I find it by searching the index of the renderer in a list of renderers
I keep (I think that you need a list of renderers anyway). The path is a
string, so there is still the possibility to parse it.
As I wrote this program several months ago, I don’t remember all the details,
but, for sure, _TreeView_ in Gtk is not a simple thing. Initially, the program
was written in PyQt. I converted it in Nim with Gtk2, then converted it to Gtk3
using _gintro_. And, as I have said, I don’t use the Gtk3 version despite the
_gintro_ code being cleaner.