From 65c4e78a6185e2e72425679d9f6d26f6ff9e0d0a Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauld.mccarthy@gmail.com>
Date: Tue, 1 Dec 2015 13:50:31 +0000
Subject: [PATCH] First attempt at making the ClusterPanel a bit more
 performant. WidgetGrid related updates elsewhere.

---
 fsl/data/strings.py                           |  2 +-
 fsl/fsleyes/controls/clusterpanel.py          | 49 +++++++++++--------
 .../controls/melodicclassificationgrid.py     |  5 ++
 fsl/fsleyes/controls/overlaydisplaypanel.py   |  2 +-
 4 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/fsl/data/strings.py b/fsl/data/strings.py
index 851b74d4b..a14d3e519 100644
--- a/fsl/data/strings.py
+++ b/fsl/data/strings.py
@@ -134,7 +134,7 @@ messages = TypeDict({
                                     'in this FEAT analysis',
     'ClusterPanel.badData'        : 'Cluster data could not be parsed - '
                                     'check your cluster_*.txt files.',
-    'ClusterPanel.loadingCluster' : 'Loading data for cluster {} ...',
+    'ClusterPanel.loadingCluster' : 'Loading clusters for COPE{} ...',
 
     'OrthoEditProfile.displaySpaceChange' : 'Setting {} as the display '
                                             'space reference image - this '
diff --git a/fsl/fsleyes/controls/clusterpanel.py b/fsl/fsleyes/controls/clusterpanel.py
index c6900e8cf..fb60a1e2c 100644
--- a/fsl/fsleyes/controls/clusterpanel.py
+++ b/fsl/fsleyes/controls/clusterpanel.py
@@ -14,7 +14,6 @@ import                        wx
 import pwidgets.widgetgrid as widgetgrid
 
 import fsl.fsleyes.panel   as fslpanel
-import fsl.utils.dialog    as fsldlg
 import fsl.data.strings    as strings
 import fsl.data.featimage  as featimage
 
@@ -152,15 +151,32 @@ class ClusterPanel(fslpanel.FSLEyesPanel):
         self.__sizer.Show(self.__mainSizer,    False)
         self.Layout()
 
+        
+    def __enable(self):
+        """Enables the ``ClusterPanel``. This amounts to hiding the
+        disabled message panel, and showing the :class:`.WidgetGrid`.
+        """
+        self.__sizer.Show(self.__disabledText, False)
+        self.__sizer.Show(self.__mainSizer,    True)
+        self.Layout() 
+
     
     def __statSelected(self, ev):
         """Called when a COPE is selected. Clears the cluster table, and
         displays clusters for the newly selected COPE (see the
         :meth:`__displayClusterData` method)
         """
-        idx  = self.__statSelect.GetSelection()
+        idx  = self.__statSelect.GetSelection() 
         data = self.__statSelect.GetClientData(idx)
-        self.__displayClusterData(data)
+        con  = idx + 1
+        
+        self.__disable(strings.messages[self, 'loadingCluster'].format(con))
+
+        self.Refresh()
+        self.Update()
+ 
+        self.__displayClusterData(con, data)
+        self.__enable()
         self.__enableOverlayButtons()
 
 
@@ -219,11 +235,14 @@ class ClusterPanel(fslpanel.FSLEyesPanel):
         self._overlayList.append(mask)
         self._displayCtx.getDisplay(mask).overlayType = 'label'
 
-        
-    def __displayClusterData(self, clusters):
+
+    def __displayClusterData(self, contrast, clusters):
         """Updates the cluster table so that it is displaying the given list
         of clusters.
 
+        :arg contrast: The number of the contrast to which the clusters are
+                       related.
+
         :arg clusters: A sequence of objects, each representing one cluster.
                        See the :meth:`.FEATImage.clusterResults` method.
         """
@@ -243,7 +262,6 @@ class ClusterPanel(fslpanel.FSLEyesPanel):
         overlay = self.__selectedOverlay
         opts    = self._displayCtx.getOpts(overlay)
 
-        grid.ClearGrid()
         grid.SetGridSize(len(clusters), 10)
 
         for col, i in cols.items():
@@ -266,15 +284,8 @@ class ClusterPanel(fslpanel.FSLEyesPanel):
 
             return sizer
 
-        dlg = fsldlg.SimpleMessageDialog()
-
-        dlg.Show()
-
         for i, clust in enumerate(clusters):
 
-            dlg.SetMessage(
-                strings.messages[self, 'loadingCluster'].format(clust.index))
-
             zmaxbtn    = makeCoordButton((clust.zmaxx,
                                           clust.zmaxy,
                                           clust.zmaxz))
@@ -297,8 +308,7 @@ class ClusterPanel(fslpanel.FSLEyesPanel):
             grid.SetWidget(i, cols['copemaxcoords'], copemaxbtn)
             grid.SetText(  i, cols['copemean'],      fmt(clust.copemean))
 
-        dlg.Close()
-        dlg.Destroy()
+        grid.Refresh()
         
 
     def __overlayListChanged(self, *a):
@@ -369,12 +379,10 @@ class ClusterPanel(fslpanel.FSLEyesPanel):
             
         self.__statSelect .Clear()
         self.__clusterList.ClearGrid()
+        self.__clusterList.Refresh()
 
         self.__selectedOverlay = overlay
 
-        self.__sizer.Show(self.__disabledText, False)
-        self.__sizer.Show(self.__mainSizer,    True)
-
         numCons  = overlay.numContrasts()
         conNames = overlay.contrastNames()
 
@@ -405,7 +413,8 @@ class ClusterPanel(fslpanel.FSLEyesPanel):
         self.__overlayName.SetLabel(overlay.getAnalysisName())
 
         self.__statSelect.SetSelection(0)
-        self.__displayClusterData(clusts[0][1])
+        self.__displayClusterData(1, clusts[0][1])
+
+        self.__enable()
 
         self.Layout()
-        return
diff --git a/fsl/fsleyes/controls/melodicclassificationgrid.py b/fsl/fsleyes/controls/melodicclassificationgrid.py
index 95113429b..6d2a7fe23 100644
--- a/fsl/fsleyes/controls/melodicclassificationgrid.py
+++ b/fsl/fsleyes/controls/melodicclassificationgrid.py
@@ -129,6 +129,7 @@ class ComponentGrid(fslpanel.FSLEyesPanel):
 
         self.__deregisterCurrentOverlay()
         self.__grid.ClearGrid()
+        self.__grid.Refresh()
 
         overlay = self._displayCtx.getSelectedOverlay()
 
@@ -183,6 +184,8 @@ class ComponentGrid(fslpanel.FSLEyesPanel):
             tags.Bind(texttag.EVT_TTP_TAG_ADDED,   self.__onTagAdded)
             tags.Bind(texttag.EVT_TTP_TAG_REMOVED, self.__onTagRemoved)
 
+        self.__grid.Refresh()
+
         self.__refreshTagOptions()
         self.__refreshTags()
 
@@ -512,6 +515,8 @@ class LabelGrid(fslpanel.FSLEyesPanel):
             tags.Bind(texttag.EVT_TTP_TAG_REMOVED, self.__onTagRemoved)
             tags.Bind(texttag.EVT_TTP_TAG_SELECT,  self.__onTagSelect)
 
+        self.__grid.Refresh()
+
 
     def __refreshTags(self):
         """Re-populates the label-component mappings shown on the
diff --git a/fsl/fsleyes/controls/overlaydisplaypanel.py b/fsl/fsleyes/controls/overlaydisplaypanel.py
index afc1dd207..aa01a05c8 100644
--- a/fsl/fsleyes/controls/overlaydisplaypanel.py
+++ b/fsl/fsleyes/controls/overlaydisplaypanel.py
@@ -40,7 +40,7 @@ class OverlayDisplayPanel(fslpanel.FSLEyesPanel):
        :scale: 50%
        :align: center
 
-    An ``OverlayDisplayPanel`` uses a :class:`.WidgetGrid` to organise the
+    An ``OverlayDisplayPanel`` uses a :class:`.WidgetList` to organise the
     settings into two main sections:
 
       - Settings which are common across all overlays - these are defined
-- 
GitLab