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

Documentation for OrthoEditToolBar and OverlayDisplayToolBar.

parent d61b6f37
No related branches found
No related tags found
No related merge requests found
doc/images/orthoedittoolbar.png

41.7 KiB

doc/images/overlaydisplaytoolbar.png

37 KiB

......@@ -30,6 +30,7 @@ The following control panels currently exist:
~fsl.fsleyes.controls.orthoedittoolbar.OrthoEditToolBar
~fsl.fsleyes.controls.orthotoolbar.OrthoToolBar
~fsl.fsleyes.controls.overlaydisplaypanel.OverlayDisplayPanel
~fsl.fsleyes.controls.overlaydisplaytoolbar.OverlayDisplayToolBar
~fsl.fsleyes.controls.overlayinfopanel.OverlayInfoPanel
~fsl.fsleyes.controls.overlaylistpanel.OverlayListPanel
~fsl.fsleyes.controls.shellpanel.ShellPanel
......
#!/usr/bin/env python
#
# orthoedittoolbar.py -
# orthoedittoolbar.py - The OrthoEditToolBar
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module provides the :class:`OrthoEditToolBar`, a
:class:`.FSLEyesToolBar` which displays controls for editing :class:`.Image`
instances in an :class:`.OrthoPanel`.
"""
import logging
......@@ -20,7 +25,144 @@ from fsl.fsleyes.profiles.orthoeditprofile import OrthoEditProfile
log = logging.getLogger(__name__)
# Some of the toolbar widgets are labelled
class OrthoEditToolBar(fsltoolbar.FSLEyesToolBar):
"""The ``OrthoEditToolBar`` is a :class:`.FSLEyesToolBar` which displays
controls for editing :class:`.Image` instances in an :class:`.OrthoPanel`.
An ``OrthoEditToolBar`` looks something like this:
.. image:: images/orthoedittoolbar.png
:scale: 50%
:align: center
The ``OrthoEditToolBar`` exposes properties and actions which are defined
on the :class:`.OrthoEditProfile` class, and allows the user to:
- Change the :class:`.OrthoPanel` profile between ``view`` and ``edit``
mode (see the :attr:`.ViewPanel.profile` property). When in ``view``
mode, all of the other controls are hidden.
- Undo/redo changes to the selection and to :class:`.Image` instances.
- Clear and fill the current selection.
- Switch between a 2D and 3D selection cursor.
- Change the selection cursor size.
- Create a new mask/ROI :class:`.Image` from the current selection.
- Switch between regular *select* mode, and *select by intensity* mode,
and adjust the select by intensity mode settings.
All of the controls shown on an ``OrthoEditToolBar`` instance are defined
in the :attr:`_TOOLBAR_SPECS` dictionary.
"""
selint = props.Boolean(default=False)
"""This property allows the user to change the :class:`.OrthoEditProfile`
between ``sel`` mode, and ``selint`` mode.
"""
def __init__(self, parent, overlayList, displayCtx, ortho):
"""Create an ``OrthoEditToolBar``.
:arg parent: The :mod:`wx` parent object.
:arg overlayList: The :class:`.OverlayList` instance.
:arg displayCtx: The :class:`.DisplayContext` instance.
:arg ortho: The :class:`.OrthoPanel` instance.
"""
fsltoolbar.FSLEyesToolBar.__init__(self,
parent,
overlayList,
displayCtx,
24)
self.__orthoPanel = ortho
self .addListener('selint', self._name, self.__selintChanged)
ortho.addListener('profile', self._name, self.__profileChanged)
self.__profileTool = props.buildGUI(
self,
ortho,
_TOOLBAR_SPECS['profile'])
self.AddTool(self.__profileTool)
self.__profileChanged()
def destroy(self):
"""Must be called when this ``OrthoEditToolBar`` is no longer
needed. Removes property listeners, and calls the
:meth:`.FSLEyesToolBar.destroy` method.
"""
self.__orthoPanel.removeListener('profile', self._name)
fsltoolbar.FSLEyesToolBar.destroy(self)
def __selintChanged(self, *a):
"""Called when the :attr:`selint` property changes. If the
:class:`OrthoPanel` is currently in ``edit`` mode, toggles the
associated :class:`.OrthoEditProfile` instance between ``sel``
and ``selint`` modes.
"""
ortho = self.__orthoPanel
if ortho.profile != 'edit':
return
profile = ortho.getCurrentProfile()
if self.selint: profile.mode = 'selint'
else: profile.mode = 'sel'
def __profileChanged(self, *a):
"""Called when the :attr:`.ViewPanel.profile` property of the
:class:`.OrthoPanel` changes. Shows/hides edit controls accordingly.
"""
# We don't want to remove the profile tool
# created in __init__, so we skip the first
# tool
self.ClearTools(startIdx=1, destroy=True, postevent=False)
ortho = self.__orthoPanel
profile = ortho.profile
profileObj = ortho.getCurrentProfile()
if profile == 'edit':
self.disableNotification('selint')
self.selint = profileObj.mode == 'selint'
self.enableNotification('selint')
specs = _TOOLBAR_SPECS[profile]
tools = []
for spec in specs:
if spec.key == 'selint': target = self
else: target = profileObj
widget = props.buildGUI(self, target, spec)
if spec.label is not None:
widget = self.MakeLabelledTool(widget, spec.label)
tools.append(widget)
self.InsertTools(tools, 1)
_LABELS = {
'selectionCursorColour' : strings.properties[OrthoEditProfile,
......@@ -36,22 +178,30 @@ _LABELS = {
'fillValue' : strings.properties[OrthoEditProfile,
'fillValue'],
}
"""This dictionary contains labels for some :class:`OrthoEditToolBar`
controls. It is referenced in the :attr:`_TOOLBAR_SPECS` dictionary.
"""
_ICONS = {
'view' : fslicons.findImageFile('eye24'),
'edit' : fslicons.findImageFile('pencil24'),
'view' : fslicons.findImageFile('eye24'),
'edit' : fslicons.findImageFile('pencil24'),
'selectionIs3D' : [fslicons.findImageFile('selection3D24'),
fslicons.findImageFile('selection2D24')],
'clearSelection' : fslicons.findImageFile('clear24'),
'undo' : fslicons.findImageFile('undo24'),
'redo' : fslicons.findImageFile('redo24'),
'fillSelection' : fslicons.findImageFile('fill24'),
'createMaskFromSelection' : fslicons.findImageFile('createMask24'),
'createROIFromSelection' : fslicons.findImageFile('createROI24'),
'limitToRadius' : fslicons.findImageFile('radius24'),
'localFill' : fslicons.findImageFile('localsearch24'),
'selint' : fslicons.findImageFile('selectByIntensity24'),
'clearSelection' : fslicons.findImageFile('clear24'),
'undo' : fslicons.findImageFile('undo24'),
'redo' : fslicons.findImageFile('redo24'),
'fillSelection' : fslicons.findImageFile('fill24'),
'createMaskFromSelection' : fslicons.findImageFile('createMask24'),
'createROIFromSelection' : fslicons.findImageFile('createROI24'),
'limitToRadius' : fslicons.findImageFile('radius24'),
'localFill' : fslicons.findImageFile('localsearch24'),
'selint' : fslicons.findImageFile('selectByIntensity24'),
}
"""This dictionary contains icons for some :class:`OrthoEditToolBar`
controls. It is referenced in the :attr:`_TOOLBAR_SPECS` dictionary.
"""
_TOOLTIPS = {
'profile' : fsltooltips.properties['OrthoPanel.profile'],
......@@ -90,6 +240,10 @@ _TOOLTIPS = {
'intensityThres' : fsltooltips.properties['OrthoEditProfile.'
'intensityThres'],
}
"""This dictionary contains tooltips for some :class:`OrthoEditToolBar`
controls. It is referenced in the :attr:`_TOOLBAR_SPECS` dictionary.
"""
_TOOLBAR_SPECS = {
......@@ -177,84 +331,16 @@ _TOOLBAR_SPECS = {
enabledWhen=lambda p: p.mode == 'selint' and p.limitToRadius)
]
}
class OrthoEditToolBar(fsltoolbar.FSLEyesToolBar):
selint = props.Boolean(default=False)
def __init__(self, parent, overlayList, displayCtx, ortho):
fsltoolbar.FSLEyesToolBar.__init__(self,
parent,
overlayList,
displayCtx,
24)
self.orthoPanel = ortho
self .addListener('selint', self._name, self.__selintChanged)
ortho.addListener('profile', self._name, self.__profileChanged)
self.__profileTool = props.buildGUI(
self,
ortho,
_TOOLBAR_SPECS['profile'])
self.AddTool(self.__profileTool)
self.__profileChanged()
def destroy(self):
self.orthoPanel.removeListener('profile', self._name)
fsltoolbar.FSLEyesToolBar.destroy(self)
def __selintChanged(self, *a):
ortho = self.orthoPanel
if ortho.profile != 'edit':
return
profile = ortho.getCurrentProfile()
if self.selint: profile.mode = 'selint'
else: profile.mode = 'sel'
def __profileChanged(self, *a):
# We don't want to remove the profile tool
# created in __init__, so we skip the first
# tool
self.ClearTools(startIdx=1, destroy=True, postevent=False)
ortho = self.orthoPanel
profile = ortho.profile
profileObj = ortho.getCurrentProfile()
if profile == 'edit':
self.disableNotification('selint')
self.selint = profileObj.mode == 'selint'
self.enableNotification('selint')
specs = _TOOLBAR_SPECS[profile]
tools = []
for spec in specs:
if spec.key == 'selint': target = self
else: target = profileObj
widget = props.buildGUI(self, target, spec)
if spec.label is not None:
widget = self.MakeLabelledTool(widget, spec.label)
tools.append(widget)
self.InsertTools(tools, 1)
"""This dictionary contains specifications for all of the tools shown in an
:class:`OrthoEditToolBar`. The following keys are defined:
=========== ===========================================================
``profile`` Contains a single specification defining the control for
switching the :class:`.OrthoPanel` between ``view`` and
``edit`` profiles.
``view`` A list of specifications defining controls to be shown when
the ``view`` profile is active.
``edit`` A list of specifications defining controls to be shown when
the ``view`` profile is active.
=========== ===========================================================
"""
#!/usr/bin/env python
#
# overlaydisplaytoolbar.py - A toolbar which shows display control options for
# the currently selected overlay.
# overlaydisplaytoolbar.py - The OverlayDisplayToolBar.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
"""A :class:`wx.Panel` which shows display control options for the currently
selected overlay.
"""This module provides the :class:`OverlyDisplyaToolBar`, a
:class:`.FSLEyesToolBar` containing controls for changing the display settings
of the currently selected overlay.
"""
import logging
import wx
......@@ -27,178 +28,56 @@ import overlaydisplaypanel as overlaydisplay
log = logging.getLogger(__name__)
def _modImageLabel(img):
if img is None: return strings.choices['VectorOpts.modulate.none']
else: return img.name
class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
"""The ``OverlyDisplyaToolBar`` is a :class:`.FSLEyesToolBar` containing
controls which allow the user to change the display settings of the
currently selected overlay (as defined by the
:attr:`.DisplayContext.selectedOverlay` property). The display settings
for an overlay are contained in the :class:`.Display` and
:class:`.DisplayOpts` instances that are associated with that overlay.
_TOOLTIPS = td.TypeDict({
'Display.name' : fsltooltips.properties['Display.name'],
'Display.overlayType' : fsltooltips.properties['Display.overlayType'],
'Display.alpha' : fsltooltips.properties['Display.alpha'],
'Display.brightness' : fsltooltips.properties['Display.brightness'],
'Display.contrast' : fsltooltips.properties['Display.contrast'],
'VolumeOpts.displayRange' : fsltooltips.properties['VolumeOpts.'
'displayRange'],
'VolumeOpts.resetDisplayRange' : fsltooltips.actions[ 'VolumeOpts.reset'
'DisplayRange'],
'VolumeOpts.cmap' : fsltooltips.properties['VolumeOpts.cmap'],
'MaskOpts.threshold' : fsltooltips.properties['MaskOpts.threshold'],
'MaskOpts.colour' : fsltooltips.properties['MaskOpts.colour'],
An ``OverlyDisplyaToolBar`` looks something like the following:
'LabelOpts.lut' : fsltooltips.properties['LabelOpts.lut'],
'LabelOpts.outline' : fsltooltips.properties['LabelOpts.outline'],
'LabelOpts.outlineWidth' : fsltooltips.properties['LabelOpts.'
'outlineWidth'],
.. image:: images/overlaydisplaytoolbar.png
:scale: 50%
:align: center
'RGBVectorOpts.modulate' : fsltooltips.properties['VectorOpts.'
'modulate'],
'RGBVectorOpts.modThreshold' : fsltooltips.properties['VectorOpts.'
'modThreshold'],
'LineVectorOpts.modulate' : fsltooltips.properties['VectorOpts.'
'modulate'],
'LineVectorOpts.modThreshold' : fsltooltips.properties['VectorOpts.'
'modThreshold'],
'LineVectorOpts.lineWidth' : fsltooltips.properties['LineVectorOpts.'
'lineWidth'],
'ModelOpts.colour' : fsltooltips.properties['ModelOpts.colour'],
'ModelOpts.outline' : fsltooltips.properties['ModelOpts.outline'],
'ModelOpts.outlineWidth' : fsltooltips.properties['ModelOpts.'
'outlineWidth'],
})
_TOOLBAR_PROPS = td.TypeDict({
'Display' : {
'name' : props.Widget(
'name',
tooltip=_TOOLTIPS['Display.name']),
'overlayType' : props.Widget(
'overlayType',
tooltip=_TOOLTIPS['Display.overlayType'],
labels=strings.choices['Display.overlayType']),
'alpha' : props.Widget(
'alpha',
spin=False,
showLimits=False,
tooltip=_TOOLTIPS['Display.alpha']),
'brightness' : props.Widget(
'brightness',
spin=False,
showLimits=False,
tooltip=_TOOLTIPS['Display.brightness']),
'contrast' : props.Widget(
'contrast',
spin=False,
showLimits=False,
tooltip=_TOOLTIPS['Display.contrast'])},
'VolumeOpts' : {
'displayRange' : props.Widget(
'displayRange',
slider=False,
showLimits=False,
tooltip=_TOOLTIPS['VolumeOpts.displayRange'],
labels=[strings.choices['VolumeOpts.displayRange.min'],
strings.choices['VolumeOpts.displayRange.max']]),
'resetDisplayRange' : actions.ActionButton(
'resetDisplayRange',
icon=icons.findImageFile('verticalReset24'),
tooltip=_TOOLTIPS['VolumeOpts.resetDisplayRange']),
'cmap' : props.Widget(
'cmap',
tooltip=_TOOLTIPS['VolumeOpts.cmap'])},
'MaskOpts' : {
'threshold' : props.Widget(
'threshold',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['MaskOpts.threshold']),
'colour' : props.Widget(
'colour',
size=(24, 24),
tooltip=_TOOLTIPS['MaskOpts.colour'])},
'LabelOpts' : {
'lut' : props.Widget(
'lut',
tooltip=_TOOLTIPS['LabelOpts.lut'],
labels=lambda l: l.name),
'outline' : props.Widget(
'outline',
tooltip=_TOOLTIPS['LabelOpts.outline'],
icon=[icons.findImageFile('outline24'),
icons.findImageFile('filled24')],
toggle=True,
enabledWhen=lambda i, sw: not sw,
dependencies=[(lambda o: o.display, 'softwareMode')]),
'outlineWidth' : props.Widget(
'outlineWidth',
tooltip=_TOOLTIPS['LabelOpts.outlineWidth'],
enabledWhen=lambda i, sw: not sw,
dependencies=[(lambda o: o.display, 'softwareMode')],
showLimits=False,
spin=False)},
'RGBVectorOpts' : {
'modulate' : props.Widget(
'modulate',
labels=_modImageLabel,
tooltip=_TOOLTIPS['RGBVectorOpts.modulate']),
'modThreshold' : props.Widget(
'modThreshold',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['RGBVectorOpts.modThreshold'])},
'LineVectorOpts' : {
'modulate' : props.Widget(
'modulate',
labels=_modImageLabel,
tooltip=_TOOLTIPS['LineVectorOpts.modulate']),
'modThreshold' : props.Widget(
'modThreshold',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['LineVectorOpts.modThreshold']),
'lineWidth' : props.Widget(
'lineWidth',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['LineVectorOpts.lineWidth']),
},
'ModelOpts' : {
'colour' : props.Widget(
'colour',
size=(24, 24),
tooltip=_TOOLTIPS['ModelOpts.colour']),
'outline' : props.Widget(
'outline',
tooltip=_TOOLTIPS['ModelOpts.outline'],
icon=[icons.findImageFile('outline24'),
icons.findImageFile('filled24')],
toggle=True),
'outlineWidth' : props.Widget(
'outlineWidth',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['ModelOpts.outlineWidth'],
enabledWhen=lambda i: i.outline)}
})
class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
The ``OverlayDisplayToolBar`` also defines an action called ``more``
(which is linked to the :meth:`showMoreSettings` method), which opens an
:class:`.OverlayDisplayPanel`.
The specific controls which are displayed are defined in the
:attr:`_TOOLBAR_PROPS` dictionary, and are created by the following
methods:
.. autosummary::
:nosignatures:
__makeDisplayTools
__makeVolumeOptsTools
__makeMaskOptsTools
__makeLabelOptsTools
__makeVectorOptsTools
__makeRGBVectorOptsTools
__makeLineVectorOptsTools
__makeModelOptsTools
"""
def __init__(self, parent, overlayList, displayCtx, viewPanel):
"""Create an ``OverlyDisplyaToolBar``.
:arg parent: The :mod:`wx` parent object.
:arg overlayList: The :class:`.OverlayList` instance.
:arg displayCtx: The :class:`.DisplayContext` instance.
:arg viewPanel: The :class:`.ViewPanel` which this
``OverlayDisplayToolBar`` is owned by.
"""
actionz = {'more' : self.showMoreSettings}
......@@ -221,7 +100,10 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
def destroy(self):
"""Deregisters property listeners. """
"""Must be called when this ``OverlyDisplyaToolBar`` is no longer
needed. Removes some property listeners, and calls the
:meth:`.FSLEyesToolBar.destroy` method.
"""
self._overlayList.removeListener('overlays', self._name)
self._displayCtx .removeListener('selectedOverlay', self._name)
......@@ -240,18 +122,82 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
def showMoreSettings(self, *a):
"""Shows/hides a :class:`.OverlayDisplayPanel` dialog. """
self.__viewPanel.togglePanel(overlaydisplay.OverlayDisplayPanel,
floatPane=True)
def __showTools(self, overlay):
"""Creates and shows a set of controls allowing the user to change
the display settings of the specified ``overlay``.
"""
oldTools = self.GetTools()
# See long comment at bottom
def destroyOldTools():
for t in oldTools:
t.Destroy()
for t in oldTools:
t.Show(False)
self.ClearTools(destroy=False, postevent=False)
log.debug('Showing tools for {}'.format(overlay))
display = self._displayCtx.getDisplay(overlay)
opts = display.getDisplayOpts()
# Display tools
tools = self.__makeDisplayTools(display)
# DisplayOpts tools
makeFunc = getattr(self, '_{}__make{}Tools'.format(
type(self).__name__, type(opts).__name__), None)
if makeFunc is not None:
tools.extend(makeFunc(opts))
# Button which opens the OverlayDisplayPanel
more = props.buildGUI(
self,
self,
view=actions.ActionButton(
'more',
icon=icons.findImageFile('gear24'),
tooltip=fsltooltips.actions[self, 'more']))
tools.insert(0, more)
self.SetTools(tools)
# 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)
def __overlayEnableChanged(self, *a):
"""Called when the :attr:`.Display.enabled` property for the currently
selected overlay changes. Enables/disables this
``OverlayDisplayToolBar`` accordingly.
"""
display = self._displayCtx.getDisplay(self.__currentOverlay)
self.Enable(display.enabled)
def __selectedOverlayChanged(self, *a):
"""Called when the :attr:`.DisplayContext.selectedOverlay`
index changes. Ensures that the correct display panel is visible.
"""Called when the :attr:`.DisplayContext.selectedOverlay` or
:class:`.OverlayList` changes. Ensures that controls for the currently
selected overlay are being shown.
"""
if self.__currentOverlay is not None and \
......@@ -282,7 +228,8 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
def __makeDisplayTools(self, display):
"""
"""Creates and returns a collection of controls for editing properties
of the given :class:`.Display` instance.
"""
dispSpecs = _TOOLBAR_PROPS[display]
......@@ -336,7 +283,8 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
def __makeVolumeOptsTools(self, opts):
"""
"""Creates and returns a collection of controls for editing properties
of the given :class:`.VolumeOpts` instance.
"""
rangeSpec = _TOOLBAR_PROPS[opts]['displayRange']
resetSpec = _TOOLBAR_PROPS[opts]['resetDisplayRange']
......@@ -354,8 +302,9 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
def __makeMaskOptsTools(self, opts):
"""
"""
"""Creates and returns a collection of controls for editing properties
of the given :class:`.MaskOpts` instance.
"""
thresSpec = _TOOLBAR_PROPS[opts]['threshold']
colourSpec = _TOOLBAR_PROPS[opts]['colour']
......@@ -366,8 +315,9 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
def __makeLabelOptsTools(self, opts):
"""
"""
"""Creates and returns a collection of controls for editing properties
of the given :class:`.LabelOpts` instance.
"""
lutSpec = _TOOLBAR_PROPS[opts]['lut']
outlineSpec = _TOOLBAR_PROPS[opts]['outline']
......@@ -401,6 +351,9 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
def __makeVectorOptsTools(self, opts):
"""Creates and returns a collection of controls for editing properties
of the given :class:`.VectorOpts` instance.
"""
modSpec = _TOOLBAR_PROPS[opts]['modulate']
thresSpec = _TOOLBAR_PROPS[opts]['modThreshold']
......@@ -425,10 +378,16 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
return [panel]
def __makeRGBVectorOptsTools(self, opts):
"""Creates and returns a collection of controls for editing properties
of the given :class:`.RGBVectorOpts` instance.
"""
return self.__makeVectorOptsTools(opts)
def __makeLineVectorOptsTools(self, opts):
"""Creates and returns a collection of controls for editing properties
of the given :class:`.LineVectorOpts` instance.
"""
widthSpec = _TOOLBAR_PROPS[opts]['lineWidth']
widget = props.buildGUI(self, opts, widthSpec)
......@@ -439,6 +398,9 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
def __makeModelOptsTools(self, opts):
"""Creates and returns a collection of controls for editing properties
of the given :class:`.ModelOpts` instance.
"""
colourSpec = _TOOLBAR_PROPS[opts]['colour']
outlineSpec = _TOOLBAR_PROPS[opts]['outline']
widthSpec = _TOOLBAR_PROPS[opts]['outlineWidth']
......@@ -452,56 +414,180 @@ class OverlayDisplayToolBar(fsltoolbar.FSLEyesToolBar):
return [colourWidget, outlineWidget, widthWidget]
def __showTools(self, overlay):
def _modImageLabel(img):
"""Used to generate labels for the :attr:`.VectorOpts.modulate`
property choices.
"""
if img is None: return strings.choices['VectorOpts.modulate.none']
else: return img.name
oldTools = self.GetTools()
_TOOLTIPS = td.TypeDict({
# See long comment at bottom
def destroyOldTools():
for t in oldTools:
t.Destroy()
'Display.name' : fsltooltips.properties['Display.name'],
'Display.overlayType' : fsltooltips.properties['Display.overlayType'],
'Display.alpha' : fsltooltips.properties['Display.alpha'],
'Display.brightness' : fsltooltips.properties['Display.brightness'],
'Display.contrast' : fsltooltips.properties['Display.contrast'],
for t in oldTools:
t.Show(False)
'VolumeOpts.displayRange' : fsltooltips.properties['VolumeOpts.'
'displayRange'],
'VolumeOpts.resetDisplayRange' : fsltooltips.actions[ 'VolumeOpts.reset'
'DisplayRange'],
'VolumeOpts.cmap' : fsltooltips.properties['VolumeOpts.cmap'],
self.ClearTools(destroy=False, postevent=False)
'MaskOpts.threshold' : fsltooltips.properties['MaskOpts.threshold'],
'MaskOpts.colour' : fsltooltips.properties['MaskOpts.colour'],
log.debug('Showing tools for {}'.format(overlay))
'LabelOpts.lut' : fsltooltips.properties['LabelOpts.lut'],
'LabelOpts.outline' : fsltooltips.properties['LabelOpts.outline'],
'LabelOpts.outlineWidth' : fsltooltips.properties['LabelOpts.'
'outlineWidth'],
display = self._displayCtx.getDisplay(overlay)
opts = display.getDisplayOpts()
'RGBVectorOpts.modulate' : fsltooltips.properties['VectorOpts.'
'modulate'],
'RGBVectorOpts.modThreshold' : fsltooltips.properties['VectorOpts.'
'modThreshold'],
# Display tools
tools = self.__makeDisplayTools(display)
'LineVectorOpts.modulate' : fsltooltips.properties['VectorOpts.'
'modulate'],
'LineVectorOpts.modThreshold' : fsltooltips.properties['VectorOpts.'
'modThreshold'],
'LineVectorOpts.lineWidth' : fsltooltips.properties['LineVectorOpts.'
'lineWidth'],
# DisplayOpts tools
makeFunc = getattr(self, '_{}__make{}Tools'.format(
type(self).__name__, type(opts).__name__), None)
'ModelOpts.colour' : fsltooltips.properties['ModelOpts.colour'],
'ModelOpts.outline' : fsltooltips.properties['ModelOpts.outline'],
'ModelOpts.outlineWidth' : fsltooltips.properties['ModelOpts.'
'outlineWidth'],
})
"""This dictionary contains tooltips for :class:`.Display` and
:class:`.DisplayOpts` properties. It is referenced in the
:attr:`_TOOLBAR_PROPS` dictionary definition.
"""
if makeFunc is not None:
tools.extend(makeFunc(opts))
# Button which opens the OverlayDisplayPanel
more = props.buildGUI(
self,
self,
view=actions.ActionButton(
'more',
icon=icons.findImageFile('gear24'),
tooltip=fsltooltips.actions[self, 'more']))
_TOOLBAR_PROPS = td.TypeDict({
tools.insert(0, more)
'Display' : {
'name' : props.Widget(
'name',
tooltip=_TOOLTIPS['Display.name']),
'overlayType' : props.Widget(
'overlayType',
tooltip=_TOOLTIPS['Display.overlayType'],
labels=strings.choices['Display.overlayType']),
'alpha' : props.Widget(
'alpha',
spin=False,
showLimits=False,
tooltip=_TOOLTIPS['Display.alpha']),
'brightness' : props.Widget(
'brightness',
spin=False,
showLimits=False,
tooltip=_TOOLTIPS['Display.brightness']),
'contrast' : props.Widget(
'contrast',
spin=False,
showLimits=False,
tooltip=_TOOLTIPS['Display.contrast'])},
self.SetTools(tools)
'VolumeOpts' : {
'displayRange' : props.Widget(
'displayRange',
slider=False,
showLimits=False,
tooltip=_TOOLTIPS['VolumeOpts.displayRange'],
labels=[strings.choices['VolumeOpts.displayRange.min'],
strings.choices['VolumeOpts.displayRange.max']]),
'resetDisplayRange' : actions.ActionButton(
'resetDisplayRange',
icon=icons.findImageFile('verticalReset24'),
tooltip=_TOOLTIPS['VolumeOpts.resetDisplayRange']),
'cmap' : props.Widget(
'cmap',
tooltip=_TOOLTIPS['VolumeOpts.cmap'])},
'MaskOpts' : {
'threshold' : props.Widget(
'threshold',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['MaskOpts.threshold']),
'colour' : props.Widget(
'colour',
size=(24, 24),
tooltip=_TOOLTIPS['MaskOpts.colour'])},
'LabelOpts' : {
'lut' : props.Widget(
'lut',
tooltip=_TOOLTIPS['LabelOpts.lut'],
labels=lambda l: l.name),
'outline' : props.Widget(
'outline',
tooltip=_TOOLTIPS['LabelOpts.outline'],
icon=[icons.findImageFile('outline24'),
icons.findImageFile('filled24')],
toggle=True,
enabledWhen=lambda i, sw: not sw,
dependencies=[(lambda o: o.display, 'softwareMode')]),
# 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)
'outlineWidth' : props.Widget(
'outlineWidth',
tooltip=_TOOLTIPS['LabelOpts.outlineWidth'],
enabledWhen=lambda i, sw: not sw,
dependencies=[(lambda o: o.display, 'softwareMode')],
showLimits=False,
spin=False)},
'RGBVectorOpts' : {
'modulate' : props.Widget(
'modulate',
labels=_modImageLabel,
tooltip=_TOOLTIPS['RGBVectorOpts.modulate']),
'modThreshold' : props.Widget(
'modThreshold',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['RGBVectorOpts.modThreshold'])},
'LineVectorOpts' : {
'modulate' : props.Widget(
'modulate',
labels=_modImageLabel,
tooltip=_TOOLTIPS['LineVectorOpts.modulate']),
'modThreshold' : props.Widget(
'modThreshold',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['LineVectorOpts.modThreshold']),
'lineWidth' : props.Widget(
'lineWidth',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['LineVectorOpts.lineWidth']),
},
'ModelOpts' : {
'colour' : props.Widget(
'colour',
size=(24, 24),
tooltip=_TOOLTIPS['ModelOpts.colour']),
'outline' : props.Widget(
'outline',
tooltip=_TOOLTIPS['ModelOpts.outline'],
icon=[icons.findImageFile('outline24'),
icons.findImageFile('filled24')],
toggle=True),
'outlineWidth' : props.Widget(
'outlineWidth',
showLimits=False,
spin=False,
tooltip=_TOOLTIPS['ModelOpts.outlineWidth'],
enabledWhen=lambda i: i.outline)}
})
"""This dictionary defines specifications for all controls shown on an
:class:`OverlayDisplayToolBar`.
"""
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