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

Re-vamped overlay display panel so it now uses the WidgetList.

parent 14cac1be
No related branches found
No related tags found
No related merge requests found
...@@ -257,6 +257,15 @@ labels = TypeDict({ ...@@ -257,6 +257,15 @@ labels = TypeDict({
'ClusterPanel.addZStats' : 'Add Z statistics', 'ClusterPanel.addZStats' : 'Add Z statistics',
'ClusterPanel.addClusterMask' : 'Add cluster mask', 'ClusterPanel.addClusterMask' : 'Add cluster mask',
'OverlayDisplayPanel.Display' : 'General display settings',
'OverlayDisplayPanel.VolumeOpts' : 'Volume settings',
'OverlayDisplayPanel.MaskOpts' : 'Mask settings',
'OverlayDisplayPanel.LabelOpts' : 'Label settings',
'OverlayDisplayPanel.RGBVectorOpts' : 'RGB vector settings',
'OverlayDisplayPanel.LineVectorOpts' : 'Line vector settings',
'OverlayDisplayPanel.ModelOpts' : 'Model settings',
}) })
...@@ -377,11 +386,12 @@ properties = TypeDict({ ...@@ -377,11 +386,12 @@ properties = TypeDict({
'LineVectorOpts.directed' : 'Interpret vectors as directed', 'LineVectorOpts.directed' : 'Interpret vectors as directed',
'LineVectorOpts.lineWidth' : 'Line width', 'LineVectorOpts.lineWidth' : 'Line width',
'ModelOpts.colour' : 'Colour', 'ModelOpts.colour' : 'Colour',
'ModelOpts.outline' : 'Show outline only', 'ModelOpts.outline' : 'Show outline only',
'ModelOpts.refImage' : 'Reference image', 'ModelOpts.outlineWidth' : 'Outline width',
'ModelOpts.coordSpace' : 'Model coordinate space', 'ModelOpts.refImage' : 'Reference image',
'ModelOpts.showName' : 'Show model name', 'ModelOpts.coordSpace' : 'Model coordinate space',
'ModelOpts.showName' : 'Show model name',
'LabelOpts.lut' : 'Look-up table', 'LabelOpts.lut' : 'Look-up table',
'LabelOpts.outline' : 'Show outline only', 'LabelOpts.outline' : 'Show outline only',
......
...@@ -14,13 +14,92 @@ import logging ...@@ -14,13 +14,92 @@ import logging
import wx import wx
import props import props
import pwidgets.widgetlist as widgetlist
import fsl.utils.typedict as td
import fsl.data.strings as strings
import fsl.fslview.panel as fslpanel import fsl.fslview.panel as fslpanel
import fsl.fslview.displaycontext as fsldisplay import fsl.fslview.displaycontext as displayctx
import overlayselectpanel as overlayselect
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
_DISPLAY_PROPS = td.TypeDict({
'Display' : [
props.Widget('name'),
props.Widget('overlayType'),
props.Widget('enabled'),
props.Widget('alpha', showLimits=False),
props.Widget('brightness', showLimits=False),
props.Widget('contrast', showLimits=False)],
'VolumeOpts' : [
props.Widget('resolution', showLimits=False),
props.Widget('transform'),
props.Widget('volume', showLimits=False),
props.Widget('interpolation'),
props.Widget('cmap'),
props.Widget('invert'),
props.Widget('invertClipping'),
props.Widget('displayRange', showLimits=False, slider=True),
props.Widget('clippingRange', showLimits=False, slider=True)],
'MaskOpts' : [
props.Widget('resolution', showLimits=False),
props.Widget('transform'),
props.Widget('volume', showLimits=False),
props.Widget('colour'),
props.Widget('invert'),
props.Widget('threshold', showLimits=False)],
'RGBVectorOpts' : [
props.Widget('resolution', showLimits=False),
props.Widget('transform'),
props.Widget('interpolation'),
props.Widget('xColour'),
props.Widget('yColour'),
props.Widget('zColour'),
props.Widget('suppressX'),
props.Widget('suppressY'),
props.Widget('suppressZ'),
props.Widget('modulate'),
props.Widget('modThreshold', showLimits=False, spin=False)],
'LineVectorOpts' : [
props.Widget('resolution', showLimits=False),
props.Widget('transform'),
props.Widget('xColour'),
props.Widget('yColour'),
props.Widget('zColour'),
props.Widget('suppressX'),
props.Widget('suppressY'),
props.Widget('suppressZ'),
props.Widget('directed'),
props.Widget('lineWidth', showLimits=False),
props.Widget('modulate'),
props.Widget('modThreshold', showLimits=False, spin=False)],
'ModelOpts' : [
props.Widget('colour'),
props.Widget('outline'),
props.Widget('outlineWidth', showLimits=False),
props.Widget('refImage'),
# props.Widget('showName'),
props.Widget('coordSpace',
enabledWhen=lambda o: o.refImage != 'none')],
'LabelOpts' : [
props.Widget('lut'),
props.Widget('outline'),
props.Widget('outlineWidth', showLimits=False),
# props.Widget('showNames'),
props.Widget('resolution', showLimits=False),
props.Widget('transform'),
props.Widget('volume', showLimits=False)]
})
class OverlayDisplayPanel(fslpanel.FSLViewPanel): class OverlayDisplayPanel(fslpanel.FSLViewPanel):
...@@ -28,40 +107,17 @@ class OverlayDisplayPanel(fslpanel.FSLViewPanel): ...@@ -28,40 +107,17 @@ class OverlayDisplayPanel(fslpanel.FSLViewPanel):
""" """
""" """
# TODO Ability to link properties across images
fslpanel.FSLViewPanel.__init__(self, parent, overlayList, displayCtx) fslpanel.FSLViewPanel.__init__(self, parent, overlayList, displayCtx)
self.overlaySelect = overlayselect.OverlaySelectPanel( self.__overlayName = wx.StaticText(self, style=wx.ALIGN_CENTRE)
self, overlayList, displayCtx) self.__widgets = widgetlist.WidgetList(self)
self.__sizer = wx.BoxSizer(wx.VERTICAL)
self.propPanel = wx.ScrolledWindow(self) self.SetSizer(self.__sizer)
self.propPanel.SetScrollRate(0, 5)
self.dispPanel = wx.Panel(self.propPanel)
self.optsPanel = wx.Panel(self.propPanel)
self.divider = wx.StaticLine( self.__sizer.Add(self.__overlayName, flag=wx.EXPAND)
self.propPanel, size=(-1, -1), style=wx.LI_HORIZONTAL) self.__sizer.Add(self.__widgets, flag=wx.EXPAND, proportion=1)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.propSizer = wx.BoxSizer(wx.VERTICAL)
self.dispSizer = wx.BoxSizer(wx.VERTICAL)
self.optsSizer = wx.BoxSizer(wx.VERTICAL)
self .SetSizer(self.sizer)
self.propPanel.SetSizer(self.propSizer)
self.dispPanel.SetSizer(self.dispSizer)
self.optsPanel.SetSizer(self.optsSizer)
self.sizer.Add(self.overlaySelect, flag=wx.EXPAND)
self.sizer.Add(self.propPanel, flag=wx.EXPAND, proportion=1)
flags = wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL
self.propSizer.Add(self.dispPanel, border=20, flag=flags)
self.propSizer.Add(self.divider, flag=flags)
self.propSizer.Add(self.optsPanel, border=20, flag=flags)
displayCtx .addListener('selectedOverlay', displayCtx .addListener('selectedOverlay',
self._name, self._name,
self.__selectedOverlayChanged) self.__selectedOverlayChanged)
...@@ -69,71 +125,108 @@ class OverlayDisplayPanel(fslpanel.FSLViewPanel): ...@@ -69,71 +125,108 @@ class OverlayDisplayPanel(fslpanel.FSLViewPanel):
self._name, self._name,
self.__selectedOverlayChanged) self.__selectedOverlayChanged)
self.__lastOverlay = None self.__currentOverlay = None
self.__selectedOverlayChanged() self.__selectedOverlayChanged()
self.propSizer.Layout()
self.Layout() self.Layout()
self.SetMinSize((100, 50))
pSize = self.propSizer.GetMinSize().Get()
size = self.sizer .GetMinSize().Get()
self.SetMinSize((max(pSize[0], size[0]), max(pSize[1], size[1]) + 20))
def destroy(self): def destroy(self):
self._displayCtx .removeListener('selectedOverlay', self._name) self._displayCtx .removeListener('selectedOverlay', self._name)
self._overlayList.removeListener('overlays', self._name) self._overlayList.removeListener('overlays', self._name)
self.overlaySelect.destroy()
for ovl in self._overlayList: if self.__currentOverlay is not None and \
display = self._displayCtx.getDisplay(ovl) self.__currentOverlay in self._overlayList:
display = self._displayCtx.getDisplay(self.__currentOverlay)
opts = display.getDisplayOpts()
display.removeListener('overlayType', self._name) display.removeListener('overlayType', self._name)
display.removeListener('name', self._name)
if isinstance(opts, displayctx.VolumeOpts):
opts.removeListener('transform', self._name)
self.__currentOverlay = None
fslpanel.FSLViewPanel.destroy(self) fslpanel.FSLViewPanel.destroy(self)
def __selectedOverlayChanged(self, *a): def __selectedOverlayChanged(self, *a):
overlay = self._displayCtx.getSelectedOverlay() overlay = self._displayCtx.getSelectedOverlay()
lastOverlay = self.__lastOverlay lastOverlay = self.__currentOverlay
if overlay is None: if overlay is None:
self.__lastOverlay = None self.__currentOverlay = None
self.dispPanel.DestroyChildren() self.__overlayName.SetLabel('')
self.optsPanel.DestroyChildren() self.__widgets.Clear()
self.Layout() self.Layout()
return return
if overlay is lastOverlay: if overlay is lastOverlay:
return return
if lastOverlay is not None: self.__currentOverlay = overlay
if lastOverlay is not None and \
lastOverlay in self._overlayList:
lastDisplay = self._displayCtx.getDisplay(lastOverlay) lastDisplay = self._displayCtx.getDisplay(lastOverlay)
lastOpts = lastDisplay.getDisplayOpts() lastOpts = lastDisplay.getDisplayOpts()
lastDisplay.removeListener('overlayType', self._name) lastDisplay.removeListener('overlayType', self._name)
lastDisplay.removeListener('name', self._name)
if isinstance(lastOpts, fsldisplay.VolumeOpts): if isinstance(lastOpts, displayctx.VolumeOpts):
lastOpts.removeListener('transform', self._name) lastOpts.removeListener('transform', self._name)
if lastOverlay is not None:
displayExpanded = self.__widgets.IsExpanded('display')
optsExpanded = self.__widgets.IsExpanded('opts')
else:
displayExpanded = True
optsExpanded = True
display = self._displayCtx.getDisplay(overlay) display = self._displayCtx.getDisplay(overlay)
opts = display.getDisplayOpts() opts = display.getDisplayOpts()
display.addListener('overlayType', display.addListener('overlayType', self._name, self.__ovlTypeChanged)
self._name, display.addListener('name', self._name, self.__ovlNameChanged)
self.__overlayTypeChanged)
if isinstance(opts, fsldisplay.VolumeOpts): if isinstance(opts, displayctx.VolumeOpts):
opts.addListener('transform', self._name, self.__transformChanged) opts.addListener('transform', self._name, self.__transformChanged)
self.__lastOverlay = overlay self.__widgets.Clear()
self.__updateProps(self.dispPanel, False) self.__widgets.AddGroup('display', strings.labels[self, display])
self.__updateProps(self.optsPanel, True) self.__widgets.AddGroup('opts', strings.labels[self, opts])
def __overlayTypeChanged(self, *a): self.__overlayName.SetLabel(display.name)
self.__updateProps(self.optsPanel, True) self.__updateWidgets(display, 'display')
self.__updateWidgets(opts, 'opts')
self.__widgets.Expand('display', displayExpanded)
self.__widgets.Expand('opts', optsExpanded)
self.Layout()
def __ovlNameChanged(self, *a):
display = self._displayCtx.getDisplay(self.__currentOverlay)
self.__overlayName.SetLabel(display.name)
self.Layout()
def __ovlTypeChanged(self, *a):
opts = self._displayCtx.getOpts(self.__currentOverlay)
self.__updateWidgets(opts, 'opts')
self.Layout()
def __transformChanged(self, *a): def __transformChanged(self, *a):
"""Called when the transform setting of the currently selected overlay """Called when the transform setting of the currently selected overlay
changes. changes.
...@@ -147,7 +240,7 @@ class OverlayDisplayPanel(fslpanel.FSLViewPanel): ...@@ -147,7 +240,7 @@ class OverlayDisplayPanel(fslpanel.FSLViewPanel):
display = self._displayCtx.getDisplay(overlay) display = self._displayCtx.getDisplay(overlay)
opts = display.getDisplayOpts() opts = display.getDisplayOpts()
if not isinstance(opts, fsldisplay.VolumeOpts): if not isinstance(opts, displayctx.VolumeOpts):
return return
choices = opts.getProp('interpolation').getChoices(display) choices = opts.getProp('interpolation').getChoices(display)
...@@ -160,21 +253,24 @@ class OverlayDisplayPanel(fslpanel.FSLViewPanel): ...@@ -160,21 +253,24 @@ class OverlayDisplayPanel(fslpanel.FSLViewPanel):
else: opts.interpolation = 'linear' else: opts.interpolation = 'linear'
def __updateProps(self, parent, opts): def __updateWidgets(self, target, groupName):
import fsl.fslview.layouts as layouts self.__widgets.ClearGroup(groupName)
overlay = self._displayCtx.getSelectedOverlay() widgets = _DISPLAY_PROPS[target]
display = self._displayCtx.getDisplay(overlay) if isinstance(target, displayctx.RGBVectorOpts):
print 'bah'
if opts: optObj = display.getDisplayOpts() labels = [strings.properties[target, w.key] for w in widgets]
else: optObj = display widgets = [props.buildGUI(self.__widgets,
target,
parent.DestroyChildren() w,
showUnlink=False)
panel = props.buildGUI( for w in widgets]
parent, optObj, view=layouts.layouts[self, optObj])
for label, widget in zip(labels, widgets):
self.__widgets.AddWidget(
widget,
label,
groupName=groupName)
parent.GetSizer().Add(panel, flag=wx.EXPAND, proportion=1) self.Layout()
panel .Layout()
parent.Layout()
...@@ -74,6 +74,7 @@ class ListItemWidget(wx.Panel): ...@@ -74,6 +74,7 @@ class ListItemWidget(wx.Panel):
self.lockButton.Bind(wx.EVT_TOGGLEBUTTON, self.__onLockButton) self.lockButton.Bind(wx.EVT_TOGGLEBUTTON, self.__onLockButton)
self .Bind(wx.EVT_WINDOW_DESTROY, self.__onDestroy) self .Bind(wx.EVT_WINDOW_DESTROY, self.__onDestroy)
self.__overlayGroupChanged()
self.__vizChanged() self.__vizChanged()
self.__saveStateChanged() self.__saveStateChanged()
......
...@@ -253,7 +253,7 @@ class GLVector(globject.GLImageObject): ...@@ -253,7 +253,7 @@ class GLVector(globject.GLImageObject):
modImage = self.displayOpts.modulate modImage = self.displayOpts.modulate
if modImage == 'none': if modImage is None or modImage == 'none':
textureData = np.zeros((5, 5, 5), dtype=np.uint8) textureData = np.zeros((5, 5, 5), dtype=np.uint8)
textureData[:] = 255 textureData[:] = 255
modImage = fslimage.Image(textureData) modImage = fslimage.Image(textureData)
......
...@@ -181,90 +181,82 @@ LabelOptsToolBarLayout = [ ...@@ -181,90 +181,82 @@ LabelOptsToolBarLayout = [
actions.ActionButton(OverlayDisplayToolBar, 'more')] actions.ActionButton(OverlayDisplayToolBar, 'more')]
DisplayLayout = props.VGroup( DisplayLayout = [
(widget(Display, 'name'), widget(Display, 'name'),
widget(Display, 'overlayType'), widget(Display, 'overlayType'),
widget(Display, 'enabled'), widget(Display, 'enabled'),
widget(Display, 'alpha', showLimits=False, editLimits=False), widget(Display, 'alpha', showLimits=False, editLimits=False),
widget(Display, 'brightness', showLimits=False, editLimits=False), widget(Display, 'brightness', showLimits=False, editLimits=False),
widget(Display, 'contrast', showLimits=False, editLimits=False))) widget(Display, 'contrast', showLimits=False, editLimits=False)]
VolumeOptsLayout = props.VGroup( VolumeOptsLayout = [
(widget(VolumeOpts, 'resolution', showLimits=False), widget(VolumeOpts, 'resolution', showLimits=False),
widget(VolumeOpts, 'transform'), widget(VolumeOpts, 'transform'),
widget(VolumeOpts, 'volume', showLimits=False), widget(VolumeOpts, 'volume', showLimits=False),
widget(VolumeOpts, 'interpolation'), widget(VolumeOpts, 'interpolation'),
widget(VolumeOpts, 'cmap'), widget(VolumeOpts, 'cmap'),
widget(VolumeOpts, 'invert'), widget(VolumeOpts, 'invert'),
widget(VolumeOpts, 'invertClipping'), widget(VolumeOpts, 'invertClipping'),
widget(VolumeOpts, 'displayRange', showLimits=False, slider=True), widget(VolumeOpts, 'displayRange', showLimits=False, slider=True),
widget(VolumeOpts, 'clippingRange', showLimits=False, slider=True))) widget(VolumeOpts, 'clippingRange', showLimits=False, slider=True)]
MaskOptsLayout = props.VGroup( MaskOptsLayout = [
(widget(MaskOpts, 'resolution', showLimits=False), widget(MaskOpts, 'resolution', showLimits=False),
widget(MaskOpts, 'transform'), widget(MaskOpts, 'transform'),
widget(MaskOpts, 'volume', showLimits=False), widget(MaskOpts, 'volume', showLimits=False),
widget(MaskOpts, 'colour'), widget(MaskOpts, 'colour'),
widget(MaskOpts, 'invert'), widget(MaskOpts, 'invert'),
widget(MaskOpts, 'threshold', showLimits=False))) widget(MaskOpts, 'threshold', showLimits=False)]
RGBVectorOptsLayout = props.VGroup(( RGBVectorOptsLayout = [
widget(RGBVectorOpts, 'resolution', showLimits=False), widget(RGBVectorOpts, 'resolution', showLimits=False),
widget(RGBVectorOpts, 'transform'), widget(RGBVectorOpts, 'transform'),
widget(RGBVectorOpts, 'interpolation'), widget(RGBVectorOpts, 'interpolation'),
props.HGroup(( widget(RGBVectorOpts, 'xColour'),
widget(RGBVectorOpts, 'xColour'), widget(RGBVectorOpts, 'yColour'),
widget(RGBVectorOpts, 'yColour'), widget(RGBVectorOpts, 'zColour'),
widget(RGBVectorOpts, 'zColour')), widget(RGBVectorOpts, 'suppressX'),
vertLabels=True), widget(RGBVectorOpts, 'suppressY'),
props.HGroup(( widget(RGBVectorOpts, 'suppressZ'),
widget(RGBVectorOpts, 'suppressX'),
widget(RGBVectorOpts, 'suppressY'),
widget(RGBVectorOpts, 'suppressZ')),
vertLabels=True),
widget(RGBVectorOpts, 'modulate'), widget(RGBVectorOpts, 'modulate'),
widget(RGBVectorOpts, 'modThreshold', showLimits=False, spin=False))) widget(RGBVectorOpts, 'modThreshold', showLimits=False, spin=False)]
LineVectorOptsLayout = props.VGroup(( LineVectorOptsLayout = [
widget(LineVectorOpts, 'resolution', showLimits=False), widget(LineVectorOpts, 'resolution', showLimits=False),
widget(LineVectorOpts, 'transform'), widget(LineVectorOpts, 'transform'),
props.HGroup(( widget(LineVectorOpts, 'xColour'),
widget(LineVectorOpts, 'xColour'), widget(LineVectorOpts, 'yColour'),
widget(LineVectorOpts, 'yColour'), widget(LineVectorOpts, 'zColour'),
widget(LineVectorOpts, 'zColour')), widget(LineVectorOpts, 'suppressX'),
vertLabels=True), widget(LineVectorOpts, 'suppressY'),
props.HGroup(( widget(LineVectorOpts, 'suppressZ'),
widget(LineVectorOpts, 'suppressX'),
widget(LineVectorOpts, 'suppressY'),
widget(LineVectorOpts, 'suppressZ')),
vertLabels=True),
widget(LineVectorOpts, 'directed'), widget(LineVectorOpts, 'directed'),
widget(LineVectorOpts, 'lineWidth', showLimits=False), widget(LineVectorOpts, 'lineWidth', showLimits=False),
widget(LineVectorOpts, 'modulate'), widget(LineVectorOpts, 'modulate'),
widget(LineVectorOpts, 'modThreshold', showLimits=False, spin=False))) widget(LineVectorOpts, 'modThreshold', showLimits=False, spin=False)]
ModelOptsLayout = props.VGroup(( ModelOptsLayout = [
widget(ModelOpts, 'colour'), widget(ModelOpts, 'colour'),
widget(ModelOpts, 'outline'), widget(ModelOpts, 'outline'),
widget(ModelOpts, 'outlineWidth', showLimits=False), widget(ModelOpts, 'outlineWidth', showLimits=False),
widget(ModelOpts, 'refImage'), widget(ModelOpts, 'refImage'),
# widget(ModelOpts, 'showName'), # widget(ModelOpts, 'showName'),
widget(ModelOpts, 'coordSpace', widget(ModelOpts, 'coordSpace',
visibleWhen=lambda o: o.refImage != 'none'))) visibleWhen=lambda o: o.refImage != 'none')]
LabelOptsLayout = props.VGroup(( LabelOptsLayout = [
widget(LabelOpts, 'lut'), widget(LabelOpts, 'lut'),
widget(LabelOpts, 'outline'), widget(LabelOpts, 'outline'),
widget(LabelOpts, 'outlineWidth', showLimits=False), widget(LabelOpts, 'outlineWidth', showLimits=False),
# widget(LabelOpts, 'showNames'), # widget(LabelOpts, 'showNames'),
widget(LabelOpts, 'resolution', showLimits=False), widget(LabelOpts, 'resolution', showLimits=False),
widget(LabelOpts, 'transform'), widget(LabelOpts, 'transform'),
widget(LabelOpts, 'volume', showLimits=False))) widget(LabelOpts, 'volume', showLimits=False)]
......
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