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

OverlayListPanel working with non-volumetric overlays. Overlay objecst

are now required to have a 'name' attribute and a 'dataSource' attribute.
parent d2eb4fe0
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,6 @@
See the :mod:`fsl.data.imageio` module for image loading/saving
functionality.
"""
import logging
......@@ -52,7 +51,7 @@ class Image(props.HasProperties):
for transforming real world coordinates into voxel
coordinates.
:ivar imageFile: The name of the file that the image was loaded from.
:ivar dataSource: The name of the file that the image was loaded from.
:ivar tempFile: The name of the temporary file which was created (in
the event that the image was large and was gzipped -
......@@ -105,9 +104,9 @@ class Image(props.HasProperties):
via the :meth:`loadData` method.
"""
self.nibImage = None
self.imageFile = None
self.tempFile = None
self.nibImage = None
self.dataSource = None
self.tempFile = None
if header is not None:
header = header.copy()
......@@ -117,16 +116,16 @@ class Image(props.HasProperties):
nibImage, filename = iio.loadImage(iio.addExt(image))
self.nibImage = nibImage
self.imageFile = image
self.dataSource = image
# if the returned file name is not the same as
# the provided file name, that means that the
# image was opened from a temporary file
if filename != image:
self.name = iio.removeExt(op.basename(self.imageFile))
self.name = iio.removeExt(op.basename(self.dataSource))
self.tempFile = nibImage.get_filename()
else:
self.name = iio.removeExt(op.basename(self.imageFile))
self.name = iio.removeExt(op.basename(self.dataSource))
self.saved = True
......@@ -255,7 +254,7 @@ class Image(props.HasProperties):
"""Return a string representation of this :class:`Image`."""
return '{}({}, {})'.format(self.__class__.__name__,
self.name,
self.imageFile)
self.dataSource)
def __repr__(self):
......
......@@ -281,13 +281,13 @@ def saveImage(image, imageList=None, fromDir=None):
lastDir = getattr(saveImage, 'lastDir', None)
if lastDir is None:
if image.imageFile is None: lastDir = os.getcwd()
else: lastDir = op.dirname(image.imageFile)
if image.dataSource is None: lastDir = os.getcwd()
else: lastDir = op.dirname(image.dataSource)
# TODO make image.name safe (spaces to
# underscores, filter non-alphanumeric)
if image.imageFile is None: filename = image.name
else: filename = op.basename(image.imageFile)
if image.dataSource is None: filename = image.name
else: filename = op.basename(image.dataSource)
filename = removeExt(filename)
......@@ -338,7 +338,7 @@ def saveImage(image, imageList=None, fromDir=None):
log.debug('Saving image ({}) to {}'.format(image, path))
nib.save(nibImage, path)
image.imageFile = path
image.dataSource = path
except Exception as e:
......
......@@ -5,8 +5,8 @@
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
import numpy as np
import os.path as op
import numpy as np
def loadVTKPolydataFile(infile):
......@@ -62,6 +62,12 @@ class PolygonModel(object):
if np.any(lengths != 3):
raise RuntimeError('All polygons in VTK file must be '
'triangles ({})'.format(infile))
self.name = op.basename(infile)
self.dataSource = infile
else:
self.name = 'Model'
self.dataSource = 'Model'
if indices is None:
indices = np.arange(data.shape[0], dtype=np.uint32)
......
......@@ -54,7 +54,7 @@ class ListItemWidget(wx.Panel):
self.name,
self._saveStateChanged)
else:
log.warn('No support for non-volumetric overlays yet')
log.warn('No save button support for non-volumetric overlays')
self.saveButton.Enable(False)
self.saveButton.Bind(wx.EVT_BUTTON, self._onSaveButton)
......@@ -81,8 +81,12 @@ class ListItemWidget(wx.Panel):
def _saveStateChanged(self, *a):
idx = self.listBox.IndexOf(self.overlay)
if not isinstance(self.overlay, fslimage.Image):
return
idx = self.listBox.IndexOf(self.overlay)
self.saveButton.Enable(not self.overlay.saved)
if self.overlay.saved:
......@@ -192,8 +196,8 @@ class OverlayListPanel(fslpanel.FSLViewPanel):
def _overlayNameChanged(self, value, valid, overlay, propName):
idx = self._displayCtx.getOverlayOrder( overlay)
display = self._displayCtx.getDisplay(overlay)
idx = self._displayCtx.getOverlayOrder(overlay)
display = self._displayCtx.getDisplay( overlay)
name = display.name
if name is None:
......@@ -218,12 +222,7 @@ class OverlayListPanel(fslpanel.FSLViewPanel):
name = display.name
if name is None: name = ''
if isinstance(overlay, fslimage.Image):
tooltip = overlay.imageFile
else:
log.warn('No support for non-volumetric overlays yet')
tooltip = 'Non-volumetric overlay - I don\'t know what to do'
tooltip = overlay.dataSource
self._listBox.Append(name, overlay, tooltip)
......
......@@ -4,7 +4,12 @@
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module defines the :class:`OverlayList` class, which is a simple but
fundamental class in FSLView - it is a container for all displayed overlays.
Only one ``OverlayList`` ever exists, and it is shared throughout the entire
application.
"""
import logging
......@@ -27,12 +32,23 @@ class OverlayList(props.HasProperties):
:attr:`overlays` property, allowing the :class:`OverlayList` to be used
as if it were a list itself.
There are no restrictions on the type of objects which may be contained
in the ``OverlayList``, but all objects must have a few attributes:
An overlay object must have an attribute called ``name``.
- ``name`` ...
- ``dataSoruce`` ..
"""
overlays = props.List()
def __validateOverlay(self, atts, overlay):
return (hasattr(overlay, 'name') and
hasattr(overlay, 'dataSource'))
overlays = props.List(
listType=props.Object(allowInvalid=False,
validateFunc=__validateOverlay))
"""A list of overlay objects to be displayed"""
......
......@@ -135,7 +135,7 @@ def _takeScreenShot(overlayList, displayCtx, canvas):
continue
display = displayCtx.getDisplay(overlay)
fname = overlay.imageFile
fname = overlay.dataSource
# Skip invisible/unsaved/in-memory images
if not (display.enabled and overlay.saved):
......
......@@ -884,7 +884,9 @@ def applyOverlayArgs(args, overlayList, displayCtx, **kwargs):
# per-overlay display arguments
for i, overlay in enumerate(overlayList):
display = displayCtx.getDisplay(overlay)
display = displayCtx.getDisplay(overlay)
display.name = overlay.name
_applyArgs(args.overlays[i], display)
# Retrieve the DisplayOpts instance
......
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