hooke.ui.gui was getting complicated, so I stripped it down for a moment.
[hooke.git] / hooke / ui / gui / menu.py
index 184e66d5de3995363b8333fb51f0542201d4a69e..836bcec92e5ef02018eaf61e03e8585b705ed98c 100644 (file)
@@ -5,44 +5,87 @@
 
 import wx
 
+from ...util.callback import callback, in_callback
+from . import panel as panel
 
-class FileMenu (wx.Menu):
-    def __init__(self, *args, **kwargs):
-        super(FileMenu, self).__init__(*args, **kwargs)
+
+class Menu (wx.Menu):
+    """A `Bind`able version of :class:`wx.Menu`.
+
+    From the `wxPython Style Guide`_, you can't do
+    wx.Menu().Bind(...), so we hack around it by bubbling the Bind up
+    to the closest parent :class:`wx.Frame`.
+
+    .. _wxPython Style Guide:
+      http://wiki.wxpython.org/wxPython%20Style%20Guide#line-101
+    """
+    def __init__(self, parent=None, **kwargs):
+        self._parent = parent
+        super(Menu, self).__init__(**kwargs)
+
+    def Bind(self, **kwargs):
+        assert 'id' in kwargs, kwargs
+        obj = self
+        while not isinstance(obj, wx.Frame):
+            obj = obj._parent
+        obj.Bind(**kwargs)
+
+
+class MenuBar (wx.MenuBar):
+    """A `Bind`able version of :class:`wx.MenuBar`.
+
+    See :class:`Menu` for the motivation.
+    """
+    def __init__(self, parent=None, **kwargs):
+        self._parent = parent
+        super(MenuBar, self).__init__(**kwargs)
+
+    def Append(self, menu, title):
+        menu._parent = self
+        super(MenuBar, self).Append(menu, title)
+
+
+class FileMenu (Menu):
+    def __init__(self, callbacks=None, **kwargs):
+        super(FileMenu, self).__init__(**kwargs)
+        if callbacks == None:
+            callbacks = {}
+        self._callbacks = callbacks
         self._c = {'exit': self.Append(wx.ID_EXIT)}
+        self.Bind(event=wx.EVT_MENU, handler=self.close, id=wx.ID_EXIT)
 
+    @callback
+    def close(self, event):
+        pass
 
-class ViewMenu (wx.Menu):
-    def __init__(self, *args, **kwargs):
-        super(ViewMenu, self).__init__(*args, **kwargs)
-        self._c = {
-            'folders': self.AppendCheckItem(id=wx.ID_ANY, text='Folders\tF5'),
-            'playlist': self.AppendCheckItem(
-                id=wx.ID_ANY, text='Playlists\tF6'),
-            'commands': self.AppendCheckItem(
-                id=wx.ID_ANY, text='Commands\tF7'),
-            'assistant': self.AppendCheckItem(
-                id=wx.ID_ANY, text='Assistant\tF9'),
-            'properties': self.AppendCheckItem(
-                id=wx.ID_ANY, text='Properties\tF8'),
-            'results': self.AppendCheckItem(id=wx.ID_ANY, text='Results\tF10'),
-            'output': self.AppendCheckItem(id=wx.ID_ANY, text='Output\tF11'),
-            'note': self.AppendCheckItem(id=wx.ID_ANY, text='Note\tF12'),
-            }
+
+class ViewMenu (Menu):
+    def __init__(self, callbacks=None, **kwargs):
+        super(ViewMenu, self).__init__(**kwargs)
+        if callbacks == None:
+            callbacks = {}
+        self._callbacks = callbacks
+        self._c = {}
+        for i,panelname in enumerate(sorted(panel.PANELS.keys())):
+            text = '%s\tF%d' % (panelname.capitalize, i+5)
+            self._c[panelname] = self.AppendCheckItem(id=wx.ID_ANY, text=text)
         for item in self._c.values():
             item.Check()
 
 
-class PerspectiveMenu (wx.Menu):
-    def __init__(self, *args, **kwargs):
-        super(PerspectiveMenu, self).__init__(*args, **kwargs)
+class PerspectiveMenu (Menu):
+    def __init__(self, callbacks=None, **kwargs):
+        super(PerspectiveMenu, self).__init__(**kwargs)
+        if callbacks == None:
+            callbacks = {}
+        self._callbacks = callbacks
         self._c = {}
 
     def update(self, perspectives, selected, callback):
         """Rebuild the perspectives menu.
         """
         for item in self.GetMenuItems():
-            self.UnBind(item)
+            self.UnBind(item.GetId)
             self.DeleteItem(item)
         self._c = {
             'save': self.Append(id=wx.ID_ANY, text='Save Perspective'),
@@ -51,27 +94,37 @@ class PerspectiveMenu (wx.Menu):
         self.AppendSeparator()
         for label in perspectives:
             self._c[label] = self.AppendRadioItem(id=wx.ID_ANY, text=label)
-            self.Bind(wx.EVT_MENU, callback, self._c[label])
+            self.Bind(event=wx.EVT_MENU, handler=callback,
+                      id=self._c[label].GetId())
             if label == selected:
                 self._c[label].Check(True)
-            
 
-class HelpMenu (wx.Menu):
-    def __init__(self, *args, **kwargs):
-        super(HelpMenu, self).__init__(*args, **kwargs)
-        self._c = {'about':self.Append(id=wx.ID_ABOUT)}
 
+class HelpMenu (Menu):
+    def __init__(self, callbacks=None, **kwargs):
+        super(HelpMenu, self).__init__(**kwargs)
+        if callbacks == None:
+            callbacks = {}
+        self._callbacks = callbacks
+        self._c = {'about': self.Append(id=wx.ID_ABOUT)}
+        self.Bind(event=wx.EVT_MENU, handler=self.about, id=wx.ID_ABOUT)
 
-class MenuBar (wx.MenuBar):
-    def __init__(self, *args, **kwargs):
-        super(MenuBar, self).__init__(*args, **kwargs)
-        self._c = {
-            'file': FileMenu(),
-            'view': ViewMenu(),
-            'perspective': PerspectiveMenu(),
-            'help': HelpMenu(),
-            }
-        self.Append(self._c['file'], 'File')
-        self.Append(self._c['view'], 'View')
-        self.Append(self._c['perspective'], 'Perspective')
-        self.Append(self._c['help'], 'Help')
+    @callback
+    def about(self, event):
+        pass
+
+
+class HookeMenuBar (MenuBar):
+    def __init__(self, callbacks=None, **kwargs):
+        super(HookeMenuBar, self).__init__(**kwargs)
+        if callbacks == None:
+            callbacks = {}
+        self._callbacks = callbacks
+        self._c = {}
+
+        # Attach *Menu() instances
+        for key in ['file', 'view', 'perspective', 'help']:
+            cap_key = key.capitalize()
+            _class = globals()['%sMenu' % cap_key]
+            self._c[key] = _class(parent=self, callbacks=callbacks)
+            self.Append(self._c[key], cap_key)