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:
>> > 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..
>>
>> This is a great point.  Decoration of a tree and the actual structure
>> of the tree are separate concerns.
>>
>> Adding decorations to a ListBox subclass wouldn't be the way to go,
>> though.  ListBox is responsible for displaying, scrolling, and passing
>> focus and the cursor position between widgets stacked vertically.
>
> So the ListBox is a special kind of Pile in fact?
> I know that Pile can be of type Flow and List can't. But conceptually, where 
> is
> the difference apart from that ListBox may display only a part of its list?
> What does Pile do if there is too little space for its entire content?
> (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.

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

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

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)
WidgetTree: provides tree of widgets (implents new tree API
get_parent, get_sibling, etc)

Subclasses of BaseTreeWalker could implement any decoration they like,
and implement folding with the widgets they return if they so choose.
I believe that folding is tied closely to the decoration.  It might
have a clickable [+] for example

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.

[...]
>> calcualte_visible is really an internal thing. It figures out which
>> widgets are visible in the ListBox given the current focus position,
>> size and list walker content.
>
> shouldn't it be "_calculate_visible" then? go for consistency :)

It should be.  Maybe I should start a list of changes for Urwid 2.0.

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

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

>> > - get_cursor_coords: i presume this is for dealing with a mouse cursor?
>> >   If so, why is this done in this widget and not some lower one?
>> >   I mean the exact location of a mouse cursor on the screen is surely 
>> > something
>> >   that one directly gets from a Screen?
>>
>> This is just part of the widget API.  See
>> http://urwid.readthedocs.org/en/latest/reference/widget.html#urwid.Widget.get_cursor_coords
>
> Do I understand correctly that this returns the position of the "keyboard 
> input cursor"
> of the terminal whithin the Widget? It's got nothing to do with the mouse 
> coursor yes?

Yes.

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

Ian

_______________________________________________
Urwid mailing list
[email protected]
http://lists.excess.org/mailman/listinfo/urwid

Reply via email to