On Wed, 14 Nov 2012 23:14:34 -0800
Keith Dart <[email protected]> wrote:
> Attached is the widget file and demo program.
Ok, new, fixed version. Sorry about the last one.
--
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Keith Dart <[email protected]>
public key: ID: 19017044
<http://www.dartworks.biz/>
=====================================================================
#!/usr/bin/python2
# -*- coding: utf-8 -*-
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
"""
Pull-down-like selector widget.
"""
import sys
import urwid
class ListScrollSelector(urwid.Widget):
"""Pulldown-like selector widget.
Emits:
click: when activiate (Enter) is pressed when focused.
change: when selection changes.
The currently selected value is available as the `value` attribute.
"""
_selectable = True
_sizing = frozenset(['flow'])
signals = ["click", "change"]
UPARR=u"â" # visual cues that you can press up and down arrows to scroll here.
DOWNARR=u"â"
def __init__(self, choicelist):
self.__super.__init__()
self._list = choicelist
self._prefix = ""
self._max = len(choicelist)
assert self._max > 0, "Need list with at least one element"
self._index = 0
self.set_text(self._list[self._index])
maxwidth = reduce(lambda c,m: max(c,m), map(lambda o: len(str(o)), choicelist), 0)
self._fmt = u"{} {{:{}.{}s}} {}".format(self.UPARR, maxwidth, maxwidth, self.DOWNARR)
def keypress(self, size, key):
cmd = self._command_map[key]
if cmd == 'cursor up':
self._prefix = ""
self._index = (self._index - 1) % self._max
self.set_text(self._list[self._index])
elif cmd == 'cursor down':
self._prefix = ""
self._index = (self._index + 1) % self._max
self.set_text(self._list[self._index])
elif cmd == "activate":
self._emit("click")
elif key == "backspace":
self._prefix = self._prefix[:-1]
elif len(key) == 1 and key.isalnum():
self._prefix += key
i = self.prefix_index(self._list, self._prefix, self._index + 1)
if i is not None:
self._index = i
self.set_text(self._list[i])
else:
return key
@staticmethod
def prefix_index(thelist, prefix, index=0):
while index < len(thelist):
if thelist[index].startswith(prefix):
return index
index += 1
return None
def rows(self, size, focus=False):
return 1
def render(self, size, focus=False):
(maxcol,) = size
text = self._fmt.format(self._text).encode("utf-8")
c = urwid.TextCanvas([text], maxcol=maxcol)
c.cursor = self.get_cursor_coords(size)
return c
def set_text(self, text):
self._text = text
self._invalidate()
self._emit("change")
def get_cursor_coords(self, size):
return None
@property
def value(self):
return self._list[self._index]
# Example usage
class TestForm(object):
LIST_HELP = {
"one": "Buckle...",
"two": "...my shoe.",
"three": "Shut...",
"four": "...the door.",
"five": "Pick up...",
"six": "...sticks.",
}
def __init__(self):
selector = ListScrollSelector(["one", "two", "three", "four", "five", "six"])
self.helptext = urwid.Text("")
urwid.connect_signal(selector, 'click', self._scroll_select)
urwid.connect_signal(selector, 'change', self._show_info)
self._show_info(selector)
cols = urwid.Columns([(25, urwid.Text("list selector:", align="right")), selector])
body = urwid.Filler(urwid.Pile([cols, self.helptext]))
self.top = urwid.Frame(body, header=urwid.Text("List selector demo"))
def _scroll_select(self, selector):
self._val = selector.value
raise urwid.ExitMainLoop()
def _show_info(self, selector):
self.helptext.set_text(TestForm.LIST_HELP[selector.value])
def unhandled_input(self, k):
if k == "esc":
raise urwid.ExitMainLoop()
def run(self):
loop = urwid.MainLoop(self.top, unhandled_input=self.unhandled_input)
loop.run()
return self._val
def main(argv):
app = TestForm()
val = app.run()
print("You selected:", val)
main(sys.argv)
_______________________________________________
Urwid mailing list
[email protected]
http://lists.excess.org/mailman/listinfo/urwid