diff --git a/fsl/fslview/orthopanel.py b/fsl/fslview/orthopanel.py index 9c77739528b3caabd15ffacaf99c9f6c371215fa..52b7921eef3d5d6ebdffacf354e7048f1f5183e4 100644 --- a/fsl/fslview/orthopanel.py +++ b/fsl/fslview/orthopanel.py @@ -16,39 +16,62 @@ import fsl.fslview.slicecanvas as slicecanvas class OrthoPanel(wx.Panel, props.HasProperties): + # Properties which toggle display of each of + # the three canvases, and the cursors on them. showXCanvas = props.Boolean(default=True) showYCanvas = props.Boolean(default=True) showZCanvas = props.Boolean(default=True) showCursor = props.Boolean(default=True) + # Properties which set the current displayed + # position (in real world coordinates) xpos = props.Double(clamped=True) ypos = props.Double(clamped=True) zpos = props.Double(clamped=True) - xCanvasZoom = props.Double(minval=1.0, - maxval=20.0, - default=1.0, - clamped=True) - yCanvasZoom = props.Double(minval=1.0, - maxval=20.0, - default=1.0, - clamped=True) - zCanvasZoom = props.Double(minval=1.0, - maxval=20.0, - default=1.0, - clamped=True) - - - def _getAxisVal(self, axis): - if axis == 0: return self.xpos - elif axis == 1: return self.ypos - elif axis == 2: return self.zpos + # Properties which set the current zoom + # factor on each of the canvases + xzoom = props.Double(minval=1.0, + maxval=10.0, + default=1.0, + clamped=True) + yzoom = props.Double(minval=1.0, + maxval=10.0, + default=1.0, + clamped=True) + zzoom = props.Double(minval=1.0, + maxval=10.0, + default=1.0, + clamped=True) + + + _view = props.HGroup(( + props.VGroup(('showCursor', + 'showXCanvas', + 'showYCanvas', + 'showZCanvas')), + props.VGroup(('xpos', 'ypos', 'zpos')), + props.VGroup(('xzoom', 'yzoom', 'zzoom')) + )) + + _labels = { + 'showCursor' : 'Show cursor', + 'showXCanvas' : 'Show X canvas', + 'showYCanvas' : 'Show Y canvas', + 'showZCanvas' : 'Show Z canvas', + 'xzoom' : 'X zoom', + 'yzoom' : 'Y zoom', + 'zzoom' : 'Z zoom', + 'xpos' : 'X position', + 'ypos' : 'Y position', + 'zpos' : 'Z position' + } + - def __init__(self, parent, imageList): """ Creates three SliceCanvas objects, each displaying the images - in the given image list along a different axis. + in the given image list along a different axis. """ if not isinstance(imageList, fslimage.ImageList): @@ -103,13 +126,17 @@ class OrthoPanel(wx.Panel, props.HasProperties): def _configPosListeners(self): + """ + Configures listeners on the xpos/ypos/zpos properties - when they + are changed, the displayed position is changed. + """ def moveX(ctx, value, valid): - self._setPosition(value, self.ypos, self.zpos) + self.setPosition(value, self.ypos, self.zpos) def moveY(ctx, value, valid): - self._setPosition(self.xpos, value, self.zpos) + self.setPosition(self.xpos, value, self.zpos) def moveZ(ctx, value, valid): - self._setPosition(self.xpos, self.ypos, value) + self.setPosition(self.xpos, self.ypos, value) self.addListener('xpos', self.name, moveX) self.addListener('ypos', self.name, moveY) @@ -117,6 +144,10 @@ class OrthoPanel(wx.Panel, props.HasProperties): def _configShowListeners(self): + """ + Configures listeners on the show* properties, so they can + be used to toggle visibility of various things. + """ def showCursor(ctx, value, valid): self.xcanvas.showCursor = value self.ycanvas.showCursor = value @@ -139,10 +170,15 @@ class OrthoPanel(wx.Panel, props.HasProperties): def _configZoomListeners(self): - + """ + Configures listeners on the x/y/zzoom properties so when + they are changed, the zoom factor on the corresponding canvas + is changed. + """ def zoom(canvas, xax, yax, value): value = 1.0 / value + xlen = value * abs(self.imageList.maxBounds[xax] - self.imageList.minBounds[xax]) ylen = value * abs(self.imageList.maxBounds[yax] - @@ -152,8 +188,8 @@ class OrthoPanel(wx.Panel, props.HasProperties): xcentre = self.imageList.minBounds[xax] + 0.5 * xlen ycentre = self.imageList.minBounds[yax] + 0.5 * ylen else: - xcentre = self._getAxisVal(xax) - ycentre = self._getAxisVal(yax) + xcentre = canvas.xmin + (canvas.xmax - canvas.xmin) / 2.0 + ycentre = canvas.ymin + (canvas.ymax - canvas.ymin) / 2.0 canvas.xmin = xcentre - 0.5 * xlen canvas.xmax = xcentre + 0.5 * xlen @@ -164,13 +200,15 @@ class OrthoPanel(wx.Panel, props.HasProperties): def yzoom(ctx, value, valid): zoom(self.ycanvas, 0, 2, value) def zzoom(ctx, value, valid): zoom(self.zcanvas, 0, 1, value) - self.addListener('xCanvasZoom', self.name, xzoom) - self.addListener('yCanvasZoom', self.name, yzoom) - self.addListener('zCanvasZoom', self.name, zzoom) + self.addListener('xzoom', self.name, xzoom) + self.addListener('yzoom', self.name, yzoom) + self.addListener('zzoom', self.name, zzoom) def _updateImageBounds(self): """ + Called when the list of displayed images changes. Updates the + minimum/maximum bounds on the x/y/zpos properties. """ xmin = self.imageList.minBounds[0] @@ -195,6 +233,11 @@ class OrthoPanel(wx.Panel, props.HasProperties): def _shiftCanvas(self, canvas, newx, newy): + """ + Called when the position has changed, and zooming is enabled on + the given canvas. Updates the display bounds on the canvas so that + the current position is within them. + """ if newx >= canvas.xmin and \ newx <= canvas.xmax and \ @@ -243,13 +286,10 @@ class OrthoPanel(wx.Panel, props.HasProperties): canvas.ymax = newymax - def _setPosition(self, xpos, ypos, zpos): + def setPosition(self, xpos, ypos, zpos): """ - Called on mouse movement and left clicks. The currently - displayed slices and cursor positions on each of the - canvases follow mouse clicks and drags, and an - EVT_LOCATION_EVENT is emitted when the cursor position - changes. + Sets the currently displayed x/y/z position (in real world + coordinates). """ self.xpos = xpos @@ -268,18 +308,16 @@ class OrthoPanel(wx.Panel, props.HasProperties): self.zcanvas.ypos = ypos self.zcanvas.zpos = zpos - if self.xCanvasZoom != 1: self._shiftCanvas(self.xcanvas, ypos, zpos) - if self.yCanvasZoom != 1: self._shiftCanvas(self.ycanvas, xpos, zpos) - if self.zCanvasZoom != 1: self._shiftCanvas(self.zcanvas, xpos, ypos) + if self.xzoom != 1: self._shiftCanvas(self.xcanvas, ypos, zpos) + if self.yzoom != 1: self._shiftCanvas(self.ycanvas, xpos, zpos) + if self.zzoom != 1: self._shiftCanvas(self.zcanvas, xpos, ypos) def _onMouseEvent(self, ev): """ Called on mouse movement and left clicks. The currently displayed slices and cursor positions on each of the - canvases follow mouse clicks and drags, and an - EVT_LOCATION_EVENT is emitted when the cursor position - changes. + canvases follow mouse clicks and drags. """ if not ev.LeftIsDown(): return @@ -294,9 +332,9 @@ class OrthoPanel(wx.Panel, props.HasProperties): xpos = source.canvasToWorldX(mx) ypos = source.canvasToWorldY(my) - if source == self.xcanvas: self._setPosition(self.xpos, xpos, ypos) - elif source == self.ycanvas: self._setPosition(xpos, self.ypos, ypos) - elif source == self.zcanvas: self._setPosition(xpos, ypos, self.zpos) + if source == self.xcanvas: self.setPosition(self.xpos, xpos, ypos) + elif source == self.ycanvas: self.setPosition(xpos, self.ypos, ypos) + elif source == self.zcanvas: self.setPosition(xpos, ypos, self.zpos) class OrthoFrame(wx.Frame):