From fe2cd1f828461b1b83e6158b5f23f7e2802fc4d9 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauld.mccarthy@gmail.com>
Date: Wed, 21 May 2014 17:02:35 +0100
Subject: [PATCH] lightboxpanel.py uses a bunch of SliceCanvas objects, and has
 rubbish performance. I'm about to start playing with a new idea, the
 LightBoxCanvas, which renders *all* slices onto a single canvas. What do you
 think? Why am i asking a git repository what it thinks?

---
 fsl/fslview/lightboxcanvas.py | 20 ++++++++++++++++
 fsl/fslview/lightboxpanel.py  | 44 ++++++++++++++++++++++++++---------
 fsl/fslview/slicecanvas.py    |  9 +++++++
 3 files changed, 62 insertions(+), 11 deletions(-)
 create mode 100644 fsl/fslview/lightboxcanvas.py

diff --git a/fsl/fslview/lightboxcanvas.py b/fsl/fslview/lightboxcanvas.py
new file mode 100644
index 000000000..fd85cfb91
--- /dev/null
+++ b/fsl/fslview/lightboxcanvas.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+#
+# lightboxcanvas.py - A wx.GLCanvas canvas whcih displays all slices from
+# a collection of 3D images.
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+
+import fsl.fslview.slicecanvas as slicecanvas
+
+
+class LightBoxCanvas(slicecanvas.SliceCanvas):
+
+    # I think this will work ...
+
+    def resize(self):
+        pass
+
+    def draw(self, ev):
+        pass
diff --git a/fsl/fslview/lightboxpanel.py b/fsl/fslview/lightboxpanel.py
index 7ec54f15d..630c149c2 100644
--- a/fsl/fslview/lightboxpanel.py
+++ b/fsl/fslview/lightboxpanel.py
@@ -7,11 +7,12 @@
 
 import wx
 
-import numpy                   as np
+import numpy                      as np
 
-import fsl.props               as props
-import fsl.data.fslimage       as fslimage
-import fsl.fslview.slicecanvas as slicecanvas
+import fsl.props                  as props
+import fsl.data.fslimage          as fslimage
+import fsl.fslview.slicecanvas    as slicecanvas
+import fsl.fslview.imagelistpanel as imagelistpanel
 
 class LightBoxPanel(wx.ScrolledWindow, props.HasProperties):
 
@@ -22,7 +23,6 @@ class LightBoxPanel(wx.ScrolledWindow, props.HasProperties):
     def __init__(self, parent, imageList):
 
         wx.ScrolledWindow.__init__(self, parent)
-        # wx.Panel.__init__(self, parent)
 
         if not isinstance(imageList, fslimage.ImageList):
             raise TypeError(
@@ -32,6 +32,13 @@ class LightBoxPanel(wx.ScrolledWindow, props.HasProperties):
         self.canvases  = []
         self.imageList = imageList
 
+        def refresh(*a):
+            self._createCanvases()
+
+        LightBoxPanel.sliceSpacing.addListener(self, 'refresh', refresh)
+        LightBoxPanel.sliceAxis   .addListener(self, 'refresh', refresh)
+
+        self._glContext = None
         self._createCanvases()
 
 
@@ -40,7 +47,6 @@ class LightBoxPanel(wx.ScrolledWindow, props.HasProperties):
         if self.sizer is not None:
             self.sizer.Clear(True)
 
-            
         axis      = int(self.sliceAxis)
         imgMin    = self.imageList.minBounds[axis]
         imgMax    = self.imageList.maxBounds[axis]
@@ -50,15 +56,17 @@ class LightBoxPanel(wx.ScrolledWindow, props.HasProperties):
         self.sizer    = wx.WrapSizer(wx.HORIZONTAL)
         self.canvases = []
 
+        print '{} slices to be drawn'.format(len(slicePoss))
+
         for i, pos in enumerate(slicePoss):
             
-            if i == 0: ctx = None
-            else:      ctx = self.canvases[0].context
-
             canvas = slicecanvas.SliceCanvas(self,
                                              self.imageList,
                                              zax=axis,
-                                             context=ctx)
+                                             context=self._glContext)
+
+            if self._glContext is None: self._glContext = canvas.context
+            
             canvas.zpos = pos
             canvas.SetMinSize((100, 100))
 
@@ -78,7 +86,21 @@ class LightBoxFrame(wx.Frame):
     def __init__(self, parent, imageList, title=None):
         
         wx.Frame.__init__(self, parent, title=title)
-        self.panel = LightBoxPanel(self, imageList)
+
+        
+
+        
+        self.mainPanel = LightBoxPanel( self, imageList)
+        self.propPanel = props.buildGUI(self, self.mainPanel)
+        self.listPanel = imagelistpanel.ImageListPanel(self, imageList)
+
+        self.sizer = wx.BoxSizer(wx.VERTICAL)
+
+        self.sizer.Add(self.propPanel, flag=wx.EXPAND)
+        self.sizer.Add(self.mainPanel, flag=wx.EXPAND, proportion=1)
+        self.sizer.Add(self.listPanel, flag=wx.EXPAND)
+
+        self.SetSizer(self.sizer)
         self.Layout()
 
 
diff --git a/fsl/fslview/slicecanvas.py b/fsl/fslview/slicecanvas.py
index 84b7f8b41..9eba4a2f4 100644
--- a/fsl/fslview/slicecanvas.py
+++ b/fsl/fslview/slicecanvas.py
@@ -305,8 +305,17 @@ class SliceCanvas(wxgl.GLCanvas):
         # so we know when to refresh the canvas.
         for image in self.imageList:
             try:
+
+                # TODO I could share GLImageData instances
+                # across different canvases which are
+                # displaying the image with the same axis
+                # orientation. Could store the GLImageData
+                # object with a geneic name, e.g.
+                # "GLImageData_0_1_2", where 0, 1, 2, are
+                # the screen x/y/z axes.
                 glData = image.getAttribute(self.name)
                 continue
+                
             except KeyError:
                 pass
                 
-- 
GitLab