diff --git a/fsl/fslview/controls/overlaydisplaytoolbar.py b/fsl/fslview/controls/overlaydisplaytoolbar.py
index 7d0334f5534c17b6f1fb8a00d67bb6f557c6e425..f7ea52f7ab39ee5039146067c858b0afcfff5dc6 100644
--- a/fsl/fslview/controls/overlaydisplaytoolbar.py
+++ b/fsl/fslview/controls/overlaydisplaytoolbar.py
@@ -10,13 +10,50 @@ selected overlay.
 """
 
 import logging
-log = logging.getLogger(__name__)
 
+import wx
+
+import props
 
 import fsl.fslview.toolbar as fsltoolbar
+import fsl.fslview.actions as actions
+import fsl.utils.typedict  as td
 import overlaydisplaypanel as overlaydisplay
 
 
+log = logging.getLogger(__name__)
+
+
+_TOOLBAR_PROPS = td.TypeDict({
+    'Display' : [
+        props.Widget('name'),
+        props.Widget('overlayType'),
+        props.Widget('alpha',      spin=False, showLimits=False),
+        props.Widget('brightness', spin=False, showLimits=False),
+        props.Widget('contrast',   spin=False, showLimits=False)],
+
+    'VolumeOpts' : [
+        props.Widget('cmap')],
+
+    'MaskOpts' : [
+        props.Widget('colour')],
+
+    'VectorOpts' : [
+        props.Widget('modulate'),
+        props.Widget('modThreshold', showLimits=False, spin=False)],
+
+    'LabelOpts' : [
+        props.Widget('lut'),
+        props.Widget('outline'),
+        props.Widget('outlineWidth', showLimits=False, spin=False)],
+
+    'ModelOpts' : [
+        props.Widget('colour'),
+        props.Widget('outline'),
+        props.Widget('outlineWidth', showLimits=False, spin=False)]
+})
+
+
 class OverlayDisplayToolBar(fsltoolbar.FSLViewToolBar):
     
     def __init__(self, parent, overlayList, displayCtx, viewPanel):
@@ -26,20 +63,19 @@ class OverlayDisplayToolBar(fsltoolbar.FSLViewToolBar):
         fsltoolbar.FSLViewToolBar.__init__(
             self, parent, overlayList, displayCtx, actionz)
 
-        self._viewPanel      = viewPanel
-        self._overlayTools   = {}
-        self._currentOverlay = None
+        self.__viewPanel      = viewPanel
+        self.__currentOverlay = None
 
         self._displayCtx.addListener(
             'selectedOverlay',
             self._name,
-            self._selectedOverlayChanged)
+            self.__selectedOverlayChanged)
         self._overlayList.addListener(
             'overlays',
             self._name,
-            self._overlayListChanged) 
+            self.__selectedOverlayChanged) 
 
-        self._selectedOverlayChanged()
+        self.__selectedOverlayChanged()
 
 
     def destroy(self):
@@ -48,165 +84,109 @@ class OverlayDisplayToolBar(fsltoolbar.FSLViewToolBar):
         self._overlayList.removeListener('overlays',        self._name)
         self._displayCtx .removeListener('selectedOverlay', self._name)
 
-        for ovl in self._overlayList:
-            
-            display = self._displayCtx.getDisplay(ovl)
+        if self.__currentOverlay is not None and \
+           self.__currentOverlay in self._overlayList:
+
+            display = self._displayCtx.getDisplay(self.__currentOverlay)
             display.removeListener('overlayType', self._name)
             display.removeListener('enabled',     self._name)
+
+        self.__currentOverlay = None
+        self.__viewPanel      = None
+            
         fsltoolbar.FSLViewToolBar.destroy(self)
 
 
     def showMoreSettings(self, *a):
-        self._viewPanel.togglePanel(overlaydisplay.OverlayDisplayPanel, True)
-
+        self.__viewPanel.togglePanel(overlaydisplay.OverlayDisplayPanel, True)
 
-    def _overlayListChanged(self, *a):
-
-        for ovl in self._overlayTools.keys():
-            if ovl not in self._overlayList:
-
-                dispTools, optsTools = self._overlayTools.pop(ovl)
-
-                log.debug('Destroying all tools for {}'.format(ovl))
-
-                if ovl is self._currentOverlay:
-                    self.ClearTools()
-
-                for tool, _ in dispTools: tool.Destroy()
-                for tool, _ in optsTools: tool.Destroy()
-
-        self._selectedOverlayChanged()
-    
-
-    def _overlayTypeChanged(self, value, valid, display, name, refresh=True):
-
-        overlay = display.getOverlay()
-
-        dispTools, oldOptsTools = self._overlayTools[overlay]
-
-        newOptsTools = self._makeOptsWidgets(overlay, self)
-
-        self._overlayTools[overlay] = (dispTools, newOptsTools)
-
-        if refresh and (overlay is self._displayCtx.getSelectedOverlay()):
-            self._refreshTools(overlay)
-
-        log.debug('Destroying opts tools for {}'.format(overlay))
-
-        for tool, _ in oldOptsTools:
-            tool.Destroy()
-
-            
-    def _toggleEnabled(self, value, valid, ovl, name):
         
-        if ovl is not self._displayCtx.getSelectedOverlay():
-            return
-        
-        display = self._displayCtx.getDisplay(ovl)
-
+    def __overlayEnableChanged(self, *a):
+        display = self._displayCtx.getDisplay(self.__currentOverlay)
         self.Enable(display.enabled)
-            
 
-    def _selectedOverlayChanged(self, *a):
+
+    def __selectedOverlayChanged(self, *a):
         """Called when the :attr:`.DisplayContext.selectedOverlay`
         index changes. Ensures that the correct display panel is visible.
         """
 
+        if self.__currentOverlay is not None and \
+           self.__currentOverlay in self._overlayList:
+            display = self._displayCtx.getDisplay(self.__currentOverlay)
+            display.removeListener('overlayType', self._name)
+            display.removeListener('enabled',     self._name)
+
         overlay = self._displayCtx.getSelectedOverlay()
 
+        self.__currentOverlay = overlay
+
         if overlay is None:
-            self.ClearTools()
+            self.ClearTools(destroy=True)
             return
 
         display = self._displayCtx.getDisplay(overlay)
 
-        # Call _toggleEnabled when
-        # the overlay is enabled/disabled
+        display.addListener('enabled',
+                            self._name,
+                            self.__overlayEnableChanged)
+        display.addListener('overlayType',
+                            self._name,
+                            self.__selectedOverlayChanged)
+
+        self.__showTools(overlay)
         self.Enable(display.enabled)
-        for ovl in self._overlayList:
-            
-            d = self._displayCtx.getDisplay(ovl)
-            
-            if ovl == overlay:
-                d.addListener('enabled',
-                              self._name,
-                              self._toggleEnabled,
-                              overwrite=True)
-            else:
-                d.removeListener('enabled', self._name)
-
-        # Build/refresh the toolbar widgets for this overlay
-        tools = self._overlayTools.get(overlay, None)
- 
-        if tools is None:
-            displayTools = self._makeDisplayWidgets(overlay, self)
-            optsTools    = self._makeOptsWidgets(   overlay, self)
-            
-            self._overlayTools[overlay] = (displayTools, optsTools)
 
-            display.addListener(
-                'overlayType',
-                self._name,
-                self._overlayTypeChanged,
-                overwrite=True)
 
-        self._refreshTools(overlay)
+    def __showTools(self, overlay):
 
+        oldTools = self.GetTools()
 
-    def _refreshTools(self, overlay):
+        # See long comment at bottom
+        def destroyOldTools():
+            for t in oldTools:
+                t.Destroy()
 
-        self._currentOverlay = overlay
+        for t in oldTools:
+            t.Show(False)
 
-        log.debug('Showing tools for {}'.format(overlay))
+        self.ClearTools(destroy=False, postevent=False)
 
-        tools = self.GetTools()
-        for widget in tools:
-            widget.Show(False)
-                
-        self.ClearTools(postevent=False)
+        log.debug('Showing tools for {}'.format(overlay))
 
-        if overlay is None:
-            self.Layout()
+        display   = self._displayCtx.getDisplay(overlay)
+        opts      = display.getDisplayOpts()
+        
+        dispSpecs = _TOOLBAR_PROPS[display]
+        optsSpecs = _TOOLBAR_PROPS[opts]
 
-        dispTools, optsTools = self._overlayTools[overlay]
+        dispTools, dispLabels = zip(*self.GenerateTools(
+            dispSpecs, display, add=False))
+        optsTools, optsLabels = zip(*self.GenerateTools(
+            optsSpecs, opts,    add=False))
 
-        dispTools, dispLabels = zip(*dispTools)
-        optsTools, optsLabels = zip(*optsTools)
-        
         tools  = list(dispTools)  + list(optsTools)
         labels = list(dispLabels) + list(optsLabels)
 
-        for tool in tools:
-            tool.Show(True) 
-
-        self.SetTools(tools, labels)
-
-        
-    def _makeDisplayWidgets(self, overlay, parent):
-        """Creates and returns panel containing widgets allowing
-        the user to edit the display properties of the given
-        overlay object. 
-        """
-
-        import fsl.fslview.layouts as layouts
+        # Button which opens the OverlayDisplayPanel
+        more = props.buildGUI(
+            self,
+            self,
+            view=actions.ActionButton(type(self), 'more'))
 
-        display   = self._displayCtx.getDisplay(overlay)
-        toolSpecs = layouts.layouts[self, display]
-
-        log.debug('Creating display tools for {}'.format(overlay))
-        
-        return self.GenerateTools(toolSpecs, display, add=False)
-
-    
-    def _makeOptsWidgets(self, overlay, parent):
-
-        import fsl.fslview.layouts as layouts
+        tools .append(more)
+        labels.append(None)
 
-        opts      = self._displayCtx.getOpts(overlay)
-        toolSpecs = layouts.layouts[self, opts]
-        targets   = { s.key : self if s.key == 'more' else opts
-                      for s in toolSpecs}
+        self.SetTools(tools, labels)
         
-        log.debug('Creating options tools for {}'.format(overlay))
-
-        return self.GenerateTools(toolSpecs, targets, add=False) 
+        # This method may have been called via an
+        # event handler an existing tool in the
+        # toolbar - in this situation, destroying
+        # that tool will result in nasty crashes,
+        # as the wx widget that generated the event
+        # will be destroyed while said event is
+        # being processed. So we destroy the old
+        # tools asynchronously, well after the event
+        # which triggered this method call will have
+        # returned.
+        wx.CallLater(1000, destroyOldTools)
diff --git a/fsl/fslview/layouts.py b/fsl/fslview/layouts.py
index 0365fac0c5709b936f9f85d25204c044a39cbd5c..e5ad39750a25ac7ddd8f7955addb47be07093cfa 100644
--- a/fsl/fslview/layouts.py
+++ b/fsl/fslview/layouts.py
@@ -22,14 +22,6 @@ from fsl.fslview.views                     import LightBoxPanel
 
 from fsl.fslview.controls                  import OrthoToolBar
 from fsl.fslview.controls                  import LightBoxToolBar
-from fsl.fslview.controls                  import OverlayDisplayToolBar
-
-from fsl.fslview.displaycontext            import Display
-from fsl.fslview.displaycontext            import VolumeOpts
-from fsl.fslview.displaycontext            import MaskOpts
-from fsl.fslview.displaycontext            import VectorOpts
-from fsl.fslview.displaycontext            import ModelOpts
-from fsl.fslview.displaycontext            import LabelOpts
 
 from fsl.fslview.displaycontext            import OrthoOpts
 from fsl.fslview.displaycontext            import LightBoxOpts
@@ -102,57 +94,8 @@ LightBoxToolBarLayout = [
     actions.ActionButton(LightBoxToolBar, 'more')]
 
 
-
-##########################################
-# Overlay display property panels/toolbars
-##########################################
-
-
-DisplayToolBarLayout = [
-    widget(Display, 'name'),
-    widget(Display, 'overlayType'),
-    widget(Display, 'alpha',      spin=False, showLimits=False),
-    widget(Display, 'brightness', spin=False, showLimits=False),
-    widget(Display, 'contrast',   spin=False, showLimits=False)]
-
-
-VolumeOptsToolBarLayout = [
-    widget(VolumeOpts, 'cmap'),
-    actions.ActionButton(OverlayDisplayToolBar, 'more')]
-
-
-MaskOptsToolBarLayout = [
-    widget(MaskOpts, 'colour'),
-    actions.ActionButton(OverlayDisplayToolBar, 'more')]
-
-
-VectorOptsToolBarLayout = [
-    widget(VectorOpts, 'modulate'),
-    widget(VectorOpts, 'modThreshold', showLimits=False, spin=False),
-    actions.ActionButton(OverlayDisplayToolBar, 'more')]
-
-ModelOptsToolBarLayout = [
-    widget(ModelOpts, 'colour'),
-    widget(ModelOpts, 'outline'),
-    widget(ModelOpts, 'outlineWidth', showLimits=False, spin=False),
-    actions.ActionButton(OverlayDisplayToolBar, 'more')]
-
-LabelOptsToolBarLayout = [
-    widget(LabelOpts, 'lut'),
-    widget(LabelOpts, 'outline'),
-    widget(LabelOpts, 'outlineWidth', showLimits=False, spin=False),
-    actions.ActionButton(OverlayDisplayToolBar, 'more')]
-
-
 layouts = td.TypeDict({
 
-    ('OverlayDisplayToolBar', 'Display')        : DisplayToolBarLayout,
-    ('OverlayDisplayToolBar', 'VolumeOpts')     : VolumeOptsToolBarLayout,
-    ('OverlayDisplayToolBar', 'MaskOpts')       : MaskOptsToolBarLayout,
-    ('OverlayDisplayToolBar', 'VectorOpts')     : VectorOptsToolBarLayout,
-    ('OverlayDisplayToolBar', 'ModelOpts')      : ModelOptsToolBarLayout,
-    ('OverlayDisplayToolBar', 'LabelOpts')      : LabelOptsToolBarLayout,
-
     'OrthoToolBar'    : OrthoToolBarLayout,
     'LightBoxToolBar' : LightBoxToolBarLayout,
 
diff --git a/fsl/fslview/toolbar.py b/fsl/fslview/toolbar.py
index e6459c2b69579221ec28164e539cb0a242a345c3..512ec43ec729b6f47e6799d8e275bc32b72e0f8f 100644
--- a/fsl/fslview/toolbar.py
+++ b/fsl/fslview/toolbar.py
@@ -70,6 +70,13 @@ class FSLViewToolBar(fslpanel._FSLViewPanel, wx.PyPanel):
                 type(self.label).__name__,
                 self.labelText)
 
+        def Enable(self, *args, **kwargs):
+            wx.Panel.Enable(self, *args, **kwargs)
+            self.tool.Enable(*args, **kwargs)
+            
+            if self.label is not None:
+                self.label.Enable(*args, **kwargs)
+
             
     def __init__(self, parent, overlayList, displayCtx, actionz=None):
         wx.PyPanel.__init__(self, parent)
@@ -187,6 +194,12 @@ class FSLViewToolBar(fslpanel._FSLViewPanel, wx.PyPanel):
         self.Layout()
 
 
+    def Enable(self, *args, **kwargs):
+        wx.PyPanel.Enable(self, *args, **kwargs)
+        for t in self.__tools:
+            t.Enable(*args, **kwargs)
+
+
     def GenerateTools(self, toolSpecs, targets, add=True):
         """
         Targets may be a single object, or a dict of [toolSpec : target]