Skip to content
Snippets Groups Projects
Commit 4b6fe081 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

FSLEyesFrame layout from previous session is restored, unless a scene is

specified on the command line. Bugfix in OverlayPlotPanel - DataSeries
property listeners were not being de-registered in destroy().
parent 33d93fcd
No related branches found
No related tags found
No related merge requests found
...@@ -42,6 +42,8 @@ messages = TypeDict({ ...@@ -42,6 +42,8 @@ messages = TypeDict({
'fsleyes.loading' : 'Loading {}', 'fsleyes.loading' : 'Loading {}',
'FSLEyesSplash.default' : 'Loading ...', 'FSLEyesSplash.default' : 'Loading ...',
'FSLEyesFrame.restoringLayout' : 'Restoring layout from last session ...',
'image.saveImage.error' : 'An error occurred saving the file. ' 'image.saveImage.error' : 'An error occurred saving the file. '
'Details: {}', 'Details: {}',
......
...@@ -56,11 +56,10 @@ class FSLEyesFrame(wx.Frame): ...@@ -56,11 +56,10 @@ class FSLEyesFrame(wx.Frame):
When a ``FSLEyesFrame`` is closed, it saves some display settings so that When a ``FSLEyesFrame`` is closed, it saves some display settings so that
they can be restored the next time a ``FSLEyesFrame`` is opened. The they can be restored the next time a ``FSLEyesFrame`` is opened. The
settings are saved using the :class:`~fsl.utils.settings` module. settings are saved using the :class:`~fsl.utils.settings` module.
Currently, the frame position, size, and layout (see the
Currently, only the frame position and size are saved - in the future, I :mod:`.perspectives` module) are saved.
plan to save and restore the ``ViewPanel`` layout as well.
**Programming interface** **Programming interface**
...@@ -85,7 +84,7 @@ class FSLEyesFrame(wx.Frame): ...@@ -85,7 +84,7 @@ class FSLEyesFrame(wx.Frame):
parent, parent,
overlayList, overlayList,
displayCtx, displayCtx,
restore=True): restore=False):
"""Create a ``FSLEyesFrame``. """Create a ``FSLEyesFrame``.
.. note:: The ``restore`` functionality is not currently implemented. .. note:: The ``restore`` functionality is not currently implemented.
...@@ -140,6 +139,11 @@ class FSLEyesFrame(wx.Frame): ...@@ -140,6 +139,11 @@ class FSLEyesFrame(wx.Frame):
self.__makeMenuBar() self.__makeMenuBar()
self.__restoreState(restore) self.__restoreState(restore)
# If we have not restored the previous
# layout, we are not going to save the
# layout on exit.
self.__saveLayout = restore
self.__auiManager.Bind(aui.EVT_AUI_PANE_CLOSE, self.__onViewPanelClose) self.__auiManager.Bind(aui.EVT_AUI_PANE_CLOSE, self.__onViewPanelClose)
self .Bind(wx.EVT_CLOSE, self.__onClose) self .Bind(wx.EVT_CLOSE, self.__onClose)
...@@ -423,12 +427,16 @@ class FSLEyesFrame(wx.Frame): ...@@ -423,12 +427,16 @@ class FSLEyesFrame(wx.Frame):
ev.Skip() ev.Skip()
size = self.GetSize().Get() if self.__saveLayout:
position = self.GetScreenPosition().Get()
size = self.GetSize().Get()
fslsettings.write('framesize', str(size)) position = self.GetScreenPosition().Get()
fslsettings.write('frameposition', str(position)) layout = perspectives.serialisePerspective(self)
fslsettings.write('framesize', str(size))
fslsettings.write('frameposition', str(position))
fslsettings.write('framelayout', layout)
# It's nice to explicitly clean # It's nice to explicitly clean
# up our FSLEyesPanels, otherwise # up our FSLEyesPanels, otherwise
# they'll probably complain # they'll probably complain
...@@ -448,59 +456,28 @@ class FSLEyesFrame(wx.Frame): ...@@ -448,59 +456,28 @@ class FSLEyesFrame(wx.Frame):
"""A proxy for the :meth:`__parseSavedSize` method.""" """A proxy for the :meth:`__parseSavedSize` method."""
return self.__parseSavedSize(size) return self.__parseSavedSize(size)
def __parseSavedLayout(self, layout):
"""Parses the given string, which is assumed to contain an encoded
:class:`.AuiManager` perspective (see
:meth:`.AuiManager.SavePerspective`).
Returns a list of class names, specifying the control panels
(e.g. :class:`.OverlayListPanel`) which were previously open, and need
to be created.
.. warning:: This method is not currently being used - it is from a
previous version. I may use it in the future to restore
``ViewPanel`` layouts, or I may re-write it.
"""
try:
names = []
sections = layout.split('|')[1:]
for section in sections:
if section.strip() == '': continue
attrs = section.split(';')
attrs = dict([tuple(nvpair.split('=')) for nvpair in attrs])
if 'name' in attrs:
names.append(attrs['name'])
return names
except:
return []
def __restoreState(self, restore=True): def __restoreState(self, restore):
"""Called by :meth:`__init__`. """Called by :meth:`__init__`.
If any frame size/layout properties have previously been saved via the If any frame size/layout properties have previously been saved via the
:mod:`~fsl.utils.settings` module, they are read in, and applied to :mod:`~fsl.utils.settings` module, they are read in, and applied to
this frame. this frame.
:arg bool default: If ``True``, any saved state is ignored. :arg restore: If ``False``, any saved layout state is ignored.
""" """
from operator import itemgetter as iget from operator import itemgetter as iget
# Restore the saved frame size/position # Restore the saved frame size/position
size = self.__parseSavedSize( size = self.__parseSavedSize( fslsettings.read('framesize'))
fslsettings.read('framesize')) position = self.__parseSavedPoint(fslsettings.read('frameposition'))
position = self.__parseSavedPoint( layout = fslsettings.read('framelayout')
fslsettings.read('frameposition'))
# We can only restore a saved layout
# if there is a saved layout to restore
restore = restore and (layout is not None)
if (size is not None) and (position is not None): if (size is not None) and (position is not None):
# Turn the saved size/pos into # Turn the saved size/pos into
...@@ -579,10 +556,12 @@ class FSLEyesFrame(wx.Frame): ...@@ -579,10 +556,12 @@ class FSLEyesFrame(wx.Frame):
else: else:
self.Centre() self.Centre()
# TODO Restore the previous view panel layout.
# Currently, we just display an OrthoPanel.
if restore: if restore:
self.addViewPanel(views.OrthoPanel) perspectives.applyPerspective(
self,
'framelayout',
layout,
message=strings.messages[self, 'restoringLayout'],)
def __makeMenuBar(self): def __makeMenuBar(self):
......
...@@ -12,6 +12,7 @@ control panel layouts for *FSLeyes*. ...@@ -12,6 +12,7 @@ control panel layouts for *FSLeyes*.
getAllPerspectives getAllPerspectives
loadPerspective loadPerspective
applyPerspective
savePerspective savePerspective
removePerspective removePerspective
serialisePerspective serialisePerspective
...@@ -50,7 +51,7 @@ def getAllPerspectives(): ...@@ -50,7 +51,7 @@ def getAllPerspectives():
return uniq return uniq
def loadPerspective(frame, name): def loadPerspective(frame, name, **kwargs):
""" """
""" """
...@@ -67,16 +68,24 @@ def loadPerspective(frame, name): ...@@ -67,16 +68,24 @@ def loadPerspective(frame, name):
raise ValueError('No perspective named "{}" exists'.format(name)) raise ValueError('No perspective named "{}" exists'.format(name))
log.debug('Serialised perspective:\n{}'.format(persp)) log.debug('Serialised perspective:\n{}'.format(persp))
applyPerspective(frame, name, persp, **kwargs)
def applyPerspective(frame, name, perspective, showMessage=True, message=None):
persp = deserialisePerspective(persp) persp = deserialisePerspective(perspective)
frameChildren, frameLayout, vpChildrens, vpLayouts = persp frameChildren, frameLayout, vpChildrens, vpLayouts = persp
# Show a message while re-configuring the frame # Show a message while re-configuring the frame
dlg = fsldlg.SimpleMessageDialog(
frame, if showMessage:
strings.messages['perspectives.applyingPerspective'].format( if message is None:
strings.perspectives.get(name, name))) message = strings.messages[
dlg.Show() 'perspectives.applyingPerspective'].format(
strings.perspectives.get(name, name))
dlg = fsldlg.SimpleMessageDialog(frame, message)
dlg.Show()
# Clear all existing view # Clear all existing view
# panels from the frame # panels from the frame
...@@ -101,8 +110,9 @@ def loadPerspective(frame, name): ...@@ -101,8 +110,9 @@ def loadPerspective(frame, name):
vp.getAuiManager().LoadPerspective(vpLayout) vp.getAuiManager().LoadPerspective(vpLayout)
dlg.Close() if showMessage:
dlg.Destroy() dlg.Close()
dlg.Destroy()
def savePerspective(frame, name): def savePerspective(frame, name):
......
...@@ -845,8 +845,8 @@ class OverlayPlotPanel(PlotPanel): ...@@ -845,8 +845,8 @@ class OverlayPlotPanel(PlotPanel):
self._overlayList.removeListener('overlays', self.__name) self._overlayList.removeListener('overlays', self.__name)
self._displayCtx .removeListener('selectedOverlay', self.__name) self._displayCtx .removeListener('selectedOverlay', self.__name)
for ds in self.__dataSeries.values(): for overlay in list(self.__dataSeries.keys()):
ds.destroy() self.clearDataSeries(overlay)
self.__dataSeries = None self.__dataSeries = None
self.__refreshProps = None self.__refreshProps = None
......
...@@ -204,9 +204,9 @@ def interface(parent, args, ctx): ...@@ -204,9 +204,9 @@ def interface(parent, args, ctx):
if ycentre is None: ycentre = displayCtx.location.xz if ycentre is None: ycentre = displayCtx.location.xz
if zcentre is None: zcentre = displayCtx.location.xy if zcentre is None: zcentre = displayCtx.location.xy
viewPanel._xcanvas.centreDisplayAt(*xcentre) viewPanel.getXCanvas().centreDisplayAt(*xcentre)
viewPanel._ycanvas.centreDisplayAt(*ycentre) viewPanel.getYCanvas().centreDisplayAt(*ycentre)
viewPanel._zcanvas.centreDisplayAt(*zcentre) viewPanel.getZCanvas().centreDisplayAt(*zcentre)
# Make sure the new frame is shown # Make sure the new frame is shown
# before destroying the splash screen # before destroying the splash screen
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment