Commit dff1e5b0d7b661e2c1ba74bed7ec5466d47434a9

Authored by Thiago Franco de Moraes
Committed by GitHub
1 parent e7500894
Exists in master

wxpython 4.1 and remove mixin from ListCtrl (#237)

- FIx sizer error to make InVesalius work with wxPython 4.1
- Not using Mixin with ListCtrl to make edition and check image
- Force X11 in Linux (wxPython with OpenGL not working in Wayland)
@@ -40,7 +40,11 @@ if sys.platform == 'win32': @@ -40,7 +40,11 @@ if sys.platform == 'win32':
40 # #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True) 40 # #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True)
41 # #wxversion.select('2.8-unicode', optionsRequired=True) 41 # #wxversion.select('2.8-unicode', optionsRequired=True)
42 # # wxversion.ensureMinimal('4.0') 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 import wx 48 import wx
45 try: 49 try:
46 from wx.adv import SplashScreen 50 from wx.adv import SplashScreen
invesalius/data/viewer_slice.py
@@ -1438,8 +1438,12 @@ class Viewer(wx.Panel): @@ -1438,8 +1438,12 @@ class Viewer(wx.Panel):
1438 index = max_slice_number - 1 1438 index = max_slice_number - 1
1439 inverted = self.mip_ctrls.inverted.GetValue() 1439 inverted = self.mip_ctrls.inverted.GetValue()
1440 border_size = self.mip_ctrls.border_spin.GetValue() 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 self.slice_data.actor.SetInputData(image) 1447 self.slice_data.actor.SetInputData(image)
1444 for actor in self.actors_by_slice_number[self.slice_data.number]: 1448 for actor in self.actors_by_slice_number[self.slice_data.number]:
1445 self.slice_data.renderer.RemoveActor(actor) 1449 self.slice_data.renderer.RemoveActor(actor)
invesalius/gui/brain_seg_dialog.py
@@ -115,7 +115,7 @@ class BrainSegmenterDialog(wx.Dialog): @@ -115,7 +115,7 @@ class BrainSegmenterDialog(wx.Dialog):
115 sizer_3.Add( 115 sizer_3.Add(
116 self.sld_threshold, 116 self.sld_threshold,
117 1, 117 1,
118 - wx.ALIGN_CENTER | wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.RIGHT, 118 + wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.RIGHT,
119 5, 119 5,
120 ) 120 )
121 sizer_3.Add(self.txt_threshold, 0, wx.ALL, 5) 121 sizer_3.Add(self.txt_threshold, 0, wx.ALL, 5)
@@ -128,15 +128,15 @@ class BrainSegmenterDialog(wx.Dialog): @@ -128,15 +128,15 @@ class BrainSegmenterDialog(wx.Dialog):
128 main_sizer.Add(time_sizer, 0, wx.EXPAND | wx.ALL, 5) 128 main_sizer.Add(time_sizer, 0, wx.EXPAND | wx.ALL, 5)
129 sizer_buttons = wx.BoxSizer(wx.HORIZONTAL) 129 sizer_buttons = wx.BoxSizer(wx.HORIZONTAL)
130 sizer_buttons.Add( 130 sizer_buttons.Add(
131 - self.btn_close, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5 131 + self.btn_close, 0, wx.ALIGN_BOTTOM | wx.ALL, 5
132 ) 132 )
133 sizer_buttons.Add( 133 sizer_buttons.Add(
134 - self.btn_stop, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5 134 + self.btn_stop, 0, wx.ALIGN_BOTTOM | wx.ALL, 5
135 ) 135 )
136 sizer_buttons.Add( 136 sizer_buttons.Add(
137 - self.btn_segment, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5 137 + self.btn_segment, 0, wx.ALIGN_BOTTOM | wx.ALL, 5
138 ) 138 )
139 - main_sizer.Add(sizer_buttons, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 0) 139 + main_sizer.Add(sizer_buttons, 0, wx.ALIGN_RIGHT | wx.ALL, 0)
140 self.SetSizer(main_sizer) 140 self.SetSizer(main_sizer)
141 main_sizer.Fit(self) 141 main_sizer.Fit(self)
142 main_sizer.SetSizeHints(self) 142 main_sizer.SetSizeHints(self)
invesalius/gui/data_notebook.py
@@ -351,18 +351,11 @@ class ButtonControlPanel(wx.Panel): @@ -351,18 +351,11 @@ class ButtonControlPanel(wx.Panel):
351 else: 351 else:
352 dlg.MaskSelectionRequiredForDuplication() 352 dlg.MaskSelectionRequiredForDuplication()
353 353
354 -class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCtrlMixin):  
355 - 354 +class MasksListCtrlPanel(wx.ListCtrl):
356 def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, 355 def __init__(self, parent, ID=-1, pos=wx.DefaultPosition,
357 - size=wx.DefaultSize, style=wx.LC_REPORT):  
358 -  
359 - # native look and feel for MacOS  
360 - #if wx.Platform == "__WXMAC__":  
361 - # wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", 0)  
362 -  
363 - wx.ListCtrl.__init__(self, parent, ID, pos, size, style=wx.LC_REPORT)  
364 - listmix.TextEditMixin.__init__(self)  
365 - listmix.CheckListCtrlMixin.__init__(self) 356 + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS):
  357 + wx.ListCtrl.__init__(self, parent, ID, pos, size, style=style)
  358 + self._click_check = False
366 self.mask_list_index = {} 359 self.mask_list_index = {}
367 self.current_index = 0 360 self.current_index = 0
368 self.__init_columns() 361 self.__init_columns()
@@ -371,11 +364,10 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt @@ -371,11 +364,10 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt
371 self.__bind_events() 364 self.__bind_events()
372 365
373 def __bind_events_wx(self): 366 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 self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel) 367 self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel)
377 self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent) 368 self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent)
378 - 369 + self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
  370 + self.Bind(wx.EVT_LEFT_UP, self.OnClickItem)
379 371
380 def __bind_events(self): 372 def __bind_events(self):
381 Publisher.subscribe(self.AddMask, 'Add mask') 373 Publisher.subscribe(self.AddMask, 'Add mask')
@@ -438,7 +430,6 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt @@ -438,7 +430,6 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt
438 self.current_index -= 1 430 self.current_index -= 1
439 self.SetItemImage(self.current_index, 1) 431 self.SetItemImage(self.current_index, 1)
440 432
441 -  
442 def OnCloseProject(self): 433 def OnCloseProject(self):
443 self.DeleteAllItems() 434 self.DeleteAllItems()
444 self.mask_list_index = {} 435 self.mask_list_index = {}
@@ -491,21 +482,14 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt @@ -491,21 +482,14 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt
491 482
492 self.image_gray = Image.open(os.path.join(inv_paths.ICON_DIR, "object_colour.jpg")) 483 self.image_gray = Image.open(os.path.join(inv_paths.ICON_DIR, "object_colour.jpg"))
493 484
494 - def OnBeginLabelEdit(self, evt):  
495 - if evt.GetColumn() == 1:  
496 - evt.Skip()  
497 - else:  
498 - evt.Veto()  
499 -  
500 def OnEditLabel(self, evt): 485 def OnEditLabel(self, evt):
501 - Publisher.sendMessage('Change mask name',  
502 - index=evt.GetIndex(), name=evt.GetLabel()) 486 + if not evt.IsEditCancelled():
  487 + index = evt.GetIndex()
  488 + self.SetItem(index, 1, evt.GetLabel())
  489 + Publisher.sendMessage('Change mask name',
  490 + index=evt.GetIndex(), name=evt.GetLabel())
503 evt.Skip() 491 evt.Skip()
504 492
505 - def OnItemActivated(self, evt):  
506 - self.ToggleItem(evt.Index)  
507 - # pass  
508 -  
509 def OnCheckItem(self, index, flag): 493 def OnCheckItem(self, index, flag):
510 if flag: 494 if flag:
511 for key in self.mask_list_index.keys(): 495 for key in self.mask_list_index.keys():
@@ -515,6 +499,28 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt @@ -515,6 +499,28 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt
515 self.current_index = index 499 self.current_index = index
516 Publisher.sendMessage('Show mask', index=index, value=flag) 500 Publisher.sendMessage('Show mask', index=index, value=flag)
517 501
  502 + def OnClickItem(self, evt):
  503 + self._click_check = False
  504 + item_idx, flag = (self.HitTest(evt.GetPosition()))
  505 + if flag == wx.LIST_HITTEST_ONITEMICON:
  506 + self._click_check = True
  507 + item = self.GetItem(item_idx, 0)
  508 + flag = not bool(item.GetImage())
  509 + self.SetItemImage(item_idx, int(flag))
  510 + self.OnCheckItem(item_idx, flag)
  511 + evt.Skip()
  512 +
  513 + def OnItemActivated(self, evt):
  514 + if not self._click_check:
  515 + item = self.GetItem(evt.GetItem().GetId(), 1)
  516 + ctrl = self.EditLabel(item.GetId())
  517 + w, h = ctrl.GetClientSize()
  518 + w = self.GetColumnWidth(1)
  519 + ctrl.SetClientSize(w, h)
  520 + ctrl.SetValue(item.GetText())
  521 + ctrl.SelectAll()
  522 + evt.Skip()
  523 +
518 def CreateColourBitmap(self, colour): 524 def CreateColourBitmap(self, colour):
519 """ 525 """
520 Create a wx Image with a mask colour. 526 Create a wx Image with a mask colour.
@@ -718,19 +724,11 @@ class SurfaceButtonControlPanel(wx.Panel): @@ -718,19 +724,11 @@ class SurfaceButtonControlPanel(wx.Panel):
718 def AffineStatus(self, affine, status): 724 def AffineStatus(self, affine, status):
719 self.affinestatus = status 725 self.affinestatus = status
720 726
721 -class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCtrlMixin):  
722 - 727 +class SurfacesListCtrlPanel(wx.ListCtrl):
723 def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, 728 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 - 729 + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS):
  730 + wx.ListCtrl.__init__(self, parent, ID, pos, size, style=style)
  731 + self._click_check = False
734 self.__init_columns() 732 self.__init_columns()
735 self.__init_image_list() 733 self.__init_image_list()
736 self.__init_evt() 734 self.__init_evt()
@@ -752,11 +750,33 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis @@ -752,11 +750,33 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis
752 Publisher.subscribe(self.OnShowMultiple, 'Show multiple surfaces') 750 Publisher.subscribe(self.OnShowMultiple, 'Show multiple surfaces')
753 751
754 def __bind_events_wx(self): 752 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 self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel) 753 self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel)
758 #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected_) 754 #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected_)
759 self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent) 755 self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent)
  756 + self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
  757 + self.Bind(wx.EVT_LEFT_UP, self.OnClickItem)
  758 +
  759 + def OnClickItem(self, evt):
  760 + self._click_check = False
  761 + item_idx, flag = (self.HitTest(evt.GetPosition()))
  762 + if flag == wx.LIST_HITTEST_ONITEMICON:
  763 + self._click_check = True
  764 + item = self.GetItem(item_idx, 0)
  765 + flag = not bool(item.GetImage())
  766 + self.SetItemImage(item_idx, int(flag))
  767 + self.OnCheckItem(item_idx, flag)
  768 + evt.Skip()
  769 +
  770 + def OnItemActivated(self, evt):
  771 + if not self._click_check:
  772 + item = self.GetItem(evt.GetItem().GetId(), 1)
  773 + ctrl = self.EditLabel(item.GetId())
  774 + w, h = ctrl.GetClientSize()
  775 + w = self.GetColumnWidth(1)
  776 + ctrl.SetClientSize(w, h)
  777 + ctrl.SetValue(item.GetText())
  778 + ctrl.SelectAll()
  779 + evt.Skip()
760 780
761 def OnKeyEvent(self, event): 781 def OnKeyEvent(self, event):
762 keycode = event.GetKeyCode() 782 keycode = event.GetKeyCode()
@@ -864,11 +884,10 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis @@ -864,11 +884,10 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis
864 evt.Veto() 884 evt.Veto()
865 885
866 def OnEditLabel(self, evt): 886 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) 887 + if not evt.IsEditCancelled():
  888 + index = evt.GetIndex()
  889 + self.SetItem(index, 1, evt.GetLabel())
  890 + Publisher.sendMessage('Change surface name', index=evt.GetIndex(), name=evt.GetLabel())
872 evt.Skip() 891 evt.Skip()
873 892
874 def OnCheckItem(self, index, flag): 893 def OnCheckItem(self, index, flag):
@@ -985,19 +1004,12 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis @@ -985,19 +1004,12 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis
985 #------------------------------------------------- 1004 #-------------------------------------------------
986 #------------------------------------------------- 1005 #-------------------------------------------------
987 1006
988 -class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCtrlMixin): 1007 +class MeasuresListCtrlPanel(wx.ListCtrl):
989 1008
990 def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, 1009 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 - 1010 + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS):
  1011 + wx.ListCtrl.__init__(self, parent, ID, pos, size, style=style)
  1012 + self._click_check = False
1001 self.__init_columns() 1013 self.__init_columns()
1002 self.__init_image_list() 1014 self.__init_image_list()
1003 self.__init_evt() 1015 self.__init_evt()
@@ -1017,11 +1029,33 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis @@ -1017,11 +1029,33 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis
1017 Publisher.subscribe(self.OnRemoveGUIMeasure, 'Remove GUI measurement') 1029 Publisher.subscribe(self.OnRemoveGUIMeasure, 'Remove GUI measurement')
1018 1030
1019 def __bind_events_wx(self): 1031 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 self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel) 1032 self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel)
1023 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected_) 1033 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected_)
1024 self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent) 1034 self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent)
  1035 + self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
  1036 + self.Bind(wx.EVT_LEFT_UP, self.OnClickItem)
  1037 +
  1038 + def OnClickItem(self, evt):
  1039 + self._click_check = False
  1040 + item_idx, flag = (self.HitTest(evt.GetPosition()))
  1041 + if flag == wx.LIST_HITTEST_ONITEMICON:
  1042 + self._click_check = True
  1043 + item = self.GetItem(item_idx, 0)
  1044 + flag = not bool(item.GetImage())
  1045 + self.SetItemImage(item_idx, int(flag))
  1046 + self.OnCheckItem(item_idx, flag)
  1047 + evt.Skip()
  1048 +
  1049 + def OnItemActivated(self, evt):
  1050 + if not self._click_check:
  1051 + item = self.GetItem(evt.GetItem().GetId(), 1)
  1052 + ctrl = self.EditLabel(item.GetId())
  1053 + w, h = ctrl.GetClientSize()
  1054 + w = self.GetColumnWidth(1)
  1055 + ctrl.SetClientSize(w, h)
  1056 + ctrl.SetValue(item.GetText())
  1057 + ctrl.SelectAll()
  1058 + evt.Skip()
1025 1059
1026 1060
1027 def OnKeyEvent(self, event): 1061 def OnKeyEvent(self, event):
@@ -1139,14 +1173,12 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis @@ -1139,14 +1173,12 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis
1139 evt.Veto() 1173 evt.Veto()
1140 1174
1141 def OnEditLabel(self, evt): 1175 def OnEditLabel(self, evt):
1142 - Publisher.sendMessage('Change measurement name', index=evt.GetIndex(), name=evt.GetLabel())  
1143 - evt.Skip()  
1144 -  
1145 - def OnItemActivated(self, evt):  
1146 - self.ToggleItem(evt.Index) 1176 + if not evt.IsEditCancelled():
  1177 + index = evt.GetIndex()
  1178 + self.SetItem(index, 1, evt.GetLabel())
  1179 + Publisher.sendMessage('Change measurement name', index=evt.GetIndex(), name=evt.GetLabel())
1147 evt.Skip() 1180 evt.Skip()
1148 1181
1149 -  
1150 def OnCheckItem(self, index, flag): 1182 def OnCheckItem(self, index, flag):
1151 Publisher.sendMessage('Show measurement', index=index, visibility=flag) 1183 Publisher.sendMessage('Show measurement', index=index, visibility=flag)
1152 1184
@@ -1273,19 +1305,12 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis @@ -1273,19 +1305,12 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis
1273 #******************************************************************* 1305 #*******************************************************************
1274 1306
1275 1307
1276 -class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCtrlMixin): 1308 +class AnnotationsListCtrlPanel(wx.ListCtrl):
1277 # TODO: Remove edimixin, allow only visible and invisible 1309 # TODO: Remove edimixin, allow only visible and invisible
1278 def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, 1310 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 - 1311 + size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_EDIT_LABELS):
  1312 + wx.ListCtrl.__init__(self, parent, ID, pos, size, style=style)
  1313 + self._click_check = False
1289 self.__init_columns() 1314 self.__init_columns()
1290 self.__init_image_list() 1315 self.__init_image_list()
1291 self.__init_evt() 1316 self.__init_evt()
invesalius/gui/default_viewers.py
@@ -111,7 +111,7 @@ class Panel(wx.Panel): @@ -111,7 +111,7 @@ class Panel(wx.Panel):
111 p3.SetPopupMenu(menu) 111 p3.SetPopupMenu(menu)
112 112
113 113
114 - if sys.platform == 'win32': 114 + if sys.platform == 'win32' or wx.VERSION >= (4, 1):
115 self.aui_manager.AddPane(p1, s1) 115 self.aui_manager.AddPane(p1, s1)
116 self.aui_manager.AddPane(p2, s2) 116 self.aui_manager.AddPane(p2, s2)
117 self.aui_manager.AddPane(p3, s3) 117 self.aui_manager.AddPane(p3, s3)
@@ -604,7 +604,7 @@ class VolumeToolPanel(wx.Panel): @@ -604,7 +604,7 @@ class VolumeToolPanel(wx.Panel):
604 id = evt.GetId() 604 id = evt.GetId()
605 item = ID_TO_ITEMSLICEMENU[id] 605 item = ID_TO_ITEMSLICEMENU[id]
606 checked = item.IsChecked() 606 checked = item.IsChecked()
607 - label = item.GetLabel() 607 + label = item.GetItemLabelText()
608 608
609 if not (checked): 609 if not (checked):
610 Publisher.sendMessage('Disable plane', plane_label=label) 610 Publisher.sendMessage('Disable plane', plane_label=label)
invesalius/gui/dialogs.py
@@ -1947,17 +1947,17 @@ class WatershedOptionsPanel(wx.Panel): @@ -1947,17 +1947,17 @@ class WatershedOptionsPanel(wx.Panel):
1947 min_value=1, max_value=10) 1947 min_value=1, max_value=10)
1948 1948
1949 box_sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Conectivity"), wx.VERTICAL) 1949 box_sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Conectivity"), wx.VERTICAL)
1950 - box_sizer.Add(self.choice_2dcon, 0, wx.ALIGN_CENTER_VERTICAL,2)  
1951 - box_sizer.Add(self.choice_3dcon, 0, wx.ALIGN_CENTER_VERTICAL,2) 1950 + box_sizer.Add(self.choice_2dcon, 0, wx.ALL, 5)
  1951 + box_sizer.Add(self.choice_3dcon, 0, wx.ALL, 5)
1952 1952
1953 g_sizer = wx.BoxSizer(wx.HORIZONTAL) 1953 g_sizer = wx.BoxSizer(wx.HORIZONTAL)
1954 - g_sizer.Add(wx.StaticText(self, -1, _("Gaussian sigma")), 0, wx.ALIGN_RIGHT | wx.ALL, 5)  
1955 - g_sizer.Add(self.gaussian_size, 0, wx.ALIGN_LEFT | wx.ALL, 5) 1954 + g_sizer.Add(wx.StaticText(self, -1, _("Gaussian sigma")), 0, wx.ALIGN_CENTER | wx.ALL, 5)
  1955 + g_sizer.Add(self.gaussian_size, 0, wx.ALL, 5)
1956 1956
1957 sizer = wx.BoxSizer(wx.VERTICAL) 1957 sizer = wx.BoxSizer(wx.VERTICAL)
1958 - sizer.Add(self.choice_algorithm, 0, wx.ALIGN_CENTER_VERTICAL,2)  
1959 - sizer.Add(box_sizer, 1, wx.EXPAND,2)  
1960 - sizer.Add(g_sizer, 0, wx.ALIGN_LEFT, 2) 1958 + sizer.Add(self.choice_algorithm, 0, wx.ALL, 5)
  1959 + sizer.Add(box_sizer, 1, wx.EXPAND | wx.ALL, 5)
  1960 + sizer.Add(g_sizer, 0, wx.ALL, 5)
1961 1961
1962 self.SetSizer(sizer) 1962 self.SetSizer(sizer)
1963 sizer.Fit(self) 1963 sizer.Fit(self)
@@ -1995,8 +1995,7 @@ class WatershedOptionsDialog(wx.Dialog): @@ -1995,8 +1995,7 @@ class WatershedOptionsDialog(wx.Dialog):
1995 btnsizer.Realize() 1995 btnsizer.Realize()
1996 1996
1997 sizer.Add(wop, 0, wx.EXPAND) 1997 sizer.Add(wop, 0, wx.EXPAND)
1998 - sizer.Add(btnsizer, 0, wx.EXPAND)  
1999 - sizer.AddSpacer(5) 1998 + sizer.Add(btnsizer, 0, wx.ALIGN_RIGHT | wx.BOTTOM, 5)
2000 1999
2001 self.SetSizer(sizer) 2000 self.SetSizer(sizer)
2002 sizer.Fit(self) 2001 sizer.Fit(self)
@@ -2057,16 +2056,16 @@ class MaskBooleanDialog(wx.Dialog): @@ -2057,16 +2056,16 @@ class MaskBooleanDialog(wx.Dialog):
2057 2056
2058 gsizer = wx.FlexGridSizer(rows=3, cols=2, hgap=5, vgap=5) 2057 gsizer = wx.FlexGridSizer(rows=3, cols=2, hgap=5, vgap=5)
2059 2058
2060 - gsizer.Add(wx.StaticText(self, -1, _(u"Mask 1"))) 2059 + gsizer.Add(wx.StaticText(self, -1, _(u"Mask 1")), 0, wx.ALIGN_CENTER_VERTICAL)
2061 gsizer.Add(self.mask1, 1, wx.EXPAND) 2060 gsizer.Add(self.mask1, 1, wx.EXPAND)
2062 - gsizer.Add(wx.StaticText(self, -1, _(u"Operation"))) 2061 + gsizer.Add(wx.StaticText(self, -1, _(u"Operation")), 0, wx.ALIGN_CENTER_VERTICAL)
2063 gsizer.Add(self.op_boolean, 1, wx.EXPAND) 2062 gsizer.Add(self.op_boolean, 1, wx.EXPAND)
2064 - gsizer.Add(wx.StaticText(self, -1, _(u"Mask 2"))) 2063 + gsizer.Add(wx.StaticText(self, -1, _(u"Mask 2")), 0, wx.ALIGN_CENTER_VERTICAL)
2065 gsizer.Add(self.mask2, 1, wx.EXPAND) 2064 gsizer.Add(self.mask2, 1, wx.EXPAND)
2066 2065
2067 sizer = wx.BoxSizer(wx.VERTICAL) 2066 sizer = wx.BoxSizer(wx.VERTICAL)
2068 - sizer.Add(gsizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5)  
2069 - sizer.Add(btnsizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) 2067 + sizer.Add(gsizer, 0, wx.EXPAND | wx.ALL, border=5)
  2068 + sizer.Add(btnsizer, 0, wx.EXPAND | wx.ALL, border=5)
2070 2069
2071 self.SetSizer(sizer) 2070 self.SetSizer(sizer)
2072 sizer.Fit(self) 2071 sizer.Fit(self)
@@ -2795,8 +2794,8 @@ class SelectPartsOptionsDialog(wx.Dialog): @@ -2795,8 +2794,8 @@ class SelectPartsOptionsDialog(wx.Dialog):
2795 sizer.AddSpacer(5) 2794 sizer.AddSpacer(5)
2796 2795
2797 btn_sizer = wx.BoxSizer(wx.HORIZONTAL) 2796 btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
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|wx.ALIGN_RIGHT, border=5) 2797 + btn_sizer.Add(self.btn_ok, 0)# flag=wx.ALIGN_RIGHT, border=5)
  2798 + btn_sizer.Add(self.btn_cancel, 0, flag=wx.LEFT, border=5)
2800 2799
2801 sizer.Add(btn_sizer, 0, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT, border=5) 2800 sizer.Add(btn_sizer, 0, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT, border=5)
2802 sizer.AddSpacer(5) 2801 sizer.AddSpacer(5)
@@ -3199,8 +3198,8 @@ class FillHolesAutoDialog(wx.Dialog): @@ -3199,8 +3198,8 @@ class FillHolesAutoDialog(wx.Dialog):
3199 sizer.AddSpacer(5) 3198 sizer.AddSpacer(5)
3200 3199
3201 btn_sizer = wx.BoxSizer(wx.HORIZONTAL) 3200 btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
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|wx.ALIGN_RIGHT, border=5) 3201 + btn_sizer.Add(self.apply_btn, 0)# flag=wx.ALIGN_RIGHT, border=5)
  3202 + btn_sizer.Add(self.close_btn, 0, flag=wx.LEFT, border=5)
3204 3203
3205 sizer.Add(btn_sizer, 0, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT, border=5) 3204 sizer.Add(btn_sizer, 0, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT, border=5)
3206 3205
invesalius/gui/frame.py
@@ -214,7 +214,7 @@ class Frame(wx.Frame): @@ -214,7 +214,7 @@ class Frame(wx.Frame):
214 # Add toolbars to manager 214 # Add toolbars to manager
215 # This is pretty tricky -- order on win32 is inverted when 215 # This is pretty tricky -- order on win32 is inverted when
216 # compared to linux2 & darwin 216 # compared to linux2 & darwin
217 - if sys.platform == 'win32': 217 + if sys.platform == 'win32' or wx.VERSION >= (4, 1):
218 t1 = ProjectToolBar(self) 218 t1 = ProjectToolBar(self)
219 t2 = HistoryToolBar(self) 219 t2 = HistoryToolBar(self)
220 t3 = LayoutToolBar(self) 220 t3 = LayoutToolBar(self)
invesalius/gui/preferences.py
@@ -49,13 +49,13 @@ class Preferences(wx.Dialog): @@ -49,13 +49,13 @@ class Preferences(wx.Dialog):
49 self.book.AddPage(self.pnl_language, _("Language")) 49 self.book.AddPage(self.pnl_language, _("Language"))
50 50
51 line = wx.StaticLine(self, -1, size=(20, -1), style=wx.LI_HORIZONTAL) 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 btnsizer = self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL) 54 btnsizer = self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL)
55 sizer.Add( 55 sizer.Add(
56 btnsizer, 56 btnsizer,
57 0, 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 5, 59 5,
60 ) 60 )
61 61
invesalius/gui/task_navigator.py
@@ -211,7 +211,7 @@ class InnerFoldPanel(wx.Panel): @@ -211,7 +211,7 @@ class InnerFoldPanel(wx.Panel):
211 line_sizer = wx.BoxSizer(wx.HORIZONTAL) 211 line_sizer = wx.BoxSizer(wx.HORIZONTAL)
212 line_sizer.Add(checkcamera, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, 5) 212 line_sizer.Add(checkcamera, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, 5)
213 line_sizer.Add(checktrigger, 0, wx.ALIGN_CENTER) 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 line_sizer.Fit(self) 215 line_sizer.Fit(self)
216 216
217 # Panel sizer to expand fold panel 217 # Panel sizer to expand fold panel
@@ -396,7 +396,7 @@ class NeuronavigationPanel(wx.Panel): @@ -396,7 +396,7 @@ class NeuronavigationPanel(wx.Panel):
396 (nav_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL)]) 396 (nav_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL)])
397 397
398 main_sizer = wx.BoxSizer(wx.HORIZONTAL) 398 main_sizer = wx.BoxSizer(wx.HORIZONTAL)
399 - main_sizer.Add(group_sizer, 1, wx.ALIGN_CENTER_HORIZONTAL, 10) 399 + main_sizer.Add(group_sizer, 1)# wx.ALIGN_CENTER_HORIZONTAL, 10)
400 self.sizer = main_sizer 400 self.sizer = main_sizer
401 self.SetSizer(main_sizer) 401 self.SetSizer(main_sizer)
402 self.Fit() 402 self.Fit()
@@ -808,7 +808,7 @@ class ObjectRegistrationPanel(wx.Panel): @@ -808,7 +808,7 @@ class ObjectRegistrationPanel(wx.Panel):
808 808
809 line_checks = wx.BoxSizer(wx.HORIZONTAL) 809 line_checks = wx.BoxSizer(wx.HORIZONTAL)
810 line_checks.Add(checkrecordcoords, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, 5) 810 line_checks.Add(checkrecordcoords, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, 5)
811 - line_checks.Add(checktrack, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.LEFT, 5) 811 + line_checks.Add(checktrack, 0, wx.RIGHT | wx.LEFT, 5)
812 812
813 # Add line sizers into main sizer 813 # Add line sizers into main sizer
814 main_sizer = wx.BoxSizer(wx.VERTICAL) 814 main_sizer = wx.BoxSizer(wx.VERTICAL)
@@ -1038,7 +1038,7 @@ class MarkersPanel(wx.Panel): @@ -1038,7 +1038,7 @@ class MarkersPanel(wx.Panel):
1038 group_sizer.Add(sizer_create, 0, wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5) 1038 group_sizer.Add(sizer_create, 0, wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5)
1039 group_sizer.Add(sizer_btns, 0, wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5) 1039 group_sizer.Add(sizer_btns, 0, wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5)
1040 group_sizer.Add(sizer_delete, 0, wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5) 1040 group_sizer.Add(sizer_delete, 0, wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL, 5)
1041 - group_sizer.Add(self.lc, 0, wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5) 1041 + group_sizer.Add(self.lc, 0, wx.EXPAND | wx.ALL, 5)
1042 group_sizer.Fit(self) 1042 group_sizer.Fit(self)
1043 1043
1044 self.SetSizer(group_sizer) 1044 self.SetSizer(group_sizer)
invesalius/gui/task_slice.py
@@ -141,7 +141,7 @@ class InnerTaskPanel(wx.Panel): @@ -141,7 +141,7 @@ class InnerTaskPanel(wx.Panel):
141 141
142 line_sizer = wx.BoxSizer(wx.HORIZONTAL) 142 line_sizer = wx.BoxSizer(wx.HORIZONTAL)
143 line_sizer.Add(check_box, 0, wx.ALIGN_LEFT|wx.RIGHT|wx.LEFT, 5) 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 line_sizer.Fit(self) 145 line_sizer.Fit(self)
146 146
147 # Add line sizers into main sizer 147 # Add line sizers into main sizer
invesalius/gui/task_surface.py
@@ -30,6 +30,7 @@ except ImportError: @@ -30,6 +30,7 @@ except ImportError:
30 30
31 from pubsub import pub as Publisher 31 from pubsub import pub as Publisher
32 import wx.lib.colourselect as csel 32 import wx.lib.colourselect as csel
  33 +import wx.lib.scrolledpanel as scrolled
33 34
34 import invesalius.constants as const 35 import invesalius.constants as const
35 import invesalius.data.slice_ as slice_ 36 import invesalius.data.slice_ as slice_
@@ -74,9 +75,9 @@ class TaskPanel(wx.Panel): @@ -74,9 +75,9 @@ class TaskPanel(wx.Panel):
74 # Contour - slider 75 # Contour - slider
75 # enable / disable Fill holes 76 # enable / disable Fill holes
76 77
77 -class InnerTaskPanel(wx.Panel): 78 +class InnerTaskPanel(scrolled.ScrolledPanel):
78 def __init__(self, parent): 79 def __init__(self, parent):
79 - wx.Panel.__init__(self, parent) 80 + scrolled.ScrolledPanel.__init__(self, parent)
80 default_colour = self.GetBackgroundColour() 81 default_colour = self.GetBackgroundColour()
81 backgroud_colour = wx.Colour(255,255,255) 82 backgroud_colour = wx.Colour(255,255,255)
82 self.SetBackgroundColour(backgroud_colour) 83 self.SetBackgroundColour(backgroud_colour)
@@ -134,6 +135,13 @@ class InnerTaskPanel(wx.Panel): @@ -134,6 +135,13 @@ class InnerTaskPanel(wx.Panel):
134 135
135 self.sizer = main_sizer 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 def OnButton(self, evt): 145 def OnButton(self, evt):
138 id = evt.GetId() 146 id = evt.GetId()
139 if id == BTN_NEW: 147 if id == BTN_NEW:
@@ -437,9 +445,9 @@ class SurfaceTools(wx.Panel): @@ -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 def __init__(self, parent): 449 def __init__(self, parent):
442 - wx.Panel.__init__(self, parent) 450 + scrolled.ScrolledPanel.__init__(self, parent)
443 try: 451 try:
444 default_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENUBAR) 452 default_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENUBAR)
445 except AttributeError: 453 except AttributeError:
@@ -507,8 +515,16 @@ class SurfaceProperties(wx.Panel): @@ -507,8 +515,16 @@ class SurfaceProperties(wx.Panel):
507 self.Update() 515 self.Update()
508 #self.SetAutoLayout(1) 516 #self.SetAutoLayout(1)
509 517
  518 + self.SetupScrolling()
  519 +
  520 + self.Bind(wx.EVT_SIZE, self.OnResize)
  521 +
510 self.__bind_events() 522 self.__bind_events()
511 523
  524 + def OnResize(self, evt):
  525 + print("Resize")
  526 + self.SetupScrolling()
  527 +
512 def __bind_events(self): 528 def __bind_events(self):
513 Publisher.subscribe(self.InsertNewSurface, 529 Publisher.subscribe(self.InsertNewSurface,
514 'Update surface info in GUI') 530 'Update surface info in GUI')
invesalius/gui/widgets/slice_menu.py
@@ -205,7 +205,7 @@ class SliceMenu(wx.Menu): @@ -205,7 +205,7 @@ class SliceMenu(wx.Menu):
205 def OnPopup(self, evt): 205 def OnPopup(self, evt):
206 id = evt.GetId() 206 id = evt.GetId()
207 item = self.ID_TO_TOOL_ITEM[evt.GetId()] 207 item = self.ID_TO_TOOL_ITEM[evt.GetId()]
208 - key = item.GetLabel() 208 + key = item.GetItemLabelText()
209 if(key in const.WINDOW_LEVEL.keys()): 209 if(key in const.WINDOW_LEVEL.keys()):
210 window, level = const.WINDOW_LEVEL[key] 210 window, level = const.WINDOW_LEVEL[key]
211 Publisher.sendMessage('Bright and contrast adjustment image', 211 Publisher.sendMessage('Bright and contrast adjustment image',