Commit 13f819f768cfbf96681f14da0f5f253878c12f16
1 parent
f7b5fc4d
Exists in
interactor_style
Created a new interactor style to handle Window level & width
Showing
2 changed files
with
82 additions
and
43 deletions
Show diff stats
invesalius/data/styles.py
| @@ -23,17 +23,39 @@ from wx.lib.pubsub import pub as Publisher | @@ -23,17 +23,39 @@ from wx.lib.pubsub import pub as Publisher | ||
| 23 | 23 | ||
| 24 | import constants as const | 24 | import constants as const |
| 25 | 25 | ||
| 26 | -class ZoomInteractorStyle(vtk.vtkInteractorStyleImage): | 26 | +class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage): |
| 27 | + def __init__(self): | ||
| 28 | + self.right_pressed = False | ||
| 29 | + self.left_pressed = False | ||
| 30 | + | ||
| 31 | + self.AddObserver("LeftButtonPressEvent", self.OnPressLeftButton) | ||
| 32 | + self.AddObserver("LeftButtonReleaseEvent", self.OnReleaseLeftButton) | ||
| 33 | + | ||
| 34 | + self.AddObserver("RightButtonPressEvent",self.OnPressRightButton) | ||
| 35 | + self.AddObserver("RightButtonReleaseEvent", self.OnReleaseRightButton) | ||
| 36 | + | ||
| 37 | + def OnPressLeftButton(self, evt, obj): | ||
| 38 | + self.left_pressed = True | ||
| 39 | + | ||
| 40 | + def OnReleaseLeftButton(self, evt, obj): | ||
| 41 | + self.left_pressed = False | ||
| 42 | + | ||
| 43 | + def OnPressRightButton(self, evt, obj): | ||
| 44 | + self.right_pressed = True | ||
| 45 | + | ||
| 46 | + def OnReleaseRightButton(self, evt, obj): | ||
| 47 | + self.right_pressed = False | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +class ZoomInteractorStyle(BaseImageInteractorStyle): | ||
| 27 | """ | 51 | """ |
| 28 | Interactor style responsible for zoom the camera. | 52 | Interactor style responsible for zoom the camera. |
| 29 | """ | 53 | """ |
| 30 | def __init__(self): | 54 | def __init__(self): |
| 31 | - self.right_pressed = False | ||
| 32 | - | 55 | + BaseImageInteractorStyle.__init__(self) |
| 33 | # Zoom using right button | 56 | # Zoom using right button |
| 34 | self.AddObserver("RightButtonPressEvent",self.OnZoomRightClick) | 57 | self.AddObserver("RightButtonPressEvent",self.OnZoomRightClick) |
| 35 | self.AddObserver("MouseMoveEvent", self.OnZoomRightMove) | 58 | self.AddObserver("MouseMoveEvent", self.OnZoomRightMove) |
| 36 | - self.AddObserver("RightButtonReleaseEvent", self.OnZoomRightRelease) | ||
| 37 | 59 | ||
| 38 | def OnZoomRightMove(self, evt, obj): | 60 | def OnZoomRightMove(self, evt, obj): |
| 39 | if (self.right_pressed): | 61 | if (self.right_pressed): |
| @@ -41,11 +63,8 @@ class ZoomInteractorStyle(vtk.vtkInteractorStyleImage): | @@ -41,11 +63,8 @@ class ZoomInteractorStyle(vtk.vtkInteractorStyleImage): | ||
| 41 | evt.OnRightButtonDown() | 63 | evt.OnRightButtonDown() |
| 42 | 64 | ||
| 43 | def OnZoomRightClick(self, evt, obj): | 65 | def OnZoomRightClick(self, evt, obj): |
| 44 | - self.right_pressed = 1 | ||
| 45 | evt.StartDolly() | 66 | evt.StartDolly() |
| 46 | 67 | ||
| 47 | - def OnZoomRightRelease(self, evt, obj): | ||
| 48 | - self.right_pressed = False | ||
| 49 | 68 | ||
| 50 | class CrossInteractorStyle(ZoomInteractorStyle): | 69 | class CrossInteractorStyle(ZoomInteractorStyle): |
| 51 | """ | 70 | """ |
| @@ -58,7 +77,6 @@ class CrossInteractorStyle(ZoomInteractorStyle): | @@ -58,7 +77,6 @@ class CrossInteractorStyle(ZoomInteractorStyle): | ||
| 58 | self.slice_actor = slice_data.actor | 77 | self.slice_actor = slice_data.actor |
| 59 | self.slice_data = slice_data | 78 | self.slice_data = slice_data |
| 60 | 79 | ||
| 61 | - self.left_pressed = False | ||
| 62 | self.picker = vtk.vtkWorldPointPicker() | 80 | self.picker = vtk.vtkWorldPointPicker() |
| 63 | 81 | ||
| 64 | self.AddObserver("MouseMoveEvent", self.OnCrossMove) | 82 | self.AddObserver("MouseMoveEvent", self.OnCrossMove) |
| @@ -66,7 +84,6 @@ class CrossInteractorStyle(ZoomInteractorStyle): | @@ -66,7 +84,6 @@ class CrossInteractorStyle(ZoomInteractorStyle): | ||
| 66 | self.AddObserver("LeftButtonReleaseEvent", self.OnReleaseLeftButton) | 84 | self.AddObserver("LeftButtonReleaseEvent", self.OnReleaseLeftButton) |
| 67 | 85 | ||
| 68 | def OnCrossMouseClick(self, obj, evt): | 86 | def OnCrossMouseClick(self, obj, evt): |
| 69 | - self.left_pressed = True | ||
| 70 | iren = obj.GetInteractor() | 87 | iren = obj.GetInteractor() |
| 71 | self.ChangeCrossPosition(iren) | 88 | self.ChangeCrossPosition(iren) |
| 72 | 89 | ||
| @@ -77,9 +94,6 @@ class CrossInteractorStyle(ZoomInteractorStyle): | @@ -77,9 +94,6 @@ class CrossInteractorStyle(ZoomInteractorStyle): | ||
| 77 | iren = obj.GetInteractor() | 94 | iren = obj.GetInteractor() |
| 78 | self.ChangeCrossPosition(iren) | 95 | self.ChangeCrossPosition(iren) |
| 79 | 96 | ||
| 80 | - def OnReleaseLeftButton(self, obj, evt): | ||
| 81 | - self.left_pressed = False | ||
| 82 | - | ||
| 83 | def ChangeCrossPosition(self, iren): | 97 | def ChangeCrossPosition(self, iren): |
| 84 | mouse_x, mouse_y = iren.GetEventPosition() | 98 | mouse_x, mouse_y = iren.GetEventPosition() |
| 85 | ren = iren.GetRenderWindow().GetRenderers().GetFirstRenderer() | 99 | ren = iren.GetRenderWindow().GetRenderers().GetFirstRenderer() |
| @@ -158,6 +172,50 @@ class CrossInteractorStyle(ZoomInteractorStyle): | @@ -158,6 +172,50 @@ class CrossInteractorStyle(ZoomInteractorStyle): | ||
| 158 | coord[0]) | 172 | coord[0]) |
| 159 | 173 | ||
| 160 | 174 | ||
| 175 | +class WWWLInteractorStyle(ZoomInteractorStyle): | ||
| 176 | + """ | ||
| 177 | + Interactor style responsible for Window Level & Width functionality. | ||
| 178 | + """ | ||
| 179 | + def __init__(self, ww, wl): | ||
| 180 | + ZoomInteractorStyle.__init__(self) | ||
| 181 | + | ||
| 182 | + self.last_x = 0 | ||
| 183 | + self.last_y = 0 | ||
| 184 | + | ||
| 185 | + self.acum_achange_window = ww | ||
| 186 | + self.acum_achange_level = wl | ||
| 187 | + | ||
| 188 | + self.AddObserver("MouseMoveEvent", self.OnWindowLevelMove) | ||
| 189 | + self.AddObserver("LeftButtonPressEvent", self.OnWindowLevelClick) | ||
| 190 | + | ||
| 191 | + def OnWindowLevelMove(self, obj, evt): | ||
| 192 | + if (self.left_pressed): | ||
| 193 | + iren = obj.GetInteractor() | ||
| 194 | + mouse_x, mouse_y = iren.GetEventPosition() | ||
| 195 | + self.acum_achange_window += mouse_x - self.last_x | ||
| 196 | + self.acum_achange_level += mouse_y - self.last_y | ||
| 197 | + self.last_x, self.last_y = mouse_x, mouse_y | ||
| 198 | + | ||
| 199 | + Publisher.sendMessage('Bright and contrast adjustment image', | ||
| 200 | + (self.acum_achange_window, self.acum_achange_level)) | ||
| 201 | + | ||
| 202 | + #self.SetWLText(self.acum_achange_level, | ||
| 203 | + # self.acum_achange_window) | ||
| 204 | + | ||
| 205 | + const.WINDOW_LEVEL['Manual'] = (self.acum_achange_window,\ | ||
| 206 | + self.acum_achange_level) | ||
| 207 | + Publisher.sendMessage('Check window and level other') | ||
| 208 | + Publisher.sendMessage('Update window level value',(self.acum_achange_window, | ||
| 209 | + self.acum_achange_level)) | ||
| 210 | + #Necessary update the slice plane in the volume case exists | ||
| 211 | + Publisher.sendMessage('Update slice viewer') | ||
| 212 | + Publisher.sendMessage('Render volume viewer') | ||
| 213 | + | ||
| 214 | + def OnWindowLevelClick(self, obj, evt): | ||
| 215 | + iren = obj.GetInteractor() | ||
| 216 | + self.last_x, self.last_y = iren.GetLastEventPosition() | ||
| 217 | + | ||
| 218 | + | ||
| 161 | class ViewerStyle: | 219 | class ViewerStyle: |
| 162 | def __init__(self): | 220 | def __init__(self): |
| 163 | self.interactor = None | 221 | self.interactor = None |
invesalius/data/viewer_slice.py
| @@ -193,6 +193,18 @@ class Viewer(wx.Panel): | @@ -193,6 +193,18 @@ class Viewer(wx.Panel): | ||
| 193 | 193 | ||
| 194 | self.__set_cross_visibility(1) | 194 | self.__set_cross_visibility(1) |
| 195 | Publisher.sendMessage('Activate ball reference') | 195 | Publisher.sendMessage('Activate ball reference') |
| 196 | + elif state == const.STATE_WL: | ||
| 197 | + self.on_wl = True | ||
| 198 | + self.wl_text.Show() | ||
| 199 | + | ||
| 200 | + ww = sl.Slice().window_width | ||
| 201 | + wl = sl.Slice().window_level | ||
| 202 | + | ||
| 203 | + style = styles.WWWLInteractorStyle(ww, wl) | ||
| 204 | + self.style = style | ||
| 205 | + self.interactor.SetInteractorStyle(style) | ||
| 206 | + self.interactor.Render() | ||
| 207 | + | ||
| 196 | else: | 208 | else: |
| 197 | self.state = state | 209 | self.state = state |
| 198 | action = { | 210 | action = { |
| @@ -227,11 +239,6 @@ class Viewer(wx.Panel): | @@ -227,11 +239,6 @@ class Viewer(wx.Panel): | ||
| 227 | "MouseMoveEvent": self.OnChangeSliceMove, | 239 | "MouseMoveEvent": self.OnChangeSliceMove, |
| 228 | "LeftButtonPressEvent": self.OnChangeSliceClick, | 240 | "LeftButtonPressEvent": self.OnChangeSliceClick, |
| 229 | }, | 241 | }, |
| 230 | - const.STATE_WL: | ||
| 231 | - { | ||
| 232 | - "MouseMoveEvent": self.OnWindowLevelMove, | ||
| 233 | - "LeftButtonPressEvent": self.OnWindowLevelClick, | ||
| 234 | - }, | ||
| 235 | const.STATE_DEFAULT: | 242 | const.STATE_DEFAULT: |
| 236 | { | 243 | { |
| 237 | }, | 244 | }, |
| @@ -353,32 +360,6 @@ class Viewer(wx.Panel): | @@ -353,32 +360,6 @@ class Viewer(wx.Panel): | ||
| 353 | self.left_pressed = 0 | 360 | self.left_pressed = 0 |
| 354 | Publisher.sendMessage('Update slice viewer') | 361 | Publisher.sendMessage('Update slice viewer') |
| 355 | 362 | ||
| 356 | - def OnWindowLevelMove(self, evt, obj): | ||
| 357 | - if (self.left_pressed): | ||
| 358 | - position = self.interactor.GetLastEventPosition() | ||
| 359 | - mouse_x, mouse_y = self.interactor.GetEventPosition() | ||
| 360 | - self.acum_achange_window += mouse_x - self.last_x | ||
| 361 | - self.acum_achange_level += mouse_y - self.last_y | ||
| 362 | - self.last_x, self.last_y = mouse_x, mouse_y | ||
| 363 | - | ||
| 364 | - Publisher.sendMessage('Bright and contrast adjustment image', | ||
| 365 | - (self.acum_achange_window, self.acum_achange_level)) | ||
| 366 | - | ||
| 367 | - #self.SetWLText(self.acum_achange_level, | ||
| 368 | - # self.acum_achange_window) | ||
| 369 | - | ||
| 370 | - const.WINDOW_LEVEL['Manual'] = (self.acum_achange_window,\ | ||
| 371 | - self.acum_achange_level) | ||
| 372 | - Publisher.sendMessage('Check window and level other') | ||
| 373 | - Publisher.sendMessage('Update window level value',(self.acum_achange_window, | ||
| 374 | - self.acum_achange_level)) | ||
| 375 | - #Necessary update the slice plane in the volume case exists | ||
| 376 | - Publisher.sendMessage('Update slice viewer') | ||
| 377 | - Publisher.sendMessage('Render volume viewer') | ||
| 378 | - | ||
| 379 | - def OnWindowLevelClick(self, evt, obj): | ||
| 380 | - self.last_x, self.last_y = self.interactor.GetLastEventPosition() | ||
| 381 | - | ||
| 382 | def UpdateWindowLevelValue(self, pubsub_evt): | 363 | def UpdateWindowLevelValue(self, pubsub_evt): |
| 383 | window, level = pubsub_evt.data | 364 | window, level = pubsub_evt.data |
| 384 | self.acum_achange_window, self.acum_achange_level = (window, level) | 365 | self.acum_achange_window, self.acum_achange_level = (window, level) |