class Thing(props.HasProperties): myobject = props.Object() mybool = props.Boolean() myint = props.Int() myreal = props.Real() mypercentage = props.Percentage() mystring = props.String() mychoice = props.Choice(('1', '2', '3', '4', '5')) myfilepath = props.FilePath() mylist = props.List() mycolour = props.Colour() mycolourmap = props.ColourMap() mybounds = props.Bounds(ndims=2) mypoint = props.Point(ndims=2) myarray = props.Array()
class OverlayList(props.HasProperties): """Class representing a collection of overlays to be displayed together. Contains a :class:`props.properties_types.List` property called :attr:`overlays`, containing overlay objects (e.g. :class:`.Image` or :class:`.TriangleMesh` objects). Listeners can be registered on the ``overlays`` property, so they are notified when the overlay list changes. An :class:`OverlayList` object has a few wrapper methods around the :attr:`overlays` property, allowing the :class:`OverlayList` to be used as if it were a list itself. The :mod:`.loadoverlay` module contains some convenience functions for loading and adding overlays. The :meth:`getData` and :meth:`setData` methods allow arbitrary bits of data associated with an overlay to be stored and retrieved. """ def __validateOverlay(self, atts, overlay): """Makes sure that the given overlay object is valid.""" 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.""" def __init__(self, overlays=None): """Create an ``OverlayList`` object from the given sequence of overlays.""" if overlays is None: overlays = [] self.overlays.extend(overlays) # The append/insert methods allow an initial # overlay type to be specified for newly # added overlays. This can be queried via # the initOverlayType method (and is done so # by DisplayContext instances). self.__initOverlayType = {} # This dictionary may be used throughout FSLeyes, # via the getData/setData methods, to store # any sort of data associated with an overlay. # It is a dict of dicts: # # { # overlay : { # key : value, # key : value, # }, # overlay : { # key : value, # key : value, # } # } self.__overlayData = weakref.WeakKeyDictionary() def initOverlayType(self, overlay): """Returns the initial type for the given ``overlay``, if it was specified via the :meth:`append` or :meth:`insert` methods. Returns ``None`` otherwise. """ return self.__initOverlayType.get(overlay, None) def getData(self, overlay, key, *args): """Returns any stored value associated with the specified ``overlay`` and ``key``. :arg default: Default value if there is no value associated with the given ``key``. If not specified, and an unknown key is given, a ``KeyError`` is raised. """ if len(args) not in (0, 1): raise RuntimeError('Invalid arguments: {}'.format(args)) ovlDict = self.__overlayData.get(overlay, {}) if len(args) == 1: return ovlDict.get(key, args[0]) else: return ovlDict[key] def setData(self, overlay, key, value): """Stores the given value via the specified ``overlay`` and ``key``. """ ovlDict = self.__overlayData.get(overlay, None) if ovlDict is not None: ovlDict[key] = value else: self.__overlayData[overlay] = {key: value} def find(self, name): """Returns the first overlay with the given ``name`` or ``dataSource``, or ``None`` if there is no overlay with said ``name``/``dataSource``. """ if name is None: return None absname = op.abspath(name) for overlay in self.overlays: if overlay.name == name: return overlay if overlay.dataSource is None: continue # Ignore file extensions for NIFTI images. if isinstance(overlay, fslimage.Image): if fslimage.removeExt(overlay.dataSource) == \ fslimage.removeExt(absname): return overlay else: if overlay.dataSource == absname: return overlay return None def __str__(self): return self.overlays.__str__() def __repr__(self): return self.overlays.__str__() # Wrappers around the overlays list property, allowing this # OverlayList object to be used as if it is actually a list. def __len__(self): return self.overlays.__len__() def __getitem__(self, key): return self.overlays.__getitem__(key) def __iter__(self): return self.overlays.__iter__() def __contains__(self, item): return self.overlays.__contains__(item) def __setitem__(self, key, val): return self.overlays.__setitem__(key, val) def __delitem__(self, key): if isinstance(key, slice): pass elif isinstance(key, int): key = slice(key, key + 1, None) else: raise IndexError('Invalid key type') ovls = self[key] for ovl in ovls: self.__initOverlayType.pop(ovl, None) return self.overlays.__delitem__(key) def index(self, item): return self.overlays.index(item) def count(self, item): return self.overlays.count(item) def append(self, item, overlayType=None): with props.suppress(self, 'overlays', notify=True): self.overlays.append(item) if overlayType is not None: self.__initOverlayType[item] = overlayType def extend(self, iterable, overlayTypes=None): with props.suppress(self, 'overlays', notify=True): result = self.overlays.extend(iterable) if overlayTypes is not None: for overlay, overlayType in overlayTypes.items(): self.__initOverlayType[overlay] = overlayType return result def pop(self, index=-1): ovl = self.overlays.pop(index) self.__initOverlayType.pop(ovl, None) return ovl def move(self, from_, to): return self.overlays.move(from_, to) def remove(self, item): self.__initOverlayType.pop(item, None) self.overlays.remove(item) def insert(self, index, item, overlayType=None): with props.suppress(self, 'overlays', notify=True): self.overlays.insert(index, item) if overlayType is not None: self.__initOverlayType[item] = overlayType def insertAll(self, index, items): return self.overlays.insertAll(index, items)