diff --git a/fsl/data/strings.py b/fsl/data/strings.py index f095c5f3f37a20318244747f679a3ecf63fb1588..df5cb2f08463ccdba986ae787d588b2809d79753 100644 --- a/fsl/data/strings.py +++ b/fsl/data/strings.py @@ -207,7 +207,7 @@ actions = TypeDict({ 'CanvasPanel.showCommandLineArgs' : 'Show command line for scene', 'CanvasPanel.toggleColourBar' : 'Colour bar', 'CanvasPanel.toggleOverlayList' : 'Overlay list', - 'CanvasPanel.toggleDisplayProperties' : 'Overlay display properties', + 'CanvasPanel.toggleDisplayProperties' : 'Overlay display toolbar', 'CanvasPanel.toggleLocationPanel' : 'Location panel', 'CanvasPanel.toggleAtlasPanel' : 'Atlas panel', 'CanvasPanel.toggleLookupTablePanel' : 'Lookup tables', @@ -216,14 +216,14 @@ actions = TypeDict({ 'CanvasPanel.toggleClassificationPanel' : 'Melodic IC classification', 'CanvasPanel.toggleShell' : 'Python shell', - 'OrthoPanel.toggleOrthoToolBar' : 'View properties', + 'OrthoPanel.toggleOrthoToolBar' : 'Ortho toolbar', 'OrthoPanel.toggleEditToolBar' : 'Edit toolbar', 'OrthoToolBar.showMoreSettings' : 'More settings', 'LightBoxToolBar.showMoreSettings' : 'More settings', 'OverlayDisplayToolBar.showMoreSettings' : 'More settings', - 'LightBoxPanel.toggleLightBoxToolBar' : 'View properties', + 'LightBoxPanel.toggleLightBoxToolBar' : 'Lightbox toolbar', 'PlotPanel.screenshot' : 'Take screenshot', 'TimeSeriesPanel.toggleTimeSeriesList' : 'Time series list', diff --git a/fsl/fsleyes/actions/__init__.py b/fsl/fsleyes/actions/__init__.py index 424a128a00e9cb7365f7628ff076fc7651b3b336..40e27a072c55a3951352af3078b605db8076429c 100644 --- a/fsl/fsleyes/actions/__init__.py +++ b/fsl/fsleyes/actions/__init__.py @@ -95,6 +95,7 @@ Some 'global' actions are also provided in this package: import logging import inspect +import functools import props @@ -259,9 +260,12 @@ class ToggleAction(Action): is flipped. """ - result = Action.__call__(self, *args, **kwargs) - - self.toggled = not self.toggled + # Copy the toggled value before running + # the action, in case it gets inadvertently + # changed + toggled = self.toggled + result = Action.__call__(self, *args, **kwargs) + self.toggled = not toggled return result @@ -467,4 +471,4 @@ class ActionFactory(object): # with the Action on the instance. action = self.__actionType(self.__func, instance) setattr(instance, self.__func.__name__, action) - return action + return functools.update_wrapper(action, self.__func) diff --git a/fsl/fsleyes/controls/lightboxtoolbar.py b/fsl/fsleyes/controls/lightboxtoolbar.py index f5ecd5a5316f86cf3ce970e45b58442c1d24ee3d..fa063cbebe69854a01c12d6842b2bef25efec072 100644 --- a/fsl/fsleyes/controls/lightboxtoolbar.py +++ b/fsl/fsleyes/controls/lightboxtoolbar.py @@ -179,4 +179,5 @@ class LightBoxToolBar(fsltoolbar.FSLEyesToolBar): self.lightBoxPanel.togglePanel( canvassettingspanel.CanvasSettingsPanel, self.lightBoxPanel, - floatPane=True) + floatPane=True, + action=self.showMoreSettings) diff --git a/fsl/fsleyes/controls/orthotoolbar.py b/fsl/fsleyes/controls/orthotoolbar.py index 1feb639cfdb03ab6e5c52b2a0a1f0c6b0cf63deb..7123021b6095fc4b537b09432f8bff942baccfe0 100644 --- a/fsl/fsleyes/controls/orthotoolbar.py +++ b/fsl/fsleyes/controls/orthotoolbar.py @@ -203,4 +203,5 @@ class OrthoToolBar(fsltoolbar.FSLEyesToolBar): import canvassettingspanel self.orthoPanel.togglePanel(canvassettingspanel.CanvasSettingsPanel, self.orthoPanel, - floatPane=True) + floatPane=True, + action=self.showMoreSettings) diff --git a/fsl/fsleyes/controls/overlaydisplaytoolbar.py b/fsl/fsleyes/controls/overlaydisplaytoolbar.py index eef6ba3cb40ea95907f3700ebc90cdd2535cc342..29daaf412795f9a117a10c376196086c43144b8e 100644 --- a/fsl/fsleyes/controls/overlaydisplaytoolbar.py +++ b/fsl/fsleyes/controls/overlaydisplaytoolbar.py @@ -123,7 +123,8 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar): def showMoreSettings(self, *a): """Shows/hides a :class:`.OverlayDisplayPanel` dialog. """ self.__viewPanel.togglePanel(overlaydisplay.OverlayDisplayPanel, - floatPane=True) + floatPane=True, + action=self.showMoreSettings) def __showTools(self, overlay): diff --git a/fsl/fsleyes/frame.py b/fsl/fsleyes/frame.py index d8f7501e1d1dc1c0453ad642c8e6101e320b0292..c6f55f9027317f45bba7c6ac8c7f9171eca96f29 100644 --- a/fsl/fsleyes/frame.py +++ b/fsl/fsleyes/frame.py @@ -258,17 +258,37 @@ class FSLEyesFrame(wx.Frame): self.__viewPanelMenus[panel] = submenu - for actionName, actionObj in actionz: + # Separate out the normal actions from + # the toggle actions, as we will put a + # separator between them. + regularActions = [] + toggleActions = [] + for actionName, actionObj in actionz: if isinstance(actionObj, actions.ToggleAction): - kind = wx.ITEM_CHECK + toggleActions .append((actionName, actionObj)) else: - kind = wx.ITEM_NORMAL + regularActions.append((actionName, actionObj)) + + # Non-toggle actions + for actionName, actionObj in regularActions: + menuItem = menu.Append( + wx.ID_ANY, + strings.actions[panel, actionName], + kind=wx.ITEM_NORMAL) + actionObj.bindToWidget(self, wx.EVT_MENU, menuItem) + + # Separator + if len(regularActions) > 0 and len(toggleActions) > 0: + menu.AppendSeparator() + + for actionName, actionObj in toggleActions: + menuItem = menu.Append( wx.ID_ANY, strings.actions[panel, actionName], - kind=kind) + kind=wx.ITEM_CHECK) actionObj.bindToWidget(self, wx.EVT_MENU, menuItem) @@ -280,11 +300,14 @@ class FSLEyesFrame(wx.Frame): self.__auiManager.ClosePane(paneInfo) self.__auiManager.Update() + # But put another separator before it + if len(regularActions) > 0 or len(toggleActions) > 0: + menu.AppendSeparator() + closeItem = menu.Append( wx.ID_ANY, strings.actions[self, 'closeViewPanel']) self.Bind(wx.EVT_MENU, closeViewPanel, closeItem) - def __onViewPanelClose(self, ev=None, paneInfo=None): @@ -320,11 +343,7 @@ class FSLEyesFrame(wx.Frame): id(panel), id(dctx))) - # Unbind view panel menu - # items, and remove the menu - for actionName, actionObj in panel.getActions().items(): - actionObj.unbindAllWidgets() - + # Remove the view panel menu if menu is not None: self.__settingsMenu.Remove(menu.GetId()) diff --git a/fsl/fsleyes/views/canvaspanel.py b/fsl/fsleyes/views/canvaspanel.py index 721bf8799c9af039a9aa9a9c018cf08d3ec2493e..9f569d837c6b7d6e04a6fdd958b83abf5ea5383e 100644 --- a/fsl/fsleyes/views/canvaspanel.py +++ b/fsl/fsleyes/views/canvaspanel.py @@ -314,7 +314,9 @@ class CanvasPanel(viewpanel.ViewPanel): """Toggles an :class:`.OverlayListPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(overlaylistpanel.OverlayListPanel, location=wx.BOTTOM) + self.togglePanel(overlaylistpanel.OverlayListPanel, + location=wx.BOTTOM, + action=self.toggleOverlayList) @actions.toggleAction @@ -322,7 +324,9 @@ class CanvasPanel(viewpanel.ViewPanel): """Toggles an :class:`.OverlayInfoPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(overlayinfopanel.OverlayInfoPanel, location=wx.LEFT) + self.togglePanel(overlayinfopanel.OverlayInfoPanel, + location=wx.LEFT, + action=self.toggleOverlayInfo) @actions.toggleAction @@ -330,7 +334,9 @@ class CanvasPanel(viewpanel.ViewPanel): """Toggles an :class:`.AtlasPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(atlaspanel.AtlasPanel, location=wx.BOTTOM) + self.togglePanel(atlaspanel.AtlasPanel, + location=wx.BOTTOM, + action=self.toggleAtlasPanel) @actions.toggleAction @@ -339,7 +345,8 @@ class CanvasPanel(viewpanel.ViewPanel): :meth:`.ViewPanel.togglePanel`. """ self.togglePanel(overlaydisplaytoolbar.OverlayDisplayToolBar, - viewPanel=self) + viewPanel=self, + action=self.toggleDisplayProperties) @actions.toggleAction @@ -347,7 +354,9 @@ class CanvasPanel(viewpanel.ViewPanel): """Toggles a :class:`.LocationPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(locationpanel.LocationPanel, location=wx.BOTTOM) + self.togglePanel(locationpanel.LocationPanel, + location=wx.BOTTOM, + action=self.toggleLocationPanel) @actions.toggleAction @@ -355,7 +364,9 @@ class CanvasPanel(viewpanel.ViewPanel): """Toggles a :class:`.ClusterPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(clusterpanel.ClusterPanel, location=wx.TOP) + self.togglePanel(clusterpanel.ClusterPanel, + location=wx.TOP, + action=self.toggleClusterPanel) @actions.toggleAction @@ -363,7 +374,9 @@ class CanvasPanel(viewpanel.ViewPanel): """Toggles a :class:`.LookupTablePanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(lookuptablepanel.LookupTablePanel, location=wx.TOP) + self.togglePanel(lookuptablepanel.LookupTablePanel, + location=wx.TO, + action=self.toggleLookupTablePanel) @actions.toggleAction def toggleClassificationPanel(self): @@ -371,7 +384,8 @@ class CanvasPanel(viewpanel.ViewPanel): :meth:`.ViewPanel.togglePanel`. """ self.togglePanel(melclasspanel.MelodicClassificationPanel, - location=wx.RIGHT) + location=wx.RIGHT, + action=self.toggleClassificationPanel) @actions.toggleAction @@ -381,7 +395,8 @@ class CanvasPanel(viewpanel.ViewPanel): """ self.togglePanel(shellpanel.ShellPanel, self.getSceneOptions(), - location=wx.BOTTOM) + location=wx.BOTTOM, + action=self.toggleShell) def getSceneOptions(self): diff --git a/fsl/fsleyes/views/histogrampanel.py b/fsl/fsleyes/views/histogrampanel.py index 57b3c483dbdd80c8a0648d592f3443e6aa8b2c1c..de1362f12925faeb9cb25355f039a400bab2a8de 100644 --- a/fsl/fsleyes/views/histogrampanel.py +++ b/fsl/fsleyes/views/histogrampanel.py @@ -115,7 +115,10 @@ class HistogramPanel(plotpanel.OverlayPlotPanel): """Shows/hides a :class:`.PlotListPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(plotlistpanel.PlotListPanel, self, location=wx.TOP) + self.togglePanel(plotlistpanel.PlotListPanel, + self, + location=wx.TOP, + action=self.toggleHistogramList) @actions.toggleAction @@ -126,7 +129,21 @@ class HistogramPanel(plotpanel.OverlayPlotPanel): self.togglePanel( histogramcontrolpanel.HistogramControlPanel, self, - location=wx.TOP) + location=wx.TOP, + action=self.toggleHistogramControl) + + + def getActions(self): + """Overrides :meth:`.ActionProvider.getActions`. Returns all of the + :mod:`.actions` that are defined on this ``HistogramPanel``. + """ + actions = [self.screenshot, + self.toggleHistogramList, + self.toggleHistogramControl] + + names = [a.__name__ for a in actions] + + return zip(names, actions) def draw(self, *a): diff --git a/fsl/fsleyes/views/lightboxpanel.py b/fsl/fsleyes/views/lightboxpanel.py index 9f99fe4250b06d2aff3f19a0c94e85e4a5a8a84e..a941edfb23bdf4d349872b20a40f1d3f32590c99 100644 --- a/fsl/fsleyes/views/lightboxpanel.py +++ b/fsl/fsleyes/views/lightboxpanel.py @@ -191,7 +191,31 @@ class LightBoxPanel(canvaspanel.CanvasPanel): """Shows/hides a :class:`.LightBoxToolBar`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(lightboxtoolbar.LightBoxToolBar, lb=self) + self.togglePanel(lightboxtoolbar.LightBoxToolBar, + lb=self, + action=self.toggleLightBoxToolBar) + + + def getActions(self): + """Overrides :meth:`.ActionProvider.getActions`. Returns all of the + :mod:`.actions` that are defined on this ``LightBoxPanel``. + """ + actions = [self.screenshot, + self.showCommandLineArgs, + self.toggleOverlayList, + self.toggleLocationPanel, + self.toggleDisplayProperties, + self.toggleLightBoxToolBar, + self.toggleOverlayInfo, + self.toggleAtlasPanel, + self.toggleLookupTablePanel, + self.toggleClusterPanel, + self.toggleClassificationPanel, + self.toggleShell] + + names = [a.__name__ for a in actions] + + return zip(names, actions) def getGLCanvases(self): diff --git a/fsl/fsleyes/views/orthopanel.py b/fsl/fsleyes/views/orthopanel.py index 6f00d4398981d7fc92a67ad264655a304c3c7255..e29a00e5be8686fa298bd189e0df4b92c9fc2eec 100644 --- a/fsl/fsleyes/views/orthopanel.py +++ b/fsl/fsleyes/views/orthopanel.py @@ -117,7 +117,6 @@ class OrthoPanel(canvaspanel.CanvasPanel): :nosignatures: ~fsl.fsleyes.controls.orthotoolbar.OrthoToolBar - ~fsl.fsleyes.controls.orthoedittoolbar.OrthoEditToolBar ~fsl.fsleyes.controls.overlaydisplaytoolbar.OverlayDisplayToolBar """ @@ -240,7 +239,6 @@ class OrthoPanel(canvaspanel.CanvasPanel): def _addToolbars(): self.toggleDisplayProperties() self.toggleOrthoToolBar() - self.toggleEditToolBar() if addToolbars: wx.CallAfter(_addToolbars) @@ -278,7 +276,9 @@ class OrthoPanel(canvaspanel.CanvasPanel): """Shows/hides an :class:`.OrthoToolBar`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(orthotoolbar.OrthoToolBar, ortho=self) + self.togglePanel(orthotoolbar.OrthoToolBar, + ortho=self, + action=self.toggleOrthoToolBar) @actions.toggleAction @@ -286,7 +286,32 @@ class OrthoPanel(canvaspanel.CanvasPanel): """Shows/hides an :class:`.OrthoEditToolBar`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(orthoedittoolbar.OrthoEditToolBar, ortho=self) + self.togglePanel(orthoedittoolbar.OrthoEditToolBar, + ortho=self, + action=self.toggleEditToolBar) + + + def getActions(self): + """Overrides :meth:`.ActionProvider.getActions`. Returns all of the + :mod:`.actions` that are defined on this ``OrthoPanel``. + """ + actions = [self.screenshot, + self.showCommandLineArgs, + self.toggleOverlayList, + self.toggleLocationPanel, + self.toggleDisplayProperties, + self.toggleOrthoToolBar, + self.toggleEditToolBar, + self.toggleOverlayInfo, + self.toggleAtlasPanel, + self.toggleLookupTablePanel, + self.toggleClusterPanel, + self.toggleClassificationPanel, + self.toggleShell] + + names = [a.__name__ for a in actions] + + return zip(names, actions) def getGLCanvases(self): diff --git a/fsl/fsleyes/views/powerspectrumpanel.py b/fsl/fsleyes/views/powerspectrumpanel.py index f8db10049ac4a146e3639607ba9bd6b0a84de958..903843ba53af1acb9648f0f4c9c06175dc1b55a1 100644 --- a/fsl/fsleyes/views/powerspectrumpanel.py +++ b/fsl/fsleyes/views/powerspectrumpanel.py @@ -128,7 +128,8 @@ class PowerSpectrumPanel(plotpanel.OverlayPlotPanel): self.togglePanel( pscontrol.PowerSpectrumControlPanel, self, - location=wx.TOP) + location=wx.TOP, + action=self.togglePowerSpectrumControl) @actions.toggleAction @@ -136,7 +137,23 @@ class PowerSpectrumPanel(plotpanel.OverlayPlotPanel): """Shows/hides a :class:`.PlotListPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(plotlistpanel.PlotListPanel, self, location=wx.TOP) + self.togglePanel(plotlistpanel.PlotListPanel, + self, + location=wx.TOP, + action=self.togglePowerSpectrumList) + + + def getActions(self): + """Overrides :meth:`.ActionProvider.getActions`. Returns all of the + :mod:`.actions` that are defined on this ``PowerSpectrumPanel``. + """ + actions = [self.screenshot, + self.togglePowerSpectrumList, + self.togglePowerSpectrumControl] + + names = [a.__name__ for a in actions] + + return zip(names, actions) def draw(self, *a): diff --git a/fsl/fsleyes/views/timeseriespanel.py b/fsl/fsleyes/views/timeseriespanel.py index b61935e27a6d9092d2c90e77c5ca9df2c305820c..75bdaea00888a31fa548d3bbfaed62750a50cca5 100644 --- a/fsl/fsleyes/views/timeseriespanel.py +++ b/fsl/fsleyes/views/timeseriespanel.py @@ -171,7 +171,10 @@ class TimeSeriesPanel(plotpanel.OverlayPlotPanel): """Shows/hides a :class:`.PlotListPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel(plotlistpanel.PlotListPanel, self, location=wx.TOP) + self.togglePanel(plotlistpanel.PlotListPanel, + self, + location=wx.TOP, + action=self.toggleTimeSeriesList) @actions.toggleAction @@ -179,10 +182,23 @@ class TimeSeriesPanel(plotpanel.OverlayPlotPanel): """Shows/hides a :class:`.TimeSeriesControlPanel`. See :meth:`.ViewPanel.togglePanel`. """ - self.togglePanel( - timeseriescontrolpanel.TimeSeriesControlPanel, - self, - location=wx.TOP) + self.togglePanel(timeseriescontrolpanel.TimeSeriesControlPanel, + self, + location=wx.TOP, + action=self.toggleTimeSeriesControl) + + + def getActions(self): + """Overrides :meth:`.ActionProvider.getActions`. Returns all of the + :mod:`.actions` that are defined on this ``TimeSeriesPanel``. + """ + actions = [self.screenshot, + self.toggleTimeSeriesList, + self.toggleTimeSeriesControl] + + names = [a.__name__ for a in actions] + + return zip(names, actions) def draw(self, *a): diff --git a/fsl/fsleyes/views/viewpanel.py b/fsl/fsleyes/views/viewpanel.py index f4149355839d91df96b9c8ed38a24f4607bd1f61..cae61fed247702661a4e1b42aa4d2487f69b169c 100644 --- a/fsl/fsleyes/views/viewpanel.py +++ b/fsl/fsleyes/views/viewpanel.py @@ -17,6 +17,7 @@ import wx.lib.agw.aui as aui import props import fsl.fsleyes.panel as fslpanel +import fsl.fsleyes.actions as actions import fsl.fsleyes.toolbar as fsltoolbar import fsl.fsleyes.profiles as profiles import fsl.fsleyes.displaycontext as fsldisplay @@ -81,7 +82,16 @@ class ViewPanel(fslpanel.FSLEyesPanel): self.__profileManager = profiles.ProfileManager( self, overlayList, displayCtx) - self.__panels = {} + # The panels dictionary stores a collection + # of {type : instance} mappings of active + # FSLeyes control panels that are contained + # in this view panel. The panelActions dict + # contains a collection of {type : Action} + # mappings, but only if the control panel + # was opened as a result of an Action on + # this view panel. + self.__panels = {} + self.__panelActions = {} self.__auiMgr = aui.AuiManager( self, @@ -197,6 +207,14 @@ class ViewPanel(fslpanel.FSLEyesPanel): :arg location: If ``floatPane=False``, the initial dock position of the panel - either ``wx.TOP``, ``wx.BOTTOM``, ``wx.LEFT``, or ``wx.RIGHT. Defaults to ``wx.BOTTOM``. + + :arg action: If this method has been called as the result of + execution of a :class:`.ToggleAction`, the + ``ToggleAction`` instance may be passed to this + method. This is so that, if the control panel is + closed directly by the user (as opposed to + re-executing the ``ToggleAction`), the ``toggled`` + state of the action can be updated. :arg kwargs: All keyword arguments, apart from ``floatPane`` and ``location``, are passed to the ``panelType`` @@ -214,13 +232,14 @@ class ViewPanel(fslpanel.FSLEyesPanel): .. warning:: Do not define a control (a.k.a. secondary) panel constructor to accept arguments with the names - ``floatPane`` or ``location``, as arguments with - those names will get eaten by this method before - they can be passed to the constructor. + ``floatPane``, ``action`` or ``location``, as + arguments with those names will get eaten by this + method before they can be passed to the constructor. """ location = kwargs.pop('location', wx.BOTTOM) floatPane = kwargs.pop('floatPane', False) + action = kwargs.pop('action', None) if location not in (wx.TOP, wx.BOTTOM, wx.LEFT, wx.RIGHT): raise ValueError('Invalid value for location') @@ -230,83 +249,83 @@ class ViewPanel(fslpanel.FSLEyesPanel): # The panel is already open - close it if window is not None: self.__onPaneClose(None, window) + return - # Create a new panel of the specified type - else: - - paneInfo = aui.AuiPaneInfo() - window = panelType( - self, self._overlayList, self._displayCtx, *args, **kwargs) + # Otherwise, create a new panel of the specified type + paneInfo = aui.AuiPaneInfo() + window = panelType( + self, self._overlayList, self._displayCtx, *args, **kwargs) + + if isinstance(window, fsltoolbar.FSLEyesToolBar): + + # ToolbarPane sets the panel layer to 10 + paneInfo.ToolbarPane() + + # We are going to put any new toolbars on + # the top of the panel, below any existing + # toolbars. This is annoyingly complicated, + # because the AUI designer(s) decided to + # give the innermost layer an index of 0. + # + # So in order to put a new toolbar at the + # innermost layer, we need to adjust the + # layers of all other existing toolbars + + for p in self.__panels.values(): + if isinstance(p, fsltoolbar.FSLEyesToolBar): + info = self.__auiMgr.GetPane(p) + + # This is nasty - the agw.aui.AuiPaneInfo + # class doesn't have any publicly documented + # methods of querying its current state. + # So I'm accessing its undocumented instance + # attributes (determined by browsing the + # source code) + if info.IsDocked() and \ + info.dock_direction == aui.AUI_DOCK_TOP: + info.Layer(info.dock_layer + 1) + + # When the toolbar contents change, + # update the layout, so that the + # toolbar's new size is accommodated + window.Bind(fsltoolbar.EVT_TOOLBAR_EVENT, self.__auiMgrUpdate) + + paneInfo.Caption(strings.titles[window]) + + # Dock the pane at the position specified + # by the location parameter + if floatPane is False: if isinstance(window, fsltoolbar.FSLEyesToolBar): - - # ToolbarPane sets the panel layer to 10 - paneInfo.ToolbarPane() - - # We are going to put any new toolbars on - # the top of the panel, below any existing - # toolbars. This is annoyingly complicated, - # because the AUI designer(s) decided to - # give the innermost layer an index of 0. - # - # So in order to put a new toolbar at the - # innermost layer, we need to adjust the - # layers of all other existing toolbars - - for p in self.__panels.values(): - if isinstance(p, fsltoolbar.FSLEyesToolBar): - info = self.__auiMgr.GetPane(p) - - # This is nasty - the agw.aui.AuiPaneInfo - # class doesn't have any publicly documented - # methods of querying its current state. - # So I'm accessing its undocumented instance - # attributes (determined by browsing the - # source code) - if info.IsDocked() and \ - info.dock_direction == aui.AUI_DOCK_TOP: - info.Layer(info.dock_layer + 1) - - # When the toolbar contents change, - # update the layout, so that the - # toolbar's new size is accommodated - window.Bind(fsltoolbar.EVT_TOOLBAR_EVENT, self.__auiMgrUpdate) - - paneInfo.Caption(strings.titles[window]) - - # Dock the pane at the position specified - # by the location parameter - if floatPane is False: - - if isinstance(window, fsltoolbar.FSLEyesToolBar): - location = aui.AUI_DOCK_TOP - else: - if location == wx.TOP: location = aui.AUI_DOCK_TOP - elif location == wx.BOTTOM: location = aui.AUI_DOCK_BOTTOM - elif location == wx.LEFT: location = aui.AUI_DOCK_LEFT - elif location == wx.RIGHT: location = aui.AUI_DOCK_RIGHT - - paneInfo.Direction(location) - - # Or, for floating panes, centre the - # floating pane on this ViewPanel + location = aui.AUI_DOCK_TOP else: + if location == wx.TOP: location = aui.AUI_DOCK_TOP + elif location == wx.BOTTOM: location = aui.AUI_DOCK_BOTTOM + elif location == wx.LEFT: location = aui.AUI_DOCK_LEFT + elif location == wx.RIGHT: location = aui.AUI_DOCK_RIGHT - selfPos = self.GetScreenPosition().Get() - selfSize = self.GetSize().Get() - selfCentre = (selfPos[0] + selfSize[0] * 0.5, - selfPos[1] + selfSize[1] * 0.5) + paneInfo.Direction(location) - paneSize = window.GetBestSize().Get() - panePos = (selfCentre[0] - paneSize[0] * 0.5, - selfCentre[1] - paneSize[1] * 0.5) + # Or, for floating panes, centre the + # floating pane on this ViewPanel + else: - paneInfo.Float() \ - .FloatingPosition(panePos) - - self.__auiMgr.AddPane(window, paneInfo) - self.__panels[panelType] = window - self.__auiMgrUpdate() + selfPos = self.GetScreenPosition().Get() + selfSize = self.GetSize().Get() + selfCentre = (selfPos[0] + selfSize[0] * 0.5, + selfPos[1] + selfSize[1] * 0.5) + + paneSize = window.GetBestSize().Get() + panePos = (selfCentre[0] - paneSize[0] * 0.5, + selfCentre[1] - paneSize[1] * 0.5) + + paneInfo.Float() \ + .FloatingPosition(panePos) + + self.__auiMgr.AddPane(window, paneInfo) + self.__panels[ panelType] = window + self.__panelActions[panelType] = action + self.__auiMgrUpdate() def isPanelOpen(self, panelType): @@ -492,12 +511,20 @@ class ViewPanel(fslpanel.FSLEyesPanel): if isinstance(panel, (fslpanel .FSLEyesPanel, fsltoolbar.FSLEyesToolBar)): - self.__panels.pop(type(panel)) + + self .__panels .pop(type(panel)) + action = self.__panelActions.pop(type(panel), None) # calling fslpanel.FSLEyesPanel.destroy() # here - wx.Destroy is done below panel.destroy() + # If this panel was opened through + # a ToggleAction, make sure that + # its toggled state is correct + if action is not None and isinstance(action, actions.ToggleAction): + action.toggled = False + # Even when the user closes a pane, # AUI does not detach said pane - # we have to do it manually