From a69e9a38afd86cd12a26c244b546fefe3f5d00b6 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 26 Jul 2010 16:43:07 -0400 Subject: [PATCH] Broke menu, navbar, statusbar, panel.notebook, and panel.welcome out of gui --- hooke/ui/gui/__init__.py | 203 +++++++-------------------------- hooke/ui/gui/menu.py | 77 +++++++++++++ hooke/ui/gui/navbar.py | 47 ++++++++ hooke/ui/gui/panel/__init__.py | 6 +- hooke/ui/gui/panel/note.py | 2 +- hooke/ui/gui/panel/notebook.py | 21 ++++ hooke/ui/gui/panel/welcome.py | 27 +++++ hooke/ui/gui/playlist.py | 7 -- hooke/ui/gui/statusbar.py | 30 +++++ 9 files changed, 251 insertions(+), 169 deletions(-) create mode 100644 hooke/ui/gui/menu.py create mode 100644 hooke/ui/gui/navbar.py create mode 100644 hooke/ui/gui/panel/notebook.py create mode 100644 hooke/ui/gui/panel/welcome.py create mode 100644 hooke/ui/gui/statusbar.py diff --git a/hooke/ui/gui/__init__.py b/hooke/ui/gui/__init__.py index 720c364..69f5a61 100644 --- a/hooke/ui/gui/__init__.py +++ b/hooke/ui/gui/__init__.py @@ -31,145 +31,24 @@ from ...command import CommandExit, Exit, Command, Argument, StoreValue from ...config import Setting from ...interaction import Request, BooleanRequest, ReloadUserInterfaceConfig from ...ui import UserInterface, CommandMessage +from . import menu as menu +from . import navbar as navbar from . import panel as panel from . import prettyformat as prettyformat - - -class Notebook (aui.AuiNotebook): - def __init__(self, *args, **kwargs): - super(Notebook, self).__init__(*args, **kwargs) - self.SetArtProvider(aui.AuiDefaultTabArt()) - #uncomment if we find a nice icon - #page_bmp = wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, wx.Size(16, 16)) - self.AddPage(self._welcome_window(), 'Welcome') - - def _welcome_window(self): - #TODO: move into panel.welcome - ctrl = wx.html.HtmlWindow(parent=self, size=wx.Size(400, 300)) - lines = [ - '

Welcome to Hooke

', - '

Features

', - '', - '

See the DocumentationIndex' - % 'http://code.google.com/p/hooke/wiki/DocumentationIndex', - 'for more information

', - ] - ctrl.SetPage('\n'.join(lines)) - return ctrl - - -class NavBar (wx.ToolBar): - def __init__(self, *args, **kwargs): - super(NavBar, self).__init__(*args, **kwargs) - self.SetToolBitmapSize(wx.Size(16,16)) - self._c = { - 'previous': self.AddLabelTool( - id=wx.ID_PREVIEW_PREVIOUS, - label='Previous', - bitmap=wx.ArtProvider_GetBitmap( - wx.ART_GO_BACK, wx.ART_OTHER, wx.Size(16, 16)), - shortHelp='Previous curve'), - 'next': self.AddLabelTool( - id=wx.ID_PREVIEW_NEXT, - label='Next', - bitmap=wx.ArtProvider_GetBitmap( - wx.ART_GO_FORWARD, wx.ART_OTHER, wx.Size(16, 16)), - shortHelp='Next curve'), - } - self.Realize() - - -class FileMenu (wx.Menu): - def __init__(self, *args, **kwargs): - super(FileMenu, self).__init__(*args, **kwargs) - self._c = {'exit': self.Append(wx.ID_EXIT)} - - -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'), - } - for item in self._c.values(): - item.Check() - - -class PerspectiveMenu (wx.Menu): - def __init__(self, *args, **kwargs): - super(PerspectiveMenu, self).__init__(*args, **kwargs) - self._c = {} - - def update(self, perspectives, selected, callback): - """Rebuild the perspectives menu. - """ - for item in self.GetMenuItems(): - self.UnBind(item) - self.DeleteItem(item) - self._c = { - 'save': self.Append(id=wx.ID_ANY, text='Save Perspective'), - 'delete': self.Append(id=wx.ID_ANY, text='Delete Perspective'), - } - 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]) - 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 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') - - -class StatusBar (wx.StatusBar): - def __init__(self, *args, **kwargs): - super(StatusBar, self).__init__(*args, **kwargs) - self.SetStatusWidths([-2, -3]) - self.SetStatusText('Ready', 0) - self.SetStatusText(u'Welcome to Hooke (version %s)' % version(), 1) +from . import statusbar as statusbar class HookeFrame (wx.Frame): - def __init__(self, gui, commands, *args, **kwargs): + """The main Hooke-interface window. + + + """ + def __init__(self, gui, commands, inqueue, outqueue, *args, **kwargs): super(HookeFrame, self).__init__(*args, **kwargs) self.gui = gui self.commands = commands + self.inqueue = inqueue + self.outqueue = outqueue self._perspectives = {} # {name: perspective_str} self._c = {} @@ -196,11 +75,14 @@ class HookeFrame (wx.Frame): # Create the menubar after the panes so that the default # perspective is created with all panes open - self._c['menu bar'] = MenuBar( + self._c['menu bar'] = menu.MenuBar( + callbacks={}, ) self.SetMenuBar(self._c['menu bar']) - self._c['status bar'] = StatusBar(self, style=wx.ST_SIZEGRIP) + self._c['status bar'] = statubar.StatusBar( + parent=self, + style=wx.ST_SIZEGRIP) self._update_perspectives() self._bind_events() @@ -285,7 +167,13 @@ class HookeFrame (wx.Frame): self._c['manager'].AddPane(panel, info) def _setup_toolbars(self): - self._c['navbar'] = NavBar(self, style=wx.TB_FLAT | wx.TB_NODIVIDER) + self._c['navbar'] = navbar.NavBar( + callbacks={ + 'next': self._next_curve, + 'previous': self._previous_curve, + }, + parent=self, + style=wx.TB_FLAT | wx.TB_NODIVIDER) self._c['manager'].AddPane( self._c['navbar'], @@ -313,9 +201,6 @@ class HookeFrame (wx.Frame): self.Bind(wx.EVT_MENU, self._on_delete_perspective, self._c['menu bar']._c['perspective']._c['delete']) - self.Bind(wx.EVT_TOOL, self._on_next, self._c['navbar']._c['next']) - self.Bind(wx.EVT_TOOL, self._on_previous,self._c['navbar']._c['previous']) - treeCtrl = self._c['folders'].GetTreeCtrl() treeCtrl.Bind(wx.EVT_LEFT_DCLICK, self._on_dir_ctrl_left_double_click) @@ -660,10 +545,7 @@ class HookeFrame (wx.Frame): def _on_erase_background(self, event): event.Skip() - def OnExit(self, event): - self.Close() - - def _on_next(self, event): + def _next_curve(self, *args): ''' NEXT Go to the next curve in the playlist. @@ -688,19 +570,11 @@ class HookeFrame (wx.Frame): playlist = self.GetActivePlaylist() if playlist.count > 1: playlist.next() - self.statusbar.SetStatusText(playlist.get_status_string(), 0) + self._c['status bar'].set_playlist(playlist) self.UpdateNote() self.UpdatePlot() - def _on_notebook_page_close(self, event): - ctrl = event.GetEventObject() - playlist_name = ctrl.GetPageText(ctrl._curpage) - self.DeleteFromPlaylists(playlist_name) - - def OnPaneClose(self, event): - event.Skip() - - def _on_previous(self, event): + def _previous_curve(self, *args): ''' PREVIOUS Go to the previous curve in the playlist. @@ -723,10 +597,18 @@ class HookeFrame (wx.Frame): playlist = self.GetActivePlaylist() if playlist.count > 1: playlist.previous() - self.statusbar.SetStatusText(playlist.get_status_string(), 0) + self._c['status bar'].set_playlist(playlist) self.UpdateNote() self.UpdatePlot() + def _on_notebook_page_close(self, event): + ctrl = event.GetEventObject() + playlist_name = ctrl.GetPageText(ctrl._curpage) + self.DeleteFromPlaylists(playlist_name) + + def OnPaneClose(self, event): + event.Skip() + def OnPropGridChanged (self, event): prop = event.GetProperty() if prop: @@ -913,7 +795,7 @@ class HookeFrame (wx.Frame): playlist = self.GetActivePlaylist() if playlist is not None: if playlist.index >= 0: - self.statusbar.SetStatusText(playlist.get_status_string(), 0) + self._c['status bar'].set_playlist(playlist) self.UpdateNote() self.UpdatePlot() @@ -1011,7 +893,7 @@ class HookeFrame (wx.Frame): playlist.figure = plotPanel.get_figure() self.playlists[playlist.name] = playlist #self.playlists[playlist.name] = [playlist, figure] - self.statusbar.SetStatusText(playlist.get_status_string(), 0) + self._c['status bar'].set_playlist(playlist) self.UpdateNote() self.UpdatePlot() @@ -1022,7 +904,7 @@ class HookeFrame (wx.Frame): if current_playlist != playlist_name: index = self._GetPlaylistTab(playlist_name) self._c['notebook'].SetSelection(index) - self.statusbar.SetStatusText(playlist.get_status_string(), 0) + self._c['status bar'].set_playlist(playlist) self.UpdateNote() self.UpdatePlot() @@ -1035,6 +917,11 @@ class HookeFrame (wx.Frame): class HookeApp (wx.App): + """A :class:`wx.App` wrapper around :class:`HookeFrame`. + + Tosses up a splash screen and then loads :class:`HookeFrame` in + its own window. + """ def __init__(self, gui, commands, inqueue, outqueue, *args, **kwargs): self.gui = gui self.commands = commands @@ -1063,7 +950,8 @@ class HookeApp (wx.App): self._c = { 'frame': HookeFrame( - self.gui, self.commands, parent=None, title='Hooke', + self.gui, self.commands, self.inqueue, self.outqueue, + parent=None, title='Hooke', pos=(left, top), size=(width, height), style=wx.DEFAULT_FRAME_STYLE|wx.SUNKEN_BORDER|wx.CLIP_CHILDREN), } @@ -1090,9 +978,6 @@ class HookeApp (wx.App): sleepFactor = 1.2 time.sleep(sleepFactor * duration / 1000) - def OnExit(self): - return True - class GUI (UserInterface): """wxWindows graphical user interface. diff --git a/hooke/ui/gui/menu.py b/hooke/ui/gui/menu.py new file mode 100644 index 0000000..184e66d --- /dev/null +++ b/hooke/ui/gui/menu.py @@ -0,0 +1,77 @@ +# Copyright + +"""Menu bar for Hooke. +""" + +import wx + + +class FileMenu (wx.Menu): + def __init__(self, *args, **kwargs): + super(FileMenu, self).__init__(*args, **kwargs) + self._c = {'exit': self.Append(wx.ID_EXIT)} + + +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'), + } + for item in self._c.values(): + item.Check() + + +class PerspectiveMenu (wx.Menu): + def __init__(self, *args, **kwargs): + super(PerspectiveMenu, self).__init__(*args, **kwargs) + self._c = {} + + def update(self, perspectives, selected, callback): + """Rebuild the perspectives menu. + """ + for item in self.GetMenuItems(): + self.UnBind(item) + self.DeleteItem(item) + self._c = { + 'save': self.Append(id=wx.ID_ANY, text='Save Perspective'), + 'delete': self.Append(id=wx.ID_ANY, text='Delete Perspective'), + } + 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]) + 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 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') diff --git a/hooke/ui/gui/navbar.py b/hooke/ui/gui/navbar.py new file mode 100644 index 0000000..c10f6a1 --- /dev/null +++ b/hooke/ui/gui/navbar.py @@ -0,0 +1,47 @@ +# Copyright + +"""Navigation bar for Hooke. +""" + +import wx + + +class NavBar (wx.ToolBar): + def __init__(self, callbacks, *args, **kwargs): + super(NavBar, self).__init__(*args, **kwargs) + self.SetToolBitmapSize(wx.Size(16,16)) + self._c = { + 'previous': self.AddLabelTool( + id=wx.ID_PREVIEW_PREVIOUS, + label='Previous', + bitmap=wx.ArtProvider_GetBitmap( + wx.ART_GO_BACK, wx.ART_OTHER, wx.Size(16, 16)), + shortHelp='Previous curve'), + 'next': self.AddLabelTool( + id=wx.ID_PREVIEW_NEXT, + label='Next', + bitmap=wx.ArtProvider_GetBitmap( + wx.ART_GO_FORWARD, wx.ART_OTHER, wx.Size(16, 16)), + shortHelp='Next curve'), + } + self.Realize() + self._callbacks = callbacks + self.Bind(wx.EVT_TOOL, self._on_next, self._c['next']) + self.Bind(wx.EVT_TOOL, self._on_previous, self._c['previous']) + + def _on_next(self, event): + self.next() + + def _on_previous(self, event): + self.previous() + + @callback + def next(self): + pass + + @callback + def previous(self): + pass + + + diff --git a/hooke/ui/gui/panel/__init__.py b/hooke/ui/gui/panel/__init__.py index c5a77e6..f542776 100644 --- a/hooke/ui/gui/panel/__init__.py +++ b/hooke/ui/gui/panel/__init__.py @@ -2,11 +2,13 @@ from . import commands as commands from . import note as note +from . import notebook as notebook from . import playlist as playlist from . import plot as plot #from . import propertyeditor as propertyeditor from . import results as results from . import selection as selection +from . import welcome as welcome -__all__ = [commands, note, playlist, plot, #propertyeditor, - results, selection] +__all__ = [commands, note, notebook, playlist, plot, #propertyeditor, + results, selection, welcome] diff --git a/hooke/ui/gui/panel/note.py b/hooke/ui/gui/panel/note.py index ff92cfe..4df7db8 100644 --- a/hooke/ui/gui/panel/note.py +++ b/hooke/ui/gui/panel/note.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +# Copyright """Note panel for Hooke. """ diff --git a/hooke/ui/gui/panel/notebook.py b/hooke/ui/gui/panel/notebook.py new file mode 100644 index 0000000..4534f42 --- /dev/null +++ b/hooke/ui/gui/panel/notebook.py @@ -0,0 +1,21 @@ +# Copyright + +"""Notebook panel for Hooke. +""" + +import wx.aui as aui + +from .welcome import Welcome + + +class Notebook (aui.AuiNotebook): + def __init__(self, *args, **kwargs): + super(Notebook, self).__init__(*args, **kwargs) + self.SetArtProvider(aui.AuiDefaultTabArt()) + #uncomment if we find a nice icon + #page_bmp = wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, wx.Size(16, 16)) + self.AddPage( + Welcome( + parent=self, + size=wx.Size(400, 300)), + 'Welcome') diff --git a/hooke/ui/gui/panel/welcome.py b/hooke/ui/gui/panel/welcome.py new file mode 100644 index 0000000..a9f8527 --- /dev/null +++ b/hooke/ui/gui/panel/welcome.py @@ -0,0 +1,27 @@ +# Copyright + +"""Welcome panel for Hooke. +""" + +import wx + + +class Welcome (wx.html.HtmlWindow): + def __init__(self, *args, **kwargs): + super(Welcome, self).__init__(self, *args, **kwargs) + lines = [ + '

Welcome to Hooke

', + '

Features

', + '', + '

See the DocumentationIndex' + % 'http://code.google.com/p/hooke/wiki/DocumentationIndex', + 'for more information

', + ] + ctrl.SetPage('\n'.join(lines)) diff --git a/hooke/ui/gui/playlist.py b/hooke/ui/gui/playlist.py index 90a730f..9b7af3f 100644 --- a/hooke/ui/gui/playlist.py +++ b/hooke/ui/gui/playlist.py @@ -66,13 +66,6 @@ class Playlist(object): ##TODO: is this the only active (or default?) plot? #return self.files[self.index].plots[0] - def get_status_string(self): - if self.count > 0: - activeFileStr = ''.join([' (%s/%s)' %(self.index + 1, self.count)]) - return ''.join([self.name, activeFileStr]) - else: - return ''.join(['The file ', self.name, ' does not contain any valid force curve data.\n']) - def load(self, filename): ''' Loads a playlist file diff --git a/hooke/ui/gui/statusbar.py b/hooke/ui/gui/statusbar.py new file mode 100644 index 0000000..59e5859 --- /dev/null +++ b/hooke/ui/gui/statusbar.py @@ -0,0 +1,30 @@ +# Copyright + +"""Status bar for Hooke. +""" + +import wx + + +class StatusBar (wx.StatusBar): + def __init__(self, *args, **kwargs): + super(StatusBar, self).__init__(*args, **kwargs) + self.SetStatusWidths([-2, -3]) + self.SetStatusText('Ready', 0) + self.SetStatusText(u'Welcome to Hooke (version %s)' % version(), 1) + + def set_playlist(self, playlist): + self.SetStatusText(self._playlist_status(playlist), 0) + + def set_curve(self, curve): + pass + + def _playlist_status(self, playlist): + fields = [ + playlist.name, + '(%d/%d)' % (playlist._index, len(playlist)), + ] + curve = playlist.current(): + if curve != None: + fields.append(curve.name) + return ' '.join(fields) -- 2.26.2