tuikit/menu.py
author Radek Brich <radek.brich@devl.cz>
Wed, 03 Sep 2014 21:56:20 +0200
changeset 113 6796adfdc7eb
parent 63 2a0e04091898
permissions -rw-r--r--
Merge. Due to my schizophrenia, I've accidentally forked my own code. The other set of changes were found in another computer.

# -*- coding: utf-8 -*-

from tuikit.widget import Widget
from tuikit.events import GenericEvent
import logging


class Menu(Widget):
    def __init__(self, items=[]):
        Widget.__init__(self)
        w = max([len(x[0]) for x in items if x is not None]) + 4
        h = len(items) + 2
        self._default_size.update(w, h)

        self.allow_focus = True

        self.bg = 'menu'
        self.highlight = 'menu-active'
        self.items = items
        self.selected = items[0]

        self.add_events('activate', GenericEvent)

    def on_draw(self, ev):
        #logging.getLogger('tuikit').info('menu draw %s %s %s', ev, ev.x, ev.y)
        ev.driver.pushcolor(self.bg)
        ev.driver.frame(ev.x, ev.y, self.width, self.height)
        i = 1
        for item in self.items:
            if item is None:
                ev.driver.puts(ev.x, ev.y + i, ev.driver.unigraph.LTEE + \
                    ev.driver.unigraph.HLINE * (self.width - 2) + ev.driver.unigraph.RTEE)
            else:
                if self.selected == item:
                    ev.driver.pushcolor(self.highlight)
                    ev.driver.puts(ev.x + 1, ev.y + i,
                        ' ' + item[0] + ' ' * (self.width - 3 - len(item[0])))
                    ev.driver.popcolor()
                else:
                    ev.driver.puts(ev.x + 1, ev.y + i,
                        ' ' + item[0] + ' ' * (self.width - 3 - len(item[0])))
            i += 1
        ev.driver.popcolor()

    def on_keypress(self, ev):
        if ev.keyname == 'up':
            self.move_selected(-1)
            return True
        if ev.keyname in ('down', 'tab'):
            self.move_selected(+1)
            return True
        if ev.keyname == 'enter':
            self.run_selected()
            return True
        self.redraw()

    def on_mousedown(self, ev):
        self.select_at_pos(ev.wy - 1)

    def on_mousemove(self, ev):
        self.select_at_pos(ev.wy - 1)

    def on_mouseup(self, ev):
        ok = self.select_at_pos(ev.wy - 1)
        if ok:
            self.run_selected()

    def select_at_pos(self, pos):
        if pos < 0:
            return False
        try:
            item = self.items[pos]
        except IndexError:
            return False
        if item is None:
            return False
        self.selected = item
        self.redraw()
        return True

    def move_selected(self, offset):
        if self.selected:
            i = self.items.index(self.selected)
            i += offset
            item = self.items[i % len(self.items)]
            if item is None:
                i += offset
                item = self.items[i % len(self.items)]
            self.selected = item
        self.redraw()

    def run_selected(self):
        if self.selected and self.selected[1] is not None:
            if isinstance(self.selected[1], str):
                self.emit('activate', self.selected[1])
            elif isinstance(self.selected[1], Widget):
                self.selected[1].show()
                self.selected[1].set_focus()
            else:
                self.selected[1]()