8 from ...util.callback import callback, in_callback
12 """A `Bind`able version of :class:`wx.Menu`.
14 From the `wxPython Style Guide`_, you can't do
15 wx.Menu().Bind(...), so we hack around it by bubbling the Bind up
16 to the closest parent :class:`wx.Frame`.
18 .. _wxPython Style Guide:
19 http://wiki.wxpython.org/wxPython%20Style%20Guide#line-101
21 def __init__(self, parent=None, **kwargs):
24 super(Menu, self).__init__(**kwargs)
26 def Bind(self, **kwargs):
27 assert 'id' in kwargs, kwargs
29 while not isinstance(obj, wx.Frame):
32 self._bindings.append(kwargs)
34 def Unbind(self, **kwargs):
35 assert 'id' in kwargs, kwargs
37 self._bindings.remove(kwargs)
40 kwargs.pop('handler', None)
42 while not isinstance(obj, wx.Frame):
46 def _unbind_all_items(self):
47 for kwargs in self._bindings:
52 class MenuBar (wx.MenuBar):
53 """A `Bind`able version of :class:`wx.MenuBar`.
55 See :class:`Menu` for the motivation.
57 def __init__(self, parent=None, **kwargs):
59 super(MenuBar, self).__init__(**kwargs)
61 def Append(self, menu, title):
63 super(MenuBar, self).Append(menu, title)
66 class FileMenu (Menu):
67 def __init__(self, callbacks=None, **kwargs):
68 super(FileMenu, self).__init__(**kwargs)
71 self._callbacks = callbacks
72 self._c = {'exit': self.Append(wx.ID_EXIT)}
73 self.Bind(event=wx.EVT_MENU, handler=self.close, id=wx.ID_EXIT)
76 def close(self, event):
80 class ViewMenu (Menu):
81 def __init__(self, panels, callbacks=None, **kwargs):
82 super(ViewMenu, self).__init__(**kwargs)
85 self._callbacks = callbacks
87 for i,panelname in enumerate(sorted([p.managed_name for p in panels])):
88 text = '%s\tF%d' % (panelname, i+5)
89 self._c[panelname] = self.AppendCheckItem(id=wx.ID_ANY, text=text)
90 for item in self._c.values():
92 self.Bind(event=wx.EVT_MENU, handler=self.view_panel, id=item.GetId())
94 def view_panel(self, event):
96 item = self.FindItemById(_id)
97 label = item.GetLabel()
98 selected = item.IsChecked()
99 in_callback(self, panel_name=label, visible=selected)
102 class PerspectiveMenu (Menu):
103 def __init__(self, callbacks=None, **kwargs):
104 super(PerspectiveMenu, self).__init__(**kwargs)
105 if callbacks == None:
107 self._callbacks = callbacks
110 def update(self, perspectives, selected):
111 """Rebuild the perspectives menu.
113 self._unbind_all_items()
114 for item in self.GetMenuItems():
115 self.DeleteItem(item)
117 'save': self.Append(id=wx.ID_ANY, text='Save Perspective'),
118 'delete': self.Append(id=wx.ID_ANY, text='Delete Perspective'),
120 self.Bind(event=wx.EVT_MENU, handler=self.save_perspective,
121 id=self._c['save'].GetId())
122 self.Bind(event=wx.EVT_MENU, handler=self.delete_perspective,
123 id=self._c['delete'].GetId())
124 self.AppendSeparator()
125 for label in perspectives:
126 self._c[label] = self.AppendRadioItem(id=wx.ID_ANY, text=label)
127 self.Bind(event=wx.EVT_MENU, handler=self.select_perspective,
128 id=self._c[label].GetId())
129 if label == selected:
130 self._c[label].Check(True)
133 def save_perspective(self, event):
137 def delete_perspective(self, event):
140 def select_perspective(self, event):
142 item = self.FindItemById(_id)
143 label = item.GetLabel()
144 selected = item.IsChecked()
145 assert selected == True, label
146 in_callback(self, name=label)
149 class HelpMenu (Menu):
150 def __init__(self, callbacks=None, **kwargs):
151 super(HelpMenu, self).__init__(**kwargs)
152 if callbacks == None:
154 self._callbacks = callbacks
155 self._c = {'about': self.Append(id=wx.ID_ABOUT)}
156 self.Bind(event=wx.EVT_MENU, handler=self.about, id=wx.ID_ABOUT)
159 def about(self, event):
163 class HookeMenuBar (MenuBar):
164 def __init__(self, panels, callbacks=None, **kwargs):
165 super(HookeMenuBar, self).__init__(**kwargs)
166 if callbacks == None:
168 self._callbacks = callbacks
171 # Attach *Menu() instances
172 for key in ['file', 'view', 'perspective', 'help']:
173 cap_key = key.capitalize()
174 _class = globals()['%sMenu' % cap_key]
177 kwargs['panels'] = panels
178 self._c[key] = _class(parent=self, callbacks=callbacks, **kwargs)
179 self.Append(self._c[key], cap_key)