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

Reply via email to