Closed kornelski closed 4 years ago
I used sortable trees in process-viewer and bound the sorting to "hidden" columns. Here are the lines that might be interesting for you: https://github.com/GuillaumeGomez/process-viewer/blob/15e9252f096f831adda747cb693f0d5c27c1ecab/src/display_procs.rs#L66-L75 and https://github.com/GuillaumeGomez/process-viewer/blob/15e9252f096f831adda747cb693f0d5c27c1ecab/src/display_procs.rs#L177-L180
But this is the thing I'm struggling with: you're storing the data in the ListStore
. I have my data in a Vec
.
You're filling the store once, fully, with insert_with_values
, and don't seem to update later.
But if vec[7]
changed in my program, how do I know where vec[7]
's data is in the TreeView? which cell do I update?
So that's a linear search. It's going to be O(n^2) for me, because in my program I emit an event "7th row of the Vec changed, 3rd row of the Vec changed, 11th row of the Vec changed". If I use a treeiter to scan through entire store every time to find where my Vec's data ended up in, it'll be super slow.
I have my expectations set by Cocoa, where I can say "treeview.column1.text
binds to mymodel.field1
" and vec[7].field1.set()
sends a message to treeview.column1
to update itself.
but here I have column.add_attribute(&cell, "text", 0);
where 0
is the column number, not name of the field in the model.
You can try the other way around: using a vec of references to the liststore
. Then no need to have the data twice.
Does the TreeIter
survive sorting? i.e. if it was iter of 0th row, and user reverses sorting, is it going start pointing to the last row?
Good question... I'm pretty sure you can have access to the data location directly, never looked how however. If you find out, please tell me. :3
gtk_list_store_set_valuesv: assertion 'iter_is_valid (iter, list_store)' failed
Nope, I can't store iters.
I think I've got a solution:
ListStore
for 1:1 relationship with Vec
, and copy data back and forth using index<>row mappingListStore
from being mixed up by wrapping it TreeModelSort
https://stackoverflow.com/a/19063670/27009
Examples show how to bind a
ListStore
orTreeStore
to aTreeView
, but it seems like this relies on the store being the source of truth for this data, and the data to be stored as separateValue
s in separate columns.What I'm missing is how to use Rust-native type as the data source for a
TreeView
, especially if theTreeView
is sortable.My data lives in a
Vec<RustStruct>
, and I'd like to display some of the fields of that struct inTreeView
's columns.I can't find a way reliably connect the
Vec
to theListStore
or use it as the data source for theTreeView
. My naive approach of mappingvec[n]
to n-th row of theListStore
worked only for non-sortable view, but as soon as the view is sorted,Vec
indices don't correspond toListStore
rows any more, so I can't update them (without searching the whole list store for a matching row).I've tried wrapping my
RustStruct
to be aGObject
subclass:but it seems like
ListStore
wants 1:1 mapping between number of columns in theListStore
:I hoped that
TreeViewColumnExt::set_cell_data_func
would let me have one object per row, and copy its properties into separate columns of theTreeView
, but apparently that's not the way to do it.So it would be helpful for me to see an example of how to go from
struct Model {column1:RefCell<String>, column2:RefCell<String>}; Vec<Model>
to a sortableTreeView
that displays model's fields, and can update them in the UI when they change.