tuikit/menu.py
author Radek Brich <radek.brich@devl.cz>
Wed, 02 Jan 2013 00:16:12 +0100
changeset 43 369c8ef5070a
parent 41 37b7dfc3eae6
child 45 43b2279b06e1
permissions -rw-r--r--
Rename emitter module to events.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     2
18
e6c3a5ee91aa Eliminate relative imports.
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
     3
from tuikit.widget import Widget
43
369c8ef5070a Rename emitter module to events.
Radek Brich <radek.brich@devl.cz>
parents: 41
diff changeset
     4
from tuikit.events import GenericEvent
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     5
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     6
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     7
class Menu(Widget):
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     8
    def __init__(self, items=[]):
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     9
        Widget.__init__(self)
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    10
        self.width = max([len(x[0]) for x in items if x is not None]) + 4
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    11
        self.height = len(items) + 2
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    12
34
e3beacd5e536 Update event propagation, keypress event, focusing.
Radek Brich <radek.brich@devl.cz>
parents: 32
diff changeset
    13
        self.allow_focus = True
e3beacd5e536 Update event propagation, keypress event, focusing.
Radek Brich <radek.brich@devl.cz>
parents: 32
diff changeset
    14
7
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
    15
        self.bg = 'menu'
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
    16
        self.highlight = 'menu-active'
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    17
        self.items = items
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    18
        self.selected = items[0]
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 1
diff changeset
    19
        self.menubar = None
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    20
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    21
        self.add_events('activate', GenericEvent)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    22
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    23
    def _handle_draw(self, ev):
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    24
        super()._handle_draw(ev)
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    25
        ev.driver.pushcolor(self.bg)
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    26
        ev.driver.frame(ev.x, ev.y, self.width, self.height)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    27
        i = 1
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    28
        for item in self.items:
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    29
            if item is None:
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    30
                ev.driver.puts(ev.x, ev.y + i, ev.driver.unigraph.LTEE + \
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    31
                    ev.driver.unigraph.HLINE * (self.width - 2) + ev.driver.unigraph.RTEE)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    32
            else:
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    33
                if self.selected == item:
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    34
                    ev.driver.pushcolor(self.highlight)
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    35
                    ev.driver.puts(ev.x + 1, ev.y + i,
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    36
                        ' ' + item[0] + ' ' * (self.width - 3 - len(item[0])))
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    37
                    ev.driver.popcolor()
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    38
                else:
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    39
                    ev.driver.puts(ev.x + 1, ev.y + i,
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    40
                        ' ' + item[0] + ' ' * (self.width - 3 - len(item[0])))
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    41
            i += 1
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    42
        ev.driver.popcolor()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    43
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    44
    def _handle_keypress(self, ev):
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    45
        super()._handle_keypress(ev)
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    46
        if ev.keyname == 'up':
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    47
            self.move_selected(-1)
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    48
        if ev.keyname == 'down':
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    49
            self.move_selected(+1)
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    50
        if ev.keyname == 'enter':
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    51
            self.run_selected()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    52
        self.redraw()
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    53
40
5faa38c10b67 Add ScrollView widget. Update Emitter, rename "on_event" methods to "_handle_event". Update VScrollbar, Layout.
Radek Brich <radek.brich@devl.cz>
parents: 38
diff changeset
    54
    def _handle_mousedown(self, ev):
5faa38c10b67 Add ScrollView widget. Update Emitter, rename "on_event" methods to "_handle_event". Update VScrollbar, Layout.
Radek Brich <radek.brich@devl.cz>
parents: 38
diff changeset
    55
        super()._handle_mousedown(ev)
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    56
        self.select_at_pos(ev.wy - 1)
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    57
40
5faa38c10b67 Add ScrollView widget. Update Emitter, rename "on_event" methods to "_handle_event". Update VScrollbar, Layout.
Radek Brich <radek.brich@devl.cz>
parents: 38
diff changeset
    58
    def _handle_mousemove(self, ev):
5faa38c10b67 Add ScrollView widget. Update Emitter, rename "on_event" methods to "_handle_event". Update VScrollbar, Layout.
Radek Brich <radek.brich@devl.cz>
parents: 38
diff changeset
    59
        super()._handle_mousemove(ev)
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    60
        self.select_at_pos(ev.wy - 1)
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    61
40
5faa38c10b67 Add ScrollView widget. Update Emitter, rename "on_event" methods to "_handle_event". Update VScrollbar, Layout.
Radek Brich <radek.brich@devl.cz>
parents: 38
diff changeset
    62
    def _handle_mouseup(self, ev):
5faa38c10b67 Add ScrollView widget. Update Emitter, rename "on_event" methods to "_handle_event". Update VScrollbar, Layout.
Radek Brich <radek.brich@devl.cz>
parents: 38
diff changeset
    63
        super()._handle_mousemove(ev)
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    64
        ok = self.select_at_pos(ev.wy - 1)
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    65
        if ok:
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    66
            self.run_selected()
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    67
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    68
    def select_at_pos(self, pos):
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    69
        if pos < 0:
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    70
            return False
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    71
        try:
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    72
            item = self.items[pos]
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    73
        except IndexError:
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    74
            return False
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    75
        if item is None:
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    76
            return False
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    77
        self.selected = item
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    78
        self.redraw()
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    79
        return True
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    80
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    81
    def move_selected(self, offset):
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    82
        if self.selected:
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    83
            i = self.items.index(self.selected)
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    84
            i += offset
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    85
            item = self.items[i % len(self.items)]
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    86
            if item is None:
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    87
                i += offset
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    88
                item = self.items[i % len(self.items)]
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    89
            self.selected = item
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    90
        self.redraw()
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    91
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    92
    def run_selected(self):
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    93
        if self.selected and self.selected[1] is not None:
10
ec1d47e6fe09 Use isinstance instead of type.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    94
            if isinstance(self.selected[1], str):
34
e3beacd5e536 Update event propagation, keypress event, focusing.
Radek Brich <radek.brich@devl.cz>
parents: 32
diff changeset
    95
                self.emit('activate', self.selected[1])
9
7175ed629a76 Added ComboBox, HorizontalLayout, TreeNode, TreeModel, TreeView. Widget is now descendant of EventSource. Improved color management (color prefixes).
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
    96
            elif isinstance(self.selected[1], Widget):
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 1
diff changeset
    97
                self.selected[1].show()
38
c6e170452c7f Documentation, fix names of focus methods.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
    98
                self.selected[1].set_focus()
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 1
diff changeset
    99
            else:
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 1
diff changeset
   100
                self.selected[1]()
1
69318aba22bf Menu development. New focus. Easier imports from tuikit package.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   101