diff --git a/fsl/data/strings.py b/fsl/data/strings.py index 94cb41835b5b073d2bc1e745987dea9760295f5d..67099b53b232a5b21702c3b8b972ba6142a81655 100644 --- a/fsl/data/strings.py +++ b/fsl/data/strings.py @@ -266,11 +266,12 @@ labels = TypeDict({ 'CanvasPanel.screenshot.notSaved.cancel' : 'Cancel screenshot', - 'LookupTablePanel.addLabel' : 'Add label', - 'LookupTablePanel.newLut' : 'New', - 'LookupTablePanel.copyLut' : 'Copy', - 'LookupTablePanel.saveLut' : 'Save', - 'LookupTablePanel.loadLut' : 'Load', + 'LookupTablePanel.addLabel' : 'Add label', + 'LookupTablePanel.removeLabel' : 'Remove label', + 'LookupTablePanel.newLut' : 'New LUT', + 'LookupTablePanel.copyLut' : 'Copy LUT', + 'LookupTablePanel.saveLut' : 'Save LUT', + 'LookupTablePanel.loadLut' : 'Load LUT', 'LutLabelDialog.value' : 'Value', 'LutLabelDialog.name' : 'Name', diff --git a/fsl/fsleyes/colourmaps.py b/fsl/fsleyes/colourmaps.py index 3fe160ff2b0023c3f01203f35cee8c9cbef7b7d5..a8b551ca0f393a6b5cbf1917d1e82c20e3e2a6b0 100644 --- a/fsl/fsleyes/colourmaps.py +++ b/fsl/fsleyes/colourmaps.py @@ -210,7 +210,8 @@ def init(): if suffix == 'cmap': registerColourMap( mapFile, **kwargs) elif suffix == 'lut': registerLookupTable(mapFile, **kwargs) - register[key].installed = True + register[key].installed = True + register[key].mapObj.saved = True except Exception as e: log.warn('Error processing custom {} ' diff --git a/fsl/fsleyes/controls/lookuptablepanel.py b/fsl/fsleyes/controls/lookuptablepanel.py index b7f5209b44eba90c92dc1831af56fc67a1d79f8e..cd26ed54772a79fbc540f63f932180d64c857720 100644 --- a/fsl/fsleyes/controls/lookuptablepanel.py +++ b/fsl/fsleyes/controls/lookuptablepanel.py @@ -33,6 +33,7 @@ import fsl.fsleyes.panel as fslpanel import fsl.fsleyes.displaycontext as displayctx import fsl.fsleyes.colourmaps as fslcmaps import fsl.data.strings as strings +import fsl.data.melodicimage as fslmelimage log = logging.getLogger(__name__) @@ -80,56 +81,55 @@ class LookupTablePanel(fslpanel.FSLEyesPanel): fslpanel.FSLEyesPanel.__init__(self, parent, overlayList, displayCtx) - self.__controlRow = wx.Panel(self) - self.__labelList = elistbox.EditableListBox( - self, - style=elistbox.ELB_NO_MOVE | elistbox.ELB_EDITABLE) - - self.__lutChoice = wx.Choice(self.__controlRow) - self.__newLutButton = wx.Button(self.__controlRow) - self.__copyLutButton = wx.Button(self.__controlRow) - self.__saveLutButton = wx.Button(self.__controlRow) - self.__loadLutButton = wx.Button(self.__controlRow) - - self.__controlRowSizer = wx.BoxSizer(wx.HORIZONTAL) - self.__sizer = wx.BoxSizer(wx.VERTICAL) - - self.__controlRow.SetSizer(self.__controlRowSizer) + self.__controlCol = wx.Panel(self) + self.__labelList = elistbox.EditableListBox( + self, style=(elistbox.ELB_NO_MOVE | + elistbox.ELB_NO_ADD | + elistbox.ELB_NO_REMOVE | + elistbox.ELB_EDITABLE)) + + self.__lutChoice = wx.Choice(self.__controlCol) + self.__addLabelButton = wx.Button(self.__controlCol) + self.__rmLabelButton = wx.Button(self.__controlCol) + self.__newLutButton = wx.Button(self.__controlCol) + self.__copyLutButton = wx.Button(self.__controlCol) + self.__saveLutButton = wx.Button(self.__controlCol) + self.__loadLutButton = wx.Button(self.__controlCol) + + self.__controlColSizer = wx.BoxSizer(wx.VERTICAL) + self.__sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.__controlCol.SetSizer(self.__controlColSizer) self .SetSizer(self.__sizer) - self.__controlRowSizer.Add(self.__lutChoice, - flag=wx.EXPAND, proportion=1) - self.__controlRowSizer.Add(self.__newLutButton, - flag=wx.EXPAND, proportion=1) - self.__controlRowSizer.Add(self.__copyLutButton, - flag=wx.EXPAND, proportion=1) - self.__controlRowSizer.Add(self.__loadLutButton, - flag=wx.EXPAND, proportion=1) - self.__controlRowSizer.Add(self.__saveLutButton, - flag=wx.EXPAND, proportion=1) - - self.__sizer.Add(self.__controlRow, flag=wx.EXPAND) + self.__controlColSizer.Add(self.__lutChoice, flag=wx.EXPAND) + self.__controlColSizer.Add(self.__addLabelButton, flag=wx.EXPAND) + self.__controlColSizer.Add(self.__rmLabelButton, flag=wx.EXPAND) + self.__controlColSizer.Add(self.__newLutButton, flag=wx.EXPAND) + self.__controlColSizer.Add(self.__copyLutButton, flag=wx.EXPAND) + self.__controlColSizer.Add(self.__loadLutButton, flag=wx.EXPAND) + self.__controlColSizer.Add(self.__saveLutButton, flag=wx.EXPAND) + + self.__sizer.Add(self.__controlCol, flag=wx.EXPAND) self.__sizer.Add(self.__labelList, flag=wx.EXPAND, proportion=1) # Label the buttons - self.__newLutButton .SetLabel(strings.labels[ self, 'newLut']) - self.__copyLutButton.SetLabel(strings.labels[ self, 'copyLut']) - self.__loadLutButton.SetLabel(strings.labels[ self, 'loadLut']) - self.__saveLutButton.SetLabel(strings.labels[ self, 'saveLut']) - - # Listen for listbox events - self.__labelList.Bind(elistbox.EVT_ELB_ADD_EVENT, - self.__onLabelAdd) - self.__labelList.Bind(elistbox.EVT_ELB_REMOVE_EVENT, - self.__onLabelRemove) - self.__labelList.Bind(elistbox.EVT_ELB_EDIT_EVENT, - self.__onLabelEdit) - - self.__lutChoice .Bind(wx.EVT_CHOICE, self.__onLutChoice) - self.__newLutButton .Bind(wx.EVT_BUTTON, self.__onNewLut) - self.__copyLutButton.Bind(wx.EVT_BUTTON, self.__onCopyLut) - self.__loadLutButton.Bind(wx.EVT_BUTTON, self.__onLoadLut) - self.__saveLutButton.Bind(wx.EVT_BUTTON, self.__onSaveLut) + self.__addLabelButton.SetLabel(strings.labels[ self, 'addLabel']) + self.__rmLabelButton .SetLabel(strings.labels[ self, 'removeLabel']) + self.__newLutButton .SetLabel(strings.labels[ self, 'newLut']) + self.__copyLutButton .SetLabel(strings.labels[ self, 'copyLut']) + self.__loadLutButton .SetLabel(strings.labels[ self, 'loadLut']) + self.__saveLutButton .SetLabel(strings.labels[ self, 'saveLut']) + + self.__labelList.Bind(elistbox.EVT_ELB_EDIT_EVENT, self.__onLabelEdit) + + self.__lutChoice .Bind(wx.EVT_CHOICE, self.__onLutChoice) + self.__addLabelButton.Bind(wx.EVT_BUTTON, self.__onLabelAdd) + self.__rmLabelButton .Bind(wx.EVT_BUTTON, self.__onLabelRemove) + self.__newLutButton .Bind(wx.EVT_BUTTON, self.__onNewLut) + self.__copyLutButton .Bind(wx.EVT_BUTTON, self.__onCopyLut) + self.__loadLutButton .Bind(wx.EVT_BUTTON, self.__onLoadLut) + self.__saveLutButton .Bind(wx.EVT_BUTTON, self.__onSaveLut) self.__selectedOverlay = None self.__selectedOpts = None @@ -270,6 +270,7 @@ class LookupTablePanel(fslpanel.FSLEyesPanel): current :class:`LookupTable` instance changes. Sets the state of the *save* button accordingly. """ + print 'Updating save state ({})'.format(self.__selectedLut.saved) self.__saveLutButton.Enable(not self.__selectedLut.saved) @@ -394,7 +395,7 @@ class LookupTablePanel(fslpanel.FSLEyesPanel): that the current :class:`LookupTable` is saved (see the :func:`.colourmaps.installLookupTable` function). """ - fslcmaps.installLookupTable(self.__selectedLut.name) + fslcmaps.installLookupTable(self.__selectedLut.key) def __onLabelAdd(self, ev): @@ -442,11 +443,13 @@ class LookupTablePanel(fslpanel.FSLEyesPanel): :class:`.LookupTable`. """ + idx = self.__labelList.GetSelection() lut = self.__selectedLut - value = lut.labels[ev.idx].value() + value = lut.labels[idx].value() lut.disableListener('labels', self._name) lut.delete(value) + self.__labelList.Delete(idx) lut.enableListener('labels', self._name) @@ -504,10 +507,18 @@ class LookupTablePanel(fslpanel.FSLEyesPanel): overlay = self.__selectedOverlay opts = None - if overlay is not None: - opts = self._displayCtx.getOpts(overlay) - + if overlay is None: + return + + opts = self._displayCtx.getOpts(overlay) + if not isinstance(opts, displayctx.LabelOpts): + + # If the image is a Melodic image, show + # the melodic classification lut + if isinstance(overlay, fslmelimage.MelodicImage): + self.__setLut(fslcmaps.getLookupTable('melodic-classes')) + return opts.addListener('lut', self._name, self.__lutChanged) diff --git a/fsl/fsleyes/luts/melodic-classes.lut b/fsl/fsleyes/luts/melodic-classes.lut index 4bed9d72e3b2bdba9109fd73d73dc0fec7d691e1..aaf2c07fce35959dea4e16af2be7324c78148f4b 100644 --- a/fsl/fsleyes/luts/melodic-classes.lut +++ b/fsl/fsleyes/luts/melodic-classes.lut @@ -1,11 +1,11 @@ -1 0.99607843 0.44313725 0.55686275 Signal -2 0.45490196 0.62352941 0.54901961 Unknown -3 0.98039216 0.47843137 0.58823529 Unclassified noise -4 0.84705882 0.61176471 0.62352941 Movement -5 0.85490196 0.43529412 0.47843137 Cardiac -6 0.49411765 0.96470588 0.98431373 White matter -7 0.98823529 0.57254902 0.44313725 Non-brain -8 0.85882353 0.85490196 0.84705882 MRI -9 0.66666667 0.97254902 0.74509804 Susceptibility-motion -10 0.52156863 0.87058824 0.39215686 Sagittal sinus -11 0.42745098 0.7254902 0.60392157 Respiratory +1 0.419608 0.619608 0.992157 Signal +2 0.490196 0.827451 0.000000 Unknown +3 0.980392 0.478431 0.588235 Unclassified noise +4 0.843137 0.776471 0.000000 Movement +5 0.850980 0.435294 0.000000 Cardiac +6 0.494118 0.964706 0.984314 White matter +7 0.984313 0.564706 0.850980 Non-brain +8 0.858824 0.854902 0.847059 MRI +9 0.666667 0.972549 0.745098 Susceptibility-motion +10 0.780392 0.470588 0.870588 Sagittal sinus +11 0.427450 0.725490 0.603922 Respiratory