Commit 66fa5cd60953006d0c96842289ec66d8044f07db
1 parent
c6e7c193
Exists in
master
and in
68 other branches
ADD: Inserted cross that follows left mouse clicks on slices 2D
Showing
6 changed files
with
287 additions
and
73 deletions
Show diff stats
invesalius/constants.py
... | ... | @@ -78,3 +78,10 @@ WINDOW_LEVEL = ({"Abdomen":(350,50), |
78 | 78 | "Vasculature - Hard":(240,80), |
79 | 79 | "Vasculature - Soft":(650,160) |
80 | 80 | }) |
81 | + | |
82 | +ORIENTATION_COLOUR = {'AXIAL': (1,0,0), # Red | |
83 | + 'CORONAL': (0,1,0), # Green | |
84 | + 'SAGITAL': (0,0,1)} # Blue | |
85 | +CAM_POSITION = {"AXIAL":(0, 0, 1), "CORONAL":(0, -1, 0), "SAGITAL":(1, 0, 0)} | |
86 | +CAM_VIEW_UP = {"AXIAL":(0, 1, 0), "CORONAL":(0, 0, 1), "SAGITAL":(0, 0, 1)} | |
87 | + | ... | ... |
invesalius/data/slice_.py
... | ... | @@ -28,6 +28,8 @@ class Slice(object): |
28 | 28 | ps.Publisher().subscribe(self.OnChangeCurrentMask, 'Change mask selected') |
29 | 29 | ps.Publisher().subscribe(self.CreateSurfaceFromIndex, |
30 | 30 | 'Create surface from index') |
31 | + ps.Publisher().subscribe(self.UpdateCursorPosition, | |
32 | + 'Update cursor position in slice') | |
31 | 33 | |
32 | 34 | def CreateSurfaceFromIndex(self, pubsub_evt): |
33 | 35 | mask_index = pubsub_evt.data |
... | ... | @@ -116,7 +118,46 @@ class Slice(object): |
116 | 118 | blend_imagedata.SetInput(1, imagedata_mask) |
117 | 119 | blend_imagedata.SetBlendModeToNormal() |
118 | 120 | blend_imagedata.GetOutput().ReleaseDataFlagOn() |
119 | - self.blend_imagedata = blend_imagedata | |
121 | + #self.blend_imagedata = blend_imagedata | |
122 | + | |
123 | + | |
124 | + #blend_imagedata.GetExtent() | |
125 | + | |
126 | + # global values | |
127 | + CURSOR_X = 0 # SAGITAL | |
128 | + CURSOR_Y = 0 # CORONAL | |
129 | + CURSOR_Z = 0 # AXIAL | |
130 | + | |
131 | + CURSOR_VALUE = 4095 | |
132 | + CURSOR_RADIUS = 1000 | |
133 | + | |
134 | + cross = vtk.vtkImageCursor3D() | |
135 | + cross.GetOutput().ReleaseDataFlagOn() | |
136 | + cross.SetInput(blend_imagedata.GetOutput()) | |
137 | + cross.SetCursorPosition(CURSOR_X, CURSOR_Y, CURSOR_Z) | |
138 | + cross.SetCursorValue(CURSOR_VALUE) | |
139 | + cross.SetCursorRadius(CURSOR_RADIUS) | |
140 | + cross.Modified() | |
141 | + self.cross = cross | |
142 | + | |
143 | + cast = vtk.vtkImageCast() | |
144 | + cast.SetInput(cross.GetOutput()) | |
145 | + cast.GetOutput().SetUpdateExtentToWholeExtent() | |
146 | + cast.SetOutputScalarTypeToUnsignedChar() | |
147 | + cast.Update() | |
148 | + | |
149 | + self.blend_imagedata = cast | |
150 | + | |
151 | + | |
152 | + def UpdateCursorPosition(self, pubsub_evt): | |
153 | + | |
154 | + new_pos = pubsub_evt.data | |
155 | + self.cross.SetCursorPosition(new_pos) | |
156 | + self.cross.Modified() | |
157 | + self.blend_imagedata.Update() | |
158 | + ps.Publisher().sendMessage('Update slice viewer', None) | |
159 | + | |
160 | + | |
120 | 161 | |
121 | 162 | def __create_background(self, imagedata): |
122 | 163 | ... | ... |
invesalius/data/viewer_slice.py
... | ... | @@ -24,35 +24,49 @@ import wx |
24 | 24 | import wx.lib.pubsub as ps |
25 | 25 | |
26 | 26 | import data.slice_ as sl |
27 | - | |
27 | +import constants as const | |
28 | 28 | import project |
29 | 29 | |
30 | 30 | class Viewer(wx.Panel): |
31 | 31 | |
32 | 32 | def __init__(self, prnt, orientation='AXIAL'): |
33 | 33 | wx.Panel.__init__(self, prnt, size=wx.Size(320, 300)) |
34 | - | |
34 | + | |
35 | + colour = [255*c for c in const.ORIENTATION_COLOUR[orientation]] | |
36 | + self.SetBackgroundColour(colour) | |
37 | + | |
35 | 38 | self.__init_gui() |
36 | - self.__config_interactor() | |
37 | 39 | |
38 | 40 | self.orientation = orientation |
39 | 41 | self.slice_number = 0 |
40 | 42 | |
43 | + # Interactor aditional style | |
44 | + self.mode = 'DEFAULT' | |
45 | + self.mouse_pressed = 0 | |
46 | + | |
47 | + # VTK pipeline and actors | |
48 | + self.__config_interactor() | |
49 | + self.pick = vtk.vtkCellPicker() | |
50 | + #self.cursor = | |
51 | + | |
41 | 52 | self.__bind_events() |
42 | 53 | self.__bind_events_wx() |
43 | 54 | |
44 | 55 | def __init_gui(self): |
56 | + | |
45 | 57 | interactor = wxVTKRenderWindowInteractor(self, -1, size=self.GetSize()) |
46 | 58 | |
47 | 59 | scroll = wx.ScrollBar(self, -1, style=wx.SB_VERTICAL) |
48 | 60 | self.scroll = scroll |
49 | 61 | |
50 | 62 | sizer = wx.BoxSizer(wx.HORIZONTAL) |
51 | - self.SetSizer(sizer) | |
52 | - | |
53 | - sizer.Add(scroll, 0, wx.EXPAND|wx.GROW) | |
54 | 63 | sizer.Add(interactor, 1, wx.EXPAND|wx.GROW) |
55 | - sizer.Fit(self) | |
64 | + | |
65 | + background_sizer = wx.BoxSizer(wx.HORIZONTAL) | |
66 | + background_sizer.AddSizer(sizer, 1, wx.EXPAND|wx.GROW|wx.ALL, 2) | |
67 | + background_sizer.Add(scroll, 0, wx.EXPAND|wx.GROW) | |
68 | + self.SetSizer(background_sizer) | |
69 | + background_sizer.Fit(self) | |
56 | 70 | |
57 | 71 | self.Layout() |
58 | 72 | self.Update() |
... | ... | @@ -61,7 +75,10 @@ class Viewer(wx.Panel): |
61 | 75 | self.interactor = interactor |
62 | 76 | |
63 | 77 | def __config_interactor(self): |
78 | + | |
64 | 79 | style = vtk.vtkInteractorStyleImage() |
80 | + self.style = style | |
81 | + | |
65 | 82 | ren = vtk.vtkRenderer() |
66 | 83 | |
67 | 84 | interactor = self.interactor |
... | ... | @@ -69,26 +86,116 @@ class Viewer(wx.Panel): |
69 | 86 | interactor.GetRenderWindow().AddRenderer(ren) |
70 | 87 | |
71 | 88 | self.cam = ren.GetActiveCamera() |
72 | - | |
73 | 89 | self.ren = ren |
74 | - | |
90 | + | |
91 | + self.SetMode(self.mode) | |
92 | + | |
93 | + def SetMode(self, mode): | |
94 | + self.mode = mode | |
95 | + # All modes and bindings | |
96 | + action = {'DEFAULT': { | |
97 | + "MouseMoveEvent": self.OnCrossMove, | |
98 | + "LeftButtonPressEvent": self.OnMouseClick, | |
99 | + "LeftButtonReleaseEvent": self.OnMouseRelease | |
100 | + }, | |
101 | + 'EDITOR': { | |
102 | + "MouseMoveEvent": self.OnBrushMove, | |
103 | + "LeftButtonPressEvent": self.OnBrushClick, | |
104 | + "LeftButtonReleaseEvent": self.OnMouseRelease | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + # Bind method according to current mode | |
109 | + style = self.style | |
110 | + style.AddObserver("MouseMoveEvent", action[mode]["MouseMoveEvent"]) | |
111 | + style.AddObserver("LeftButtonPressEvent", action[mode]["LeftButtonPressEvent"]) | |
112 | + style.AddObserver("LeftButtonReleaseEvent", action[mode]["LeftButtonReleaseEvent"]) | |
113 | + | |
114 | + def OnMouseClick(self, obj, evt_vtk): | |
115 | + self.mouse_pressed = 1 | |
116 | + | |
117 | + def OnMouseRelease(self, obj, evt_vtk): | |
118 | + self.mouse_pressed = 0 | |
119 | + | |
120 | + def OnBrushClick(self, obj, evt_vtk): | |
121 | + self.mouse_pressed = 1 | |
122 | + coord = self.GetCoordinate() | |
123 | + print "Edit pixel region based on origin:", coord | |
124 | + | |
125 | + def OnBrushMove(self, obj, evt_vtk): | |
126 | + coord = self.GetCoordinate() | |
127 | + if self.mouse_pressed: | |
128 | + print "Edit pixel region based on origin:", coord | |
129 | + | |
130 | + def OnCrossMove(self, obj, evt_vtk): | |
131 | + coord = self.GetCoordinate() | |
132 | + # Update position in other slices | |
133 | + if self.mouse_pressed: | |
134 | + ps.Publisher().sendMessage('Update cursor position in slice', coord) | |
135 | + ps.Publisher().sendMessage(('Set scroll position', 'SAGITAL'), coord[0]) | |
136 | + ps.Publisher().sendMessage(('Set scroll position', 'CORONAL'), coord[1]) | |
137 | + ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), coord[2]) | |
138 | + | |
139 | + def GetCoordinate(self): | |
140 | + | |
141 | + # Find position | |
142 | + mouse_x, mouse_y = self.interactor.GetEventPosition() | |
143 | + self.pick.Pick(mouse_x, mouse_y, 0, self.ren) | |
144 | + x, y, z = self.pick.GetPickPosition() | |
145 | + | |
146 | + # First we fix the position origin, based on vtkActor bounds | |
147 | + bounds = self.actor.GetBounds() | |
148 | + bound_xi, bound_xf, bound_yi, bound_yf, bound_zi, bound_zf = bounds | |
149 | + x = float(x - bound_xi) | |
150 | + y = float(y - bound_yi) | |
151 | + z = float(z - bound_zi) | |
152 | + | |
153 | + # Then we fix the porpotion, based on vtkImageData spacing | |
154 | + spacing_x, spacing_y, spacing_z = self.imagedata.GetSpacing() | |
155 | + x = x/spacing_x | |
156 | + y = y/spacing_y | |
157 | + z = z/spacing_z | |
158 | + | |
159 | + # Based on the current orientation, we define 3D position | |
160 | + coordinates = {"SAGITAL": [self.slice_number, y, z], | |
161 | + "CORONAL": [x, self.slice_number, z], | |
162 | + "AXIAL": [x, y, self.slice_number]} | |
163 | + coord = [int(coord) for coord in coordinates[self.orientation]] | |
164 | + | |
165 | + # According to vtkImageData extent, we limit min and max value | |
166 | + # If this is not done, a VTK Error occurs when mouse is pressed outside | |
167 | + # vtkImageData extent | |
168 | + extent = self.imagedata.GetWholeExtent() | |
169 | + extent_min = extent[0], extent[2], extent[4] | |
170 | + extent_max = extent[1], extent[3], extent[5] | |
171 | + for index in xrange(3): | |
172 | + if coord[index] > extent_max[index]: | |
173 | + coord[index] = extent_max[index] | |
174 | + elif coord[index] < extent_min[index]: | |
175 | + coord[index] = extent_min[index] | |
176 | + | |
177 | + print "New coordinate: ", coord | |
178 | + | |
179 | + return coord | |
180 | + | |
75 | 181 | def __bind_events(self): |
76 | 182 | ps.Publisher().subscribe(self.LoadImagedata, 'Load slice to viewer') |
77 | 183 | ps.Publisher().subscribe(self.SetColour, 'Change mask colour') |
78 | 184 | ps.Publisher().subscribe(self.UpdateRender, 'Update slice viewer') |
79 | - ps.Publisher().subscribe(self.SetScrollPosition, ('Set scroll position', | |
185 | + ps.Publisher().subscribe(self.ChangeSliceNumber, ('Set scroll position', | |
80 | 186 | self.orientation)) |
81 | 187 | |
82 | 188 | def __bind_events_wx(self): |
83 | 189 | self.scroll.Bind(wx.EVT_SCROLL, self.OnScrollBar) |
84 | - #self.interactor.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) | |
85 | 190 | |
86 | 191 | def LoadImagedata(self, pubsub_evt): |
87 | 192 | imagedata = pubsub_evt.data |
88 | 193 | self.SetInput(imagedata) |
89 | 194 | |
90 | 195 | def SetInput(self, imagedata): |
196 | + | |
91 | 197 | self.imagedata = imagedata |
198 | + | |
92 | 199 | ren = self.ren |
93 | 200 | interactor = self.interactor |
94 | 201 | |
... | ... | @@ -101,77 +208,72 @@ class Viewer(wx.Panel): |
101 | 208 | actor.SetInput(slice_.GetOutput()) |
102 | 209 | self.actor = actor |
103 | 210 | |
211 | + colour = const.ORIENTATION_COLOUR[self.orientation] | |
212 | + | |
213 | + text_property = vtk.vtkTextProperty() | |
214 | + text_property.SetFontSize(16) | |
215 | + text_property.SetFontFamilyToArial() | |
216 | + text_property.BoldOn() | |
217 | + text_property.SetColor(colour) | |
218 | + | |
219 | + # Text related to slice number shown | |
220 | + text_mapper = vtk.vtkTextMapper() | |
221 | + text_mapper.SetInput("%d"%(self.slice_number)) | |
222 | + text_mapper.GetTextProperty().ShallowCopy(text_property) | |
223 | + self.text_mapper = text_mapper | |
224 | + | |
225 | + text_actor = vtk.vtkActor2D() | |
226 | + text_actor.SetMapper(text_mapper) | |
227 | + text_actor.SetLayerNumber(1) | |
228 | + text_actor.GetPositionCoordinate().SetValue(self.GetSize()[0] - 80, 20) | |
229 | + text_actor.SetVisibility(1) | |
230 | + | |
104 | 231 | ren.AddActor(actor) |
232 | + ren.AddActor(text_actor) | |
105 | 233 | self.__update_camera() |
106 | 234 | |
107 | 235 | max_slice_number = actor.GetSliceNumberMax() |
108 | 236 | self.scroll.SetScrollbar(wx.SB_VERTICAL, 1, max_slice_number, |
109 | 237 | max_slice_number) |
238 | + self.SetScrollPosition(0) | |
110 | 239 | |
111 | 240 | def SetOrientation(self, orientation): |
112 | 241 | self.orientation = orientation |
113 | 242 | self.__update_camera() |
114 | 243 | |
115 | 244 | def __update_camera(self): |
116 | - cam = self.cam | |
117 | - | |
118 | 245 | orientation = self.orientation |
119 | 246 | |
120 | - if orientation == "AXIAL": | |
121 | - cam.SetFocalPoint(0, 0, 0) | |
122 | - cam.SetPosition(0, 0, 1) | |
123 | - cam.ComputeViewPlaneNormal() | |
124 | - cam.SetViewUp(0, 1, 0) | |
125 | - elif orientation == "CORONAL": | |
126 | - cam.SetFocalPoint(0, 0, 0) | |
127 | - cam.SetPosition(0, -1, 0) | |
128 | - cam.ComputeViewPlaneNormal() | |
129 | - cam.SetViewUp(0, 0, 1) | |
130 | - elif orientation == "SAGITAL": | |
131 | - cam.SetFocalPoint(0, 0, 0) | |
132 | - cam.SetPosition(1, 0, 0) | |
133 | - cam.ComputeViewPlaneNormal() | |
134 | - cam.SetViewUp(0, 0, 1) | |
135 | - | |
247 | + cam = self.cam | |
248 | + cam.SetFocalPoint(0, 0, 0) | |
249 | + cam.SetPosition(const.CAM_POSITION[self.orientation]) | |
250 | + cam.SetViewUp(const.CAM_VIEW_UP[self.orientation]) | |
251 | + cam.ComputeViewPlaneNormal() | |
136 | 252 | cam.OrthogonalizeViewUp() |
253 | + cam.ParallelProjectionOn() | |
254 | + | |
137 | 255 | self.__update_display_extent() |
138 | - cam.ParallelProjectionOn() | |
256 | + | |
139 | 257 | self.ren.ResetCamera() |
140 | 258 | self.ren.Render() |
141 | 259 | |
142 | 260 | def __update_display_extent(self): |
143 | - actor = self.actor | |
144 | - slice_number = self.slice_number | |
145 | - extent = self.imagedata.GetWholeExtent() | |
146 | - if self.orientation == "AXIAL": | |
147 | - xs = extent[1] - extent[0] + 1 | |
148 | - ys = extent[3] - extent[2] + 1 | |
149 | - actor.SetDisplayExtent(extent[0], extent[1], | |
150 | - extent[2], extent[3], | |
151 | - slice_number, slice_number) | |
152 | - elif self.orientation == "CORONAL": | |
153 | - xs = extent[1] - extent[0] + 1 | |
154 | - ys = extent[5] - extent[4] + 1 | |
155 | - actor.SetDisplayExtent(extent[0], extent[1], | |
156 | - slice_number,slice_number, | |
157 | - extent[4], extent[5]) | |
158 | - elif self.orientation == "SAGITAL": | |
159 | - xs = extent[3] - extent[2] + 1 | |
160 | - ys = extent[5] - extent[4] + 1 | |
161 | - actor.SetDisplayExtent(slice_number, slice_number, | |
162 | - extent[2], extent[3], | |
163 | - extent[4], extent[5]) | |
164 | 261 | |
262 | + pos = self.slice_number | |
263 | + e = self.imagedata.GetWholeExtent() | |
264 | + | |
265 | + new_extent = {"SAGITAL": (pos, pos, e[2], e[3], e[4], e[5]), | |
266 | + "CORONAL": (e[0], e[1], pos, pos, e[4], e[5]), | |
267 | + "AXIAL": (e[0], e[1], e[2], e[3], pos, pos)} | |
268 | + | |
269 | + self.actor.SetDisplayExtent(new_extent[self.orientation]) | |
165 | 270 | self.ren.ResetCameraClippingRange() |
166 | 271 | self.ren.Render() |
167 | 272 | |
168 | 273 | def UpdateRender(self, evt): |
169 | 274 | self.interactor.Render() |
170 | 275 | |
171 | - def SetScrollPosition(self, pubsub_evt): | |
172 | - value = pubsub_evt.data | |
173 | - position = self.scroll.GetThumbPosition() | |
174 | - position += value | |
276 | + def SetScrollPosition(self, position): | |
175 | 277 | self.scroll.SetThumbPosition(position) |
176 | 278 | self.OnScrollBar() |
177 | 279 | |
... | ... | @@ -183,9 +285,16 @@ class Viewer(wx.Panel): |
183 | 285 | evt.Skip() |
184 | 286 | |
185 | 287 | def SetSliceNumber(self, index): |
288 | + self.text_mapper.SetInput(str(index)) | |
186 | 289 | self.slice_number = index |
187 | 290 | self.__update_display_extent() |
188 | 291 | |
292 | + def ChangeSliceNumber(self, pubsub_evt): | |
293 | + index = pubsub_evt.data | |
294 | + self.SetSliceNumber(index) | |
295 | + self.scroll.SetThumbPosition(index) | |
296 | + self.interactor.Render() | |
297 | + | |
189 | 298 | def SetColour(self, pubsub_evt): |
190 | 299 | colour_wx = pubsub_evt.data |
191 | 300 | colour_vtk = [colour/float(255) for colour in colour_wx] | ... | ... |
invesalius/data/viewer_volume.py
... | ... | @@ -61,6 +61,26 @@ class Viewer(wx.Panel): |
61 | 61 | def __bind_events(self): |
62 | 62 | ps.Publisher().subscribe(self.LoadActor, 'Load surface actor into viewer') |
63 | 63 | ps.Publisher().subscribe(self.UpdateRender, 'Render volume viewer') |
64 | + ps.Publisher().subscribe(self.ChangeBackgroundColour, | |
65 | + 'Change volume viewer background colour') | |
66 | + ps.Publisher().subscribe(self.ShowRaycastingVolume, | |
67 | + 'Show raycasting volume') | |
68 | + ps.Publisher().subscribe(self.HideRaycastingVolume, | |
69 | + 'Hide raycasting volume') | |
70 | + | |
71 | + | |
72 | + def ShowRaycastingVolume(self, pubsub_evt): | |
73 | + pass | |
74 | + | |
75 | + def HideRaycastingVolume(self, pubsub_evt): | |
76 | + pass | |
77 | + | |
78 | + | |
79 | + | |
80 | + def ChangeBackgroundColour(self, pubsub_evt): | |
81 | + colour = pubsub_evt.data | |
82 | + self.ren.SetBackground(colour) | |
83 | + self.UpdateRender() | |
64 | 84 | |
65 | 85 | def LoadActor(self, pubsub_evt): |
66 | 86 | actor = pubsub_evt.data |
... | ... | @@ -76,7 +96,7 @@ class Viewer(wx.Panel): |
76 | 96 | |
77 | 97 | self.iren.Render() |
78 | 98 | |
79 | - def UpdateRender(self, evt_pubsub): | |
99 | + def UpdateRender(self, evt_pubsub=None): | |
80 | 100 | self.iren.Render() |
81 | 101 | |
82 | 102 | def CreatePlanes(self): | ... | ... |
invesalius/gui/default_viewers.py
... | ... | @@ -21,18 +21,6 @@ import wx.lib.agw.fourwaysplitter as fws |
21 | 21 | import data.viewer_slice as slice_viewer |
22 | 22 | import data.viewer_volume as volume_viewer |
23 | 23 | |
24 | -class SamplePane(wx.Panel): | |
25 | - """ | |
26 | - Just a simple test window to put into the splitter. | |
27 | - """ | |
28 | - def __init__(self, parent, colour, label): | |
29 | - wx.Panel.__init__(self, parent, style=wx.BORDER_SUNKEN) | |
30 | - self.SetBackgroundColour(colour) | |
31 | - wx.StaticText(self, -1, label, (5,5)) | |
32 | - | |
33 | - def SetOtherLabel(self, label): | |
34 | - wx.StaticText(self, -1, label, (5, 30)) | |
35 | - | |
36 | 24 | |
37 | 25 | class Panel(wx.Panel): |
38 | 26 | def __init__(self, parent): |
... | ... | @@ -89,7 +77,8 @@ class Panel(wx.Panel): |
89 | 77 | Name("Sagital Slice").Caption("Sagital slice"). |
90 | 78 | MaximizeButton(True).CloseButton(False)) |
91 | 79 | |
92 | - self.aui_manager.AddPane(volume_viewer.Viewer(self), | |
80 | + self.aui_manager.AddPane(VolumeViewerCover(self), | |
81 | + #self.aui_manager.AddPane(volume_viewer.Viewer(self) | |
93 | 82 | wx.aui.AuiPaneInfo().Row(1).Name("Volume"). |
94 | 83 | Bottom().Centre().Caption("Volume"). |
95 | 84 | MaximizeButton(True).CloseButton(False)) |
... | ... | @@ -150,8 +139,8 @@ class Panel(wx.Panel): |
150 | 139 | Name("Sagittal Slice").Caption("Sagittal slice"). |
151 | 140 | MaximizeButton(True).CloseButton(False)) |
152 | 141 | |
153 | - p4 = volume_viewer.Viewer(self) | |
154 | - aui_manager.AddPane(p4, | |
142 | + #p4 = volume_viewer.Viewer(self) | |
143 | + aui_manager.AddPane(VolumeViewerCover, | |
155 | 144 | wx.aui.AuiPaneInfo(). |
156 | 145 | Name("Volume").Caption("Volume"). |
157 | 146 | MaximizeButton(True).CloseButton(False)) |
... | ... | @@ -163,3 +152,50 @@ class Panel(wx.Panel): |
163 | 152 | |
164 | 153 | |
165 | 154 | aui_manager.Update() |
155 | + | |
156 | +class VolumeViewerCover(wx.Panel): | |
157 | + def __init__(self, parent): | |
158 | + wx.Panel.__init__(self, parent) | |
159 | + | |
160 | + sizer = wx.BoxSizer(wx.HORIZONTAL) | |
161 | + sizer.Add(volume_viewer.Viewer(self), 1, wx.EXPAND|wx.GROW) | |
162 | + sizer.Add(VolumeToolPanel(self), 0, wx.EXPAND) | |
163 | + self.SetSizer(sizer) | |
164 | + sizer.Fit(self) | |
165 | + | |
166 | +#import wx.lib.platebtn as pbtn | |
167 | +import wx.lib.buttons as btn | |
168 | +import wx.lib.pubsub as ps | |
169 | +import wx.lib.colourselect as csel | |
170 | + | |
171 | +class VolumeToolPanel(wx.Panel): | |
172 | + def __init__(self, parent): | |
173 | + wx.Panel.__init__(self, parent, size = (8,100)) | |
174 | + | |
175 | + BMP_RAYCASTING = wx.Bitmap("../icons/volume_raycasting.png", wx.BITMAP_TYPE_PNG) | |
176 | + BMP_RAYCASTING.SetWidth(22) | |
177 | + BMP_RAYCASTING.SetHeight(22) | |
178 | + | |
179 | + button_raycasting=btn.GenBitmapToggleButton(self, 1, BMP_RAYCASTING, size=(24,24)) | |
180 | + button_raycasting.Bind(wx.EVT_BUTTON, self.OnToggleRaycasting) | |
181 | + self.button_raycasting = button_raycasting | |
182 | + | |
183 | + button_colour= csel.ColourSelect(self, 111,colour=(0,0,0),size=(24,24)) | |
184 | + button_colour.Bind(csel.EVT_COLOURSELECT, self.OnSelectColour) | |
185 | + self.button_colour = button_colour | |
186 | + | |
187 | + sizer = wx.BoxSizer(wx.VERTICAL) | |
188 | + sizer.Add(button_colour, 0, wx.ALL, 1) | |
189 | + sizer.Add(button_raycasting, 0, wx.ALL, 1) | |
190 | + self.SetSizer(sizer) | |
191 | + sizer.Fit(self) | |
192 | + | |
193 | + def OnSelectColour(self, evt): | |
194 | + colour = c = [i/255.0 for i in evt.GetValue()] | |
195 | + ps.Publisher().sendMessage('Change volume viewer background colour', colour) | |
196 | + | |
197 | + def OnToggleRaycasting(self, evt): | |
198 | + if self.button_raycasting.GetToggle(): | |
199 | + ps.Publisher().sendMessage('Show raycasting volume') | |
200 | + else: | |
201 | + ps.Publisher().sendMessage('Hide raycasting volume') | ... | ... |
invesalius/gui/frame.py
... | ... | @@ -30,7 +30,8 @@ import default_viewers as viewers |
30 | 30 | class Frame(wx.Frame): |
31 | 31 | def __init__(self, prnt): |
32 | 32 | wx.Frame.__init__(self, id=-1, name='', parent=prnt, |
33 | - pos=wx.Point(0, 0), size=wx.Size(1024, 768), | |
33 | + pos=wx.Point(0, 0), | |
34 | + size=wx.Size(1024, 768), #size = wx.DisplaySize(), | |
34 | 35 | style=wx.DEFAULT_FRAME_STYLE, title='InVesalius 3.0') |
35 | 36 | self.Center(wx.BOTH) |
36 | 37 | self.SetIcon(wx.Icon("../icons/invesalius.ico", wx.BITMAP_TYPE_ICO)) | ... | ... |