Commit e2a484bd6cf01d05f6daaf85ee8feeb6a7285194
Exists in
master
Merge branch 'master' into icp
Showing
113 changed files
with
355 additions
and
317 deletions
Show diff stats
app.py
... | ... | @@ -40,7 +40,11 @@ if sys.platform == 'win32': |
40 | 40 | # #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True) |
41 | 41 | # #wxversion.select('2.8-unicode', optionsRequired=True) |
42 | 42 | # # wxversion.ensureMinimal('4.0') |
43 | - | |
43 | + | |
44 | +# Forcing to use X11, OpenGL in wxPython doesn't work with Wayland. | |
45 | +if sys.platform not in ("win32", "darwin"): | |
46 | + os.environ["GDK_BACKEND"] = "x11" | |
47 | + | |
44 | 48 | import wx |
45 | 49 | try: |
46 | 50 | from wx.adv import SplashScreen |
... | ... | @@ -98,7 +102,7 @@ class InVesalius(wx.App): |
98 | 102 | """ |
99 | 103 | Initialize splash screen and main frame. |
100 | 104 | """ |
101 | - | |
105 | + | |
102 | 106 | from multiprocessing import freeze_support |
103 | 107 | freeze_support() |
104 | 108 | |
... | ... | @@ -179,18 +183,18 @@ class Inv3SplashScreen(SplashScreen): |
179 | 183 | |
180 | 184 | # session.SaveConfigFileBackup() |
181 | 185 | |
182 | - | |
186 | + | |
183 | 187 | # Only after language was defined, splash screen will be |
184 | 188 | # shown |
185 | 189 | if lang: |
186 | - | |
190 | + | |
187 | 191 | #import locale |
188 | 192 | #try: |
189 | 193 | # locale.setlocale(locale.LC_ALL, '') |
190 | 194 | #except locale.Error: |
191 | 195 | # pass |
192 | - | |
193 | - | |
196 | + | |
197 | + | |
194 | 198 | # For pt_BR, splash_pt.png should be used |
195 | 199 | if (lang.startswith('pt')): |
196 | 200 | icon_file = "splash_pt.png" |
... | ... | @@ -202,13 +206,13 @@ class Inv3SplashScreen(SplashScreen): |
202 | 206 | abs_file_path = os.path.abspath(".." + os.sep) |
203 | 207 | path = abs_file_path |
204 | 208 | path = os.path.join(path, 'icons', icon_file) |
205 | - | |
209 | + | |
206 | 210 | else: |
207 | 211 | |
208 | 212 | path = os.path.join(".","icons", icon_file) |
209 | 213 | if not os.path.exists(path): |
210 | 214 | path = os.path.join(".", "icons", "splash_en.png") |
211 | - | |
215 | + | |
212 | 216 | bmp = wx.Image(path).ConvertToBitmap() |
213 | 217 | |
214 | 218 | try: |
... | ... | @@ -232,10 +236,10 @@ class Inv3SplashScreen(SplashScreen): |
232 | 236 | from invesalius.gui.frame import Frame |
233 | 237 | from invesalius.control import Controller |
234 | 238 | from invesalius.project import Project |
235 | - | |
239 | + | |
236 | 240 | self.main = Frame(None) |
237 | 241 | self.control = Controller(self.main) |
238 | - | |
242 | + | |
239 | 243 | self.fc = wx.CallLater(200, self.ShowMain) |
240 | 244 | options, args = parse_comand_line() |
241 | 245 | wx.CallLater(1, use_cmd_optargs, options, args) |
... | ... | @@ -498,7 +502,7 @@ def main(): |
498 | 502 | if __name__ == '__main__': |
499 | 503 | #Is needed because of pyinstaller |
500 | 504 | multiprocessing.freeze_support() |
501 | - | |
505 | + | |
502 | 506 | #Needed in win 32 exe |
503 | 507 | if hasattr(sys,"frozen") and sys.platform.startswith('win'): |
504 | 508 | |
... | ... | @@ -523,4 +527,3 @@ if __name__ == '__main__': |
523 | 527 | |
524 | 528 | # Init application |
525 | 529 | main() |
526 | - | ... | ... |
icons/3D_glasses_original.png
icons/be.bmp
No preview for this file type
595 Bytes
icons/brush_circle.jpg
1.17 KB
1.07 KB
icons/brush_square.jpg
1022 Bytes
934 Bytes
icons/ca.bmp
No preview for this file type
307 Bytes
icons/cross_original.png
icons/cs.bmp
No preview for this file type
646 Bytes
icons/de_DE.bmp
No preview for this file type
562 Bytes
icons/el_GR.bmp
No preview for this file type
576 Bytes
icons/en.bmp
No preview for this file type
957 Bytes
icons/es.bmp
No preview for this file type
472 Bytes
icons/file_from_internet_original.png
icons/file_import_original.png
icons/file_open_original.png
icons/file_save_original.png
icons/fr.bmp
No preview for this file type
360 Bytes
icons/it.bmp
No preview for this file type
icons/it.png
icons/ja.bmp
No preview for this file type
431 Bytes
icons/ko.bmp
No preview for this file type
721 Bytes
icons/layout_data_only.gif
1.17 KB
icons/layout_data_only.png
icons/layout_data_only_original.gif
788 Bytes
icons/layout_data_only_original.png
icons/layout_full.gif
1.17 KB
icons/layout_full.png
icons/layout_full_original.gif
804 Bytes
icons/layout_full_original.png
icons/measure_angle.jpg
701 Bytes
icons/measure_angle.png
icons/measure_angle_original.jpg
1.79 KB
icons/measure_angle_original.png
icons/measure_line_original.png
icons/object_add.gif
1.58 KB
icons/object_add_original.png
icons/object_colour.jpg
360 Bytes
352 Bytes
icons/object_invisible.jpg
297 Bytes
284 Bytes
icons/object_remove.gif
1.65 KB
icons/object_remove_original.png
icons/object_visible.jpg
1.88 KB
3.34 KB
icons/print_original.png
icons/pt.bmp
No preview for this file type
651 Bytes
icons/pt_BR.bmp
No preview for this file type
596 Bytes
icons/redo_original.png
icons/ro.bmp
No preview for this file type
278 Bytes
icons/ru.bmp
No preview for this file type
289 Bytes
icons/slice_original.png
icons/slice_plane_original.png
icons/surface_export_original.png
icons/text.gif
243 Bytes
icons/text.png
icons/text_inverted_original.png
icons/text_original.png
icons/tool_annotation_original.png
icons/tool_contrast_original.png
icons/tool_photo_original.png
icons/tool_rotate_original.gif
1.63 KB
icons/tool_rotate_original.png
icons/tool_translate_original.png
icons/tool_zoom_in_original.png
icons/tool_zoom_original.png
icons/tool_zoom_out_original.png
icons/tool_zoom_select_original.png
icons/tr_TR.bmp
No preview for this file type
409 Bytes
icons/undo_original.png
icons/volume_raycasting_original.png
icons/zh_TW.bmp
No preview for this file type
846 Bytes
invesalius/data/imagedata_utils.py
... | ... | @@ -500,34 +500,6 @@ def img2memmap(group): |
500 | 500 | return matrix, scalar_range, temp_file |
501 | 501 | |
502 | 502 | |
503 | -def imgnormalize(data, srange=(0, 255)): | |
504 | - """ | |
505 | - Normalize image pixel intensity for int16 gray scale values. | |
506 | - | |
507 | - :param data: image matrix | |
508 | - :param srange: range for normalization, default is 0 to 255 | |
509 | - :return: normalized pixel intensity matrix | |
510 | - """ | |
511 | - | |
512 | - dataf = numpy.asarray(data) | |
513 | - rangef = numpy.asarray(srange) | |
514 | - faux = numpy.ravel(dataf).astype(float) | |
515 | - minimum = numpy.min(faux) | |
516 | - maximum = numpy.max(faux) | |
517 | - lower = rangef[0] | |
518 | - upper = rangef[1] | |
519 | - | |
520 | - if minimum == maximum: | |
521 | - datan = numpy.ones(dataf.shape)*(upper + lower) / 2. | |
522 | - else: | |
523 | - datan = (faux-minimum)*(upper-lower) / (maximum-minimum) + lower | |
524 | - | |
525 | - datan = numpy.reshape(datan, dataf.shape) | |
526 | - datan = datan.astype(numpy.int16) | |
527 | - | |
528 | - return datan | |
529 | - | |
530 | - | |
531 | 503 | def get_LUT_value_255(data, window, level): |
532 | 504 | shape = data.shape |
533 | 505 | data_ = data.ravel() |
... | ... | @@ -539,6 +511,8 @@ def get_LUT_value_255(data, window, level): |
539 | 511 | return data |
540 | 512 | |
541 | 513 | |
542 | -def image_normalize(image, min_=0.0, max_=1.0): | |
514 | +def image_normalize(image, min_=0.0, max_=1.0, output_dtype=np.int16): | |
515 | + output = np.empty(shape=image.shape, dtype=output_dtype) | |
543 | 516 | imin, imax = image.min(), image.max() |
544 | - return (image - imin) * ((max_ - min_) / (imax - imin)) + min_ | |
517 | + output[:] = (image - imin) * ((max_ - min_) / (imax - imin)) + min_ | |
518 | + return output | ... | ... |
invesalius/data/slice_.py
... | ... | @@ -301,7 +301,10 @@ class Slice(metaclass=utils.Singleton): |
301 | 301 | |
302 | 302 | for name in self.aux_matrices: |
303 | 303 | m = self.aux_matrices[name] |
304 | - f = m.filename | |
304 | + try: | |
305 | + f = m.filename | |
306 | + except AttributeError: | |
307 | + continue | |
305 | 308 | m._mmap.close() |
306 | 309 | m = None |
307 | 310 | os.remove(f) |
... | ... | @@ -347,6 +350,8 @@ class Slice(metaclass=utils.Singleton): |
347 | 350 | self.SetMaskEditionThreshold(index, threshold_range) |
348 | 351 | |
349 | 352 | def __set_current_mask_threshold(self, threshold_range): |
353 | + if self.current_mask is None: | |
354 | + return | |
350 | 355 | index = self.current_mask.index |
351 | 356 | self.num_gradient += 1 |
352 | 357 | self.current_mask.matrix[:] = 0 |
... | ... | @@ -387,6 +392,8 @@ class Slice(metaclass=utils.Singleton): |
387 | 392 | Publisher.sendMessage("Reload actual slice") |
388 | 393 | |
389 | 394 | def __set_current_mask_threshold_actual_slice(self, threshold_range): |
395 | + if self.current_mask is None: | |
396 | + return | |
390 | 397 | index = self.current_mask.index |
391 | 398 | for orientation in self.buffer_slices: |
392 | 399 | self.buffer_slices[orientation].discard_vtk_mask() |
... | ... | @@ -624,7 +631,7 @@ class Slice(metaclass=utils.Singleton): |
624 | 631 | self.buffer_slices[orientation].vtk_image = image |
625 | 632 | self.buffer_slices[orientation].vtk_mask = mask |
626 | 633 | |
627 | - if self.to_show_aux == "watershed" and self.current_mask.is_shown: | |
634 | + if self.to_show_aux == "watershed" and self.current_mask is not None and self.current_mask.is_shown: | |
628 | 635 | m = self.get_aux_slice("watershed", orientation, slice_number) |
629 | 636 | tmp_vimage = converters.to_vtk(m, self.spacing, slice_number, orientation) |
630 | 637 | cimage = self.do_custom_colour( | ... | ... |
invesalius/data/viewer_slice.py
... | ... | @@ -102,13 +102,13 @@ class ContourMIPConfig(wx.Panel): |
102 | 102 | self.txt_mip_border = wx.StaticText(self, -1, _("Sharpness")) |
103 | 103 | |
104 | 104 | sizer = wx.BoxSizer(wx.HORIZONTAL) |
105 | - sizer.Add(txt_mip_size, 0, wx.EXPAND | wx.ALL, 2) | |
105 | + sizer.Add(txt_mip_size, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) | |
106 | 106 | sizer.Add(self.mip_size_spin, 0) |
107 | 107 | try: |
108 | 108 | sizer.Add(10, 0) |
109 | 109 | except TypeError: |
110 | 110 | sizer.Add((10, 0)) |
111 | - sizer.Add(self.txt_mip_border, 0, wx.EXPAND | wx.ALL, 2) | |
111 | + sizer.Add(self.txt_mip_border, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) | |
112 | 112 | sizer.Add(self.border_spin, 0, wx.EXPAND) |
113 | 113 | try: |
114 | 114 | sizer.Add(10, 0) |
... | ... | @@ -1438,8 +1438,12 @@ class Viewer(wx.Panel): |
1438 | 1438 | index = max_slice_number - 1 |
1439 | 1439 | inverted = self.mip_ctrls.inverted.GetValue() |
1440 | 1440 | border_size = self.mip_ctrls.border_spin.GetValue() |
1441 | - image = self.slice_.GetSlices(self.orientation, index, | |
1442 | - self.number_slices, inverted, border_size) | |
1441 | + try: | |
1442 | + image = self.slice_.GetSlices(self.orientation, index, | |
1443 | + self.number_slices, inverted, | |
1444 | + border_size) | |
1445 | + except IndexError: | |
1446 | + return | |
1443 | 1447 | self.slice_data.actor.SetInputData(image) |
1444 | 1448 | for actor in self.actors_by_slice_number[self.slice_data.number]: |
1445 | 1449 | self.slice_data.renderer.RemoveActor(actor) | ... | ... |
invesalius/gui/brain_seg_dialog.py
... | ... | @@ -81,6 +81,8 @@ class BrainSegmenterDialog(wx.Dialog): |
81 | 81 | self.txt_threshold.SetMinClientSize((w, -1)) |
82 | 82 | self.chk_new_mask = wx.CheckBox(self, wx.ID_ANY, _("Create new mask")) |
83 | 83 | self.chk_new_mask.SetValue(True) |
84 | + self.chk_apply_wwwl = wx.CheckBox(self, wx.ID_ANY, _("Apply WW&WL")) | |
85 | + self.chk_apply_wwwl.SetValue(False) | |
84 | 86 | self.progress = wx.Gauge(self, -1) |
85 | 87 | self.lbl_progress_caption = wx.StaticText(self, -1, _("Elapsed time:")) |
86 | 88 | self.lbl_time = wx.StaticText(self, -1, _("00:00:00")) |
... | ... | @@ -115,11 +117,12 @@ class BrainSegmenterDialog(wx.Dialog): |
115 | 117 | sizer_3.Add( |
116 | 118 | self.sld_threshold, |
117 | 119 | 1, |
118 | - wx.ALIGN_CENTER | wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.RIGHT, | |
120 | + wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.RIGHT, | |
119 | 121 | 5, |
120 | 122 | ) |
121 | 123 | sizer_3.Add(self.txt_threshold, 0, wx.ALL, 5) |
122 | 124 | main_sizer.Add(sizer_3, 0, wx.EXPAND, 0) |
125 | + main_sizer.Add(self.chk_apply_wwwl, 0, wx.EXPAND | wx.ALL, 5) | |
123 | 126 | main_sizer.Add(self.chk_new_mask, 0, wx.EXPAND | wx.ALL, 5) |
124 | 127 | main_sizer.Add(self.progress, 0, wx.EXPAND | wx.ALL, 5) |
125 | 128 | time_sizer = wx.BoxSizer(wx.HORIZONTAL) |
... | ... | @@ -128,15 +131,15 @@ class BrainSegmenterDialog(wx.Dialog): |
128 | 131 | main_sizer.Add(time_sizer, 0, wx.EXPAND | wx.ALL, 5) |
129 | 132 | sizer_buttons = wx.BoxSizer(wx.HORIZONTAL) |
130 | 133 | sizer_buttons.Add( |
131 | - self.btn_close, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5 | |
134 | + self.btn_close, 0, wx.ALIGN_BOTTOM | wx.ALL, 5 | |
132 | 135 | ) |
133 | 136 | sizer_buttons.Add( |
134 | - self.btn_stop, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5 | |
137 | + self.btn_stop, 0, wx.ALIGN_BOTTOM | wx.ALL, 5 | |
135 | 138 | ) |
136 | 139 | sizer_buttons.Add( |
137 | - self.btn_segment, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5 | |
140 | + self.btn_segment, 0, wx.ALIGN_BOTTOM | wx.ALL, 5 | |
138 | 141 | ) |
139 | - main_sizer.Add(sizer_buttons, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 0) | |
142 | + main_sizer.Add(sizer_buttons, 0, wx.ALIGN_RIGHT | wx.ALL, 0) | |
140 | 143 | self.SetSizer(main_sizer) |
141 | 144 | main_sizer.Fit(self) |
142 | 145 | main_sizer.SetSizeHints(self) |
... | ... | @@ -216,6 +219,7 @@ class BrainSegmenterDialog(wx.Dialog): |
216 | 219 | device_id = self.plaidml_devices[self.cb_devices.GetValue()] |
217 | 220 | except (KeyError, AttributeError): |
218 | 221 | device_id = "llvm_cpu.0" |
222 | + apply_wwwl = self.chk_apply_wwwl.GetValue() | |
219 | 223 | create_new_mask = self.chk_new_mask.GetValue() |
220 | 224 | use_gpu = self.chk_use_gpu.GetValue() |
221 | 225 | prob_threshold = self.sld_threshold.GetValue() / 100.0 |
... | ... | @@ -224,8 +228,11 @@ class BrainSegmenterDialog(wx.Dialog): |
224 | 228 | self.btn_segment.Disable() |
225 | 229 | self.chk_new_mask.Disable() |
226 | 230 | |
231 | + window_width = slc.Slice().window_width | |
232 | + window_level = slc.Slice().window_level | |
233 | + | |
227 | 234 | try: |
228 | - self.ps = segment.SegmentProcess(image, create_new_mask, backend, device_id, use_gpu) | |
235 | + self.ps = segment.SegmentProcess(image, create_new_mask, backend, device_id, use_gpu, apply_wwwl, window_width, window_level) | |
229 | 236 | self.ps.start() |
230 | 237 | except (multiprocessing.ProcessError, OSError, ValueError) as err: |
231 | 238 | self.OnStop(None) | ... | ... |
invesalius/gui/data_notebook.py
... | ... | @@ -351,18 +351,89 @@ class ButtonControlPanel(wx.Panel): |
351 | 351 | else: |
352 | 352 | dlg.MaskSelectionRequiredForDuplication() |
353 | 353 | |
354 | -class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCtrlMixin): | |
355 | 354 | |
355 | +class InvListCtrl(wx.ListCtrl): | |
356 | 356 | def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, |
357 | - size=wx.DefaultSize, style=wx.LC_REPORT): | |
357 | + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS): | |
358 | + wx.ListCtrl.__init__(self, parent, ID, pos, size, style=style) | |
359 | + self.__bind_events_wx() | |
358 | 360 | |
359 | - # native look and feel for MacOS | |
360 | - #if wx.Platform == "__WXMAC__": | |
361 | - # wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", 0) | |
361 | + def __bind_events_wx(self): | |
362 | + self.Bind(wx.EVT_LEFT_DOWN, self.OnClickItem) | |
363 | + self.Bind(wx.EVT_LEFT_DCLICK, self.OnDblClickItem) | |
364 | + | |
365 | + def CreateColourBitmap(self, colour): | |
366 | + """ | |
367 | + Create a wx Image with a mask colour. | |
368 | + colour: colour in rgb format(0 - 1) | |
369 | + """ | |
370 | + image = self.image_gray | |
371 | + new_image = Image.new("RGB", image.size) | |
372 | + for x in range(image.size[0]): | |
373 | + for y in range(image.size[1]): | |
374 | + pixel_colour = [int(i*image.getpixel((x,y))) | |
375 | + for i in colour] | |
376 | + new_image.putpixel((x,y), tuple(pixel_colour)) | |
377 | + | |
378 | + wx_image = wx.Image(new_image.size[0], | |
379 | + new_image.size[1]) | |
380 | + try: | |
381 | + wx_image.SetData(new_image.tostring()) | |
382 | + except Exception: | |
383 | + wx_image.SetData(new_image.tobytes()) | |
384 | + return wx.Bitmap(wx_image.Scale(16, 16)) | |
385 | + | |
386 | + def OnClickItem(self, evt): | |
387 | + self._click_check = False | |
388 | + item_idx, flag = (self.HitTest(evt.GetPosition())) | |
389 | + if item_idx > -1: | |
390 | + column_clicked = self.get_column_clicked(evt.GetPosition()) | |
391 | + if column_clicked == 0: | |
392 | + self._click_check = True | |
393 | + item = self.GetItem(item_idx, 0) | |
394 | + flag = not bool(item.GetImage()) | |
395 | + self.SetItemImage(item_idx, int(flag)) | |
396 | + self.OnCheckItem(item_idx, flag) | |
397 | + return | |
398 | + evt.Skip() | |
362 | 399 | |
363 | - wx.ListCtrl.__init__(self, parent, ID, pos, size, style=wx.LC_REPORT) | |
364 | - listmix.TextEditMixin.__init__(self) | |
365 | - listmix.CheckListCtrlMixin.__init__(self) | |
400 | + def OnDblClickItem(self, evt): | |
401 | + self._click_check = False | |
402 | + item_idx, flag = (self.HitTest(evt.GetPosition())) | |
403 | + if item_idx > -1: | |
404 | + column_clicked = self.get_column_clicked(evt.GetPosition()) | |
405 | + if column_clicked == 1: | |
406 | + item = self.GetItem(item_idx, 1) | |
407 | + self.enter_edition(item) | |
408 | + return | |
409 | + evt.Skip() | |
410 | + | |
411 | + def enter_edition(self, item): | |
412 | + ctrl = self.EditLabel(item.GetId()) | |
413 | + w, h = ctrl.GetClientSize() | |
414 | + w = self.GetColumnWidth(1) | |
415 | + ctrl.SetClientSize(w, h) | |
416 | + ctrl.SetValue(item.GetText()) | |
417 | + ctrl.SelectAll() | |
418 | + | |
419 | + | |
420 | + def get_column_clicked(self, position): | |
421 | + epx, epy = position | |
422 | + wpx, wpy = self.GetPosition() | |
423 | + width_sum = 0 | |
424 | + for i in range(self.GetColumnCount()): | |
425 | + width_sum += self.GetColumnWidth(i) | |
426 | + if (epx - wpx) <= width_sum: | |
427 | + return i | |
428 | + return -1 | |
429 | + | |
430 | + | |
431 | + | |
432 | +class MasksListCtrlPanel(InvListCtrl): | |
433 | + def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, | |
434 | + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS): | |
435 | + super().__init__(parent, ID, pos, size, style=style) | |
436 | + self._click_check = False | |
366 | 437 | self.mask_list_index = {} |
367 | 438 | self.current_index = 0 |
368 | 439 | self.__init_columns() |
... | ... | @@ -371,12 +442,9 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt |
371 | 442 | self.__bind_events() |
372 | 443 | |
373 | 444 | def __bind_events_wx(self): |
374 | - self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) | |
375 | - self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginLabelEdit) | |
376 | 445 | self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel) |
377 | 446 | self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent) |
378 | 447 | |
379 | - | |
380 | 448 | def __bind_events(self): |
381 | 449 | Publisher.subscribe(self.AddMask, 'Add mask') |
382 | 450 | Publisher.subscribe(self.EditMaskThreshold, |
... | ... | @@ -438,7 +506,6 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt |
438 | 506 | self.current_index -= 1 |
439 | 507 | self.SetItemImage(self.current_index, 1) |
440 | 508 | |
441 | - | |
442 | 509 | def OnCloseProject(self): |
443 | 510 | self.DeleteAllItems() |
444 | 511 | self.mask_list_index = {} |
... | ... | @@ -475,13 +542,13 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt |
475 | 542 | def __init_image_list(self): |
476 | 543 | self.imagelist = wx.ImageList(16, 16) |
477 | 544 | |
478 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_invisible.jpg")) | |
545 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_invisible.png")) | |
479 | 546 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
480 | 547 | bitmap.SetWidth(16) |
481 | 548 | bitmap.SetHeight(16) |
482 | 549 | img_null = self.imagelist.Add(bitmap) |
483 | 550 | |
484 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_visible.jpg")) | |
551 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_visible.png")) | |
485 | 552 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
486 | 553 | bitmap.SetWidth(16) |
487 | 554 | bitmap.SetHeight(16) |
... | ... | @@ -489,23 +556,16 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt |
489 | 556 | |
490 | 557 | self.SetImageList(self.imagelist,wx.IMAGE_LIST_SMALL) |
491 | 558 | |
492 | - self.image_gray = Image.open(os.path.join(inv_paths.ICON_DIR, "object_colour.jpg")) | |
493 | - | |
494 | - def OnBeginLabelEdit(self, evt): | |
495 | - if evt.GetColumn() == 1: | |
496 | - evt.Skip() | |
497 | - else: | |
498 | - evt.Veto() | |
559 | + self.image_gray = Image.open(os.path.join(inv_paths.ICON_DIR, "object_colour.png")) | |
499 | 560 | |
500 | 561 | def OnEditLabel(self, evt): |
501 | - Publisher.sendMessage('Change mask name', | |
502 | - index=evt.GetIndex(), name=evt.GetLabel()) | |
562 | + if not evt.IsEditCancelled(): | |
563 | + index = evt.GetIndex() | |
564 | + self.SetItem(index, 1, evt.GetLabel()) | |
565 | + Publisher.sendMessage('Change mask name', | |
566 | + index=evt.GetIndex(), name=evt.GetLabel()) | |
503 | 567 | evt.Skip() |
504 | 568 | |
505 | - def OnItemActivated(self, evt): | |
506 | - self.ToggleItem(evt.Index) | |
507 | - # pass | |
508 | - | |
509 | 569 | def OnCheckItem(self, index, flag): |
510 | 570 | if flag: |
511 | 571 | for key in self.mask_list_index.keys(): |
... | ... | @@ -515,26 +575,7 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt |
515 | 575 | self.current_index = index |
516 | 576 | Publisher.sendMessage('Show mask', index=index, value=flag) |
517 | 577 | |
518 | - def CreateColourBitmap(self, colour): | |
519 | - """ | |
520 | - Create a wx Image with a mask colour. | |
521 | - colour: colour in rgb format(0 - 1) | |
522 | - """ | |
523 | - image = self.image_gray | |
524 | - new_image = Image.new("RGB", image.size) | |
525 | - for x in range(image.size[0]): | |
526 | - for y in range(image.size[1]): | |
527 | - pixel_colour = [int(i*image.getpixel((x,y))) | |
528 | - for i in colour] | |
529 | - new_image.putpixel((x,y), tuple(pixel_colour)) | |
530 | 578 | |
531 | - wx_image = wx.Image(new_image.size[0], | |
532 | - new_image.size[1]) | |
533 | - try: | |
534 | - wx_image.SetData(new_image.tostring()) | |
535 | - except Exception: | |
536 | - wx_image.SetData(new_image.tobytes()) | |
537 | - return wx.Bitmap(wx_image.Scale(16, 16)) | |
538 | 579 | |
539 | 580 | def InsertNewItem(self, index=0, label=_("Mask"), threshold="(1000, 4500)", |
540 | 581 | colour=None): |
... | ... | @@ -718,19 +759,11 @@ class SurfaceButtonControlPanel(wx.Panel): |
718 | 759 | def AffineStatus(self, affine, status): |
719 | 760 | self.affinestatus = status |
720 | 761 | |
721 | -class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCtrlMixin): | |
722 | - | |
762 | +class SurfacesListCtrlPanel(InvListCtrl): | |
723 | 763 | def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, |
724 | - size=wx.DefaultSize, style=wx.LC_REPORT): | |
725 | - | |
726 | - # native look and feel for MacOS | |
727 | - #if wx.Platform == "__WXMAC__": | |
728 | - # wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", 0) | |
729 | - | |
730 | - wx.ListCtrl.__init__(self, parent, ID, pos, size, style=wx.LC_REPORT) | |
731 | - listmix.TextEditMixin.__init__(self) | |
732 | - listmix.CheckListCtrlMixin.__init__(self) | |
733 | - | |
764 | + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS): | |
765 | + super().__init__(parent, ID, pos, size, style=style) | |
766 | + self._click_check = False | |
734 | 767 | self.__init_columns() |
735 | 768 | self.__init_image_list() |
736 | 769 | self.__init_evt() |
... | ... | @@ -752,8 +785,6 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
752 | 785 | Publisher.subscribe(self.OnShowMultiple, 'Show multiple surfaces') |
753 | 786 | |
754 | 787 | def __bind_events_wx(self): |
755 | - self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) | |
756 | - self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginLabelEdit) | |
757 | 788 | self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel) |
758 | 789 | #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected_) |
759 | 790 | self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent) |
... | ... | @@ -841,13 +872,13 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
841 | 872 | def __init_image_list(self): |
842 | 873 | self.imagelist = wx.ImageList(16, 16) |
843 | 874 | |
844 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_invisible.jpg")) | |
875 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_invisible.png")) | |
845 | 876 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
846 | 877 | bitmap.SetWidth(16) |
847 | 878 | bitmap.SetHeight(16) |
848 | 879 | img_null = self.imagelist.Add(bitmap) |
849 | 880 | |
850 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_visible.jpg")) | |
881 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_visible.png")) | |
851 | 882 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
852 | 883 | bitmap.SetWidth(16) |
853 | 884 | bitmap.SetHeight(16) |
... | ... | @@ -855,7 +886,7 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
855 | 886 | |
856 | 887 | self.SetImageList(self.imagelist,wx.IMAGE_LIST_SMALL) |
857 | 888 | |
858 | - self.image_gray = Image.open(os.path.join(inv_paths.ICON_DIR, "object_colour.jpg")) | |
889 | + self.image_gray = Image.open(os.path.join(inv_paths.ICON_DIR, "object_colour.png")) | |
859 | 890 | |
860 | 891 | def OnBeginLabelEdit(self, evt): |
861 | 892 | if evt.GetColumn() == 1: |
... | ... | @@ -864,11 +895,10 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
864 | 895 | evt.Veto() |
865 | 896 | |
866 | 897 | def OnEditLabel(self, evt): |
867 | - Publisher.sendMessage('Change surface name', index=evt.GetIndex(), name=evt.GetLabel()) | |
868 | - evt.Skip() | |
869 | - | |
870 | - def OnItemActivated(self, evt): | |
871 | - self.ToggleItem(evt.Index) | |
898 | + if not evt.IsEditCancelled(): | |
899 | + index = evt.GetIndex() | |
900 | + self.SetItem(index, 1, evt.GetLabel()) | |
901 | + Publisher.sendMessage('Change surface name', index=evt.GetIndex(), name=evt.GetLabel()) | |
872 | 902 | evt.Skip() |
873 | 903 | |
874 | 904 | def OnCheckItem(self, index, flag): |
... | ... | @@ -944,28 +974,6 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
944 | 974 | self.SetItem(index, 4, transparency) |
945 | 975 | self.SetItemImage(index, 1) |
946 | 976 | |
947 | - def CreateColourBitmap(self, colour): | |
948 | - """ | |
949 | - Create a wx Image with a mask colour. | |
950 | - colour: colour in rgb format(0 - 1) | |
951 | - """ | |
952 | - image = self.image_gray | |
953 | - new_image = Image.new("RGB", image.size) | |
954 | - for x in range(image.size[0]): | |
955 | - for y in range(image.size[1]): | |
956 | - pixel_colour = [int(i*image.getpixel((x,y))) | |
957 | - for i in colour] | |
958 | - new_image.putpixel((x,y), tuple(pixel_colour)) | |
959 | - | |
960 | - wx_image = wx.Image(new_image.size[0], | |
961 | - new_image.size[1]) | |
962 | - try: | |
963 | - wx_image.SetData(new_image.tostring()) | |
964 | - except Exception: | |
965 | - wx_image.SetData(new_image.tobytes()) | |
966 | - | |
967 | - return wx.Bitmap(wx_image.Scale(16, 16)) | |
968 | - | |
969 | 977 | def EditSurfaceTransparency(self, surface_index, transparency): |
970 | 978 | """ |
971 | 979 | Set actor transparency (oposite to opacity) according to given actor |
... | ... | @@ -985,19 +993,11 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
985 | 993 | #------------------------------------------------- |
986 | 994 | #------------------------------------------------- |
987 | 995 | |
988 | -class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCtrlMixin): | |
989 | - | |
996 | +class MeasuresListCtrlPanel(InvListCtrl): | |
990 | 997 | def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, |
991 | - size=wx.DefaultSize, style=wx.LC_REPORT): | |
992 | - | |
993 | - # native look and feel for MacOS | |
994 | - #if wx.Platform == "__WXMAC__": | |
995 | - # wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", 0) | |
996 | - | |
997 | - wx.ListCtrl.__init__(self, parent, ID, pos, size, style=wx.LC_REPORT) | |
998 | - listmix.TextEditMixin.__init__(self) | |
999 | - listmix.CheckListCtrlMixin.__init__(self) | |
1000 | - | |
998 | + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS): | |
999 | + super().__init__(parent, ID, pos, size, style=style) | |
1000 | + self._click_check = False | |
1001 | 1001 | self.__init_columns() |
1002 | 1002 | self.__init_image_list() |
1003 | 1003 | self.__init_evt() |
... | ... | @@ -1017,13 +1017,10 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
1017 | 1017 | Publisher.subscribe(self.OnRemoveGUIMeasure, 'Remove GUI measurement') |
1018 | 1018 | |
1019 | 1019 | def __bind_events_wx(self): |
1020 | - self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) | |
1021 | - self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginLabelEdit) | |
1022 | 1020 | self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel) |
1023 | 1021 | self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected_) |
1024 | 1022 | self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent) |
1025 | 1023 | |
1026 | - | |
1027 | 1024 | def OnKeyEvent(self, event): |
1028 | 1025 | keycode = event.GetKeyCode() |
1029 | 1026 | # Delete key |
... | ... | @@ -1116,13 +1113,13 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
1116 | 1113 | def __init_image_list(self): |
1117 | 1114 | self.imagelist = wx.ImageList(16, 16) |
1118 | 1115 | |
1119 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_invisible.jpg")) | |
1116 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_invisible.png")) | |
1120 | 1117 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
1121 | 1118 | bitmap.SetWidth(16) |
1122 | 1119 | bitmap.SetHeight(16) |
1123 | 1120 | img_null = self.imagelist.Add(bitmap) |
1124 | 1121 | |
1125 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_visible.jpg")) | |
1122 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_visible.png")) | |
1126 | 1123 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
1127 | 1124 | bitmap.SetWidth(16) |
1128 | 1125 | bitmap.SetHeight(16) |
... | ... | @@ -1130,7 +1127,7 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
1130 | 1127 | |
1131 | 1128 | self.SetImageList(self.imagelist,wx.IMAGE_LIST_SMALL) |
1132 | 1129 | |
1133 | - self.image_gray = Image.open(os.path.join(inv_paths.ICON_DIR, "object_colour.jpg")) | |
1130 | + self.image_gray = Image.open(os.path.join(inv_paths.ICON_DIR, "object_colour.png")) | |
1134 | 1131 | |
1135 | 1132 | def OnBeginLabelEdit(self, evt): |
1136 | 1133 | if evt.GetColumn() == 1: |
... | ... | @@ -1139,14 +1136,12 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
1139 | 1136 | evt.Veto() |
1140 | 1137 | |
1141 | 1138 | def OnEditLabel(self, evt): |
1142 | - Publisher.sendMessage('Change measurement name', index=evt.GetIndex(), name=evt.GetLabel()) | |
1139 | + if not evt.IsEditCancelled(): | |
1140 | + index = evt.GetIndex() | |
1141 | + self.SetItem(index, 1, evt.GetLabel()) | |
1142 | + Publisher.sendMessage('Change measurement name', index=evt.GetIndex(), name=evt.GetLabel()) | |
1143 | 1143 | evt.Skip() |
1144 | 1144 | |
1145 | - def OnItemActivated(self, evt): | |
1146 | - self.ToggleItem(evt.Index) | |
1147 | - evt.Skip() | |
1148 | - | |
1149 | - | |
1150 | 1145 | def OnCheckItem(self, index, flag): |
1151 | 1146 | Publisher.sendMessage('Show measurement', index=index, visibility=flag) |
1152 | 1147 | |
... | ... | @@ -1238,27 +1233,6 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
1238 | 1233 | self.SetItemImage(index, 1) |
1239 | 1234 | self.Refresh() |
1240 | 1235 | |
1241 | - def CreateColourBitmap(self, colour): | |
1242 | - """ | |
1243 | - Create a wx Image with a mask colour. | |
1244 | - colour: colour in rgb format(0 - 1) | |
1245 | - """ | |
1246 | - image = self.image_gray | |
1247 | - new_image = Image.new("RGB", image.size) | |
1248 | - for x in range(image.size[0]): | |
1249 | - for y in range(image.size[1]): | |
1250 | - pixel_colour = [int(i*image.getpixel((x,y))) | |
1251 | - for i in colour] | |
1252 | - new_image.putpixel((x,y), tuple(pixel_colour)) | |
1253 | - | |
1254 | - wx_image = wx.Image(new_image.size[0], | |
1255 | - new_image.size[1]) | |
1256 | - try: | |
1257 | - wx_image.SetData(new_image.tostring()) | |
1258 | - except: | |
1259 | - wx_image.SetData(new_image.tobytes()) | |
1260 | - return wx.Bitmap(wx_image.Scale(16, 16)) | |
1261 | - | |
1262 | 1236 | def EditItemColour(self, measure_index, colour): |
1263 | 1237 | """ |
1264 | 1238 | """ |
... | ... | @@ -1273,19 +1247,12 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis |
1273 | 1247 | #******************************************************************* |
1274 | 1248 | |
1275 | 1249 | |
1276 | -class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCtrlMixin): | |
1250 | +class AnnotationsListCtrlPanel(wx.ListCtrl): | |
1277 | 1251 | # TODO: Remove edimixin, allow only visible and invisible |
1278 | 1252 | def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, |
1279 | - size=wx.DefaultSize, style=wx.LC_REPORT): | |
1280 | - | |
1281 | - # native look and feel for MacOS | |
1282 | - #if wx.Platform == "__WXMAC__": | |
1283 | - # wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", 0) | |
1284 | - | |
1285 | - wx.ListCtrl.__init__(self, parent, ID, pos, size, style=wx.LC_REPORT) | |
1286 | - listmix.TextEditMixin.__init__(self) | |
1287 | - listmix.CheckListCtrlMixin.__init__(self) | |
1288 | - | |
1253 | + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS): | |
1254 | + wx.ListCtrl.__init__(self, parent, ID, pos, size, style=style) | |
1255 | + self._click_check = False | |
1289 | 1256 | self.__init_columns() |
1290 | 1257 | self.__init_image_list() |
1291 | 1258 | self.__init_evt() |
... | ... | @@ -1311,19 +1278,19 @@ class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.Check |
1311 | 1278 | def __init_image_list(self): |
1312 | 1279 | self.imagelist = wx.ImageList(16, 16) |
1313 | 1280 | |
1314 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_visible.jpg")) | |
1281 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_visible.png")) | |
1315 | 1282 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
1316 | 1283 | bitmap.SetWidth(16) |
1317 | 1284 | bitmap.SetHeight(16) |
1318 | 1285 | img_check = self.imagelist.Add(bitmap) |
1319 | 1286 | |
1320 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_invisible.jpg")) | |
1287 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_invisible.png")) | |
1321 | 1288 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
1322 | 1289 | bitmap.SetWidth(16) |
1323 | 1290 | bitmap.SetHeight(16) |
1324 | 1291 | img_null = self.imagelist.Add(bitmap) |
1325 | 1292 | |
1326 | - image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_colour.jpg")) | |
1293 | + image = wx.Image(os.path.join(inv_paths.ICON_DIR, "object_colour.png")) | |
1327 | 1294 | bitmap = wx.Bitmap(image.Scale(16, 16)) |
1328 | 1295 | bitmap.SetWidth(16) |
1329 | 1296 | bitmap.SetHeight(16) | ... | ... |
invesalius/gui/default_tasks.py
invesalius/gui/default_viewers.py
... | ... | @@ -111,7 +111,7 @@ class Panel(wx.Panel): |
111 | 111 | p3.SetPopupMenu(menu) |
112 | 112 | |
113 | 113 | |
114 | - if sys.platform == 'win32': | |
114 | + if sys.platform == 'win32' or wx.VERSION >= (4, 1): | |
115 | 115 | self.aui_manager.AddPane(p1, s1) |
116 | 116 | self.aui_manager.AddPane(p2, s2) |
117 | 117 | self.aui_manager.AddPane(p3, s3) |
... | ... | @@ -604,7 +604,7 @@ class VolumeToolPanel(wx.Panel): |
604 | 604 | id = evt.GetId() |
605 | 605 | item = ID_TO_ITEMSLICEMENU[id] |
606 | 606 | checked = item.IsChecked() |
607 | - label = item.GetLabel() | |
607 | + label = item.GetItemLabelText() | |
608 | 608 | |
609 | 609 | if not (checked): |
610 | 610 | Publisher.sendMessage('Disable plane', plane_label=label) | ... | ... |
invesalius/gui/dialogs.py
... | ... | @@ -245,9 +245,7 @@ WILDCARD_OPEN = "InVesalius 3 project (*.inv3)|*.inv3|" \ |
245 | 245 | WILDCARD_ANALYZE = "Analyze 7.5 (*.hdr)|*.hdr|" \ |
246 | 246 | "All files (*.*)|*.*" |
247 | 247 | |
248 | -WILDCARD_NIFTI = "NIfTI 1 (*.nii)|*.nii|" \ | |
249 | - "Compressed NIfTI (*.nii.gz)|*.nii.gz|" \ | |
250 | - "HDR NIfTI (*.hdr)|*.hdr|" \ | |
248 | +WILDCARD_NIFTI = "NIfTI 1 (*.nii;*.nii.gz;*.hdr)|*.nii;*.nii.gz;*.hdr|" \ | |
251 | 249 | "All files (*.*)|*.*" |
252 | 250 | #".[jJ][pP][gG]" |
253 | 251 | WILDCARD_PARREC = "PAR/REC (*.par)|*.par|" \ |
... | ... | @@ -1950,17 +1948,17 @@ class WatershedOptionsPanel(wx.Panel): |
1950 | 1948 | min_value=1, max_value=10) |
1951 | 1949 | |
1952 | 1950 | box_sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Conectivity"), wx.VERTICAL) |
1953 | - box_sizer.Add(self.choice_2dcon, 0, wx.ALIGN_CENTER_VERTICAL,2) | |
1954 | - box_sizer.Add(self.choice_3dcon, 0, wx.ALIGN_CENTER_VERTICAL,2) | |
1951 | + box_sizer.Add(self.choice_2dcon, 0, wx.ALL, 5) | |
1952 | + box_sizer.Add(self.choice_3dcon, 0, wx.ALL, 5) | |
1955 | 1953 | |
1956 | 1954 | g_sizer = wx.BoxSizer(wx.HORIZONTAL) |
1957 | - g_sizer.Add(wx.StaticText(self, -1, _("Gaussian sigma")), 0, wx.ALIGN_RIGHT | wx.ALL, 5) | |
1958 | - g_sizer.Add(self.gaussian_size, 0, wx.ALIGN_LEFT | wx.ALL, 5) | |
1955 | + g_sizer.Add(wx.StaticText(self, -1, _("Gaussian sigma")), 0, wx.ALIGN_CENTER | wx.ALL, 5) | |
1956 | + g_sizer.Add(self.gaussian_size, 0, wx.ALL, 5) | |
1959 | 1957 | |
1960 | 1958 | sizer = wx.BoxSizer(wx.VERTICAL) |
1961 | - sizer.Add(self.choice_algorithm, 0, wx.ALIGN_CENTER_VERTICAL,2) | |
1962 | - sizer.Add(box_sizer, 1, wx.EXPAND,2) | |
1963 | - sizer.Add(g_sizer, 0, wx.ALIGN_LEFT, 2) | |
1959 | + sizer.Add(self.choice_algorithm, 0, wx.ALL, 5) | |
1960 | + sizer.Add(box_sizer, 1, wx.EXPAND | wx.ALL, 5) | |
1961 | + sizer.Add(g_sizer, 0, wx.ALL, 5) | |
1964 | 1962 | |
1965 | 1963 | self.SetSizer(sizer) |
1966 | 1964 | sizer.Fit(self) |
... | ... | @@ -1998,8 +1996,7 @@ class WatershedOptionsDialog(wx.Dialog): |
1998 | 1996 | btnsizer.Realize() |
1999 | 1997 | |
2000 | 1998 | sizer.Add(wop, 0, wx.EXPAND) |
2001 | - sizer.Add(btnsizer, 0, wx.EXPAND) | |
2002 | - sizer.AddSpacer(5) | |
1999 | + sizer.Add(btnsizer, 0, wx.ALIGN_RIGHT | wx.BOTTOM, 5) | |
2003 | 2000 | |
2004 | 2001 | self.SetSizer(sizer) |
2005 | 2002 | sizer.Fit(self) |
... | ... | @@ -2060,16 +2057,16 @@ class MaskBooleanDialog(wx.Dialog): |
2060 | 2057 | |
2061 | 2058 | gsizer = wx.FlexGridSizer(rows=3, cols=2, hgap=5, vgap=5) |
2062 | 2059 | |
2063 | - gsizer.Add(wx.StaticText(self, -1, _(u"Mask 1"))) | |
2060 | + gsizer.Add(wx.StaticText(self, -1, _(u"Mask 1")), 0, wx.ALIGN_CENTER_VERTICAL) | |
2064 | 2061 | gsizer.Add(self.mask1, 1, wx.EXPAND) |
2065 | - gsizer.Add(wx.StaticText(self, -1, _(u"Operation"))) | |
2062 | + gsizer.Add(wx.StaticText(self, -1, _(u"Operation")), 0, wx.ALIGN_CENTER_VERTICAL) | |
2066 | 2063 | gsizer.Add(self.op_boolean, 1, wx.EXPAND) |
2067 | - gsizer.Add(wx.StaticText(self, -1, _(u"Mask 2"))) | |
2064 | + gsizer.Add(wx.StaticText(self, -1, _(u"Mask 2")), 0, wx.ALIGN_CENTER_VERTICAL) | |
2068 | 2065 | gsizer.Add(self.mask2, 1, wx.EXPAND) |
2069 | 2066 | |
2070 | 2067 | sizer = wx.BoxSizer(wx.VERTICAL) |
2071 | - sizer.Add(gsizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) | |
2072 | - sizer.Add(btnsizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) | |
2068 | + sizer.Add(gsizer, 0, wx.EXPAND | wx.ALL, border=5) | |
2069 | + sizer.Add(btnsizer, 0, wx.EXPAND | wx.ALL, border=5) | |
2073 | 2070 | |
2074 | 2071 | self.SetSizer(sizer) |
2075 | 2072 | sizer.Fit(self) |
... | ... | @@ -2798,8 +2795,8 @@ class SelectPartsOptionsDialog(wx.Dialog): |
2798 | 2795 | sizer.AddSpacer(5) |
2799 | 2796 | |
2800 | 2797 | btn_sizer = wx.BoxSizer(wx.HORIZONTAL) |
2801 | - btn_sizer.Add(self.btn_ok, 0, flag=wx.ALIGN_RIGHT, border=5) | |
2802 | - btn_sizer.Add(self.btn_cancel, 0, flag=wx.LEFT|wx.ALIGN_RIGHT, border=5) | |
2798 | + btn_sizer.Add(self.btn_ok, 0)# flag=wx.ALIGN_RIGHT, border=5) | |
2799 | + btn_sizer.Add(self.btn_cancel, 0, flag=wx.LEFT, border=5) | |
2803 | 2800 | |
2804 | 2801 | sizer.Add(btn_sizer, 0, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT, border=5) |
2805 | 2802 | sizer.AddSpacer(5) |
... | ... | @@ -3202,8 +3199,8 @@ class FillHolesAutoDialog(wx.Dialog): |
3202 | 3199 | sizer.AddSpacer(5) |
3203 | 3200 | |
3204 | 3201 | btn_sizer = wx.BoxSizer(wx.HORIZONTAL) |
3205 | - btn_sizer.Add(self.apply_btn, 0, flag=wx.ALIGN_RIGHT, border=5) | |
3206 | - btn_sizer.Add(self.close_btn, 0, flag=wx.LEFT|wx.ALIGN_RIGHT, border=5) | |
3202 | + btn_sizer.Add(self.apply_btn, 0)# flag=wx.ALIGN_RIGHT, border=5) | |
3203 | + btn_sizer.Add(self.close_btn, 0, flag=wx.LEFT, border=5) | |
3207 | 3204 | |
3208 | 3205 | sizer.Add(btn_sizer, 0, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT, border=5) |
3209 | 3206 | ... | ... |
invesalius/gui/dicom_preview_panel.py
... | ... | @@ -789,8 +789,8 @@ class SingleImagePreview(wx.Panel): |
789 | 789 | in_sizer.Add(checkbox, 0) |
790 | 790 | |
791 | 791 | sizer = wx.BoxSizer(wx.VERTICAL) |
792 | - sizer.Add(self.panel, 20, wx.GROW|wx.EXPAND) | |
793 | - sizer.Add(in_sizer, 1, wx.GROW|wx.EXPAND) | |
792 | + sizer.Add(self.panel, 1, wx.GROW|wx.EXPAND) | |
793 | + sizer.Add(in_sizer, 0, wx.GROW|wx.EXPAND) | |
794 | 794 | sizer.Fit(self) |
795 | 795 | |
796 | 796 | self.SetSizer(sizer) | ... | ... |
invesalius/gui/frame.py
... | ... | @@ -214,7 +214,7 @@ class Frame(wx.Frame): |
214 | 214 | # Add toolbars to manager |
215 | 215 | # This is pretty tricky -- order on win32 is inverted when |
216 | 216 | # compared to linux2 & darwin |
217 | - if sys.platform == 'win32': | |
217 | + if sys.platform == 'win32' or wx.VERSION >= (4, 1): | |
218 | 218 | t1 = ProjectToolBar(self) |
219 | 219 | t2 = HistoryToolBar(self) |
220 | 220 | t3 = LayoutToolBar(self) |
... | ... | @@ -259,6 +259,8 @@ class Frame(wx.Frame): |
259 | 259 | # TODO: Allow saving and restoring perspectives |
260 | 260 | self.perspective_all = aui_manager.SavePerspective() |
261 | 261 | |
262 | + self.Layout() | |
263 | + | |
262 | 264 | def _BeginBusyCursor(self): |
263 | 265 | """ |
264 | 266 | Start busy cursor. |
... | ... | @@ -1941,11 +1943,11 @@ class LayoutToolBar(AuiToolBar): |
1941 | 1943 | d = inv_paths.ICON_DIR |
1942 | 1944 | if sys.platform == 'darwin': |
1943 | 1945 | # Bitmaps for show/hide task panel item |
1944 | - p = os.path.join(d, "layout_data_only_original.gif") | |
1945 | - self.BMP_WITH_MENU = wx.Bitmap(str(p), wx.BITMAP_TYPE_GIF) | |
1946 | + p = os.path.join(d, "layout_data_only_original.png") | |
1947 | + self.BMP_WITH_MENU = wx.Bitmap(str(p), wx.BITMAP_TYPE_PNG) | |
1946 | 1948 | |
1947 | - p = os.path.join(d, "layout_full_original.gif") | |
1948 | - self.BMP_WITHOUT_MENU = wx.Bitmap(str(p), wx.BITMAP_TYPE_GIF) | |
1949 | + p = os.path.join(d, "layout_full_original.png") | |
1950 | + self.BMP_WITHOUT_MENU = wx.Bitmap(str(p), wx.BITMAP_TYPE_PNG) | |
1949 | 1951 | |
1950 | 1952 | # Bitmaps for show/hide task item |
1951 | 1953 | p = os.path.join(d, "text_inverted_original.png") |
... | ... | @@ -1956,11 +1958,11 @@ class LayoutToolBar(AuiToolBar): |
1956 | 1958 | |
1957 | 1959 | else: |
1958 | 1960 | # Bitmaps for show/hide task panel item |
1959 | - p = os.path.join(d, "layout_data_only.gif") | |
1960 | - self.BMP_WITH_MENU = wx.Bitmap(str(p), wx.BITMAP_TYPE_GIF) | |
1961 | + p = os.path.join(d, "layout_data_only.png") | |
1962 | + self.BMP_WITH_MENU = wx.Bitmap(str(p), wx.BITMAP_TYPE_PNG) | |
1961 | 1963 | |
1962 | - p = os.path.join(d, "layout_full.gif") | |
1963 | - self.BMP_WITHOUT_MENU = wx.Bitmap(str(p), wx.BITMAP_TYPE_GIF) | |
1964 | + p = os.path.join(d, "layout_full.png") | |
1965 | + self.BMP_WITHOUT_MENU = wx.Bitmap(str(p), wx.BITMAP_TYPE_PNG) | |
1964 | 1966 | |
1965 | 1967 | # Bitmaps for show/hide task item |
1966 | 1968 | p = os.path.join(d, "text_inverted.png") | ... | ... |
invesalius/gui/import_panel.py
... | ... | @@ -104,7 +104,7 @@ class InnerPanel(wx.Panel): |
104 | 104 | |
105 | 105 | inner_sizer = wx.BoxSizer(wx.HORIZONTAL) |
106 | 106 | inner_sizer.Add(btnsizer, 0, wx.LEFT|wx.TOP, 5) |
107 | - inner_sizer.Add(self.combo_interval, 0, wx.LEFT|wx.RIGHT|wx.TOP, 5) | |
107 | + inner_sizer.Add(self.combo_interval, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT|wx.TOP, 5) | |
108 | 108 | panel.SetSizer(inner_sizer) |
109 | 109 | inner_sizer.Fit(panel) |
110 | 110 | ... | ... |
invesalius/gui/language_dialog.py
... | ... | @@ -71,8 +71,8 @@ class ComboBoxLanguage: |
71 | 71 | self.bitmapCmb = bitmapCmb = BitmapComboBox(parent, style=wx.CB_READONLY) |
72 | 72 | for key in self.locales_key: |
73 | 73 | # Based on composed flag filename, get bitmap |
74 | - filepath = os.path.join(ICON_DIR, "%s.bmp"%(key)) | |
75 | - bmp = wx.Bitmap(filepath, wx.BITMAP_TYPE_BMP) | |
74 | + filepath = os.path.join(ICON_DIR, "%s.png" % (key)) | |
75 | + bmp = wx.Bitmap(filepath, wx.BITMAP_TYPE_PNG) | |
76 | 76 | # Add bitmap and info to Combo |
77 | 77 | bitmapCmb.Append(dict_locales[key], bmp, key) |
78 | 78 | # Set default combo item if available on the list |
... | ... | @@ -123,8 +123,8 @@ class LanguageDialog(wx.Dialog): |
123 | 123 | # self.bitmapCmb = bitmapCmb = BitmapComboBox(self, style=wx.CB_READONLY) |
124 | 124 | # for key in self.locales_key: |
125 | 125 | # # Based on composed flag filename, get bitmap |
126 | - # filepath = os.path.join(ICON_DIR, "%s.bmp"%(key)) | |
127 | - # bmp = wx.Bitmap(filepath, wx.BITMAP_TYPE_BMP) | |
126 | + # filepath = os.path.join(ICON_DIR, "%s.png"%(key)) | |
127 | + # bmp = wx.Bitmap(filepath, wx.BITMAP_TYPE_PNG) | |
128 | 128 | # # Add bitmap and info to Combo |
129 | 129 | # bitmapCmb.Append(dict_locales[key], bmp, key) |
130 | 130 | # # Set default combo item if available on the list | ... | ... |
invesalius/gui/preferences.py
... | ... | @@ -49,13 +49,13 @@ class Preferences(wx.Dialog): |
49 | 49 | self.book.AddPage(self.pnl_language, _("Language")) |
50 | 50 | |
51 | 51 | line = wx.StaticLine(self, -1, size=(20, -1), style=wx.LI_HORIZONTAL) |
52 | - sizer.Add(line, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP, 5) | |
52 | + sizer.Add(line, 0, wx.GROW | wx.RIGHT | wx.TOP, 5) | |
53 | 53 | |
54 | 54 | btnsizer = self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL) |
55 | 55 | sizer.Add( |
56 | 56 | btnsizer, |
57 | 57 | 0, |
58 | - wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP | wx.BOTTOM, | |
58 | + wx.GROW | wx.RIGHT | wx.TOP | wx.BOTTOM, | |
59 | 59 | 5, |
60 | 60 | ) |
61 | 61 | ... | ... |
invesalius/gui/task_navigator.py
... | ... | @@ -211,7 +211,7 @@ class InnerFoldPanel(wx.Panel): |
211 | 211 | line_sizer = wx.BoxSizer(wx.HORIZONTAL) |
212 | 212 | line_sizer.Add(checkcamera, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, 5) |
213 | 213 | line_sizer.Add(checktrigger, 0, wx.ALIGN_CENTER) |
214 | - line_sizer.Add(checkobj, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.LEFT, 5) | |
214 | + line_sizer.Add(checkobj, 0, wx.RIGHT | wx.LEFT, 5) | |
215 | 215 | line_sizer.Fit(self) |
216 | 216 | |
217 | 217 | # Panel sizer to expand fold panel |
... | ... | @@ -410,7 +410,7 @@ class NeuronavigationPanel(wx.Panel): |
410 | 410 | (nav_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL)]) |
411 | 411 | |
412 | 412 | main_sizer = wx.BoxSizer(wx.HORIZONTAL) |
413 | - main_sizer.Add(group_sizer, 1, wx.ALIGN_CENTER_HORIZONTAL, 10) | |
413 | + main_sizer.Add(group_sizer, 1)# wx.ALIGN_CENTER_HORIZONTAL, 10) | |
414 | 414 | self.sizer = main_sizer |
415 | 415 | self.SetSizer(main_sizer) |
416 | 416 | self.Fit() |
... | ... | @@ -852,7 +852,7 @@ class ObjectRegistrationPanel(wx.Panel): |
852 | 852 | |
853 | 853 | line_checks = wx.BoxSizer(wx.HORIZONTAL) |
854 | 854 | line_checks.Add(checkrecordcoords, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, 5) |
855 | - line_checks.Add(checktrack, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.LEFT, 5) | |
855 | + line_checks.Add(checktrack, 0, wx.RIGHT | wx.LEFT, 5) | |
856 | 856 | |
857 | 857 | # Add line sizers into main sizer |
858 | 858 | main_sizer = wx.BoxSizer(wx.VERTICAL) |
... | ... | @@ -1082,7 +1082,7 @@ class MarkersPanel(wx.Panel): |
1082 | 1082 | group_sizer.Add(sizer_create, 0, wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5) |
1083 | 1083 | group_sizer.Add(sizer_btns, 0, wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5) |
1084 | 1084 | group_sizer.Add(sizer_delete, 0, wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5) |
1085 | - group_sizer.Add(self.lc, 0, wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5) | |
1085 | + group_sizer.Add(self.lc, 0, wx.EXPAND | wx.ALL, 5) | |
1086 | 1086 | group_sizer.Fit(self) |
1087 | 1087 | |
1088 | 1088 | self.SetSizer(group_sizer) | ... | ... |
invesalius/gui/task_slice.py
... | ... | @@ -141,7 +141,7 @@ class InnerTaskPanel(wx.Panel): |
141 | 141 | |
142 | 142 | line_sizer = wx.BoxSizer(wx.HORIZONTAL) |
143 | 143 | line_sizer.Add(check_box, 0, wx.ALIGN_LEFT|wx.RIGHT|wx.LEFT, 5) |
144 | - line_sizer.Add(next_btn_sizer, 1, wx.EXPAND|wx.ALIGN_RIGHT|wx.RIGHT|wx.LEFT, 5) | |
144 | + line_sizer.Add(next_btn_sizer, 1, wx.EXPAND|wx.RIGHT|wx.LEFT, 5) | |
145 | 145 | line_sizer.Fit(self) |
146 | 146 | |
147 | 147 | # Add line sizers into main sizer |
... | ... | @@ -423,6 +423,7 @@ class InnerFoldPanel(wx.Panel): |
423 | 423 | try: |
424 | 424 | _id = panel_seg_id[panel_id] |
425 | 425 | self.fold_panel.Expand(self.fold_panel.GetFoldPanel(_id)) |
426 | + self.Layout() | |
426 | 427 | except KeyError: |
427 | 428 | pass |
428 | 429 | |
... | ... | @@ -688,11 +689,11 @@ class EditionTools(wx.Panel): |
688 | 689 | ## LINE 2 |
689 | 690 | menu = wx.Menu() |
690 | 691 | |
691 | - CIRCLE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_circle.jpg"), wx.BITMAP_TYPE_JPEG) | |
692 | + CIRCLE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_circle.png"), wx.BITMAP_TYPE_PNG) | |
692 | 693 | item = wx.MenuItem(menu, MENU_BRUSH_CIRCLE, _("Circle")) |
693 | 694 | item.SetBitmap(CIRCLE_BMP) |
694 | 695 | |
695 | - SQUARE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_square.jpg"), wx.BITMAP_TYPE_JPEG) | |
696 | + SQUARE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_square.png"), wx.BITMAP_TYPE_PNG) | |
696 | 697 | item2 = wx.MenuItem(menu, MENU_BRUSH_SQUARE, _("Square")) |
697 | 698 | item2.SetBitmap(SQUARE_BMP) |
698 | 699 | |
... | ... | @@ -803,8 +804,8 @@ class EditionTools(wx.Panel): |
803 | 804 | threshold_range=(thresh_min, thresh_max)) |
804 | 805 | |
805 | 806 | def OnMenu(self, evt): |
806 | - SQUARE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_square.jpg"), wx.BITMAP_TYPE_JPEG) | |
807 | - CIRCLE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_circle.jpg"), wx.BITMAP_TYPE_JPEG) | |
807 | + SQUARE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_square.png"), wx.BITMAP_TYPE_PNG) | |
808 | + CIRCLE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_circle.png"), wx.BITMAP_TYPE_PNG) | |
808 | 809 | |
809 | 810 | brush = {MENU_BRUSH_CIRCLE: const.BRUSH_CIRCLE, |
810 | 811 | MENU_BRUSH_SQUARE: const.BRUSH_SQUARE} |
... | ... | @@ -852,11 +853,11 @@ class WatershedTool(EditionTools): |
852 | 853 | ## LINE 2 |
853 | 854 | menu = wx.Menu() |
854 | 855 | |
855 | - CIRCLE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_circle.jpg"), wx.BITMAP_TYPE_JPEG) | |
856 | + CIRCLE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_circle.png"), wx.BITMAP_TYPE_PNG) | |
856 | 857 | item = wx.MenuItem(menu, MENU_BRUSH_CIRCLE, _("Circle")) |
857 | 858 | item.SetBitmap(CIRCLE_BMP) |
858 | 859 | |
859 | - SQUARE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_square.jpg"), wx.BITMAP_TYPE_JPEG) | |
860 | + SQUARE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_square.png"), wx.BITMAP_TYPE_PNG) | |
860 | 861 | item2 = wx.MenuItem(menu, MENU_BRUSH_SQUARE, _("Square")) |
861 | 862 | item2.SetBitmap(SQUARE_BMP) |
862 | 863 | |
... | ... | @@ -973,8 +974,8 @@ class WatershedTool(EditionTools): |
973 | 974 | self.gradient_thresh.SetMaxValue(thresh_max) |
974 | 975 | |
975 | 976 | def OnMenu(self, evt): |
976 | - SQUARE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_square.jpg"), wx.BITMAP_TYPE_JPEG) | |
977 | - CIRCLE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_circle.jpg"), wx.BITMAP_TYPE_JPEG) | |
977 | + SQUARE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_square.png"), wx.BITMAP_TYPE_PNG) | |
978 | + CIRCLE_BMP = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "brush_circle.png"), wx.BITMAP_TYPE_PNG) | |
978 | 979 | |
979 | 980 | brush = {MENU_BRUSH_CIRCLE: const.BRUSH_CIRCLE, |
980 | 981 | MENU_BRUSH_SQUARE: const.BRUSH_SQUARE} | ... | ... |
invesalius/gui/task_surface.py
... | ... | @@ -30,6 +30,7 @@ except ImportError: |
30 | 30 | |
31 | 31 | from pubsub import pub as Publisher |
32 | 32 | import wx.lib.colourselect as csel |
33 | +import wx.lib.scrolledpanel as scrolled | |
33 | 34 | |
34 | 35 | import invesalius.constants as const |
35 | 36 | import invesalius.data.slice_ as slice_ |
... | ... | @@ -74,9 +75,9 @@ class TaskPanel(wx.Panel): |
74 | 75 | # Contour - slider |
75 | 76 | # enable / disable Fill holes |
76 | 77 | |
77 | -class InnerTaskPanel(wx.Panel): | |
78 | +class InnerTaskPanel(scrolled.ScrolledPanel): | |
78 | 79 | def __init__(self, parent): |
79 | - wx.Panel.__init__(self, parent) | |
80 | + scrolled.ScrolledPanel.__init__(self, parent) | |
80 | 81 | default_colour = self.GetBackgroundColour() |
81 | 82 | backgroud_colour = wx.Colour(255,255,255) |
82 | 83 | self.SetBackgroundColour(backgroud_colour) |
... | ... | @@ -134,6 +135,13 @@ class InnerTaskPanel(wx.Panel): |
134 | 135 | |
135 | 136 | self.sizer = main_sizer |
136 | 137 | |
138 | + self.SetupScrolling() | |
139 | + | |
140 | + self.Bind(wx.EVT_SIZE, self.OnSize) | |
141 | + | |
142 | + def OnSize(self, evt): | |
143 | + self.SetupScrolling() | |
144 | + | |
137 | 145 | def OnButton(self, evt): |
138 | 146 | id = evt.GetId() |
139 | 147 | if id == BTN_NEW: |
... | ... | @@ -437,9 +445,9 @@ class SurfaceTools(wx.Panel): |
437 | 445 | |
438 | 446 | |
439 | 447 | |
440 | -class SurfaceProperties(wx.Panel): | |
448 | +class SurfaceProperties(scrolled.ScrolledPanel): | |
441 | 449 | def __init__(self, parent): |
442 | - wx.Panel.__init__(self, parent) | |
450 | + scrolled.ScrolledPanel.__init__(self, parent) | |
443 | 451 | try: |
444 | 452 | default_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENUBAR) |
445 | 453 | except AttributeError: |
... | ... | @@ -507,8 +515,16 @@ class SurfaceProperties(wx.Panel): |
507 | 515 | self.Update() |
508 | 516 | #self.SetAutoLayout(1) |
509 | 517 | |
518 | + self.SetupScrolling() | |
519 | + | |
520 | + self.Bind(wx.EVT_SIZE, self.OnResize) | |
521 | + | |
510 | 522 | self.__bind_events() |
511 | 523 | |
524 | + def OnResize(self, evt): | |
525 | + print("Resize") | |
526 | + self.SetupScrolling() | |
527 | + | |
512 | 528 | def __bind_events(self): |
513 | 529 | Publisher.subscribe(self.InsertNewSurface, |
514 | 530 | 'Update surface info in GUI') | ... | ... |
invesalius/gui/task_tools.py
... | ... | @@ -79,7 +79,7 @@ class InnerTaskPanel(wx.Panel): |
79 | 79 | |
80 | 80 | # Image(s) for buttons |
81 | 81 | BMP_ANNOTATE = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "annotation.png"), wx.BITMAP_TYPE_PNG) |
82 | - BMP_ANGLE = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "measure_angle.jpg"), wx.BITMAP_TYPE_JPEG) | |
82 | + BMP_ANGLE = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "measure_angle.png"), wx.BITMAP_TYPE_PNG) | |
83 | 83 | BMP_DISTANCE = wx.Bitmap(os.path.join(inv_paths.ICON_DIR, "measure_line.png"), wx.BITMAP_TYPE_PNG) |
84 | 84 | BMP_ANNOTATE.SetWidth(25) |
85 | 85 | BMP_ANNOTATE.SetHeight(25) | ... | ... |
invesalius/gui/widgets/gradient.py
... | ... | @@ -26,7 +26,15 @@ from wx.lib import intctrl |
26 | 26 | |
27 | 27 | from invesalius.gui.widgets.inv_spinctrl import InvSpinCtrl |
28 | 28 | |
29 | -PUSH_WIDTH = 7 | |
29 | +try: | |
30 | + dc = wx.MemoryDC() | |
31 | + font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) | |
32 | + dc.SetFont(font) | |
33 | + PUSH_WIDTH = dc.GetTextExtent("M")[0] // 2 + 1 | |
34 | + del dc | |
35 | + del font | |
36 | +except Exception: | |
37 | + PUSH_WIDTH = 7 | |
30 | 38 | |
31 | 39 | myEVT_SLIDER_CHANGED = wx.NewEventType() |
32 | 40 | EVT_SLIDER_CHANGED = wx.PyEventBinder(myEVT_SLIDER_CHANGED, 1) |
... | ... | @@ -70,6 +78,8 @@ class GradientSlider(wx.Panel): |
70 | 78 | self.colour = colour |
71 | 79 | self.selected = 0 |
72 | 80 | |
81 | + self._gradient_colours = None | |
82 | + | |
73 | 83 | self.CalculateControlPositions() |
74 | 84 | |
75 | 85 | def _bind_events_wx(self): |
... | ... | @@ -131,27 +141,43 @@ class GradientSlider(wx.Panel): |
131 | 141 | |
132 | 142 | width_transparency = self.max_position - self.min_position |
133 | 143 | |
134 | - # Drawing the left blank area. | |
135 | - pen = wx.Pen((0, 0, 0)) | |
136 | - brush = wx.Brush((0, 0, 0)) | |
137 | - dc.SetPen(pen) | |
138 | - dc.SetBrush(brush) | |
139 | - dc.DrawRectangle(0, 0, PUSH_WIDTH, h) | |
140 | - | |
141 | - # Drawing the right blank area. | |
142 | - pen = wx.Pen((255, 255, 255)) | |
143 | - brush = wx.Brush((255, 255, 255)) | |
144 | - dc.SetPen(pen) | |
145 | - dc.SetBrush(brush) | |
146 | - dc.DrawRectangle(x_init_gradient + width_gradient, 0, PUSH_WIDTH, h) | |
147 | - | |
148 | - # Drawing the gradient. | |
149 | - dc.GradientFillLinear( | |
150 | - (x_init_gradient, y_init_gradient, width_gradient, height_gradient), | |
151 | - (0, 0, 0), | |
152 | - (255, 255, 255), | |
153 | - ) | |
154 | - | |
144 | + gc = wx.GraphicsContext.Create(dc) | |
145 | + | |
146 | + points = ((0, PUSH_WIDTH, (0, 0, 0), (0, 0, 0)), | |
147 | + (PUSH_WIDTH, w - PUSH_WIDTH, (0, 0, 0), (255, 255, 255)), | |
148 | + (w - PUSH_WIDTH, w, (255, 255, 255), (255, 255, 255))) | |
149 | + | |
150 | + # Drawing the gradient background | |
151 | + for p1, p2, c1, c2 in points: | |
152 | + brush = gc.CreateLinearGradientBrush(p1, 0, p2, h, c1, c2) | |
153 | + gc.SetBrush(brush) | |
154 | + path = gc.CreatePath() | |
155 | + path.AddRectangle(p1, 0, p2 - p1, h) | |
156 | + gc.StrokePath(path) | |
157 | + gc.FillPath(path) | |
158 | + | |
159 | + # Drawing the transparent coloured overlay | |
160 | + if self._gradient_colours is None: | |
161 | + brush = wx.Brush(wx.Colour(*self.colour)) | |
162 | + pen = wx.Pen(wx.Colour(*self.colour)) | |
163 | + gc.SetBrush(brush) | |
164 | + gc.SetPen(pen) | |
165 | + path = gc.CreatePath() | |
166 | + path.AddRectangle(self.min_position, 0, width_transparency, h) | |
167 | + gc.FillPath(path) | |
168 | + gc.StrokePath(path) | |
169 | + else: | |
170 | + for i, (c1, c2) in enumerate(zip(self._gradient_colours, self._gradient_colours[1:])): | |
171 | + p1 = self.min_position + i * width_transparency / len(self._gradient_colours) | |
172 | + p2 = self.min_position + (i + 1) * width_transparency / len(self._gradient_colours) | |
173 | + brush = gc.CreateLinearGradientBrush(p1, 0, p2, h, c1, c2) | |
174 | + gc.SetBrush(brush) | |
175 | + path = gc.CreatePath() | |
176 | + path.AddRectangle(p1, 0, p2 - p1, h) | |
177 | + gc.StrokePath(path) | |
178 | + gc.FillPath(path) | |
179 | + | |
180 | + # Drawing the pushes | |
155 | 181 | try: |
156 | 182 | n = wx.RendererNative.Get() |
157 | 183 | except AttributeError: |
... | ... | @@ -161,14 +187,14 @@ class GradientSlider(wx.Panel): |
161 | 187 | n.DrawPushButton(self, dc, (x_init_push1, 0, PUSH_WIDTH, h)) |
162 | 188 | n.DrawPushButton(self, dc, (x_init_push2, 0, PUSH_WIDTH, h)) |
163 | 189 | |
164 | - # Drawing the transparent slider. | |
165 | - bytes = numpy.array(self.colour * width_transparency * h, "B") | |
166 | - try: | |
167 | - slider = wx.Bitmap.FromBufferRGBA(width_transparency, h, bytes) | |
168 | - except: | |
169 | - pass | |
170 | - else: | |
171 | - dc.DrawBitmap(slider, self.min_position, 0, True) | |
190 | + # # Drawing the transparent slider. | |
191 | + # bytes = numpy.array(self.colour * width_transparency * h, "B") | |
192 | + # try: | |
193 | + # slider = wx.Bitmap.FromBufferRGBA(width_transparency, h, bytes) | |
194 | + # except: | |
195 | + # pass | |
196 | + # else: | |
197 | + # dc.DrawBitmap(slider, self.min_position, 0, True) | |
172 | 198 | |
173 | 199 | def OnEraseBackGround(self, evt): |
174 | 200 | # Only to avoid this widget to flick. |
... | ... | @@ -316,6 +342,9 @@ class GradientSlider(wx.Panel): |
316 | 342 | def SetColour(self, colour): |
317 | 343 | self.colour = colour |
318 | 344 | |
345 | + def SetGradientColours(self, colors): | |
346 | + self._gradient_colours = colors | |
347 | + | |
319 | 348 | def SetMinRange(self, min_range): |
320 | 349 | self.min_range = min_range |
321 | 350 | self.CalculateControlPositions() |
... | ... | @@ -485,6 +514,9 @@ class GradientCtrl(wx.Panel): |
485 | 514 | self.gradient_slider.SetColour(colour) |
486 | 515 | self.gradient_slider.Refresh() |
487 | 516 | |
517 | + def SetGradientColours(self, colors): | |
518 | + self.gradient_slider.SetGradientColours(colors) | |
519 | + | |
488 | 520 | def SetMaxRange(self, value): |
489 | 521 | self.spin_min.SetMax(value) |
490 | 522 | self.spin_max.SetMax(value) | ... | ... |
invesalius/gui/widgets/slice_menu.py
... | ... | @@ -205,7 +205,7 @@ class SliceMenu(wx.Menu): |
205 | 205 | def OnPopup(self, evt): |
206 | 206 | id = evt.GetId() |
207 | 207 | item = self.ID_TO_TOOL_ITEM[evt.GetId()] |
208 | - key = item.GetLabel() | |
208 | + key = item.GetItemLabelText() | |
209 | 209 | if(key in const.WINDOW_LEVEL.keys()): |
210 | 210 | window, level = const.WINDOW_LEVEL[key] |
211 | 211 | Publisher.sendMessage('Bright and contrast adjustment image', | ... | ... |
invesalius/inv_paths.py
... | ... | @@ -38,6 +38,8 @@ OLD_USER_LOG_DIR = OLD_USER_INV_DIR.joinpath("logs") |
38 | 38 | |
39 | 39 | INV_TOP_DIR = pathlib.Path(__file__).parent.parent.resolve() |
40 | 40 | |
41 | +PLUGIN_DIRECTORY = INV_TOP_DIR.joinpath("plugins") | |
42 | + | |
41 | 43 | ICON_DIR = INV_TOP_DIR.joinpath("icons") |
42 | 44 | SAMPLE_DIR = INV_TOP_DIR.joinpath("samples") |
43 | 45 | DOC_DIR = INV_TOP_DIR.joinpath("docs") | ... | ... |
invesalius/plugins.py
... | ... | @@ -25,6 +25,7 @@ from pubsub import pub as Publisher |
25 | 25 | |
26 | 26 | import invesalius.constants as consts |
27 | 27 | from invesalius import inv_paths |
28 | +from itertools import chain | |
28 | 29 | |
29 | 30 | |
30 | 31 | def import_source(module_name, module_file_path): |
... | ... | @@ -44,7 +45,8 @@ class PluginManager: |
44 | 45 | |
45 | 46 | def find_plugins(self): |
46 | 47 | self.plugins = {} |
47 | - for p in sorted(inv_paths.USER_PLUGINS_DIRECTORY.glob("*")): | |
48 | + for p in sorted(chain(inv_paths.USER_PLUGINS_DIRECTORY.glob("*"),\ | |
49 | + inv_paths.PLUGIN_DIRECTORY.glob("*"))): | |
48 | 50 | if p.is_dir(): |
49 | 51 | try: |
50 | 52 | with p.joinpath("plugin.json").open() as f: | ... | ... |
invesalius/reader/dicom_grouper.py
... | ... | @@ -130,23 +130,23 @@ class DicomGroup: |
130 | 130 | else: |
131 | 131 | filelist = [dicom.image.file for dicom in |
132 | 132 | self.slices_dict.values()] |
133 | - | |
133 | + | |
134 | 134 | # Sort slices using GDCM |
135 | - if (self.dicom.image.orientation_label != "CORONAL"): | |
136 | - #Organize reversed image | |
137 | - sorter = gdcm.IPPSorter() | |
138 | - sorter.SetComputeZSpacing(True) | |
139 | - sorter.SetZSpacingTolerance(1e-10) | |
140 | - try: | |
141 | - sorter.Sort([utils.encode(i, const.FS_ENCODE) for i in filelist]) | |
142 | - except TypeError: | |
143 | - sorter.Sort(filelist) | |
144 | - filelist = sorter.GetFilenames() | |
135 | + #if (self.dicom.image.orientation_label != "CORONAL"): | |
136 | + #Organize reversed image | |
137 | + sorter = gdcm.IPPSorter() | |
138 | + sorter.SetComputeZSpacing(True) | |
139 | + sorter.SetZSpacingTolerance(1e-10) | |
140 | + try: | |
141 | + sorter.Sort([utils.encode(i, const.FS_ENCODE) for i in filelist]) | |
142 | + except TypeError: | |
143 | + sorter.Sort(filelist) | |
144 | + filelist = sorter.GetFilenames() | |
145 | 145 | |
146 | 146 | # for breast-CT of koning manufacturing (KBCT) |
147 | 147 | if list(self.slices_dict.values())[0].parser.GetManufacturerName() == "Koning": |
148 | 148 | filelist.sort() |
149 | - | |
149 | + | |
150 | 150 | return filelist |
151 | 151 | |
152 | 152 | def GetHandSortedList(self): | ... | ... |
invesalius/reader/dicom_reader.py
... | ... | @@ -82,15 +82,15 @@ def SelectLargerDicomGroup(patient_group): |
82 | 82 | def SortFiles(filelist, dicom): |
83 | 83 | # Sort slices |
84 | 84 | # FIXME: Coronal Crash. necessary verify |
85 | - if (dicom.image.orientation_label != "CORONAL"): | |
86 | - ##Organize reversed image | |
87 | - sorter = gdcm.IPPSorter() | |
88 | - sorter.SetComputeZSpacing(True) | |
89 | - sorter.SetZSpacingTolerance(1e-10) | |
90 | - sorter.Sort(filelist) | |
91 | - | |
92 | - #Getting organized image | |
93 | - filelist = sorter.GetFilenames() | |
85 | + # if (dicom.image.orientation_label != "CORONAL"): | |
86 | + ##Organize reversed image | |
87 | + sorter = gdcm.IPPSorter() | |
88 | + sorter.SetComputeZSpacing(True) | |
89 | + sorter.SetZSpacingTolerance(1e-10) | |
90 | + sorter.Sort(filelist) | |
91 | + | |
92 | + #Getting organized image | |
93 | + filelist = sorter.GetFilenames() | |
94 | 94 | |
95 | 95 | return filelist |
96 | 96 | ... | ... |
invesalius/segmentation/brain/segment.py
... | ... | @@ -20,6 +20,17 @@ SIZE = 48 |
20 | 20 | OVERLAP = SIZE // 2 + 1 |
21 | 21 | |
22 | 22 | |
23 | +def get_LUT_value(data, window, level): | |
24 | + shape = data.shape | |
25 | + data_ = data.ravel() | |
26 | + data = np.piecewise(data_, | |
27 | + [data_ <= (level - 0.5 - (window-1)/2), | |
28 | + data_ > (level - 0.5 + (window-1)/2)], | |
29 | + [0, window, lambda data_: ((data_ - (level - 0.5))/(window-1) + 0.5)*(window)]) | |
30 | + data.shape = shape | |
31 | + return data | |
32 | + | |
33 | + | |
23 | 34 | def gen_patches(image, patch_size, overlap): |
24 | 35 | sz, sy, sx = image.shape |
25 | 36 | i_cuts = list( |
... | ... | @@ -63,8 +74,10 @@ def brain_segment(image, probability_array, comm_array): |
63 | 74 | model = keras.models.model_from_json(json_file.read()) |
64 | 75 | model.load_weights(str(folder.joinpath("model.h5"))) |
65 | 76 | model.compile("Adam", "binary_crossentropy") |
77 | + | |
78 | + keras.utils.plot_model(model, "model.png", show_shapes=True, show_layer_names=True) | |
66 | 79 | |
67 | - image = imagedata_utils.image_normalize(image, 0.0, 1.0) | |
80 | + image = imagedata_utils.image_normalize(image, 0.0, 1.0, output_dtype=np.float32) | |
68 | 81 | sums = np.zeros_like(image) |
69 | 82 | # segmenting by patches |
70 | 83 | for completion, sub_image, patch in gen_patches(image, SIZE, OVERLAP): |
... | ... | @@ -80,7 +93,7 @@ def brain_segment(image, probability_array, comm_array): |
80 | 93 | |
81 | 94 | ctx = multiprocessing.get_context('spawn') |
82 | 95 | class SegmentProcess(ctx.Process): |
83 | - def __init__(self, image, create_new_mask, backend, device_id, use_gpu): | |
96 | + def __init__(self, image, create_new_mask, backend, device_id, use_gpu, apply_wwwl=False, window_width=255, window_level=127): | |
84 | 97 | multiprocessing.Process.__init__(self) |
85 | 98 | |
86 | 99 | self._image_filename = image.filename |
... | ... | @@ -102,6 +115,10 @@ class SegmentProcess(ctx.Process): |
102 | 115 | self.device_id = device_id |
103 | 116 | self.use_gpu = use_gpu |
104 | 117 | |
118 | + self.apply_wwwl = apply_wwwl | |
119 | + self.window_width = window_width | |
120 | + self.window_level = window_level | |
121 | + | |
105 | 122 | self._pconn, self._cconn = multiprocessing.Pipe() |
106 | 123 | self._exception = None |
107 | 124 | |
... | ... | @@ -122,6 +139,12 @@ class SegmentProcess(ctx.Process): |
122 | 139 | shape=self._image_shape, |
123 | 140 | mode="r", |
124 | 141 | ) |
142 | + | |
143 | + print(image.min(), image.max()) | |
144 | + if self.apply_segment_threshold: | |
145 | + print("Applying window level") | |
146 | + image = get_LUT_value(image, self.window_width, self.window_level) | |
147 | + | |
125 | 148 | probability_array = np.memmap( |
126 | 149 | self._prob_array_filename, |
127 | 150 | dtype=np.float32, | ... | ... |