diff --git a/fsl/fsleyes/gl/annotations.py b/fsl/fsleyes/gl/annotations.py index e73348e827acb1be0bf7bd7a78bf9d94ed007c2b..40aaccb3192efd91e114aad7cd19d167cc2a4492 100644 --- a/fsl/fsleyes/gl/annotations.py +++ b/fsl/fsleyes/gl/annotations.py @@ -31,10 +31,11 @@ import logging import numpy as np import OpenGL.GL as gl -import fsl.fsleyes.gl.globject as globject -import fsl.fsleyes.gl.routines as glroutines -import fsl.fsleyes.gl.textures as textures -import fsl.utils.transform as transform +import fsl.fsleyes.gl.globject as globject +import fsl.fsleyes.gl.routines as glroutines +import fsl.fsleyes.gl.resources as glresources +import fsl.fsleyes.gl.textures as textures +import fsl.utils.transform as transform log = logging.getLogger(__name__) @@ -525,9 +526,13 @@ class VoxelSelection(AnnotationObject): self.displayToVoxMat = displayToVoxMat self.voxToDisplayMat = voxToDisplayMat self.offsets = offsets + + texName = '{}_{}'.format(type(self).__name__, id(selection)) - self.texture = textures.SelectionTexture( - '{}_{}'.format(type(self).__name__, id(selection)), + self.texture = glresources.get( + texName, + textures.SelectionTexture, + texName, selection) @@ -535,7 +540,7 @@ class VoxelSelection(AnnotationObject): """Must be called when this ``VoxelSelection`` is no longer needed. Destroys the :class:`.SelectionTexture`. """ - self.texture.destroy() + glresources.delete(self.texture.getTextureName()) self.texture = None diff --git a/fsl/fsleyes/gl/resources.py b/fsl/fsleyes/gl/resources.py index 7df347ca5ec5e3303f5539490c0da153fc5d6f67..a80ef172a9a8407f2a62d33b519bd1ef0cb973fd 100644 --- a/fsl/fsleyes/gl/resources.py +++ b/fsl/fsleyes/gl/resources.py @@ -46,7 +46,7 @@ texture, and will increase its reference count:: interp=gl.GL_LINEAR) -.. note:: Here, we have used ``'myTexture'`` as the resource key in practice, +.. note:: Here, we have used ``'myTexture'`` as the resource key. In practice, you will need to use something that is guaranteed to be unique throughout your application. diff --git a/fsl/fsleyes/profiles/orthoeditprofile.py b/fsl/fsleyes/profiles/orthoeditprofile.py index 2b8caa54f51ce15dfb934908fcac2d17c35bd93d..b0ecc45786d36bad5d4c10810923d962b0dcf3b6 100644 --- a/fsl/fsleyes/profiles/orthoeditprofile.py +++ b/fsl/fsleyes/profiles/orthoeditprofile.py @@ -194,7 +194,9 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): self.__xcanvas = viewPanel.getXCanvas() self.__ycanvas = viewPanel.getYCanvas() self.__zcanvas = viewPanel.getZCanvas() - self.__selAnnotation = None + self.__xselAnnotation = None + self.__yselAnnotation = None + self.__zselAnnotation = None self.__selecting = False self.__currentOverlay = None @@ -239,14 +241,29 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): editor.removeListener('canRedo', self._name) editor.destroy() - if self.__selAnnotation is not None: - self.__selAnnotaiton.destroy() + xannot = self.__xcanvas.getAnnotations() + yannot = self.__ycanvas.getAnnotations() + zannot = self.__zcanvas.getAnnotations() + + if self.__xselAnnotation is not None: + xannot.dequeue(self.__xselAnnotation, hold=True) + self.__xselAnnotaiton.destroy() + + if self.__yselAnnotation is not None: + yannot.dequeue(self.__yselAnnotation, hold=True) + self.__yselAnnotaiton.destroy() + + if self.__zselAnnotation is not None: + zannot.dequeue(self.__zselAnnotation, hold=True) + self.__zselAnnotaiton.destroy() self.__editors = None self.__xcanvas = None self.__ycanvas = None self.__zcanvas = None - self.__selAnnotation = None + self.__xselAnnotation = None + self.__yselAnnotation = None + self.__zselAnnotation = None self.__currentOverlay = None orthoviewprofile.OrthoViewProfile.destroy(self) @@ -256,14 +273,26 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): """Destroys all :mod:`.annotations`, and calls :meth:`.OrthoViewProfile.deregister`. """ - if self.__selAnnotation is not None: - sa = self.__selAnnotation - self.__xcanvas.getAnnotations().dequeue(sa, hold=True) - self.__ycanvas.getAnnotations().dequeue(sa, hold=True) - self.__zcanvas.getAnnotations().dequeue(sa, hold=True) - sa.destroy() - - self.__selAnnotation = None + + xannot = self.__xcanvas.getAnnotations() + yannot = self.__ycanvas.getAnnotations() + zannot = self.__zcanvas.getAnnotations() + + if self.__xselAnnotation is not None: + xannot.dequeue(self.__xselAnnotation, hold=True) + self.__xselAnnotation.destroy() + + if self.__yselAnnotation is not None: + yannot.dequeue(self.__yselAnnotation, hold=True) + self.__yselAnnotation.destroy() + + if self.__zselAnnotation is not None: + zannot.dequeue(self.__zselAnnotation, hold=True) + self.__zselAnnotation.destroy() + + self.__xselAnnotation = None + self.__yselAnnotation = None + self.__zselAnnotation = None orthoviewprofile.OrthoViewProfile.deregister(self) @@ -359,7 +388,7 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): editor.getSelection().enableNotification('selection') self.__selectionChanged() - self.__selAnnotation.texture.refresh() + self.__xselAnnotation.texture.refresh() self._viewPanel.Refresh() @@ -374,12 +403,14 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): editor = self.__editors[self.__currentOverlay] + # See comment in undo method + # about disabling notification editor.getSelection().disableNotification('selection') editor.redo() editor.getSelection().enableNotification('selection') self.__selectionChanged() - self.__selAnnotation.texture.refresh() + self.__xselAnnotation.texture.refresh() self._viewPanel.Refresh() @@ -409,8 +440,14 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): Updates the :mod:`.annotations` colours accordingly. """ - if self.__selAnnotation is not None: - self.__selAnnotation.colour = self.selectionOverlayColour + if self.__xselAnnotation is not None: + self.__xselAnnotation.colour = self.selectionOverlayColour + + if self.__yselAnnotation is not None: + self.__yselAnnotation.colour = self.selectionOverlayColour + + if self.__zselAnnotation is not None: + self.__zselAnnotation.colour = self.selectionOverlayColour def __setFillValueLimits(self, overlay): @@ -483,14 +520,21 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): zannot = self.__zcanvas.getAnnotations() # Clear the selection annotation - if self.__selAnnotation is not None: - xannot.dequeue(self.__selAnnotation, hold=True) - yannot.dequeue(self.__selAnnotation, hold=True) - zannot.dequeue(self.__selAnnotation, hold=True) + if self.__xselAnnotation is not None: + xannot.dequeue(self.__xselAnnotation, hold=True) + self.__xselAnnotation.destroy() + + if self.__yselAnnotation is not None: + yannot.dequeue(self.__yselAnnotation, hold=True) + self.__yselAnnotation.destroy() - self.__selAnnotation.destroy() + if self.__zselAnnotation is not None: + zannot.dequeue(self.__zselAnnotation, hold=True) + self.__zselAnnotation.destroy() - self.__selAnnotation = None + self.__xselAnnotation = None + self.__yselAnnotation = None + self.__zselAnnotation = None # Remove property listeners from the # editor/selection instances associated @@ -604,15 +648,33 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): # Create a selection annotation and # queue it on the canvases for drawing - self.__selAnnotation = annotations.VoxelSelection( + self.__xselAnnotation = annotations.VoxelSelection( + self.__xcanvas.xax, + self.__xcanvas.yax, + editor.getSelection(), + opts.getTransform('pixdim', 'voxel'), + opts.getTransform('voxel', 'pixdim'), + colour=self.selectionOverlayColour) + + self.__yselAnnotation = annotations.VoxelSelection( + self.__ycanvas.xax, + self.__ycanvas.yax, editor.getSelection(), opts.getTransform('pixdim', 'voxel'), opts.getTransform('voxel', 'pixdim'), colour=self.selectionOverlayColour) + + self.__zselAnnotation = annotations.VoxelSelection( + self.__zcanvas.xax, + self.__zcanvas.yax, + editor.getSelection(), + opts.getTransform('pixdim', 'voxel'), + opts.getTransform('voxel', 'pixdim'), + colour=self.selectionOverlayColour) - xannot.obj(self.__selAnnotation, hold=True) - yannot.obj(self.__selAnnotation, hold=True) - zannot.obj(self.__selAnnotation, hold=True) + xannot.obj(self.__xselAnnotation, hold=True) + yannot.obj(self.__yselAnnotation, hold=True) + zannot.obj(self.__zselAnnotation, hold=True) self._viewPanel.Refresh() @@ -674,9 +736,11 @@ class OrthoEditProfile(orthoviewprofile.OrthoViewProfile): kwargs = {'colour' : self.selectionCursorColour, 'width' : 2} - cursors = [annotations.Rect((0, 0), 0, 0, **kwargs), - annotations.Rect((0, 0), 0, 0, **kwargs), - annotations.Rect((0, 0), 0, 0, **kwargs)] + cursors = [] + + for c in canvases: + r = annotations.Rect(c.xax, c.yax, (0, 0), 0, 0, **kwargs) + cursors.append(r) # If we are running in a low # performance mode, the cursor diff --git a/fsl/fsleyes/profiles/profilemap.py b/fsl/fsleyes/profiles/profilemap.py index 16c365c1a12a98a5934f6d7ac48c69db10faf070..bc73b0a80af58f55295d745950c5a01407650cb0 100644 --- a/fsl/fsleyes/profiles/profilemap.py +++ b/fsl/fsleyes/profiles/profilemap.py @@ -159,8 +159,8 @@ altHandlerMap = { (('desel', 'MiddleMouseDrag'), ('pan', 'LeftMouseDrag')), (('selint', 'MiddleMouseDrag'), ('pan', 'LeftMouseDrag')), - (('sel', 'MouseWheel'), ('chsize', 'MiddleMouse')), - (('desel', 'MouseWheel'), ('chsize', 'MiddleMouse')), + (('sel', 'MouseWheel'), ('chsize', 'MouseWheel')), + (('desel', 'MouseWheel'), ('chsize', 'MouseWheel')), (('selint', 'MouseWheel'), ('chthres', 'MouseWheel')), # Keyboard navigation works in the