[Urwid] redesigning the tree API

Ian Ward ian at excess.org
Tue Oct 9 18:29:27 EDT 2012

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).

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:


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.

> 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.

> 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.
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.

The case of a static tree should be made super-easy.
SimpleTreeWalker? :-)  positions could be tuples of indexes starting
from the root level.

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.


More information about the Urwid mailing list