Quoting Ian Ward (2012-10-14 15:18:05)
> On Sat, Oct 13, 2012 at 12:42 PM, Patrick Totzke
> <[email protected]> wrote:
> > Quoting Ian Ward (2012-10-13 14:47:04)
> >> On Fri, Oct 12, 2012 at 6:23 PM, Patrick Totzke <[email protected]>
> >> wrote:
> > What does Pile do if there is too little space for its entire content?
question remains..
> > (Why do these widgets not share more code)?
> Not sharing more code is mostly historical. Pile used to be a flow
> widget that contained flow widgets. Now it's a box/flow widget that
> can contain a mix of box/flow widgets (It can now actually replace
> what Frame, Divider and BoxAdapter do). But even now you could only
> really compare
>
> Pile([('flow', widget1), .. ,('flow', widgetn), SolidFill()])
>
> to
>
> ListBox(SimpleListWalker([widget1, .., widgetn])
>
> where widget1 .. widgetn fit on the screen. That's a pretty narrow
> similarity.
I see, thx.
> >> It's already the most complicated widget in the library, adding a
> >> feature that decorates widgets that come from a list walker (or tree
> >> walker) doesn't fit.
> >
> > I agree that It'd be ugly to put yet another feature into ListBox.
> > But I have no good intuition how to place ListBox into some nice
> > inheritance structure that also contains Pile and TreeBox ATM.
> > Certainly those three widgets have a lot in common and thus should share
> > code.
>
> I'm holding off on that until I rewrite the way rendering works. My
> plan is to make container and decoration widgets just return a
> description about which other widgets to render where and with what
> clipping, instead of actually doing the rendering as they do now.
> Then I can throw out lots of duplicated code in mouse event handling
> for instance.
I'd be happy to see this change. Not exactly sure what you mean but
if it leads to less code duplication and possibly the ability
to build horizontally scrolling widgets I'm in :)
> >> Here's another idea: do the decoration in a ListWalker subclass that
> >> takes a tree walker object which only implements tree operations (not
> >> a superclass or subclass of ListWalker). This way we can mix and
> >> match different types of trees and different decorations.
> >
> > I don't like this idea to be honest. Its not much different from
> > making TreeBox a WidgetWrap'ed ListBox, adding some padding to the left in
> > each line.
> > In fact, *this* would be the easy way to come up with a Widget for
> > displaying TreeWalker.
> > Maybe I'll build this as a short term solution. But its not pretty.
> > I'd like to keep the Walkers semantical objects only: no decorations, no
> > info on folding.
> > In my opinion these Walkers form some topology that one can explore by
> > means of a TreeBox-Widget
> > that defines the way one sees and moves in the structure. </metaphermode>
>
OK I added a widget to my POC repository that does exactly this.
check out https://github.com/pazz/urwidtrees
But we should be aware that this can only be a short term solution
as this means that the screen width and indentation level imply a fixed!
tree-depth one can display. In the long run I think a "TreeBox"
that generalizes ListBox, scrolling in two dimensions is inevitable!
> Maybe I explained that poorly.
>
> ListBox: knows about scrolling and selection for vertically stacked
> widgets (implements widget API)
> BaseTreeWalker: provides vertically stacked widget view of a tree of
> widgets (implements list walker API)
..called ListWalkerAdapter in my code.
> WidgetTree: provides tree of widgets (implents new tree API
> get_parent, get_sibling, etc)
Called TreeWalker in my code.
> Subclasses of BaseTreeWalker could implement any decoration they like,
> and implement folding with the widgets they return if they so choose.
agreed (for now)
> I believe that folding is tied closely to the decoration. It might
> have a clickable [+] for example
definitely. folding and decoration should be handeled in the same class:
in the Widget that displays a TreeWalker.
In my code this is TreeBox (via its ListWalkerAdapter).
> Classes that implement the tree API act as an adapter for their
> particular tree format and return widgets corresponding to the
> elements in the tree but not the decorations.
yes.
> >> Horizontal scrolling means the widgets in the ListBox would have to be
> >> fixed widgets not flow widgets.
> >
> > Yes, agreed: this is problematic. Maybe there should be some complement
> > method of
> > `pack` (that if i understand correctly computes the most compact way one
> > can display the widget),
> > namely one method that returns the size of the widget if one gives it as
> > much horizontal
> > space as it wants. For Text for instance, this would return the maximal
> > length of any contained
> > text line. One had to ensure that all basic widgets return a finite value
> > here. then this would
> > propagate to higher level containers.
>
> Text already does :-)
>
> >>> Text('Hello World').pack()
> (11, 1)
> >>> Text('Hello World').pack((10,))
> (5, 2)
Well, I meant something that gives you the horizontal space needed if you
provide
the vertical space. Something like
>>> Text('Hello World').vpack()
11
>>> Text('Hello\nWorld!').vpack()
6
> >> Having a way to display that sort of
> >> widget would be useful outside of just trees, and maybe should be a
> >> separate discussion. I've done some thinking about the best way to
> >> accomplish something like that with horizontal list boxes nested in a
> >> normal ListBox (this way we could have unbounded scrolling in all
> >> directions :-)
> >
> > How about having some widget that can display iclipped Canvases?
>
> Padding can clip a fixed widget, which is approximately the same
> thing. urwid.graphics.PythonLogo is a fixed widget made from a
> canvas.
I'd have to dig deeper here, but intuitively I'd say don't build anything on
top of ListBox because it is not erally maintainable as it is.
Lets get to the nitty gritty :)
> >> > - set_focus_valign this is to position the visible area around the
> >> > focussed widget.
> >> > It needs to be overwritten for TreeBox as the visible area is now two
> >> > dimensional.
> >> > Whats the difference to `shift_focus` and why does the latter need to
> >> > know the size
> >> > of the whole TreeBox?
> >>
> >> One acts immediately and the other does the next time one of the
> >> normal widget APIs gets the "current" size. Remember widgets
> >> don't have a size:
> >> http://urwid.readthedocs.org/en/latest/manual/widgets.html#custom-widgets
> >
> > I agree with the concept that a Widget itself has no size and can be
> > rendered
> > on a Canvas in different sizes. This means that whenever you want to
> > `render`,
> > you need to provide a size, OK.
> > But i fail to see why one would ever need that size while reacting to input.
> > I get some input, i make some internal changes, if these trigger changes
> > that need to be made
> > visible, then i trigger a 'modified' signal (or sth similar) and this in
> > turn
> > will result in the Mainloop re-rendering this Widget and *then* will
> > provide the necessary
> > dimension to `render`. Maybe I'm not seeing something obvious here but
> > `keypress` itself should
> > not need that parameter right?
>
> One case where it is needed is in an Edit widget where the text is
> wrapped. keypress(down/up) needs to know how the text is wrapped to
> figure out what the new cursor position is. ListBox also needs to
> know the size to figure out how and when update the scrolling position
> in response to up/down/page up/page down.
Edit: I see that if you press key down/up in a Edit, then the next cursor
position
depends on the way the Widget *is* currently rendered, because this is what the
user bases
his keypress on: he wants to move to the word that is currently displayes in
direction X.
But this information you can get by remembering the last size given to render().
(if the widget wasn't rendered before that input was pointless).
ListBox: I do not understand why keypress is so complicated in ListBox:
Sure, the visible part needs to be determined and this depends on the focus.
But you only really need to update this visible area when it is rendered.
So Im my opinion, keypress yould simply update the focus position
and all the complicated update-visible-part stuff should go into render(),
which already knows the size.
All in all it is good practice to keep the API as clean as possible reagrding
accepted parameters: for a user of the API it is hard to grasp why keypress
should
depend in any way on the size or colour of the widget in question.
Best,
/p
_______________________________________________
Urwid mailing list
[email protected]
http://lists.excess.org/mailman/listinfo/urwid