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
|