View previous topic :: View next topic |
Author |
Message |
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Fri Apr 08, 2011 2:40 pm Post subject: Objects and TreeModel |
|
|
While reading this Mono tutorial, I discovered the excellent setCellDataFunc and related functions. Unfortunately I'm having trouble setting up the TreeStore to use with objects. Here are the sticky points:
1) Constructing the TreeStore. Right now I'm using this:
Code: | lstSongs = new TreeStore([GType.OBJECT]); |
Is this correct when using a list of D objects?
2) Populating the store. In the example, they use an AppendValue method that I can't find any equivalent to in the GtkD documentation. Here's what I'm trying to do currently:
Code: | Song[] songs;
...
foreach (song; songs)
{
auto iter = lstSongs.append(null);
lstSongs.setValue(iter, 0, song);
} |
But there is no overload of setValue that takes an arbitrary object. The closest I could find is one that takes a Value, which I'm not sure how to use. |
|
Back to top |
|
|
Mike Wey
Joined: 07 May 2007 Posts: 428
|
Posted: Sun Apr 10, 2011 11:38 am Post subject: |
|
|
You'll probably have to use pointers, like this:
Code: |
lstSongs = new TreeStore([GType.POINTER]);
...
Song[] songs;
...
foreach (song; songs)
{
auto iter = lstSongs.append(null);
Value value = new Value():
value.init(GType.POINTER);
value.setPointer(cast(void*)song);
lstSongs.setValue(iter, 0, value);
}
|
You'll need to make sure that the GC doesn't collect the songs though. |
|
Back to top |
|
|
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Tue Apr 19, 2011 3:00 pm Post subject: |
|
|
Thanks Mike. I've actually decided to go with a custom TreeModel, following the great example in the demos. |
|
Back to top |
|
|
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Thu Apr 21, 2011 12:36 pm Post subject: |
|
|
If I can pick this thread back up, I've run into a new problem. I've gotten my custom model working nicely and now I'd like to make it filterable. Unfortunately, TreeModelFilter doesn't seem to like my subclass. Here's an outline pulled together from several files:
Code: |
class DatabaseModel : TreeModel { ... }
...while building a layout:
auto baseModel = new DatabaseModel();
auto filteredModel = new TreeModelFilter(baseModel, new TreePath("0"));
|
I get the following error:
Code: | (main:21530): Gtk-CRITICAL **: IA__gtk_tree_model_filter_new: assertion `GTK_IS_TREE_MODEL (child_model)' failed
Construction failure, null returned by gtk_tree_model_filter_new((childModel is null) ? null : childModel.getTreeModelTStruct(), (root is null) ? null : root.getTreePathStruct()) |
Any suggestions? |
|
Back to top |
|
|
Mike Wey
Joined: 07 May 2007 Posts: 428
|
Posted: Thu Apr 21, 2011 4:19 pm Post subject: |
|
|
I can't seem to reproduce this by adding a filter to the CustomList demo.
Does DatabaseModel.getTreeModelTStruct() return null? |
|
Back to top |
|
|
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Thu Apr 21, 2011 5:10 pm Post subject: |
|
|
Bizarrely, I can't reproduce it anymore either. Ah well, while you're messing with the CustomList demo, can you try using the setVisibleFunc? Here's what I'm doing:
Code: | ...
auto filtered = new TreeModelFilter(customlist, new TreePath("0"));
filtered.setVisibleFunc(cast(GtkTreeModelFilterVisibleFunc)&searchFilterFunc, null, null);
view = new TreeView(filtered);
... |
And searchFilterFunc:
Code: | int searchFilterFunc(GtkTreeModel* mod_, GtkTreeIter* iter_, void* data)
{
auto mod = new TreeModel(mod_);
auto iter = new TreeIter(iter_);
assert(mod !is null);
assert(iter !is null);
// show everything
return true;
} |
That should show everything in the model, but when I run it, it shows no items. |
|
Back to top |
|
|
Mike Wey
Joined: 07 May 2007 Posts: 428
|
Posted: Fri Apr 22, 2011 4:36 am Post subject: |
|
|
I' m having the same problem, The GtkTreeModelFilterVisibleFunc never gets called.
I've been looking trough the GtkTreeModelFilter implementation, and it uses the row-changed signal for it's filtering.
Now at the start of the signal handler it checks the path depth: (pseudocode)
Code: |
if ( pathSetInConstructor.depth >= pathFromTheSignal.depth )
return;
|
Since with lists the path is always 1 the TreeModelFilter doesn't work on lists. |
|
Back to top |
|
|
Mike Wey
Joined: 07 May 2007 Posts: 428
|
Posted: Sat Apr 23, 2011 4:52 am Post subject: |
|
|
It work if you pass null as the TreePath like this:
Code: | ...
auto filtered = new TreeModelFilter(customlist, null);
filtered.setVisibleFunc(cast(GtkTreeModelFilterVisibleFunc)&searchFilterFunc, null, null);
view = new TreeView(filtered);
... |
You can find the code for a working example here: http://pastebin.com/BrQEed8P
Only works with svn r830. |
|
Back to top |
|
|
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Wed May 04, 2011 12:09 pm Post subject: |
|
|
I've been trying to get TreeModelFilter to work with custom tree models with limited success. My filtered view accurately reflects the state of the model when the filter was instantiated with it (including child nodes), but adding child nodes to the base model after instantiating the filtered model makes it go wonky. I assume that TreeModelFilter watches the onRowInserted signal and I call the rowInserted method faithfully, but still experience weirdness and get the following GTK errors:
Code: | (filter_test:8321): GLib-GObject-CRITICAL **: g_object_set_property: assertion `G_IS_VALUE (value)' failed
(filter_test:8321): GLib-GObject-CRITICAL **: g_value_unset: assertion `G_IS_VALUE (value)' failed
|
Backtracing produces this: Code: |
gdb ./filter_test
<snip>
(gdb) r --g-fatal-warnings
Starting program: filter_test --g-fatal-warnings
[Thread debugging using libthread_db enabled]
0 = filter_test.Person (Jill)
1 = filter_test.Person (Mary)
added 'Billy' to 'Jill' at 0:0
added 'Sally' to 'Jill' at 0:1
GLib-GObject-CRITICAL **: g_object_set_property: assertion `G_IS_VALUE (value)' failed
aborting...
Program received signal SIGABRT, Aborted.
0x00007ffff71ccd05 in raise (sig=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
in ../nptl/sysdeps/unix/sysv/linux/raise.c
(gdb) bt
#0 0x00007ffff71ccd05 in raise (sig=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff71d0ab6 in abort () at abort.c:92
#2 0x00007ffff6ef5a22 in g_logv ()
from /usr/lib/x86_64-linux-gnu/libglib-2.0.so
#3 0x00007ffff6ef5aaf in g_log ()
from /usr/lib/x86_64-linux-gnu/libglib-2.0.so
#4 0x00007ffff5bd9aba in g_object_set_property (object=0xadf880,
property_name=0xabf3d0 "text", value=0x7fffffffdb90)
at /build/buildd/glib2.0-2.28.6/./gobject/gobject.c:1892
#5 0x00007ffff1f3b8dc in gtk_tree_view_column_cell_set_cell_data ()
from /usr/lib/libgtk-x11-2.0.so
#6 0x00007ffff1f23d07 in ?? () from /usr/lib/libgtk-x11-2.0.so
#7 0x00007ffff1f26e83 in ?? () from /usr/lib/libgtk-x11-2.0.so
#8 0x00007ffff1f27292 in ?? () from /usr/lib/libgtk-x11-2.0.so
#9 0x00007ffff1f27329 in ?? () from /usr/lib/libgtk-x11-2.0.so
#10 0x00007ffff67d4c46 in ?? () from /usr/lib/libgdk-x11-2.0.so
#11 0x00007ffff6eecbcd in g_main_context_dispatch ()
from /usr/lib/x86_64-linux-gnu/libglib-2.0.so
#12 0x00007ffff6eed3a8 in ?? () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so
#13 0x00007ffff6eed9f2 in g_main_loop_run ()
from /usr/lib/x86_64-linux-gnu/libglib-2.0.so
<snip>
|
My actual use is rather large and complicated, but here's a smaller, self-contained test case that exhibits the behavior: http://pastebin.com/mCtj8Xyk
Can be built with:
Code: | dmd -m64 filter_test.d -I<gtkd 'src' dir> -L<gtkd>libgtkd.a -L-ldl |
If the Code: | version=USE_FILTER; | is commented out, the example works fine.
Tested with DMD 2.052 and gtkD revision 844. |
|
Back to top |
|
|
Mike Wey
Joined: 07 May 2007 Posts: 428
|
Posted: Wed May 04, 2011 2:45 pm Post subject: |
|
|
I'm still not sure whats going on, but only the first child added has a valid iter, if you change getFlags to:
Code: | override GtkTreeModelFlags getFlags()
{
return cast(GtkTreeModelFlags)0; //GtkTreeModelFlags.ITERS_PERSIST;
} |
It starts working. |
|
Back to top |
|
|
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Wed May 04, 2011 3:23 pm Post subject: |
|
|
Yes, this does fix the problem for me. |
|
Back to top |
|
|
Mike Wey
Joined: 07 May 2007 Posts: 428
|
Posted: Wed May 04, 2011 3:31 pm Post subject: |
|
|
I found the bug that is causing this.
Because i recently moved the checks for the stamp to gtk.TreeModel the stamp isn't set when the iterFunctions are called directly.
So for the iter thats passed to rowInserted the stamp isn't set and this causes the problems. |
|
Back to top |
|
|
Mike Wey
Joined: 07 May 2007 Posts: 428
|
Posted: Wed May 04, 2011 4:02 pm Post subject: |
|
|
I've decided to revert the stamp changes. see svn r845. |
|
Back to top |
|
|
|