[wxruby-users] ReOrdering Wx::TreeCtrl Items

Alex Fenton alex at pressure.to
Wed Jan 2 18:17:19 EST 2008


Hi

EchoB wrote:
> The big picture is to be able to populate the tree control and then 
> re-order (NOT sorting) the items in the tree control. Is this possible?
>
>   
There's two ways to sort a TreeCtrl. Either

1) Subclass TreeCtrl and create an on_compare_items method in your 
subclass. This will be called whenever the 'sort_items' is called. The 
method will be passed pairs of TreeItem ids to compare, and should 
return -1, 0 or 1 to indicate whether the first item comes before, equal 
to or after the second item.

http://wxruby.rubyforge.org/doc/treectrl.html#TreeCtrl_oncompareitems

2) Maintain the order of the items as they are inserted. 
TreeCtrl#append_item is commonly used in the samples and adds the new 
item as the last child of the specified parent. But you can also add 
items to the tree using TreeCtrl#insert_item and #insert_item_before. 
With these you pass an additional argument to specify where the new item 
should be placed relative to the existing children of the parent item:

http://wxruby.rubyforge.org/doc/treectrl.html#TreeCtrl_insertitem

The second way is probably better (simpler, more efficient) if the 
project/task children in your example should always be shown in the same 
order. 1) is really useful if you want the user to be able to vary the 
order in which children are shown, for example, if you want them to be 
able to order by start date OR end date OR name.

As a side hint in case you hadn't seen this feature, if the items in a 
TreeCtrl are closely linked to program or database objects like a 
"Project" or "Task", look into using item_data (which can be passed as 
an argument to insert/append) to maintain that link. It means the 
TreeCtrl can work like a Ruby hash using get_item_data. This will make 
sorting the items easier.

Note that there is no method in Wx to _move_ a TreeItem. It must be 
deleted and re-inserted/re-appended somewhere else.
> Also I am noticing an odd thing (and I'm sure this must be something I'm 
> doing) - When looking at my TreeCtrl - Contract0/Contract1 show up at 
> the _bottom_ of the list, not at the top. Contract3 is at the top.
This is because in ruby 1.8 the order in which key/value pairs are added 
to a hash isn't guaranteed to be the order in which calling "each" and 
similar will yield the pairs. Hashes, unlike Arrays, aren't ordered. 
Testing your example with ruby 1.8, Contract3 _is_ the first key yielded 
by each.

This changes in Ruby 1.9, in which hash is ordered and "each" will 
return the items in your example in order they're declared.

cheers
alex


More information about the wxruby-users mailing list