diff --git a/fsl/data/fslimage.py b/fsl/data/fslimage.py index fdd64959057f4f8819778171f99410e040c5fc91..15d6c7c9afe8e7e1c90e90a7b0f953b8d6422985 100644 --- a/fsl/data/fslimage.py +++ b/fsl/data/fslimage.py @@ -305,8 +305,13 @@ class ImageList(object): Updates the xyz bounds. """ - minBounds = 3 * [ sys.float_info.max] - maxBounds = 3 * [-sys.float_info.max] + if len(self._items) == 0: + minBounds = [0.0, 0.0, 0.0] + maxBounds = [0.0, 0.0, 0.0] + + else: + minBounds = 3 * [ sys.float_info.max] + maxBounds = 3 * [-sys.float_info.max] for img in self._items: diff --git a/fsl/fslview/lightboxcanvas.py b/fsl/fslview/lightboxcanvas.py index 3e3e5f944005c52341cdbfe50ee7d373c9d58d72..f8b18baf1c872b8c751ec07f99bd051caa7d6ddc 100644 --- a/fsl/fslview/lightboxcanvas.py +++ b/fsl/fslview/lightboxcanvas.py @@ -62,12 +62,10 @@ class LightBoxCanvas(slicecanvas.SliceCanvas): position the slice on the canvas. """ - self._updateScrollBar() - # recalculate image bounds, and create # GL data for any newly added images. slicecanvas.SliceCanvas._imageListChanged(self) - + # calculate the locations, in real world coordinates, # of all slices to be displayed on the canvas sliceLocs = np.arange( @@ -77,7 +75,7 @@ class LightBoxCanvas(slicecanvas.SliceCanvas): self._nslices = len(sliceLocs) self._nrows = int(np.ceil(self._nslices / float(self._ncols))) - + self._sliceIdxs = [] self._transforms = [] @@ -97,6 +95,11 @@ class LightBoxCanvas(slicecanvas.SliceCanvas): self._transforms[-1].append(xform) self._sliceIdxs[ -1].append(imgZi) + # update the scrollbar (if there is one), + # as the image bounds and hence the number + # of slices may have changed + self._updateScrollBar() + def _updateScrollBar(self): """ @@ -106,12 +109,17 @@ class LightBoxCanvas(slicecanvas.SliceCanvas): """ if self._scrollbar is None: return + + if len(self.imageList) == 0: + self._scrollbar.SetScrollbar(0, 99, 1, 99, True) + return screenSize = self.GetClientSize() sliceRatio = abs(self.xmax - self.xmin) / abs(self.ymax - self.ymin) - + sliceWidth = screenSize.width / float(self._ncols) sliceHeight = sliceWidth * sliceRatio + rowsOnScreen = int(np.floor(screenSize.height / sliceHeight)) oldPos = self._scrollbar.GetThumbPosition() @@ -261,38 +269,68 @@ class LightBoxCanvas(slicecanvas.SliceCanvas): self.SwapBuffers() -class LightBoxFrame(wx.Frame): + +class LightBoxPanel(wx.Panel): """ - Convenience class for displaying a LightBoxPanel in a standalone window. + A LightBoxCanvas with a scrollbar and mouse-scrolling behaviour. """ - def __init__(self, parent, imageList, title=None): + def __init__(self, parent, *args, **kwargs): + """ + Accepts the same parameters as the LightBoxCanvas constructor, + although if you pass in a scrollbar, it will be ignored. + """ - wx.Frame.__init__(self, parent, title=title) + wx.Panel.__init__(self, parent) - import fsl.fslview.imagelistpanel as imagelistpanel + self.scrollbar = wx.ScrollBar(self, style=wx.SB_VERTICAL) + + kwargs['scrollbar'] = self.scrollbar + + self.canvas = LightBoxCanvas(self, *args, **kwargs) + + self.sizer = wx.BoxSizer(wx.HORIZONTAL) + self.SetSizer(self.sizer) + self.sizer.Add(self.canvas, flag=wx.EXPAND, proportion=1) + self.sizer.Add(self.scrollbar, flag=wx.EXPAND) - self.canvasPanel = wx.Panel(self) - self.listPanel = imagelistpanel.ImageListPanel(self, imageList) + def scrollOnMouse(ev): + wheelDir = ev.GetWheelRotation() - self.scrollbar = wx.ScrollBar( self.canvasPanel, style=wx.SB_VERTICAL) - self.mainPanel = LightBoxCanvas(self.canvasPanel, imageList, zax=1, - scrollbar=self.scrollbar, - sliceSpacing=0.5, - ncols=10) + if wheelDir > 0: wheelDir = -1 + elif wheelDir < 0: wheelDir = 1 - self.canvasSizer = wx.BoxSizer(wx.HORIZONTAL) - self.canvasPanel.SetSizer(self.canvasSizer) + curPos = self.scrollbar.GetThumbPosition() + self.scrollbar.SetThumbPosition(curPos + wheelDir) + self.canvas._draw(None) + + self.Bind(wx.EVT_MOUSEWHEEL, scrollOnMouse) + + self.Layout() + + +class LightBoxFrame(wx.Frame): + """ + Convenience class for displaying a LightBoxPanel in a standalone window. + """ + + def __init__(self, parent, imageList, title=None): + + wx.Frame.__init__(self, parent, title=title) + + import fsl.fslview.imagelistpanel as imagelistpanel - self.canvasSizer.Add(self.mainPanel, flag=wx.EXPAND, proportion=1) - self.canvasSizer.Add(self.scrollbar, flag=wx.EXPAND) + self.listPanel = imagelistpanel.ImageListPanel(self, imageList) + self.mainPanel = LightBoxPanel(self, imageList, zax=1, + sliceSpacing=0.5, + ncols=10) self.sizer = wx.BoxSizer(wx.VERTICAL) - self.sizer.Add(self.canvasPanel, flag=wx.EXPAND, proportion=1) - self.sizer.Add(self.listPanel, 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 99f904c6bc283e298deb2bbe4cde3c9194c31903..faba5a56773eeee124587cd2b34dd3d84401a784 100644 --- a/fsl/fslview/slicecanvas.py +++ b/fsl/fslview/slicecanvas.py @@ -509,6 +509,15 @@ class SliceCanvas(wxgl.GLCanvas): x, y, width, height = bbox + # If there are no images to be displayed, + # the dimension bounds will all be 0, + # which causes glOrtho to throw an error. + if len(self.imageList) == 0: + xmin = -1.0 + xmax = 1.0 + ymin = -1.0 + ymax = 1.0 + # set up 2D orthographic drawing gl.glViewport(x, y, width, height) gl.glMatrixMode(gl.GL_PROJECTION)