Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pynxc/waxy/menu.py
blob: ef587fc275399b281d3ecd0d4df20612aafedeec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# menu.py

import wx
import waxyobject
import string

class Menu(wx.Menu, waxyobject.WaxyObject):

    def __init__(self, parent, autoevents=1):
        wx.Menu.__init__(self)
        self.parent = parent    # necessary for hooking up events
        self.autoevents = autoevents

    def Append(self, title, event=None, tooltip="", type="", hotkey="",special=''):
        # Note: the order is different from wx.Menu.Append!
        style = 0
        style |= {
            "r": wx.ITEM_RADIO,
            "c": wx.ITEM_CHECK,
        }.get(type.lower()[:1], wx.ITEM_NORMAL)

        if hotkey:
            title = title + "\t" + hotkey

        if special.lower()=='about':
            id=wx.ID_ABOUT
        elif special.lower()=='exit':
            id=wx.ID_EXIT
        else:
            id = wx.NewId()
            
        item = wx.Menu.Append(self, id, title, tooltip, style)
        if event:
            # you *can* choose to specify no event, but that doesn't seem very
            # useful
            wx.EVT_MENU(self.parent, id, event)
        elif self.autoevents:
            wx.EVT_MENU(self.parent, id, self.HandleAutoEvent)

        return item

    def AppendMenu(self, title, menu):
        id = wx.NewId()
        return wx.Menu.AppendMenu(self, id, title, menu)
        # I suppose there's room for an event here, but why bother...?

    def GetItem(self, title):
        """ Find item by title, bypassing the internal id. """
        id = self.FindItem(title)
        item = self.FindItemById(id)
        return item

    def Delete(self, obj):
        # according to the wxWindows reference, wx.Menu.Delete() also accepts
        # MenuItems... but apparently that isn't true, at least not in wxPython.
        # So let's fix it:
        if isinstance(obj, wx.MenuItem):
            id = obj.GetId()
            return wx.Menu.Delete(self, id)
        else:
            # assume it's a number
            return wx.Menu.Delete(self, obj)

    def HandleAutoEvent(self, event):
        id = event.GetId()
        menuitem = self.FindItemById(id)

        def GetFullTitle(id):
            menubar = self.parent.GetMenuBar()
            if menubar:
                for mwitem in menubar.Walk():
                    if mwitem.items and mwitem.items[-1].GetId() == id:
                        title = mwitem.name
                        for menuitem in mwitem.items:
                            title = title + " " + menuitem.GetLabel()
                        return title
            return None

        title = GetFullTitle(id)
        if title:
            methodname = "Menu_" + genmethodname(title)
            #print "Looking for:", methodname
            if hasattr(self.parent, methodname):
                f = getattr(self.parent, methodname)
                f(event)

    # these aliases make sense...
    Add = Append
    AddMenu = AppendMenu

    def Walk(self):
        for menuitem in self.GetMenuItems():
            yield [menuitem]
            submenu = menuitem.GetSubMenu()
            if submenu:
                for subitem in submenu.Walk():
                    yield [menuitem] + subitem

    # TODO: Is it possible to write a better GetTitle() or GetRealTitle()
    # or something, that gives us the actual label of the menu?

class MenuBar(wx.MenuBar, waxyobject.WaxyObject):
    def __init__(self, parent=None, *args, **kwargs):
        wx.MenuBar.__init__(self, *args, **kwargs)
        if parent: parent.SetMenuBar(self)

    def Append(self, menu, text):
        wx.MenuBar.Append(self, menu, text)

    def Walk(self):
        for i in range(self.GetMenuCount()):
            menu = self.GetMenu(i)
            for items in menu.Walk():
                menuwalkitem = _MenuWalkItem()
                menuwalkitem.name = self.GetLabelTop(i)
                menuwalkitem.menu = menu
                menuwalkitem.items = items
                yield menuwalkitem

class _MenuWalkItem:
    pass

#
# auxiliary methods

def genmethodname(title):
    allowed = string.letters + string.digits + "_"
    name = ""
    for char in title:
        if char in allowed:
            name = name + char
        elif char == ' ':
            name = name + '_'
    return name