from ...command import CommandExit, Exit, Success, Failure, Command, Argument
from ...config import Setting
+from ...engine import CommandMessage
from ...interaction import Request, BooleanRequest, ReloadUserInterfaceConfig
-from ...ui import UserInterface, CommandMessage
+from ...ui import UserInterface
from .dialog.selection import Selection as SelectionDialog
from .dialog.save_file import select_save_file
from . import menu as menu
self._setup_perspectives()
self._bind_events()
return # TODO: cleanup
- self.playlists = self._c['playlist'].Playlists
self._displayed_plot = None
#load default list, if possible
self.do_loadlist(self.GetStringFromConfig('core', 'preferences', 'playlists'))
commands=self.commands,
selected=self.gui.config['selected command'],
callbacks={
- 'execute': self.execute_command,
+ 'execute': self.explicit_execute_command,
'select_plugin': self.select_plugin,
'select_command': self.select_command,
# 'selection_changed': self.panelProperties.select(self, method, command), #SelectedTreeItem = selected_item,
# ('results', panel.results.Results(self), 'bottom'),
]:
self._add_panel(p, style)
+ self.execute_command( # setup already loaded playlists
+ command=self._command_by_name('playlists'))
+ self.execute_command( # setup already loaded curve
+ command=self._command_by_name('get curve'))
def _add_panel(self, panel, style):
self._c[panel.name] = panel
self.Bind(wx.EVT_ERASE_BACKGROUND, self._on_erase_background)
self.Bind(wx.EVT_SIZE, self._on_size)
self.Bind(wx.EVT_CLOSE, self._on_close)
- self.Bind(aui.EVT_AUI_PANE_CLOSE, self.OnPaneClose)
- self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self._on_notebook_page_close)
+ self.Bind(aui.EVT_AUI_PANE_CLOSE, self._on_pane_close)
return # TODO: cleanup
treeCtrl = self._c['folders'].GetTreeCtrl()
treeCtrl.Bind(wx.EVT_LEFT_DCLICK, self._on_dir_ctrl_left_double_click)
-
- #property editor
- self.panelProperties.pg.Bind(wxpg.EVT_PG_CHANGED, self.OnPropGridChanged)
- #results panel
- self.panelResults.results_list.OnCheckItem = self.OnResultsCheck
def _on_about(self, *args):
dialog = wx.MessageDialog(
dialog.ShowModal()
dialog.Destroy()
+ def _on_size(self, event):
+ event.Skip()
+
def _on_close(self, *args):
self.log.info('closing GUI framework')
# apply changes
- self.gui.config['main height'] = str(self.GetSize().GetHeight())
- self.gui.config['main left'] = str(self.GetPosition()[0])
- self.gui.config['main top'] = str(self.GetPosition()[1])
- self.gui.config['main width'] = str(self.GetSize().GetWidth())
- # push changes back to Hooke.config?
+ self._set_config('main height', self.GetSize().GetHeight())
+ self._set_config('main left', self.GetPosition()[0])
+ self._set_config('main top', self.GetPosition()[1])
+ self._set_config('main width', self.GetSize().GetWidth())
self._c['manager'].UnInit()
del self._c['manager']
self.Destroy()
+ def _on_erase_background(self, event):
+ event.Skip()
+
# Panel utility functions
raise Exception('Multiple commands named "%s"' % name)
return cs[0]
+ def explicit_execute_command(self, _class=None, method=None,
+ command=None, args=None):
+ return self.execute_command(
+ _class=_class, method=method, command=command, args=args,
+ explicit_user_call=True)
+
def execute_command(self, _class=None, method=None,
- command=None, args=None):
+ command=None, args=None, explicit_user_call=False):
if args == None:
args = {}
if ('property editor' in self._c
- and self.gui.config['selected command'] == command):
+ and self.gui.config['selected command'] == command.name):
for name,value in self._c['property editor'].get_values().items():
arg = self._c['property editor']._argument_from_label.get(
name, None)
index = int(name[len(arg.name):])
args[arg.name][index] = value
for arg in command.arguments:
+ if arg.name not in args:
+ continue # undisplayed argument, e.g. 'driver' types.
count = arg.count
if hasattr(arg, '_display_count'): # support HACK in props_from_argument()
count = arg._display_count
args[arg.name].pop()
if len(args[arg.name]) == 0:
args[arg.name] = arg.default
- self.log.debug('executing %s with %s' % (command.name, args))
- self.inqueue.put(CommandMessage(command, args))
+ cm = CommandMessage(command.name, args)
+ self.gui._submit_command(
+ cm, self.inqueue, explicit_user_call=explicit_user_call)
+ # TODO: skip responses for commands that were captured by the
+ # command stack. We'd need to poll on each request, remember
+ # capture state, or add a flag to the response...
+ return self._handle_response(command_message=cm)
+
+ def _handle_response(self, command_message):
results = []
while True:
msg = self.outqueue.get()
h.run(self, msg) # TODO: pause for response?
continue
pp = getattr(
- self, '_postprocess_%s' % command.name.replace(' ', '_'),
- self._postprocess_text)
- pp(command=command, args=args, results=results)
+ self, '_postprocess_%s' % command_message.command.replace(' ', '_'),
+ self._postprocess_text)
+ pp(command=command_message.command,
+ args=command_message.arguments,
+ results=results)
return results
def _handle_request(self, msg):
continue
self.inqueue.put(response)
+ def _set_config(self, option, value, section=None):
+ self.gui._set_config(section=section, option=option, value=value,
+ ui_to_command_queue=self.inqueue,
+ response_handler=self._handle_response)
# Command-specific postprocessing
self._c['output'].write(result.__class__.__name__+'\n')
self._c['output'].write(str(result).rstrip()+'\n')
+ def _postprocess_playlists(self, command, args={}, results=None):
+ """Update `self` to show the playlists.
+ """
+ if not isinstance(results[-1], Success):
+ self._postprocess_text(command, results=results)
+ return
+ assert len(results) == 2, results
+ playlists = results[0]
+ if 'playlist' in self._c:
+ for playlist in playlists:
+ if self._c['playlist'].is_playlist_loaded(playlist):
+ self._c['playlist'].update_playlist(playlist)
+ else:
+ self._c['playlist'].add_playlist(playlist)
+
+ def _postprocess_new_playlist(self, command, args={}, results=None):
+ """Update `self` to show the new playlist.
+ """
+ if not isinstance(results[-1], Success):
+ self._postprocess_text(command, results=results)
+ return
+ assert len(results) == 2, results
+ playlist = results[0]
+ if 'playlist' in self._c:
+ loaded = self._c['playlist'].is_playlist_loaded(playlist)
+ assert loaded == False, loaded
+ self._c['playlist'].add_playlist(playlist)
+
def _postprocess_load_playlist(self, command, args={}, results=None):
"""Update `self` to show the playlist.
"""
return
assert len(results) == 2, results
playlist = results[0]
- self._c['playlist']._c['tree'].add_playlist(playlist)
+ self._c['playlist'].add_playlist(playlist)
def _postprocess_get_playlist(self, command, args={}, results=[]):
if not isinstance(results[-1], Success):
return
assert len(results) == 2, results
playlist = results[0]
- self._c['playlist']._c['tree'].update_playlist(playlist)
+ if 'playlist' in self._c:
+ loaded = self._c['playlist'].is_playlist_loaded(playlist)
+ assert loaded == True, loaded
+ self._c['playlist'].update_playlist(playlist)
def _postprocess_get_curve(self, command, args={}, results=[]):
"""Update `self` to show the curve.
else:
raise NotImplementedError()
if 'note' in self._c:
- self._c['note'].set_text(curve.info['note'])
+ self._c['note'].set_text(curve.info.get('note', ''))
if 'playlist' in self._c:
- self._c['playlist']._c['tree'].set_selected_curve(
+ self._c['playlist'].set_selected_curve(
playlist, curve)
if 'plot' in self._c:
self._c['plot'].set_curve(curve, config=self.gui.config)
"""
pass
+ def _postprocess_glob_curves_to_playlist(
+ self, command, args={}, results=[]):
+ """Update `self` to show new curves.
+ """
+ if not isinstance(results[-1], Success):
+ self._postprocess_text(command, results=results)
+ return
+ if 'playlist' in self._c:
+ if args.get('playlist', None) != None:
+ playlist = args['playlist']
+ pname = playlist.name
+ loaded = self._c['playlist'].is_playlist_name_loaded(pname)
+ assert loaded == True, loaded
+ for curve in results[:-1]:
+ self._c['playlist']._add_curve(pname, curve)
+ else:
+ self.execute_command(
+ command=self._command_by_name('get playlist'))
+
def _postprocess_zero_block_surface_contact_point(
self, command, args={}, results=[]):
"""Update the curve, since the available columns may have changed.
- # TODO: cruft
-
- def _GetActiveFileIndex(self):
- lib.playlist.Playlist = self.GetActivePlaylist()
- #get the selected item from the tree
- selected_item = self._c['playlist']._c['tree'].GetSelection()
- #test if a playlist or a curve was double-clicked
- if self._c['playlist']._c['tree'].ItemHasChildren(selected_item):
- return -1
- else:
- count = 0
- selected_item = self._c['playlist']._c['tree'].GetPrevSibling(selected_item)
- while selected_item.IsOk():
- count += 1
- selected_item = self._c['playlist']._c['tree'].GetPrevSibling(selected_item)
- return count
-
- def _GetPlaylistTab(self, name):
- for index, page in enumerate(self._c['notebook']._tabs._pages):
- if page.caption == name:
- return index
- return -1
-
- def select_plugin(self, _class=None, method=None, plugin=None):
- pass
-
- def AddPlaylistFromFiles(self, files=[], name='Untitled'):
- if files:
- playlist = lib.playlist.Playlist(self, self.drivers)
- for item in files:
- playlist.add_curve(item)
- if playlist.count > 0:
- playlist.name = self._GetUniquePlaylistName(name)
- playlist.reset()
- self.AddTayliss(playlist)
-
- def AppliesPlotmanipulator(self, name):
- '''
- Returns True if the plotmanipulator 'name' is applied, False otherwise
- name does not contain 'plotmanip_', just the name of the plotmanipulator (e.g. 'flatten')
- '''
- return self.GetBoolFromConfig('core', 'plotmanipulators', name)
-
- def ApplyPlotmanipulators(self, plot, plot_file):
- '''
- Apply all active plotmanipulators.
- '''
- if plot is not None and plot_file is not None:
- manipulated_plot = copy.deepcopy(plot)
- for plotmanipulator in self.plotmanipulators:
- if self.GetBoolFromConfig('core', 'plotmanipulators', plotmanipulator.name):
- manipulated_plot = plotmanipulator.method(manipulated_plot, plot_file)
- return manipulated_plot
-
- def GetActiveFigure(self):
- playlist_name = self.GetActivePlaylistName()
- figure = self.playlists[playlist_name].figure
- if figure is not None:
- return figure
- return None
-
- def GetActiveFile(self):
- playlist = self.GetActivePlaylist()
- if playlist is not None:
- return playlist.get_active_file()
- return None
-
- def GetActivePlot(self):
- playlist = self.GetActivePlaylist()
- if playlist is not None:
- return playlist.get_active_file().plot
- return None
-
- def GetDisplayedPlot(self):
- plot = copy.deepcopy(self.displayed_plot)
- #plot.curves = []
- #plot.curves = copy.deepcopy(plot.curves)
- return plot
-
- def GetDisplayedPlotCorrected(self):
- plot = copy.deepcopy(self.displayed_plot)
- plot.curves = []
- plot.curves = copy.deepcopy(plot.corrected_curves)
- return plot
-
- def GetDisplayedPlotRaw(self):
- plot = copy.deepcopy(self.displayed_plot)
- plot.curves = []
- plot.curves = copy.deepcopy(plot.raw_curves)
- return plot
-
- def GetDockArt(self):
- return self._c['manager'].GetArtProvider()
-
- def GetPlotmanipulator(self, name):
- '''
- Returns a plot manipulator function from its name
- '''
- for plotmanipulator in self.plotmanipulators:
- if plotmanipulator.name == name:
- return plotmanipulator
- return None
-
- def HasPlotmanipulator(self, name):
- '''
- returns True if the plotmanipulator 'name' is loaded, False otherwise
- '''
- for plotmanipulator in self.plotmanipulators:
- if plotmanipulator.command == name:
- return True
- return False
-
-
- def _on_dir_ctrl_left_double_click(self, event):
- file_path = self.panelFolders.GetPath()
- if os.path.isfile(file_path):
- if file_path.endswith('.hkp'):
- self.do_loadlist(file_path)
- event.Skip()
-
- def _on_erase_background(self, event):
- event.Skip()
-
- 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:
- item_section = self.panelProperties.SelectedTreeItem
- item_plugin = self._c['commands']._c['tree'].GetItemParent(item_section)
- plugin = self._c['commands']._c['tree'].GetItemText(item_plugin)
- config = self.gui.config[plugin]
- property_section = self._c['commands']._c['tree'].GetItemText(item_section)
- property_key = prop.GetName()
- property_value = prop.GetDisplayedString()
-
- config[property_section][property_key]['value'] = property_value
-
- def OnResultsCheck(self, index, flag):
- results = self.GetActivePlot().results
- if results.has_key(self.results_str):
- results[self.results_str].results[index].visible = flag
- results[self.results_str].update()
- self.UpdatePlot()
-
-
- def _on_size(self, event):
- event.Skip()
-
- def UpdatePlaylistsTreeSelection(self):
- playlist = self.GetActivePlaylist()
- if playlist is not None:
- if playlist.index >= 0:
- self._c['status bar'].set_playlist(playlist)
- self.UpdateNote()
- self.UpdatePlot()
-
- def _on_curve_select(self, playlist, curve):
- #create the plot tab and add playlist to the dictionary
- plotPanel = panel.plot.PlotPanel(self, ID_FirstPlot + len(self.playlists))
- notebook_tab = self._c['notebook'].AddPage(plotPanel, playlist.name, True)
- #tab_index = self._c['notebook'].GetSelection()
- playlist.figure = plotPanel.get_figure()
- self.playlists[playlist.name] = playlist
- #self.playlists[playlist.name] = [playlist, figure]
- self._c['status bar'].set_playlist(playlist)
- self.UpdateNote()
- self.UpdatePlot()
-
-
- def _on_playlist_left_doubleclick(self):
- index = self._c['notebook'].GetSelection()
- current_playlist = self._c['notebook'].GetPageText(index)
- if current_playlist != playlist_name:
- index = self._GetPlaylistTab(playlist_name)
- self._c['notebook'].SetSelection(index)
- self._c['status bar'].set_playlist(playlist)
- self.UpdateNote()
- self.UpdatePlot()
-
- def _on_playlist_delete(self, playlist):
- notebook = self.Parent.plotNotebook
- index = self.Parent._GetPlaylistTab(playlist.name)
- notebook.SetSelection(index)
- notebook.DeletePage(notebook.GetSelection())
- self.Parent.DeleteFromPlaylists(playlist_name)
-
-
-
# Command panel interface
def select_command(self, _class, method, command):
self._c['property editor']._argument_from_label[label] = (
argument)
- self.gui.config['selected command'] = command # TODO: push to engine
+ self._set_config('selected command', command.name)
+
+ def select_plugin(self, _class=None, method=None, plugin=None):
+ pass
+
+
+
+ # Folders panel interface
+
+ def _on_dir_ctrl_left_double_click(self, event):
+ file_path = self.panelFolders.GetPath()
+ if os.path.isfile(file_path):
+ if file_path.endswith('.hkp'):
+ self.do_loadlist(file_path)
+ event.Skip()
# Panel display handling
+ def _on_pane_close(self, event):
+ pane = event.pane
+ view = self._c['menu bar']._c['view']
+ if pane.name in view._c.keys():
+ view._c[pane.name].Check(False)
+ event.Skip()
+
def _on_panel_visibility(self, _class, method, panel_name, visible):
pane = self._c['manager'].GetPane(panel_name)
pane.Show(visible)
selected_perspective = self.gui.config['active perspective']
if not self._perspectives.has_key(selected_perspective):
- self.gui.config['active perspective'] = 'Default' # TODO: push to engine's Hooke
+ self._set_config('active perspective', 'Default')
self._restore_perspective(selected_perspective, force=True)
self._update_perspective_menu()
def _restore_perspective(self, name, force=False):
if name != self.gui.config['active perspective'] or force == True:
self.log.debug('restore perspective %s' % name)
- self.gui.config['active perspective'] = name # TODO: push to engine's Hooke
+ self._set_config('active perspective', name)
self._c['manager'].LoadPerspective(self._perspectives[name])
self._c['manager'].Update()
for pane in self._c['manager'].GetAllPanes():