[Urwid] redesigning the tree API

Patrick Totzke patricktotzke at gmail.com
Fri Oct 12 18:23:39 EDT 2012


Hi again!

I have a proof of concept for the Walker classes. So far we lack a complementary
TreeBox widget to display structures represented by these though.

You can find the code here: https://github.com/pazz/urwidtrees

These Walkers are compatible with the current ListWalker API;
In fact, the provided examples work by passing them on to a ListBox,
that displays all nodes of the trees in depth-first order.

Quoting Ian Ward (2012-10-09 23:29:27)
> On Mon, Oct 8, 2012 at 10:48 AM, Patrick Totzke <patricktotzke at gmail.com> wrote:
> > Hi all,
> >
> > some thoughts about $topic, as recently posted in #urwid:
> >
> > 08:52:27 <pazz> I stopped trying to improve this and started thinking about how the API *should* be. how
> >                 do you feel about the following:
> > 08:58:42 <pazz> we introdude a TreeWalker, that depends on virtual methods get_[previous|next]_sibbling,
> >                 get_parent, and get_children, each getting one key. if you want to make anything usefull,
> >                 you must overwrite them, otherwise they default to "return None", which means that there
> >                 is nothing.
> 
> Yes, this is sensible.
> 
> > 08:59:35 <pazz> based on this, we define get_[next|previous], that takes a key and returns the next key in
> >                 depth-first order.
> > 09:00:29 <pazz> Now we introduce a TreeBox, that like ListBox works on a TreeWalker.
> 
> I would really like this to work without any custom ListBox at all (if
> the user likes).

Yes, it does atm.
> 
> Currently TreeListBox adds 'home'/'end' handling, which really should
> apply to any ListBox.  The new List Walker API supports use of a
> "positions" method that returns an iterable that could be used for
> this purpose in the normal ListBox widget:

I see. Not sure if this makes sense for trees, but it could be easily added based on
get_next/prev.
> 
> The "collapse" and "move to parent" functions are probably still best
> implemented in a ListBox subclass, however.  At least factoring out
> the 'home'/'end' behaviour would make that class simpler.

Agreed. this stuff should be part of some TreeBox that displays the walker.

> > 09:01:57 <pazz> In fact, we can now let ListBox derive from TreeBox, because a ListWalker is just a
> >                 TreeWalker that lets the get_[parent|children] methods untouched.
> 
> That seems backwards to me.  I understand that a list could be viewed
> as a special case of a tree, but since we can already implement the
> tree with a custom list walker It seems more flexible the way it is.

I am not sure in which direction we should subclass here.
For sure, a TreeWalker should be more general than a ListWalker because
if you just use the next/prev_sibbling_pos and keep the default implementation of
parent_position and first/last_child_position.. what you get is exactly a ListWalker.
But I'm open for proposals here. after all the ListBox widget is yet to be written :)

> > 09:02:58 <pazz> now all the helper ListWalker classes can derive from TreeWalker directly, so that the API
> >                 for easy tasks don't change.
> > 09:05:06 <pazz> all the fancy displaying magic goes into TreeWidget, for example the bars that indicate
> >                 the tree structure (see
> > https://github.com/pazz/alot/blob/master/extra/themes/screenshots/solarized.thread.png?raw=true)
> > 09:06:07 <pazz> or these folding icons from the current implementation. all optional, including
> >                 indentation (sth i need for my app)..
> 
> Fancy widget decorations could be generated from the TreeWalker.

aye!

> Maybe a decoration function that is passed the widget, the depth and
> any other information that might be useful for drawing little arrows
> and such could be defined.  The default could just return
> Padding(widget, 'left', ('relative, 100), left=depth*2) or something.

I think it should be the TreeBox responsible for the construction of any kind of 
decoration and not the Walker itself. I want to be able to display the same walker
with or without indentation and so on..

> The case of a static tree should be made super-easy.
> SimpleTreeWalker? :-)  positions could be tuples of indexes starting
> from the root level.
Have a look at my SimpleTreeWalker.
In fact it is a simple list-of-tree walker ATM. I think this is necessary
if you want to be able to display trees with unbounded (dynamically loaded)
children.

> TreeWidget, TreeNode and ParentNode could all be deprecated.
> 
> It might be reasonable to maintain TreeWalker backwards compatibility
> by checking if a TreeNode is passed to the TreeWalker.  Would it be
> terrible to rename the current class to LegacyTreeWalker and have one
> of those returned from TreeWalker.__new__ in the "I was passed a
> TreeNode" case?  Seems like a nicer idea than mixing the old and new
> code together in the same class.
If you think you really need backwards compatibility with the old tree api so be it.
I for myself see your point for doing so, but can't imagine that this is really used by many.
Also, i don;t have a high opinion of the current implementation so I don't think it is 
worth preserving at all.
You could also introduce urwid.depricated and put the old stuff in there..

Best,
/p
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: signature
Url : http://lists.excess.org/pipermail/urwid/attachments/20121012/ddfd887b/attachment.pgp 


More information about the Urwid mailing list