Jan-Philip Gehrcke | 18 Jul 2009 18:21

permanent prompt at the bottom, while stdout grows above (scrollable)

Hey urwid list!

I am planning a commandline application with a special design and would
like to know if urwid is the module I need to realize this :-)

The structure of the application I imagine:

1) the "endless loop part":
---------------------------
A background thread permanently runs and checks a web service let's say
every X seconds. Depending on what it sees and on special user-given
parameters it makes some decisions and runs this, this or that
function/code. During this endless process, some stdout is produced to
log to the terminal what's happening.

2) the "deterministic part":
----------------------------
The user should be able to interact with the application using a prompt
where he can enter special commands by typing "command + ENTER". When he
presses ENTER, the command is processed by the deterministic part of the
application; the "user-input-processing-part" so to say. This starts
some special code, e.g. changing some variables, running some functions
and -- of course -- producing some output to stdout, too. The code
invoked by entering a command is deterministic (not an endless loop, no
endless stdout).

Regarding the prompt and displaying stdout I would like to have the
following behaviour:
- the prompt is one line fixed on the screen (let's say on the bottom)
- Before pressing ENTER, the user should be able to move through what
(Continue reading)

Max E. Kuznecov | 19 Jul 2009 21:21
Picon
Gravatar

TextCanvas rendering multibyte strings

Hi,
I've found a strange behaviour of TextCanvas in my application: it is
a visual shell, like mc.
The idea is well-known: I display filesystem objects in two panels,
each object can have different atrributes depending on its type, name
etc.
So I found that filenames in multibyte characters (in my case
-cyrillic) are incorrectly rendered, more precisely - background
doesn't fit into overall panel width (see attached screenshot).
You can see that both objects with cyrillic names have a  trailing
block not covered with required palette, while file with latin name
(XYZ) renders just fine.
Code is something like:

x = lowui.TextCanvas(text=[_text],
                                     attr=[[(_own_attr, maxcol)]],
                                     maxcol=maxcol)
                canvases.append((x, i, False))

It cycles through all objects in directory, renders it one by one and
then combines canvases.

I've skimmed through TextCanvas definition - there is a line in constructor:
a_gap = len(text[i]) - rle_len( attr[i] )
which uses len() on multibyte string, I've tried to replace it with
calc_width() from utils but then I got a different error. Nevertheless
I'm not deeply familiar with urwid's internals so I'd better ask here:
Is it a bug or maybe there is a different way to achieve the desired result.
Thanks.

(Continue reading)

Ian Ward | 21 Jul 2009 13:03
Favicon
Gravatar

Re: TextCanvas rendering multibyte strings

Max E. Kuznecov wrote:
> Hi,
> I've found a strange behaviour of TextCanvas in my application: it is
> a visual shell, like mc.
> The idea is well-known: I display filesystem objects in two panels,
> each object can have different atrributes depending on its type, name
> etc.
> So I found that filenames in multibyte characters (in my case
> -cyrillic) are incorrectly rendered, more precisely - background
> doesn't fit into overall panel width (see attached screenshot).
> You can see that both objects with cyrillic names have a  trailing
> block not covered with required palette, while file with latin name
> (XYZ) renders just fine.
> Code is something like:
>
> x = lowui.TextCanvas(text=[_text],
>                                      attr=[[(_own_attr, maxcol)]],
>                                      maxcol=maxcol)
>                 canvases.append((x, i, False))
>
> It cycles through all objects in directory, renders it one by one and
> then combines canvases.
>
> I've skimmed through TextCanvas definition - there is a line in constructor:
> a_gap = len(text[i]) - rle_len( attr[i] )
> which uses len() on multibyte string, I've tried to replace it with
> calc_width() from utils but then I got a different error. Nevertheless
> I'm not deeply familiar with urwid's internals so I'd better ask here:
> Is it a bug or maybe there is a different way to achieve the desired result.
> Thanks.
(Continue reading)

Max E. Kuznecov | 21 Jul 2009 13:36
Picon
Gravatar

Re: TextCanvas rendering multibyte strings

Here you go:

#!/usr/bin/env python
#-*- coding: utf8 -*

import urwid.curses_display
import urwid

ui = urwid.curses_display.Screen()

ui.register_palette( [
    ('banner', 'black', 'light gray', ('standout', 'underline')),
    ] )

def run():
    cols, rows = ui.get_cols_rows()

    canvases = []
    canvases.append((urwid.TextCanvas(text=["Entry1"],
                                      attr=[[('banner', cols)]],
                                      maxcol=cols), 0, False))

    canvases.append((urwid.TextCanvas(text=["Entry2"],
                                      attr=[[('banner', cols)]],
                                      maxcol=cols), 1, False))
    canvases.append((urwid.TextCanvas(text=["НЕЧТО"],
                                      attr=[[('banner', cols)]],
                                      maxcol=cols), 2, False))

    combined = urwid.CanvasCombine(canvases)
(Continue reading)

Ian Ward | 21 Jul 2009 13:46
Favicon
Gravatar

Re: permanent prompt at the bottom, while stdout grows above (scrollable)

Jan-Philip Gehrcke wrote:
> Hey urwid list!
> 
> I am planning a commandline application with a special design and would
> like to know if urwid is the module I need to realize this :-)
> 
> The structure of the application I imagine:
> 
> 1) the "endless loop part":
> ---------------------------
> A background thread permanently runs and checks a web service let's say
> every X seconds. Depending on what it sees and on special user-given
> parameters it makes some decisions and runs this, this or that
> function/code. During this endless process, some stdout is produced to
> log to the terminal what's happening.

You can run a separate thread/process then put messages in a queue for 
the interface to display.  You will need to either poll that queue from 
the interface thread/process or set up your event loop to handle message 
arrival - the SelectEventLoop in the development version can do this for 
you.

> 
> 2) the "deterministic part":
> ----------------------------
> The user should be able to interact with the application using a prompt
> where he can enter special commands by typing "command + ENTER". When he
> presses ENTER, the command is processed by the deterministic part of the
> application; the "user-input-processing-part" so to say. This starts
> some special code, e.g. changing some variables, running some functions
(Continue reading)

Ian Ward | 21 Jul 2009 15:22
Favicon
Gravatar

Re: TextCanvas rendering multibyte strings

Max E. Kuznecov wrote:
>     canvases.append((urwid.TextCanvas(text=["НЕЧТО"],
>                                       attr=[[('banner', cols)]],
>                                       maxcol=cols), 2, False))

try this instead:

canvases.append((urwid.AttrWrap(urwid.Text('НЕЧТО'),
                                 'banner').render((cols,)), 2, False))

The TextCanvas attr parameter is a list of (attribute, num_bytes) not 
(attribute, columns), so you could calculate that yourself or just let 
Text do it like I did above.

Ian

_______________________________________________
Urwid mailing list
Urwid <at> lists.excess.org
http://lists.excess.org/mailman/listinfo/urwid
Max E. Kuznecov | 21 Jul 2009 16:06
Picon
Gravatar

Re: TextCanvas rendering multibyte strings

Works like charm ;) Thanks.

2009/7/21 Ian Ward <ian <at> excess.org>:
> Max E. Kuznecov wrote:
>>     canvases.append((urwid.TextCanvas(text=["НЕЧТО"],
>>                                       attr=[[('banner', cols)]],
>>                                       maxcol=cols), 2, False))
>
> try this instead:
>
> canvases.append((urwid.AttrWrap(urwid.Text('НЕЧТО'),
>                                 'banner').render((cols,)), 2, False))
>
> The TextCanvas attr parameter is a list of (attribute, num_bytes) not
> (attribute, columns), so you could calculate that yourself or just let
> Text do it like I did above.
>
> Ian
>
>
> _______________________________________________
> Urwid mailing list
> Urwid <at> lists.excess.org
> http://lists.excess.org/mailman/listinfo/urwid
>

--

-- 
~syhpoon

_______________________________________________
(Continue reading)

Jan-Philip Gehrcke | 27 Jul 2009 06:21

ListBox magically scrolls with mousewheel (but only with a self-written main loop)

Hello list,

while Ian says that a "ListBox doesn't have code to scroll on mouse 
wheel events", I noticed that it works accidentally, but only with my 
self-written main loop, not with the new urwid.MainLoop() from the 
development version. Due to a lack of time, I did not reduce my working 
examples to the absolutely necessary to reproduce the issue (feature!), 
but the examples are short anyway :-)

1) It scrolls!
==============
The following piece of code starts a self-written urwid main loop in the 
main thread, while another thread writes 100 lines of stuff into a file. 
Within urwid's main loop this file is polled and the content is 
displayed as new urwid.Text()'s in the ListBox. The overall amout of 
items in the ListBox is limited to 50:

http://paste.pocoo.org/show/nrbHdItPOpyzAApYfLpQ/

Okay, after you've started the script, you will soon have reached the 
final state: a ListBox, populated with 50 items. When I then use my 
mousewheel, it scrolls the ListBox; it works like a charm. Is this true 
on your machines, too? I've tested it on Ubuntu 9.04 with "terminal" and 
"konsole", with "raw_diplay" and "curses_display" and with urwid 0.9.8.4 
and the latest hg tip: it just works :-)

2) It doesn't :(
================
I've another example code that populates the ListBox, but this time with 
an os.pipe() (that's not interesting for now). The main difference is, 
(Continue reading)

Jan-Philip Gehrcke | 27 Jul 2009 07:39

Re: ListBox magically scrolls with mousewheel (but only with a self-written main loop)

I believe that this change: http://pastebin.com/f6b6d19e4
is needed to get example (2) working properly. Ian found this yesterday evening and I think it's not committed until now.


2009/7/27 Jan-Philip Gehrcke <jgehrcke <at> googlemail.com>
Hello list,

while Ian says that a "ListBox doesn't have code to scroll on mouse wheel events", I noticed that it works accidentally, but only with my self-written main loop, not with the new urwid.MainLoop() from the development version. Due to a lack of time, I did not reduce my working examples to the absolutely necessary to reproduce the issue (feature!), but the examples are short anyway :-)

1) It scrolls!
==============
The following piece of code starts a self-written urwid main loop in the main thread, while another thread writes 100 lines of stuff into a file. Within urwid's main loop this file is polled and the content is displayed as new urwid.Text()'s in the ListBox. The overall amout of items in the ListBox is limited to 50:

http://paste.pocoo.org/show/nrbHdItPOpyzAApYfLpQ/

Okay, after you've started the script, you will soon have reached the final state: a ListBox, populated with 50 items. When I then use my mousewheel, it scrolls the ListBox; it works like a charm. Is this true on your machines, too? I've tested it on Ubuntu 9.04 with "terminal" and "konsole", with "raw_diplay" and "curses_display" and with urwid 0.9.8.4 and the latest hg tip: it just works :-)

2) It doesn't :(
================
I've another example code that populates the ListBox, but this time with an os.pipe() (that's not interesting for now). The main difference is, that I used urwid.MainLoop() here:

http://paste.pocoo.org/show/ZoEpBjDJ8ZZDwp0DMCMX/

Run it, see your ListBox getting populated with items and use your mouse wheel after the final state is reached: does it do anything? Not for me. The feature is gone :-)

I'm interested in the reasons for this phenomenon! And I think that official and always-working mousewheel support would be great in general!

Greetings,

Jan-Philip Gehrcke


_______________________________________________
Urwid mailing list
Urwid <at> lists.excess.org
http://lists.excess.org/mailman/listinfo/urwid
Ian Ward | 27 Jul 2009 22:09
Favicon
Gravatar

Re: ListBox magically scrolls with mousewheel (but only with a self-written main loop)

Jan-Philip Gehrcke wrote:
>     2) It doesn't :(
>     ================
>     I've another example code that populates the ListBox, but this time
>     with an os.pipe() (that's not interesting for now). The main
>     difference is, that I used urwid.MainLoop() here:
> 
>     http://paste.pocoo.org/show/ZoEpBjDJ8ZZDwp0DMCMX/
> 
>     Run it, see your ListBox getting populated with items and use your
>     mouse wheel after the final state is reached: does it do anything?
>     Not for me. The feature is gone :-)
> 
>     I'm interested in the reasons for this phenomenon! And I think that
>     official and always-working mousewheel support would be great in
>     general!

If you add "handle_mouse = False," to the MainLoop constructor this
example also scrolls.  Likely because your terminal is helpfully
converting mouse wheel events to key-presses when the application has
not asked for mouse events to be sent to it.

The proper way to add scroll wheel support would be adding some code to
ListBox.mouse_event to handle button press 4 and 5 events (possibly
after letting their children handle them, in case you have a scrolling
widget inside a scrolling widget).

Ian

Gmane