diff --git a/app.py b/app.py index 54d8b54..9049972 100644 --- a/app.py +++ b/app.py @@ -247,9 +247,9 @@ class Inv3SplashScreen(SplashScreen): self.main = Frame(None) self.control = Controller(self.main) - self.fc = wx.FutureCall(1, self.ShowMain) + self.fc = wx.CallLater(200, self.ShowMain) options, args = parse_comand_line() - wx.FutureCall(1, use_cmd_optargs, options, args) + wx.CallLater(1, use_cmd_optargs, options, args) # Check for updates from threading import Thread diff --git a/invesalius/data/styles.py b/invesalius/data/styles.py index ee06774..5f302d4 100644 --- a/invesalius/data/styles.py +++ b/invesalius/data/styles.py @@ -467,9 +467,9 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): else: mx, my = self.viewer.interactor.GetEventPosition() if self._verify_clicked_display(mx, my): - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_HAND)) else: - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_DEFAULT)) def OnLeaveMeasureInteractor(self, obj, evt): if self.creating or self.selected: @@ -922,7 +922,7 @@ class EditorInteractorStyle(DefaultInteractorStyle): w_x, w_y, w_z = self.viewer.get_coordinate_cursor(x, y, self.picker) self.viewer.slice_data.cursor.SetPosition((w_x, w_y, w_z)) - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_BLANK)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_BLANK)) self.viewer.interactor.Render() def CleanUp(self): @@ -931,7 +931,7 @@ class EditorInteractorStyle(DefaultInteractorStyle): Publisher.unsubscribe(self.set_boperation, 'Set edition operation') self.viewer.slice_data.cursor.Show(0) - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_DEFAULT)) self.viewer.interactor.Render() def set_bsize(self, size): @@ -967,12 +967,12 @@ class EditorInteractorStyle(DefaultInteractorStyle): if (self.viewer.slice_.buffer_slices[self.orientation].mask is None): return self.viewer.slice_data.cursor.Show() - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_BLANK)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_BLANK)) self.viewer.interactor.Render() def OnLeaveInteractor(self, obj, evt): self.viewer.slice_data.cursor.Show(0) - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_DEFAULT)) self.viewer.interactor.Render() def OnBrushClick(self, obj, evt): @@ -1230,7 +1230,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): w_x, w_y, w_z = self.viewer.get_coordinate_cursor(x, y, self.picker) self.viewer.slice_data.cursor.SetPosition((w_x, w_y, w_z)) - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_BLANK)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_BLANK)) self.viewer.interactor.Render() def CleanUp(self): @@ -1243,7 +1243,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): self.viewer.OnScrollBar() self.viewer.slice_data.cursor.Show(0) - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_DEFAULT)) self.viewer.interactor.Render() def _create_mask(self): @@ -1290,12 +1290,12 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): if (self.viewer.slice_.buffer_slices[self.orientation].mask is None): return self.viewer.slice_data.cursor.Show() - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_BLANK)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_BLANK)) self.viewer.interactor.Render() def OnLeaveInteractor(self, obj, evt): self.viewer.slice_data.cursor.Show(0) - self.viewer.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) + self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_DEFAULT)) self.viewer.interactor.Render() def WOnScrollBackward(self, obj, evt): @@ -1757,10 +1757,10 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): dist_center = ((mx - cx)**2 + (my - cy)**2)**0.5 if dist_center <= 15: self._over_center = True - cursor = wx.StockCursor(wx.CURSOR_SIZENESW) + cursor = wx.Cursor(wx.CURSOR_SIZENESW) else: self._over_center = False - cursor = wx.StockCursor(wx.CURSOR_DEFAULT) + cursor = wx.Cursor(wx.CURSOR_DEFAULT) self.viewer.interactor.SetCursor(cursor) diff --git a/invesalius/data/viewer_slice.py b/invesalius/data/viewer_slice.py index c6663b0..f95f3f8 100644 --- a/invesalius/data/viewer_slice.py +++ b/invesalius/data/viewer_slice.py @@ -49,6 +49,7 @@ import invesalius.session as ses import invesalius.data.converters as converters import invesalius.data.measures as measures +from invesalius.gui.widgets.inv_spinctrl import InvSpinCtrl, InvFloatSpinCtrl from invesalius.gui.widgets.canvas_renderer import CanvasRendererCTX if sys.platform == 'win32': @@ -73,25 +74,22 @@ ORIENTATIONS = { class ContourMIPConfig(wx.Panel): def __init__(self, prnt, orientation): wx.Panel.__init__(self, prnt) - self.mip_size_spin = wx.SpinCtrl(self, -1, min=1, max=240, - initial=const.PROJECTION_MIP_SIZE) - self.mip_size_spin.SetValue(const.PROJECTION_MIP_SIZE) + self.mip_size_spin = InvSpinCtrl(self, -1, value=const.PROJECTION_MIP_SIZE, min_value=1, max_value=240) self.mip_size_spin.SetToolTip(wx.ToolTip(_("Number of slices used to compound the visualization."))) - w, h = self.mip_size_spin.GetTextExtent('M') - self.mip_size_spin.SetMinSize((5 * w + 10, -1)) - self.mip_size_spin.SetMaxSize((5 * w + 10, -1)) + self.mip_size_spin.CalcSizeFromTextSize('MMM') - self.border_spin = FS.FloatSpin(self, -1, min_val=0, max_val=10, + self.border_spin = InvFloatSpinCtrl(self, -1, min_value=0, max_value=10, increment=0.1, value=const.PROJECTION_BORDER_SIZE, - digits=1, agwStyle=FS.FS_LEFT) + digits=1) self.border_spin.SetToolTip(wx.ToolTip(_("Controls the sharpness of the" " contour. The greater the" " value, the sharper the" " contour."))) - w, h = self.border_spin.GetTextExtent('M') - self.border_spin.SetMinSize((5 * w + 10, -1)) - self.border_spin.SetMaxSize((5 * w + 10, -1)) + self.border_spin.CalcSizeFromTextSize() + # w, h = self.border_spin.GetTextExtent('M') + # self.border_spin.SetMinSize((5 * w + 10, -1)) + # self.border_spin.SetMaxSize((5 * w + 10, -1)) self.inverted = wx.CheckBox(self, -1, _("Inverted order")) self.inverted.SetToolTip(wx.ToolTip(_("If checked, the slices are" @@ -105,7 +103,7 @@ class ContourMIPConfig(wx.Panel): sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(txt_mip_size, 0, wx.EXPAND | wx.ALL, 2) - sizer.Add(self.mip_size_spin, 0, wx.EXPAND) + sizer.Add(self.mip_size_spin, 0) try: sizer.Add(10, 0) except TypeError: @@ -883,19 +881,19 @@ class Viewer(wx.Panel): self.Refresh() def SetDefaultCursor(self): - self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) + self.interactor.SetCursor(wx.Cursor(wx.CURSOR_DEFAULT)) def SetSizeNSCursor(self): - self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS)) + self.interactor.SetCursor(wx.Cursor(wx.CURSOR_SIZENS)) def SetSizeWECursor(self): - self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_SIZEWE)) + self.interactor.SetCursor(wx.Cursor(wx.CURSOR_SIZEWE)) def SetSizeNWSECursor(self): if sys.platform.startswith('linux'): - self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_SIZENWSE)) + self.interactor.SetCursor(wx.Cursor(wx.CURSOR_SIZENWSE)) else: - self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_SIZING)) + self.interactor.SetCursor(wx.Cursor(wx.CURSOR_SIZING)) def SetFocus(self): Publisher.sendMessage('Set viewer orientation focus', diff --git a/invesalius/gui/bitmap_preview_panel.py b/invesalius/gui/bitmap_preview_panel.py index 33b675b..12b8968 100644 --- a/invesalius/gui/bitmap_preview_panel.py +++ b/invesalius/gui/bitmap_preview_panel.py @@ -115,7 +115,7 @@ class DicomPaintPanel(wx.Panel): self.Bind(wx.EVT_SIZE, self.OnSize) def _build_bitmap(self, image): - bmp = wx.BitmapFromImage(image) + bmp = wx.Bitmap(image) return bmp def _image_resize(self, image): diff --git a/invesalius/gui/data_notebook.py b/invesalius/gui/data_notebook.py index 53e153a..1bc1140 100644 --- a/invesalius/gui/data_notebook.py +++ b/invesalius/gui/data_notebook.py @@ -168,20 +168,20 @@ class MeasureButtonControlPanel(wx.Panel): BMP_NEW, style=button_style, size = wx.Size(24, 20)) - button_new.SetToolTipString(_("Create a new measure")) + button_new.SetToolTip(_("Create a new measure")) self.button_new = button_new button_remove = pbtn.PlateButton(self, BTN_REMOVE, "", BMP_REMOVE, style=button_style, size = wx.Size(24, 20)) - button_remove.SetToolTipString(_("Remove measure")) + button_remove.SetToolTip(_("Remove measure")) button_duplicate = pbtn.PlateButton(self, BTN_DUPLICATE, "", BMP_DUPLICATE, style=button_style, size = wx.Size(24, 20)) - button_duplicate.SetToolTipString(_("Duplicate measure")) + button_duplicate.SetToolTip(_("Duplicate measure")) button_duplicate.Disable() # Add all controls to gui @@ -195,10 +195,10 @@ class MeasureButtonControlPanel(wx.Panel): menu = wx.Menu() item = wx.MenuItem(menu, const.MEASURE_LINEAR, _("Measure distance")) - menu.AppendItem(item) + menu.Append(item) item = wx.MenuItem(menu, const.MEASURE_ANGULAR, _("Measure angle")) - menu.AppendItem(item) + menu.Append(item) menu.Bind(wx.EVT_MENU, self.OnMenu) self.menu = menu @@ -286,19 +286,19 @@ class ButtonControlPanel(wx.Panel): BMP_NEW, style=button_style, size = wx.Size(24, 20)) - button_new.SetToolTipString(_("Create a new mask")) + button_new.SetToolTip(_("Create a new mask")) button_remove = pbtn.PlateButton(self, BTN_REMOVE, "", BMP_REMOVE, style=button_style, size = wx.Size(24, 20)) - button_remove.SetToolTipString(_("Remove mask")) + button_remove.SetToolTip(_("Remove mask")) button_duplicate = pbtn.PlateButton(self, BTN_DUPLICATE, "", BMP_DUPLICATE, style=button_style, size = wx.Size(24, 20)) - button_duplicate.SetToolTipString(_("Duplicate mask")) + button_duplicate.SetToolTip(_("Duplicate mask")) # Add all controls to gui sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -474,13 +474,13 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt self.imagelist = wx.ImageList(16, 16) image = wx.Image(os.path.join(const.ICON_DIR, "object_invisible.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) img_null = self.imagelist.Add(bitmap) image = wx.Image(os.path.join(const.ICON_DIR, "object_visible.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) img_check = self.imagelist.Add(bitmap) @@ -526,20 +526,20 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt for i in colour] new_image.putpixel((x,y), tuple(pixel_colour)) - wx_image = wx.EmptyImage(new_image.size[0], - new_image.size[1]) + wx_image = wx.Image(new_image.size[0], + new_image.size[1]) try: wx_image.SetData(new_image.tostring()) except Exception: wx_image.SetData(new_image.tobytes()) - return wx.BitmapFromImage(wx_image.Scale(16, 16)) + return wx.Bitmap(wx_image.Scale(16, 16)) def InsertNewItem(self, index=0, label=_("Mask"), threshold="(1000, 4500)", colour=None): - self.InsertStringItem(index, "") - self.SetStringItem(index, 1, label, + self.InsertItem(index, "") + self.SetItem(index, 1, label, imageId=self.mask_list_index[index]) - self.SetStringItem(index, 2, threshold) + self.SetItem(index, 2, threshold) # self.SetItemImage(index, 1) # for key in self.mask_list_index.keys(): # if key != index: @@ -553,7 +553,7 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckListCt self.InsertNewItem(mask.index, mask.name, str(mask.threshold_range)) def EditMaskThreshold(self, index, threshold_range): - self.SetStringItem(index, 2, str(threshold_range)) + self.SetItem(index, 2, str(threshold_range)) def EditMaskColour(self, index, colour): image = self.CreateColourBitmap(colour) @@ -631,25 +631,25 @@ class SurfaceButtonControlPanel(wx.Panel): BMP_NEW, style=button_style, size = wx.Size(24, 20)) - button_new.SetToolTipString(_("Create a new surface")) + button_new.SetToolTip(_("Create a new surface")) button_remove = pbtn.PlateButton(self, BTN_REMOVE, "", BMP_REMOVE, style=button_style, size = wx.Size(24, 20)) - button_remove.SetToolTipString(_("Remove surface")) + button_remove.SetToolTip(_("Remove surface")) button_duplicate = pbtn.PlateButton(self, BTN_DUPLICATE, "", BMP_DUPLICATE, style=button_style, size = wx.Size(24, 20)) - button_duplicate.SetToolTipString(_("Duplicate surface")) + button_duplicate.SetToolTip(_("Duplicate surface")) button_open = pbtn.PlateButton(self, BTN_OPEN, "", BMP_OPEN, style=button_style, size = wx.Size(24, 20)) - button_open.SetToolTipString(_("Import a surface file into InVesalius")) + button_open.SetToolTip(_("Import a surface file into InVesalius")) # Add all controls to gui sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -840,13 +840,13 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis self.imagelist = wx.ImageList(16, 16) image = wx.Image(os.path.join(const.ICON_DIR, "object_invisible.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) img_null = self.imagelist.Add(bitmap) image = wx.Image(os.path.join(const.ICON_DIR, "object_visible.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) img_check = self.imagelist.Add(bitmap) @@ -923,23 +923,23 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis def InsertNewItem(self, index=0, label="Surface 1", volume="0 mm3", area="0 mm2", transparency="0%%", colour=None): - self.InsertStringItem(index, "") - self.SetStringItem(index, 1, label, + self.InsertItem(index, "") + self.SetItem(index, 1, label, imageId = self.surface_list_index[index]) - self.SetStringItem(index, 2, volume) - self.SetStringItem(index, 3, area) - self.SetStringItem(index, 4, transparency) + self.SetItem(index, 2, volume) + self.SetItem(index, 3, area) + self.SetItem(index, 4, transparency) self.SetItemImage(index, 1) def UpdateItemInfo(self, index=0, label="Surface 1", volume="0 mm3", area="0 mm2", transparency="0%%", colour=None): print("UpdateItemInfo", index) # TODO: Retornar esse codigo - self.SetStringItem(index, 1, label, + self.SetItem(index, 1, label, imageId = self.surface_list_index[index]) - self.SetStringItem(index, 2, volume) - self.SetStringItem(index, 3, area) - self.SetStringItem(index, 4, transparency) + self.SetItem(index, 2, volume) + self.SetItem(index, 3, area) + self.SetItem(index, 4, transparency) self.SetItemImage(index, 1) def CreateColourBitmap(self, colour): @@ -955,21 +955,21 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis for i in colour] new_image.putpixel((x,y), tuple(pixel_colour)) - wx_image = wx.EmptyImage(new_image.size[0], - new_image.size[1]) + wx_image = wx.Image(new_image.size[0], + new_image.size[1]) try: wx_image.SetData(new_image.tostring()) except Exception: wx_image.SetData(new_image.tobytes()) - return wx.BitmapFromImage(wx_image.Scale(16, 16)) + return wx.Bitmap(wx_image.Scale(16, 16)) def EditSurfaceTransparency(self, surface_index, transparency): """ Set actor transparency (oposite to opacity) according to given actor index and value. """ - self.SetStringItem(surface_index, 4, "%d%%"%(int(transparency*100))) + self.SetItem(surface_index, 4, "%d%%"%(int(transparency*100))) def EditSurfaceColour(self, surface_index, colour): """ @@ -1115,13 +1115,13 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis self.imagelist = wx.ImageList(16, 16) image = wx.Image(os.path.join(const.ICON_DIR, "object_invisible.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) img_null = self.imagelist.Add(bitmap) image = wx.Image(os.path.join(const.ICON_DIR, "object_visible.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) img_check = self.imagelist.Add(bitmap) @@ -1217,22 +1217,22 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis def InsertNewItem(self, index=0, label="Measurement 1", colour=None, location="SURFACE", type_="LINEAR", value="0 mm"): - self.InsertStringItem(index, "") - self.SetStringItem(index, 1, label, + self.InsertItem(index, "") + self.SetItem(index, 1, label, imageId = self._list_index[index]) - self.SetStringItem(index, 2, location) - self.SetStringItem(index, 3, type_) - self.SetStringItem(index, 4, value) + self.SetItem(index, 2, location) + self.SetItem(index, 3, type_) + self.SetItem(index, 4, value) self.SetItemImage(index, 1) self.Refresh() def UpdateItemInfo(self, index=0, label="Measurement 1", colour=None, location="SURFACE", type_="LINEAR", value="0 mm"): - self.SetStringItem(index, 1, label, + self.SetItem(index, 1, label, imageId = self._list_index[index]) - self.SetStringItem(index, 2, location) - self.SetStringItem(index, 3, type_) - self.SetStringItem(index, 4, value) + self.SetItem(index, 2, location) + self.SetItem(index, 3, type_) + self.SetItem(index, 4, value) self.SetItemImage(index, 1) self.Refresh() @@ -1249,13 +1249,13 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.CheckLis for i in colour] new_image.putpixel((x,y), tuple(pixel_colour)) - wx_image = wx.EmptyImage(new_image.size[0], - new_image.size[1]) + wx_image = wx.Image(new_image.size[0], + new_image.size[1]) try: wx_image.SetData(new_image.tostring()) except: wx_image.SetData(new_image.tobytes()) - return wx.BitmapFromImage(wx_image.Scale(16, 16)) + return wx.Bitmap(wx_image.Scale(16, 16)) def EditItemColour(self, measure_index, colour): """ @@ -1310,19 +1310,19 @@ class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.Check self.imagelist = wx.ImageList(16, 16) image = wx.Image(os.path.join(const.ICON_DIR, "object_visible.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) img_check = self.imagelist.Add(bitmap) image = wx.Image(os.path.join(const.ICON_DIR, "object_invisible.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) img_null = self.imagelist.Add(bitmap) image = wx.Image(os.path.join(const.ICON_DIR, "object_colour.jpg")) - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) + bitmap = wx.Bitmap(image.Scale(16, 16)) bitmap.SetWidth(16) bitmap.SetHeight(16) self.img_colour = self.imagelist.Add(bitmap) @@ -1342,10 +1342,10 @@ class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin, listmix.Check def InsertNewItem(self, index=0, name="Axial 1", type_="2d", value="bla", colour=None): - self.InsertStringItem(index, "") - self.SetStringItem(index, 1, name, imageId = self.img_colour) - self.SetStringItem(index, 2, type_) - self.SetStringItem(index, 3, value) + self.InsertItem(index, "") + self.SetItem(index, 1, name, imageId = self.img_colour) + self.SetItem(index, 2, type_) + self.SetItem(index, 3, value) def Populate(self): dict = ((0, "Axial 1", "2D", "blalbalblabllablalbla"), diff --git a/invesalius/gui/default_tasks.py b/invesalius/gui/default_tasks.py index 788568d..83bb35e 100644 --- a/invesalius/gui/default_tasks.py +++ b/invesalius/gui/default_tasks.py @@ -58,12 +58,12 @@ zzW\xcff&\xb8,\x89\xa8@Q\xd6\xaaf\xdfRm,\xee\xb1BDxr#\xae\xf5|\xddo\xd6\xe2H\ \x00\x00\x00IEND\xaeB`\x82' def GetCollapsedIconBitmap(): - return wx.BitmapFromImage(GetCollapsedIconImage()) + return wx.Bitmap(GetCollapsedIconImage()) def GetCollapsedIconImage(): from io import BytesIO stream = BytesIO(GetCollapsedIconData()) - return wx.ImageFromStream(stream) + return wx.Image(stream) def GetExpandedIconData(): return \ @@ -89,12 +89,12 @@ b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ `\x82' def GetExpandedIconBitmap(): - return wx.BitmapFromImage(GetExpandedIconImage()) + return wx.Bitmap(GetExpandedIconImage()) def GetExpandedIconImage(): from io import BytesIO stream = BytesIO(GetExpandedIconData()) - return wx.ImageFromStream(stream) + return wx.Image(stream) # Main panel diff --git a/invesalius/gui/default_viewers.py b/invesalius/gui/default_viewers.py index 68605cb..2105cae 100644 --- a/invesalius/gui/default_viewers.py +++ b/invesalius/gui/default_viewers.py @@ -506,7 +506,7 @@ class VolumeToolPanel(wx.Panel): for name in const.RAYCASTING_TYPES: id = wx.NewId() item = wx.MenuItem(menu, id, name, kind=wx.ITEM_RADIO) - menu.AppendItem(item) + menu.Append(item) if name == const.RAYCASTING_OFF_LABEL: self.off_item = item item.Check(1) @@ -522,12 +522,12 @@ class VolumeToolPanel(wx.Panel): self.id_cutplane = id item = wx.MenuItem(submenu, id, name, kind=wx.ITEM_CHECK) - submenu.AppendItem(item) + submenu.Append(item) ID_TO_TOOL[id] = name ID_TO_TOOL_ITEM[id] = item TOOL_STATE[id] = False self.submenu_raycasting_tools = submenu - menu.AppendMenu(RAYCASTING_TOOLS, _("Tools"), submenu) + menu.Append(RAYCASTING_TOOLS, _("Tools"), submenu) menu.Enable(RAYCASTING_TOOLS, 0) self.menu_raycasting = menu @@ -544,7 +544,7 @@ class VolumeToolPanel(wx.Panel): bmp = wx.Bitmap(ID_TO_BMP[id][1], wx.BITMAP_TYPE_PNG) item = wx.MenuItem(menu, id, ID_TO_BMP[id][0]) item.SetBitmap(bmp) - menu.AppendItem(item) + menu.Append(item) menu.Bind(wx.EVT_MENU, self.OnMenuView) self.menu_view = menu @@ -558,7 +558,7 @@ class VolumeToolPanel(wx.Panel): item = wx.MenuItem(slice_plane_menu, new_id, value, kind = wx.ITEM_CHECK) ID_TO_ITEMSLICEMENU[new_id] = item - slice_plane_menu.AppendItem(item) + slice_plane_menu.Append(item) slice_plane_menu.Bind(wx.EVT_MENU, self.OnMenuPlaneSlice) @@ -577,7 +577,7 @@ class VolumeToolPanel(wx.Panel): ID_TO_ITEM_3DSTEREO[new_id] = item ID_TO_STEREO_NAME[new_id] = value - stereo_menu.AppendItem(item) + stereo_menu.Append(item) stereo_menu.Bind(wx.EVT_MENU, self.OnMenuStereo) diff --git a/invesalius/gui/dialogs.py b/invesalius/gui/dialogs.py index 4a1cf44..1c912c5 100644 --- a/invesalius/gui/dialogs.py +++ b/invesalius/gui/dialogs.py @@ -48,6 +48,7 @@ from wx.lib.agw import floatspin from wx.lib.wordwrap import wordwrap from wx.lib.pubsub import pub as Publisher + try: from wx.adv import AboutDialogInfo, AboutBox except ImportError: @@ -58,6 +59,7 @@ import invesalius.data.coordinates as dco import invesalius.gui.widgets.gradient as grad import invesalius.session as ses import invesalius.utils as utils +from invesalius.gui.widgets.inv_spinctrl import InvSpinCtrl, InvFloatSpinCtrl from invesalius.gui.widgets import clut_imagedata from invesalius.gui.widgets.clut_imagedata import CLUTImageDataWidget, EVT_CLUT_NODE_CHANGED import numpy as np @@ -78,16 +80,9 @@ EVT_MASK_SET = wx.PyEventBinder(myEVT_MASK_SET, 1) class NumberDialog(wx.Dialog): def __init__(self, message, value=0): - try: - pre = wx.PreDialog() - pre.Create(None, -1, "InVesalius 3", size=wx.DefaultSize, - pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, None, -1, "InVesalius 3", size=wx.DefaultSize, - pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE) + wx.Dialog.__init__(self, None, -1, "InVesalius 3", size=wx.DefaultSize, + pos=wx.DefaultPosition, + style=wx.DEFAULT_DIALOG_STYLE) # Static text which contains message to user label = wx.StaticText(self, -1, message) @@ -133,16 +128,9 @@ class NumberDialog(wx.Dialog): class ResizeImageDialog(wx.Dialog): def __init__(self):#, message, value=0): - try: - pre = self.pre = wx.PreDialog() - pre.Create(None, -1, "InVesalius 3", size=wx.DefaultSize, - pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, None, -1, "InVesalius 3", size=wx.DefaultSize, - pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE) + wx.Dialog.__init__(self, None, -1, "InVesalius 3", size=wx.DefaultSize, + pos=wx.DefaultPosition, + style=wx.DEFAULT_DIALOG_STYLE) lbl_message = wx.StaticText(self, -1, _("InVesalius is running on a 32-bit operating system or has insufficient memory. \nIf you want to work with 3D surfaces or volume rendering, \nit is recommended to reduce the medical images resolution.")) icon = wx.ArtProvider.GetBitmap(wx.ART_WARNING, wx.ART_MESSAGE_BOX, (32,32)) @@ -160,8 +148,7 @@ class ResizeImageDialog(wx.Dialog): lbl_message_percent = wx.StaticText(self, -1,_("Percentage of original resolution")) - num_ctrl_percent = wx.SpinCtrl(self, -1) - num_ctrl_percent.SetRange(20,100) + num_ctrl_percent = InvSpinCtrl(self, -1, value=100, min_value=20, max_value=100) self.num_ctrl_porcent = num_ctrl_percent sizer_percent = wx.BoxSizer(wx.HORIZONTAL) @@ -675,14 +662,8 @@ def ShowLoadRegistrationDialog(): class MessageDialog(wx.Dialog): def __init__(self, message): - try: - pre = wx.PreDialog() - pre.Create(None, -1, "InVesalius 3", size=(360, 370), pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE|wx.ICON_INFORMATION) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, None, -1, "InVesalius 3", size=(360, 370), pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE|wx.ICON_INFORMATION) + wx.Dialog.__init__(self, None, -1, "InVesalius 3", size=(360, 370), pos=wx.DefaultPosition, + style=wx.DEFAULT_DIALOG_STYLE|wx.ICON_INFORMATION) # Static text which contains message to user label = wx.StaticText(self, -1, message) @@ -721,14 +702,8 @@ class UpdateMessageDialog(wx.Dialog): title=_("Invesalius Update") self.url = url - try: - pre = wx.PreDialog() - pre.Create(None, -1, title, size=(360, 370), pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE|wx.ICON_INFORMATION) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, None, -1, title, size=(360, 370), pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE|wx.ICON_INFORMATION) + wx.Dialog.__init__(self, None, -1, title, size=(360, 370), pos=wx.DefaultPosition, + style=wx.DEFAULT_DIALOG_STYLE|wx.ICON_INFORMATION) # Static text which contains message to user label = wx.StaticText(self, -1, msg) @@ -1066,22 +1041,8 @@ class NewMask(wx.Dialog): import invesalius.data.mask as mask import invesalius.project as prj - try: - # Instead of calling wx.Dialog.__init__ we precreate the dialog - # so we can set an extra style that must be set before - # creation, and then we create the GUI object using the Create - # method. - pre = wx.PreDialog() - pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) - pre.Create(parent, ID, title, pos, (500,300), style) - # This next step is the most important, it turns this Python - # object into the real wrapper of the dialog (instead of pre) - # as far as the wxPython extension is concerned. - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, parent, ID, title, pos, (500,300), style) - self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) - + wx.Dialog.__init__(self, parent, ID, title, pos, style=style) + self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) self.CenterOnScreen() @@ -1127,10 +1088,10 @@ class NewMask(wx.Dialog): self.colour = original_colour colour = [255*i for i in original_colour] colour.append(100) - gradient = grad.GradientSlider(self, -1, int(bound_min), - int(bound_max), - int(thresh_min), int(thresh_max), - colour) + gradient = grad.GradientCtrl(self, -1, int(bound_min), + int(bound_max), + int(thresh_min), int(thresh_max), + colour) self.gradient = gradient # OVERVIEW @@ -1162,11 +1123,12 @@ class NewMask(wx.Dialog): # Merge all sizers and checkboxes sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(fixed_sizer, 0, wx.ALL|wx.GROW|wx.EXPAND, 15) - sizer.Add(gradient, 1, wx.BOTTOM|wx.RIGHT|wx.LEFT|wx.EXPAND|wx.GROW, 20) + sizer.Add(gradient, 0, wx.BOTTOM|wx.RIGHT|wx.LEFT|wx.EXPAND|wx.GROW, 20) sizer.Add(btnsizer, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 10) self.SetSizer(sizer) sizer.Fit(self) + self.Layout() self.Bind(grad.EVT_THRESHOLD_CHANGED, self.OnSlideChanged, self.gradient) self.combo_thresh.Bind(wx.EVT_COMBOBOX, self.OnComboThresh) @@ -1362,22 +1324,8 @@ class NewSurfaceDialog(wx.Dialog): import invesalius.data.surface as surface import invesalius.project as prj - try: - # Instead of calling wx.Dialog.__init__ we precreate the dialog - # so we can set an extra style that must be set before - # creation, and then we create the GUI object using the Create - # method. - pre = wx.PreDialog() - pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) - pre.Create(parent, ID, title, pos, (500,300), style) - - # This next step is the most important, it turns this Python - # object into the real wrapper of the dialog (instead of pre) - # as far as the wxPython extension is concerned. - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, parent, ID, title, pos, (500,300), style) - self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) + wx.Dialog.__init__(self, parent, ID, title, pos, (500,300), style) + self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) self.CenterOnScreen() @@ -1579,28 +1527,10 @@ class SurfaceCreationDialog(wx.Dialog): style=wx.DEFAULT_DIALOG_STYLE, useMetal=False, mask_edited=False): - # Instead of calling wx.Dialog.__init__ we precreate the dialog - # so we can set an extra style that must be set before - # creation, and then we create the GUI object using the Create - # method. - try: - pre = wx.PreDialog() - pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) - pre.Create(parent, ID, title, pos, (500,300), style) - - # This extra style can be set after the UI object has been created. - if 'wxMac' in wx.PlatformInfo and useMetal: - self.SetExtraStyle(wx.DIALOG_EX_METAL) - - # This next step is the most important, it turns this Python - # object into the real wrapper of the dialog (instead of pre) - # as far as the wxPython extension is concerned. - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, parent, ID, title, pos, size, style) - self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) - if 'wxMac' in wx.PlatformInfo and useMetal: - self.SetExtraStyle(wx.DIALOG_EX_METAL) + wx.Dialog.__init__(self, parent, ID, title, pos, size, style) + self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) + if 'wxMac' in wx.PlatformInfo and useMetal: + self.SetExtraStyle(wx.DIALOG_EX_METAL) self.CenterOnScreen() @@ -1772,19 +1702,19 @@ class CAOptions(wx.Panel): def _build_widgets(self): sb = wx.StaticBox(self, -1, _('Options')) - self.angle = floatspin.FloatSpin(self, -1, value=0.7, min_val=0.0, - max_val=1.0, increment=0.1, - digits=1) + self.angle = InvFloatSpinCtrl(self, -1, value=0.7, min_value=0.0, + max_value=1.0, increment=0.1, + digits=1) - self.max_distance = floatspin.FloatSpin(self, -1, value=3.0, min_val=0.0, - max_val=100.0, increment=0.1, + self.max_distance = InvFloatSpinCtrl(self, -1, value=3.0, min_value=0.0, + max_value=100.0, increment=0.1, digits=2) - self.min_weight = floatspin.FloatSpin(self, -1, value=0.5, min_val=0.0, - max_val=1.0, increment=0.1, + self.min_weight = InvFloatSpinCtrl(self, -1, value=0.5, min_value=0.0, + max_value=1.0, increment=0.1, digits=1) - self.steps = wx.SpinCtrl(self, -1, value='10', min=1, max=100) + self.steps = InvSpinCtrl(self, -1, value=10, min_value=1, max_value=100) layout_sizer = wx.FlexGridSizer(rows=4, cols=2, hgap=5, vgap=5) layout_sizer.Add(wx.StaticText(self, -1, _(u'Angle:')), 0, wx.EXPAND) @@ -1826,12 +1756,12 @@ class SurfaceMethodPanel(wx.Panel): choices=[i for i in sorted(self.alg_types) if not (self.mask_edited and i in self.edited_imp)], style=wx.CB_READONLY) - w, h = self.cb_types.GetSizeTuple() + w, h = self.cb_types.GetSize() icon = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_MESSAGE_BOX, (h * 0.8, h * 0.8)) self.bmp = wx.StaticBitmap(self, -1, icon) - self.bmp.SetToolTipString(_("It is not possible to use the Default method because the mask was edited.")) + self.bmp.SetToolTip(_("It is not possible to use the Default method because the mask was edited.")) self.method_sizer = wx.BoxSizer(wx.HORIZONTAL) self.method_sizer.Add(wx.StaticText(self, -1, _(u'Method:')), 0, @@ -1906,12 +1836,7 @@ class SurfaceMethodPanel(wx.Panel): class ClutImagedataDialog(wx.Dialog): def __init__(self, histogram, init, end, nodes=None): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), -1, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) self.histogram = histogram self.init = init @@ -1981,8 +1906,8 @@ class WatershedOptionsPanel(wx.Panel): style=wx.NO_BORDER | wx.HORIZONTAL) self.choice_3dcon.SetSelection(self.con3d_choices.index(self.config.con_3d)) - self.gaussian_size = wx.SpinCtrl(self, -1, "", min=1, max=10) - self.gaussian_size.SetValue(self.config.mg_size) + self.gaussian_size = InvSpinCtrl(self, -1, value=self.config.mg_size, + min_value=1, max_value=10) box_sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Conectivity"), wx.VERTICAL) box_sizer.Add(self.choice_2dcon, 0, wx.ALIGN_CENTER_VERTICAL,2) @@ -2010,12 +1935,7 @@ class WatershedOptionsPanel(wx.Panel): class WatershedOptionsDialog(wx.Dialog): def __init__(self, config, ID=-1, title=_(u'Watershed'), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), ID, title=title, style=style) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) self.config = config @@ -2054,12 +1974,7 @@ class WatershedOptionsDialog(wx.Dialog): class MaskBooleanDialog(wx.Dialog): def __init__(self, masks, ID=-1, title=_(u"Boolean operations"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), ID, title=title, style=style) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) self._init_gui(masks) self.CenterOnScreen() @@ -2138,12 +2053,7 @@ class MaskBooleanDialog(wx.Dialog): class ReorientImageDialog(wx.Dialog): def __init__(self, ID=-1, title=_(u'Image reorientation'), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), ID, title=title, style=style) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) self._closed = False @@ -2263,16 +2173,10 @@ class ImportBitmapParameters(wx.Dialog): else: size=wx.Size(380,210) - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), -1, _(u"Create project from bitmap"),size=size, - style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, - _(u"Create project from bitmap"), - size=size, - style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, + _(u"Create project from bitmap"), + size=size, + style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) self.interval = 0 @@ -2325,16 +2229,16 @@ class ImportBitmapParameters(wx.Dialog): gbs_spacing = wx.GridBagSizer(2, 6) stx_spacing_x = stx_spacing_x = wx.StaticText(p, -1, _(u"X:")) - fsp_spacing_x = self.fsp_spacing_x = FS.FloatSpin(p, -1, min_val=0,\ + fsp_spacing_x = self.fsp_spacing_x = InvFloatSpinCtrl(p, -1, min_value=0, max_value=1000000000, increment=0.25, value=1.0, digits=8) stx_spacing_y = stx_spacing_y = wx.StaticText(p, -1, _(u"Y:")) - fsp_spacing_y = self.fsp_spacing_y = FS.FloatSpin(p, -1, min_val=0,\ + fsp_spacing_y = self.fsp_spacing_y = InvFloatSpinCtrl(p, -1, min_value=0, max_value=1000000000, increment=0.25, value=1.0, digits=8) stx_spacing_z = stx_spacing_z = wx.StaticText(p, -1, _(u"Z:")) - fsp_spacing_z = self.fsp_spacing_z = FS.FloatSpin(p, -1, min_val=0,\ + fsp_spacing_z = self.fsp_spacing_z = InvFloatSpinCtrl(p, -1, min_value=0, max_value=1000000000, increment=0.25, value=1.0, digits=8) @@ -2594,12 +2498,11 @@ class PanelFFillDynamic(wx.Panel): self.use_ww_wl = wx.CheckBox(self, -1, _(u"Use WW&WL")) self.use_ww_wl.SetValue(self.config.use_ww_wl) - self.deviation_min = wx.SpinCtrl(self, -1, value='%d' % self.config.dev_min, min=0, max=10000) - w, h = self.deviation_min.GetTextExtent('M') - self.deviation_min.SetMinSize((w*5, -1)) + self.deviation_min = InvSpinCtrl(self, -1, value=self.config.dev_min, min_value=0, max_value=10000) + self.deviation_min.CalcSizeFromTextSize() - self.deviation_max = wx.SpinCtrl(self, -1, value='%d' % self.config.dev_max, min=0, max=10000) - self.deviation_max.SetMinSize((w*5, -1)) + self.deviation_max = InvSpinCtrl(self, -1, value=self.config.dev_max, min_value=0, max_value=10000) + self.deviation_max.CalcSizeFromTextSize() sizer = wx.GridBagSizer(5, 5) @@ -2656,17 +2559,16 @@ class PanelFFillConfidence(wx.Panel): self.use_ww_wl = wx.CheckBox(self, -1, _(u"Use WW&WL")) self.use_ww_wl.SetValue(self.config.use_ww_wl) - self.spin_mult = floatspin.FloatSpin(self, -1, - value=self.config.confid_mult, - min_val=1.0, max_val=10.0, - increment=0.1, digits=1, - style=wx.TE_PROCESS_TAB|wx.TE_PROCESS_ENTER, - agwStyle=floatspin.FS_RIGHT) - w, h = self.spin_mult.GetTextExtent('M') - self.spin_mult.SetMinSize((w*7, -1)) + self.spin_mult = InvFloatSpinCtrl(self, -1, + value=self.config.confid_mult, + min_value=1.0, max_value=10.0, + increment=0.1, digits=1) + # style=wx.TE_PROCESS_TAB|wx.TE_PROCESS_ENTER, + # agwStyle=floatspin.FS_RIGHT) + self.spin_mult.CalcSizeFromTextSize() - self.spin_iters = wx.SpinCtrl(self, -1, value='%d' % self.config.confid_iters, min=0, max=100) - self.spin_iters.SetMinSize((w*7, -1)) + self.spin_iters = InvSpinCtrl(self, -1, value=self.config.confid_iters, min_value=0, max_value=100) + self.spin_iters.CalcSizeFromTextSize() sizer = wx.GridBagSizer(5, 5) @@ -2713,12 +2615,7 @@ class PanelFFillConfidence(wx.Panel): class FFillOptionsDialog(wx.Dialog): def __init__(self, title, config): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) self.config = config @@ -2826,12 +2723,7 @@ class FFillOptionsDialog(wx.Dialog): class SelectPartsOptionsDialog(wx.Dialog): def __init__(self, config): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), -1, _(u"Select mask parts"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, _(u"Select mask parts"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, _(u"Select mask parts"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) self.config = config @@ -2911,12 +2803,7 @@ class SelectPartsOptionsDialog(wx.Dialog): class FFillSegmentationOptionsDialog(wx.Dialog): def __init__(self, config, ID=-1, title=_(u"Region growing"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), ID, title=title, style=style) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) self.config = config @@ -3117,15 +3004,7 @@ class CropOptionsDialog(wx.Dialog): def __init__(self, config, ID=-1, title=_(u"Crop mask"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP): self.config = config - try: - pre = wx.PreDialog() - - pre.Create(wx.GetApp().GetTopWindow(), ID, title=title, style=style) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) - - + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) self._init_gui() def UpdateValues(self, limits): @@ -3236,13 +3115,7 @@ class CropOptionsDialog(wx.Dialog): class FillHolesAutoDialog(wx.Dialog): def __init__(self, title): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) - + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) self._init_gui() def _init_gui(self): @@ -3251,7 +3124,7 @@ class FillHolesAutoDialog(wx.Dialog): else: border_style = wx.SUNKEN_BORDER - self.spin_size = wx.SpinCtrl(self, -1, value='1000', min=1, max=1000000000) + self.spin_size = InvSpinCtrl(self, -1, value=1000, min_value=1, max_value=1000000000) self.panel_target = PanelTargeFFill(self, style=border_style|wx.TAB_TRAVERSAL) self.panel2dcon = Panel2DConnectivity(self, show_orientation=True, style=border_style|wx.TAB_TRAVERSAL) self.panel3dcon = Panel3DConnectivity(self, style=border_style|wx.TAB_TRAVERSAL) @@ -3340,14 +3213,8 @@ class FillHolesAutoDialog(wx.Dialog): class MaskDensityDialog(wx.Dialog): def __init__(self, title): - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), -1, _(u"Mask density"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, _(u"Mask density"), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT) - + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, _(u"Mask density"), + style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT) self._init_gui() self._bind_events() @@ -3456,14 +3323,8 @@ class ObjectCalibrationDialog(wx.Dialog): self.obj_fiducials = np.full([5, 3], np.nan) self.obj_orients = np.full([5, 3], np.nan) - try: - pre = wx.PreDialog() - pre.Create(wx.GetApp().GetTopWindow(), -1, _(u"Object calibration"), size=(450, 440), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, _(u"Object calibration"), size=(450, 440), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, _(u"Object calibration"), size=(450, 440), + style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) self._init_gui() self.LoadObject() diff --git a/invesalius/gui/dicom_preview_panel.py b/invesalius/gui/dicom_preview_panel.py index d9fa764..8d66d67 100644 --- a/invesalius/gui/dicom_preview_panel.py +++ b/invesalius/gui/dicom_preview_panel.py @@ -149,7 +149,7 @@ class DicomPaintPanel(wx.Panel): self.Bind(wx.EVT_SIZE, self.OnSize) def _build_bitmap(self, image): - bmp = wx.BitmapFromImage(image) + bmp = wx.Bitmap(image) return bmp def _image_resize(self, image): diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index d9fb36a..c0761ae 100644 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -820,7 +820,7 @@ class MenuBar(wx.MenuBar): app = file_menu.Append app(const.ID_DICOM_IMPORT, _("Import DICOM...\tCtrl+I")) #app(const.ID_DICOM_NETWORK, _("Retrieve DICOM from PACS")) - file_menu.AppendMenu(const.ID_IMPORT_OTHERS_FILES, _("Import other files..."), others_file_menu) + file_menu.Append(const.ID_IMPORT_OTHERS_FILES, _("Import other files..."), others_file_menu) app(const.ID_PROJECT_OPEN, _("Open project...\tCtrl+O")) app(const.ID_PROJECT_SAVE, _("Save project\tCtrl+S")) app(const.ID_PROJECT_SAVE_AS, _("Save project as...\tCtrl+Shift+S")) @@ -848,12 +848,12 @@ class MenuBar(wx.MenuBar): file_edit_item_undo = wx.MenuItem(file_edit, wx.ID_UNDO, _("Undo\tCtrl+Z")) file_edit_item_undo.SetBitmap(self.BMP_UNDO) - file_edit.AppendItem(file_edit_item_undo) + file_edit.Append(file_edit_item_undo) file_edit_item_undo.Enable(False) file_edit_item_redo = wx.MenuItem(file_edit, wx.ID_REDO, _("Redo\tCtrl+Y")) file_edit_item_redo.SetBitmap(self.BMP_REDO) - file_edit.AppendItem(file_edit_item_redo) + file_edit.Append(file_edit_item_redo) file_edit_item_redo.Enable(False) else: file_edit.Append(wx.ID_UNDO, _("Undo\tCtrl+Z")).Enable(False) @@ -925,17 +925,17 @@ class MenuBar(wx.MenuBar): swap_axes_menu.Append(const.ID_SWAP_XZ, _("From Right-Left to Top-Bottom")).Enable(False) swap_axes_menu.Append(const.ID_SWAP_YZ, _("From Anterior-Posterior to Top-Bottom")).Enable(False) - image_menu.AppendMenu(wx.NewId(), _('Flip'), flip_menu) - image_menu.AppendMenu(wx.NewId(), _('Swap axes'), swap_axes_menu) + image_menu.Append(wx.NewId(), _('Flip'), flip_menu) + image_menu.Append(wx.NewId(), _('Swap axes'), swap_axes_menu) mask_density_menu = image_menu.Append(const.ID_MASK_DENSITY_MEASURE, _(u'Mask Density measure')) reorient_menu = image_menu.Append(const.ID_REORIENT_IMG, _(u'Reorient image\tCtrl+Shift+R')) reorient_menu.Enable(False) - tools_menu.AppendMenu(-1, _(u'Image'), image_menu) - tools_menu.AppendMenu(-1, _(u"Mask"), mask_menu) - tools_menu.AppendMenu(-1, _(u"Segmentation"), segmentation_menu) - tools_menu.AppendMenu(-1, _(u"Surface"), surface_menu) + tools_menu.Append(-1, _(u'Image'), image_menu) + tools_menu.Append(-1, _(u"Mask"), mask_menu) + tools_menu.Append(-1, _(u"Segmentation"), segmentation_menu) + tools_menu.Append(-1, _(u"Surface"), surface_menu) #View self.view_menu = view_menu = wx.Menu() @@ -961,7 +961,7 @@ class MenuBar(wx.MenuBar): #view_menu = wx.Menu() #app = view_menu.Append - #appm = view_menu.AppendMenu + #appm = view_menu.Append #appm(-1, "Toolbars",view_tool_menu) #appm(-1, "Layout", view_layout_menu) #view_menu.AppendSeparator() @@ -2007,8 +2007,8 @@ class HistoryToolBar(AuiToolBar): Bind normal events from wx (except pubsub related). """ #self.Bind(wx.EVT_TOOL, self.OnToggle) - wx.EVT_TOOL( self, wx.ID_UNDO, self.OnUndo ) - wx.EVT_TOOL( self, wx.ID_REDO, self.OnRedo ) + self.Bind(wx.EVT_TOOL, self.OnUndo, id=wx.ID_UNDO) + self.Bind(wx.EVT_TOOL, self.OnRedo, id=wx.ID_REDO) def __init_items(self): """ diff --git a/invesalius/gui/import_network_panel.py b/invesalius/gui/import_network_panel.py index 2d0629c..f460bb5 100644 --- a/invesalius/gui/import_network_panel.py +++ b/invesalius/gui/import_network_panel.py @@ -675,24 +675,24 @@ class NodesPanel(wx.Panel): self.hosts[0] = [True, "localhost", "", "invesalius"] try: - index = self.tree_node.InsertStringItem(sys.maxsize, "") + index = self.tree_node.InsertItem(sys.maxsize, "") except (OverflowError, AssertionError): - index = self.tree_node.InsertStringItem(sys.maxint, "") - self.tree_node.SetStringItem(index, 1, "localhost") - self.tree_node.SetStringItem(index, 2, "") - self.tree_node.SetStringItem(index, 3, "invesalius") - self.tree_node.SetStringItem(index, 4, "ok") + index = self.tree_node.InsertItem(sys.maxint, "") + self.tree_node.SetItem(index, 1, "localhost") + self.tree_node.SetItem(index, 2, "") + self.tree_node.SetItem(index, 3, "invesalius") + self.tree_node.SetItem(index, 4, "ok") self.tree_node.CheckItem(index) self.tree_node.SetItemBackgroundColour(index, wx.Colour(245,245,245)) #print ">>>>>>>>>>>>>>>>>>>>>", sys.maxint - #index = self.tree_node.InsertStringItem(sys.maxint, "")#adiciona vazio a coluna de check - #self.tree_node.SetStringItem(index, 1, "200.144.114.19") - #self.tree_node.SetStringItem(index, 2, "80") + #index = self.tree_node.InsertItem(sys.maxint, "")#adiciona vazio a coluna de check + #self.tree_node.SetItem(index, 1, "200.144.114.19") + #self.tree_node.SetItem(index, 2, "80") #self.tree_node.SetItemData(index, 0) - #index2 = self.tree_node.InsertStringItem(sys.maxint, "")#adiciona vazio a coluna de check - #self.tree_node.SetStringItem(index2, 1, "200.144.114.19") - #self.tree_node.SetStringItem(index2, 2, "80") + #index2 = self.tree_node.InsertItem(sys.maxint, "")#adiciona vazio a coluna de check + #self.tree_node.SetItem(index2, 1, "200.144.114.19") + #self.tree_node.SetItem(index2, 2, "80") #self.tree_node.SetItemData(index2, 0) self.btn_add = wx.Button(self, -1, _("Add")) @@ -732,12 +732,12 @@ class NodesPanel(wx.Panel): def OnButtonAdd(self, evt): #adiciona vazio a coluna de check - index = self.tree_node.InsertStringItem(sys.maxsize, "") + index = self.tree_node.InsertItem(sys.maxsize, "") self.hosts[index] = [True, "localhost", "80", ""] - self.tree_node.SetStringItem(index, 1, "localhost") - self.tree_node.SetStringItem(index, 2, "80") - self.tree_node.SetStringItem(index, 3, "") + self.tree_node.SetItem(index, 1, "localhost") + self.tree_node.SetItem(index, 2, "80") + self.tree_node.SetItem(index, 3, "") self.tree_node.CheckItem(index) def OnLeftDown(self, evt): @@ -770,9 +770,9 @@ class NodesPanel(wx.Panel): dn.SetAETitle(self.hosts[0][3]) if dn.RunCEcho(): - self.tree_node.SetStringItem(key, 4, _("ok")) + self.tree_node.SetItem(key, 4, _("ok")) else: - self.tree_node.SetStringItem(key, 4, _("error")) + self.tree_node.SetItem(key, 4, _("error")) def RightButton(self,evt): event.Skip() diff --git a/invesalius/gui/preferences.py b/invesalius/gui/preferences.py index 1841c01..1dc0564 100644 --- a/invesalius/gui/preferences.py +++ b/invesalius/gui/preferences.py @@ -17,15 +17,8 @@ class Preferences(wx.Dialog): def __init__( self, parent, id = ID, title = _("Preferences"), size=wx.DefaultSize,\ pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): - try: - pre = wx.PreDialog() - pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) - pre.Create(parent, ID, title, pos, size, style) - - self.PostCreate(pre) - except AttributeError: - wx.Dialog.__init__(self, parent, ID, title, pos, size, style) - self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) + wx.Dialog.__init__(self, parent, ID, title, pos, size, style) + self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) sizer = wx.BoxSizer(wx.VERTICAL) diff --git a/invesalius/gui/task_exporter.py b/invesalius/gui/task_exporter.py index 8594888..b87966f 100644 --- a/invesalius/gui/task_exporter.py +++ b/invesalius/gui/task_exporter.py @@ -257,7 +257,7 @@ class InnerTaskPanel(wx.Panel): for id in self.id_to_name: item = wx.MenuItem(menu, id, self.id_to_name[id]) - menu.AppendItem(item) + menu.Append(item) self.menu_picture = menu menu.Bind(wx.EVT_MENU, self.OnMenuPicture) diff --git a/invesalius/gui/task_navigator.py b/invesalius/gui/task_navigator.py index 8670880..9165f81 100644 --- a/invesalius/gui/task_navigator.py +++ b/invesalius/gui/task_navigator.py @@ -1093,7 +1093,7 @@ class MarkersPanel(wx.Panel): if id_label == 'TARGET': id_label = '' dlg.InvalidTargetID() - self.lc.SetStringItem(list_index, 4, id_label) + self.lc.SetItem(list_index, 4, id_label) # Add the new ID to exported list if len(self.list_coord[list_index]) > 8: self.list_coord[list_index][10] = str(id_label) @@ -1107,7 +1107,7 @@ class MarkersPanel(wx.Panel): if self.tgt_flag: self.lc.SetItemBackgroundColour(self.tgt_index, 'white') Publisher.sendMessage('Set target transparency', status=False, index=self.tgt_index) - self.lc.SetStringItem(self.tgt_index, 4, '') + self.lc.SetItem(self.tgt_index, 4, '') # Add the new ID to exported list if len(self.list_coord[self.tgt_index]) > 8: self.list_coord[self.tgt_index][10] = str('') @@ -1197,7 +1197,7 @@ class MarkersPanel(wx.Panel): del self.list_coord[i] self.lc.DeleteItem(i) for n in range(0, self.lc.GetItemCount()): - self.lc.SetStringItem(n, 0, str(n+1)) + self.lc.SetItem(n, 0, str(n+1)) self.marker_ind -= 1 Publisher.sendMessage('Remove marker', index=index) @@ -1312,11 +1312,11 @@ class MarkersPanel(wx.Panel): # Add item to list control in panel num_items = self.lc.GetItemCount() - self.lc.InsertStringItem(num_items, str(num_items + 1)) - self.lc.SetStringItem(num_items, 1, str(round(coord[0], 2))) - self.lc.SetStringItem(num_items, 2, str(round(coord[1], 2))) - self.lc.SetStringItem(num_items, 3, str(round(coord[2], 2))) - self.lc.SetStringItem(num_items, 4, str(marker_id)) + self.lc.InsertItem(num_items, str(num_items + 1)) + self.lc.SetItem(num_items, 1, str(round(coord[0], 2))) + self.lc.SetItem(num_items, 2, str(round(coord[1], 2))) + self.lc.SetItem(num_items, 3, str(round(coord[2], 2))) + self.lc.SetItem(num_items, 4, str(marker_id)) self.lc.EnsureVisible(num_items) def GetSelectedItems(self): diff --git a/invesalius/gui/task_slice.py b/invesalius/gui/task_slice.py index 21d45b2..80fd062 100644 --- a/invesalius/gui/task_slice.py +++ b/invesalius/gui/task_slice.py @@ -38,6 +38,7 @@ import invesalius.data.slice_ as slice_ import invesalius.constants as const import invesalius.gui.dialogs as dlg import invesalius.gui.widgets.gradient as grad +from invesalius.gui.widgets.inv_spinctrl import InvSpinCtrl from invesalius.project import Project import invesalius.session as ses @@ -693,8 +694,8 @@ class EditionTools(wx.Panel): item2 = wx.MenuItem(menu, MENU_BRUSH_SQUARE, _("Square")) item2.SetBitmap(SQUARE_BMP) - menu.AppendItem(item) - menu.AppendItem(item2) + menu.Append(item) + menu.Append(item2) bmp_brush_format = {const.BRUSH_CIRCLE: CIRCLE_BMP, const.BRUSH_SQUARE: SQUARE_BMP} @@ -705,14 +706,9 @@ class EditionTools(wx.Panel): btn_brush_format.SetMenu(menu) self.btn_brush_format = btn_brush_format + spin_brush_size = InvSpinCtrl(self, -1, value=const.BRUSH_SIZE, min_value=1, max_value=1000, spin_button=False) # To calculate best width to spinctrl - dc = wx.WindowDC(self) - dc.SetFont(self.GetFont()) - width, height = dc.GetTextExtent("MMM") - - spin_brush_size = wx.SpinCtrl(self, -1, "", size=(width + 20, -1)) - spin_brush_size.SetRange(1,100) - spin_brush_size.SetValue(const.BRUSH_SIZE) + spin_brush_size.CalcSizeFromTextSize("MMMM") spin_brush_size.Bind(wx.EVT_SPINCTRL, self.OnBrushSize) self.spin = spin_brush_size @@ -861,8 +857,8 @@ class WatershedTool(EditionTools): item2 = wx.MenuItem(menu, MENU_BRUSH_SQUARE, _("Square")) item2.SetBitmap(SQUARE_BMP) - menu.AppendItem(item) - menu.AppendItem(item2) + menu.Append(item) + menu.Append(item2) bmp_brush_format = {const.BRUSH_CIRCLE: CIRCLE_BMP, const.BRUSH_SQUARE: SQUARE_BMP} @@ -873,14 +869,9 @@ class WatershedTool(EditionTools): btn_brush_format.SetMenu(menu) self.btn_brush_format = btn_brush_format + spin_brush_size = InvSpinCtrl(self, -1, value=const.BRUSH_SIZE, min_value=1, max_value=1000, spin_button=False) # To calculate best width to spinctrl - dc = wx.WindowDC(self) - dc.SetFont(self.GetFont()) - width, height = dc.GetTextExtent("MMM") - - spin_brush_size = wx.SpinCtrl(self, -1, "", size=(width + 20, -1)) - spin_brush_size.SetRange(1,100) - spin_brush_size.SetValue(const.BRUSH_SIZE) + spin_brush_size.CalcSizeFromTextSize("MMMM") spin_brush_size.Bind(wx.EVT_SPINCTRL, self.OnBrushSize) self.spin = spin_brush_size diff --git a/invesalius/gui/task_surface.py b/invesalius/gui/task_surface.py index 5bd4ca5..6ab4754 100644 --- a/invesalius/gui/task_surface.py +++ b/invesalius/gui/task_surface.py @@ -38,6 +38,8 @@ import wx.lib.platebtn as pbtn import invesalius.project as prj import invesalius.utils as utl +from invesalius.gui.widgets.inv_spinctrl import InvSpinCtrl, InvFloatSpinCtrl + #INTERPOLATION_MODE_LIST = ["Cubic", "Linear", "NearestNeighbor"] MIN_TRANSPARENCY = 0 MAX_TRANSPARENCY = 100 @@ -620,9 +622,7 @@ class QualityAdjustment(wx.Panel): text_decimate = wx.StaticText(self, -1, _("Decimate resolution:")) - spin_decimate = wx.SpinCtrl(self, -1, "", (30, 50)) - spin_decimate.SetRange(1,100) - spin_decimate.SetValue(30) + spin_decimate = InvSpinCtrl(self, -1, value=30, min_value=1, max_value=100, size=(30, 50)) #spin_decimate.Bind(wx.EVT_TEXT, self.OnDecimate) # LINE 3 @@ -630,9 +630,7 @@ class QualityAdjustment(wx.Panel): text_smooth = wx.StaticText(self, -1, _("Smooth iterations:")) - spin_smooth = wx.SpinCtrl(self, -1, "", (30, 50)) - spin_smooth.SetRange(1,100) - spin_smooth.SetValue(0) + spin_smooth = InvSpinCtrl(self, -1, value=0, min_value=1, max_values=100, size=(30, 50)) # MIXED LINE 2 AND 3 flag_link = wx.EXPAND|wx.GROW|wx.RIGHT|wx.LEFT diff --git a/invesalius/gui/widgets/canvas_renderer.py b/invesalius/gui/widgets/canvas_renderer.py index b8efde7..7688082 100644 --- a/invesalius/gui/widgets/canvas_renderer.py +++ b/invesalius/gui/widgets/canvas_renderer.py @@ -140,7 +140,7 @@ class CanvasRendererCTX: self.rgb = np.zeros((h, w, 3), dtype=np.uint8) self.alpha = np.zeros((h, w, 1), dtype=np.uint8) - self.bitmap = wx.EmptyBitmapRGBA(w, h) + self.bitmap = wx.Bitmap.FromRGBA(w, h) try: self.image = wx.Image(w, h, self.rgb, self.alpha) except TypeError: @@ -155,7 +155,7 @@ class CanvasRendererCTX: self.rgb = np.zeros((h, w, 3), dtype=np.uint8) self.alpha = np.zeros((h, w, 1), dtype=np.uint8) - self.bitmap = wx.EmptyBitmapRGBA(w, h) + self.bitmap = wx.Bitmap.FromRGBA(w, h) try: self.image = wx.Image(w, h, self.rgb, self.alpha) except TypeError: @@ -379,7 +379,7 @@ class CanvasRendererCTX: if size is None: size = self.canvas_renderer.GetSize() w, h = size - image = wx.EmptyImage(w, h) + image = wx.Image(w, h) image.Clear() arr = np.zeros((h, w, 4), dtype=np.uint8) diff --git a/invesalius/gui/widgets/clut_raycasting.py b/invesalius/gui/widgets/clut_raycasting.py index ce6d97a..56134dd 100644 --- a/invesalius/gui/widgets/clut_raycasting.py +++ b/invesalius/gui/widgets/clut_raycasting.py @@ -383,7 +383,7 @@ class CLUTRaycastingWidget(wx.Panel): self.to_render = True i,j = self.point_dragged - width, height= self.GetVirtualSizeTuple() + width, height= self.GetVirtualSize() if y >= height - self.padding: y = height - self.padding @@ -525,7 +525,7 @@ class CLUTRaycastingWidget(wx.Panel): x,y = node.x, node.y value = node.graylevel alpha = node.opacity - widget_width, widget_height = self.GetVirtualSizeTuple() + widget_width, widget_height = self.GetVirtualSize() font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetWeight(wx.BOLD) @@ -600,7 +600,7 @@ class CLUTRaycastingWidget(wx.Panel): def Render(self, dc): ctx = wx.GraphicsContext.Create(dc) - width, height= self.GetVirtualSizeTuple() + width, height= self.GetVirtualSize() height -= (self.padding * 2) width -= self.padding @@ -614,7 +614,7 @@ class CLUTRaycastingWidget(wx.Panel): self._draw_selected_point_text(ctx) def _build_histogram(self): - width, height = self.GetVirtualSizeTuple() + width, height = self.GetVirtualSize() width -= self.padding height -= (self.padding * 2) x_init = self.Histogram.init @@ -638,7 +638,7 @@ class CLUTRaycastingWidget(wx.Panel): width = img.GetWidth() height = img.GetHeight() self.save_button = Button() - self.save_button.image = wx.BitmapFromImage(img) + self.save_button.image = wx.Bitmap(img) self.save_button.size = (width, height) def __sort_pixel_points(self): @@ -684,7 +684,7 @@ class CLUTRaycastingWidget(wx.Panel): """ Given a Hounsfield point returns a pixel point in the canvas. """ - width,height = self.GetVirtualSizeTuple() + width,height = self.GetVirtualSize() width -= (TOOLBAR_SIZE) proportion = width * 1.0 / (self.end - self.init) x = (graylevel - self.init) * proportion + TOOLBAR_SIZE @@ -694,7 +694,7 @@ class CLUTRaycastingWidget(wx.Panel): """ Given a Opacity point returns a pixel point in the canvas. """ - width,height = self.GetVirtualSizeTuple() + width,height = self.GetVirtualSize() height -= (self.padding * 2) y = height - (opacity * height) + self.padding return y @@ -703,7 +703,7 @@ class CLUTRaycastingWidget(wx.Panel): """ Translate from pixel point to Hounsfield scale. """ - width, height= self.GetVirtualSizeTuple() + width, height= self.GetVirtualSize() width -= (TOOLBAR_SIZE) proportion = width * 1.0 / (self.end - self.init) graylevel = (x - TOOLBAR_SIZE) / proportion - abs(self.init) @@ -713,7 +713,7 @@ class CLUTRaycastingWidget(wx.Panel): """ Translate from pixel point to opacity. """ - width, height= self.GetVirtualSizeTuple() + width, height= self.GetVirtualSize() height -= (self.padding * 2) opacity = (height - y + self.padding) * 1.0 / height return opacity diff --git a/invesalius/gui/widgets/gradient.py b/invesalius/gui/widgets/gradient.py index 29d7551..e51ced8 100644 --- a/invesalius/gui/widgets/gradient.py +++ b/invesalius/gui/widgets/gradient.py @@ -1,12 +1,12 @@ # -*- coding: UTF-8 -*- -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- # Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas # Copyright: (C) 2001 Centro de Pesquisas Renato Archer # Homepage: http://www.softwarepublico.gov.br # Contact: invesalius@cti.gov.br # License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- # Este programa e software livre; voce pode redistribui-lo e/ou # modifica-lo sob os termos da Licenca Publica Geral GNU, conforme # publicada pela Free Software Foundation; de acordo com a versao 2 @@ -17,14 +17,15 @@ # COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais # detalhes. -#-------------------------------------------------------------------------- +# -------------------------------------------------------------------------- import sys import numpy import wx - from wx.lib import intctrl +from invesalius.gui.widgets.inv_spinctrl import InvSpinCtrl + PUSH_WIDTH = 7 myEVT_SLIDER_CHANGED = wx.NewEventType() @@ -39,14 +40,16 @@ EVT_THRESHOLD_CHANGED = wx.PyEventBinder(myEVT_THRESHOLD_CHANGED, 1) myEVT_THRESHOLD_CHANGING = wx.NewEventType() EVT_THRESHOLD_CHANGING = wx.PyEventBinder(myEVT_THRESHOLD_CHANGING, 1) + class SliderEvent(wx.PyCommandEvent): - def __init__(self , evtType, id, minRange, maxRange, minValue, maxValue): - wx.PyCommandEvent.__init__(self, evtType, id,) + def __init__(self, evtType, id, minRange, maxRange, minValue, maxValue): + wx.PyCommandEvent.__init__(self, evtType, id) self.min_range = minRange self.max_range = maxRange self.minimun = minValue self.maximun = maxValue + class GradientSlider(wx.Panel): # This widget is formed by a gradient background (black-white), two push # buttons change the min and max values respectively and a slider which you can drag to @@ -57,7 +60,7 @@ class GradientSlider(wx.Panel): # minValue: the least value in the range # maxValue: the most value in the range # colour: colour used in this widget. - super(GradientSlider, self).__init__(parent, id, size = (100, 25)) + super(GradientSlider, self).__init__(parent, id) self._bind_events_wx() self.min_range = minRange @@ -75,24 +78,50 @@ class GradientSlider(wx.Panel): self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackGround) - if sys.platform == 'win32': + if sys.platform == "win32": self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) self.Bind(wx.EVT_MOTION, self.OnMotion) self.Bind(wx.EVT_SIZE, self.OnSize) def OnLeaveWindow(self, evt): + if self.selected == 0: + return + + x = evt.GetX() + w, h = self.GetSize() + + if self.selected == 1: + if x - PUSH_WIDTH < 0: + x = PUSH_WIDTH + elif x >= self.max_position: + x = self.max_position + value = self._min_position_to_minimun(x) + self.minimun = value + self.min_position = x + + # The user is moving the second push (Max) + elif self.selected == 2: + if x + PUSH_WIDTH > w: + x = w - PUSH_WIDTH + elif x < self.min_position: + x = self.min_position + + value = self._max_position_to_maximun(x) + self.maximun = value + self.max_position = x + self.selected = 0 + self._generate_event(myEVT_SLIDER_CHANGED) evt.Skip() - def OnPaint(self, evt): # Where the magic happens. Here the controls are drawn. dc = wx.BufferedPaintDC(self) dc.Clear() - + w, h = self.GetSize() - width_gradient = w - 2*PUSH_WIDTH + width_gradient = w - 2 * PUSH_WIDTH height_gradient = h x_init_gradient = PUSH_WIDTH y_init_gradient = 0 @@ -117,9 +146,11 @@ class GradientSlider(wx.Panel): dc.DrawRectangle(x_init_gradient + width_gradient, 0, PUSH_WIDTH, h) # Drawing the gradient. - dc.GradientFillLinear((x_init_gradient, y_init_gradient, - width_gradient, height_gradient), - (0, 0, 0), (255,255, 255)) + dc.GradientFillLinear( + (x_init_gradient, y_init_gradient, width_gradient, height_gradient), + (0, 0, 0), + (255, 255, 255), + ) try: n = wx.RendererNative.Get() @@ -131,9 +162,9 @@ class GradientSlider(wx.Panel): n.DrawPushButton(self, dc, (x_init_push2, 0, PUSH_WIDTH, h)) # Drawing the transparent slider. - bytes = numpy.array(self.colour * width_transparency * h, 'B') + bytes = numpy.array(self.colour * width_transparency * h, "B") try: - slider = wx.BitmapFromBufferRGBA(width_transparency, h, bytes) + slider = wx.Bitmap.FromBufferRGBA(width_transparency, h, bytes) except: pass else: @@ -151,7 +182,7 @@ class GradientSlider(wx.Panel): if not self.selected: # The user is over a push button, change the cursor. if self._is_over_what(x) in (1, 2): - self.SetCursor(wx.StockCursor(wx.CURSOR_SIZEWE)) + self.SetCursor(wx.Cursor(wx.CURSOR_SIZEWE)) else: self.SetCursor(wx.NullCursor) @@ -168,7 +199,7 @@ class GradientSlider(wx.Panel): self.min_position = x self._generate_event(myEVT_SLIDER_CHANGING) self.Refresh() - + # The user is moving the second push (Max) elif self.selected == 2: x -= self._delta @@ -188,13 +219,13 @@ class GradientSlider(wx.Panel): x -= self._delta slider_size = self.max_position - self.min_position diff_values = self.maximun - self.minimun - + if x - PUSH_WIDTH < 0: min_x = PUSH_WIDTH self.minimun = self._min_position_to_minimun(min_x) self.maximun = self.minimun + diff_values self.CalculateControlPositions() - + elif x + slider_size + PUSH_WIDTH > w: max_x = w - PUSH_WIDTH self.maximun = self._max_position_to_maximun(max_x) @@ -211,7 +242,6 @@ class GradientSlider(wx.Panel): self.Refresh() evt.Skip() - def OnClick(self, evt): x = evt.GetX() self.selected = self._is_over_what(x) @@ -240,34 +270,34 @@ class GradientSlider(wx.Panel): widget. """ w, h = self.GetSize() - window_width = w - 2*PUSH_WIDTH + window_width = w - 2 * PUSH_WIDTH proportion = window_width / float(self.max_range - self.min_range) - self.min_position = int(round((self.minimun - self.min_range) * \ - proportion)) + PUSH_WIDTH - self.max_position = int(round((self.maximun - self.min_range) * \ - proportion)) + PUSH_WIDTH + self.min_position = ( + int(round((self.minimun - self.min_range) * proportion)) + PUSH_WIDTH + ) + self.max_position = ( + int(round((self.maximun - self.min_range) * proportion)) + PUSH_WIDTH + ) def _max_position_to_maximun(self, max_position): - """ + """ Calculates the min and max value based on the control positions. """ w, h = self.GetSize() - window_width = w - 2*PUSH_WIDTH + window_width = w - 2 * PUSH_WIDTH proportion = window_width / float(self.max_range - self.min_range) - maximun = int(round((max_position - PUSH_WIDTH)/proportion + \ - self.min_range)) + maximun = int(round((max_position - PUSH_WIDTH) / proportion + self.min_range)) return maximun def _min_position_to_minimun(self, min_position): w, h = self.GetSize() - window_width = w - 2*PUSH_WIDTH + window_width = w - 2 * PUSH_WIDTH proportion = window_width / float(self.max_range - self.min_range) - minimun = int(round((min_position - PUSH_WIDTH)/proportion + \ - self.min_range)) + minimun = int(round((min_position - PUSH_WIDTH) / proportion + self.min_range)) return minimun @@ -313,18 +343,20 @@ class GradientSlider(wx.Panel): return self.minimun def _generate_event(self, event): - evt = SliderEvent(event, self.GetId(), self.min_range, - self.max_range, self.minimun, self.maximun) + evt = SliderEvent( + event, + self.GetId(), + self.min_range, + self.max_range, + self.minimun, + self.maximun, + ) self.GetEventHandler().ProcessEvent(evt) class GradientCtrl(wx.Panel): def __init__(self, parent, id, minRange, maxRange, minValue, maxValue, colour): super(GradientCtrl, self).__init__(parent, id) - self.sizer = wx.BoxSizer(wx.HORIZONTAL) - self.SetSizer(self.sizer) - self.sizer.Fit(self) - self.SetAutoLayout(1) self.min_range = minRange self.max_range = maxRange self.minimun = minValue @@ -336,43 +368,56 @@ class GradientCtrl(wx.Panel): self.Show() def _draw_controls(self): - self.gradient_slider = GradientSlider(self, -1, self.min_range, - self.max_range, self.minimun, - self.maximun, self.colour) - - self.spin_min = intctrl.IntCtrl(self, size=(40,20), - style=wx.TE_PROCESS_ENTER) - self.spin_min.SetValue(self.minimun) - if sys.platform != 'win32': + self.gradient_slider = GradientSlider( + self, + -1, + self.min_range, + self.max_range, + self.minimun, + self.maximun, + self.colour, + ) + + self.spin_min = InvSpinCtrl( + self, + value=self.minimun, + min_value=self.min_range, + max_value=self.max_range, + spin_button=False, + ) + if sys.platform != "win32": self.spin_min.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) - self.spin_max = intctrl.IntCtrl(self, size=(40,20), - style=wx.TE_PROCESS_ENTER) - self.spin_max.SetValue(self.maximun) - if sys.platform != 'win32': + self.spin_max = InvSpinCtrl( + self, + value=self.maximun, + min_value=self.min_range, + max_value=self.max_range, + spin_button=False, + ) + if sys.platform != "win32": self.spin_max.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) + self.spin_min.CalcSizeFromTextSize() + self.spin_max.CalcSizeFromTextSize() + sizer = wx.BoxSizer(wx.HORIZONTAL) - sizer.Add(self.spin_min, 0, wx.EXPAND | wx.RIGHT, 2) + sizer.Add(self.spin_min, 0, wx.RIGHT, 2) sizer.Add(self.gradient_slider, 1, wx.EXPAND) - sizer.Add(self.spin_max, 0, wx.EXPAND | wx.LEFT, 2) + sizer.Add(self.spin_max, 0, wx.LEFT, 2) + + self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.sizer.Add(sizer, 1, wx.EXPAND) + self.SetSizer(self.sizer) + self.sizer.Fit(self) + # self.SetAutoLayout(1) def _bind_events_wx(self): self.gradient_slider.Bind(EVT_SLIDER_CHANGING, self.OnSliding) self.gradient_slider.Bind(EVT_SLIDER_CHANGED, self.OnSlider) - # self.spin_min.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMinValue) - self.spin_min.Bind(wx.EVT_LEAVE_WINDOW, self._FireSpinMinChange) - self.spin_min.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMinChange) - #self.spin_min.Bind(wx.EVT_KEY_DOWN, self._FireSpinMinChange) - self.spin_min.Bind(wx.EVT_MOUSEWHEEL, self.OnMinMouseWheel) - - # self.spin_max.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMaxValue) - self.spin_max.Bind(wx.EVT_LEAVE_WINDOW, self._FireSpinMaxChange) - self.spin_max.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMaxChange) - #self.spin_max.Bind(wx.EVT_KEY_DOWN, self._FireSpinMaxChange) - self.spin_max.Bind(wx.EVT_MOUSEWHEEL, self.OnMaxMouseWheel) + self.spin_min.Bind(wx.EVT_SPINCTRL, self.OnMinMouseWheel) + self.spin_max.Bind(wx.EVT_SPINCTRL, self.OnMaxMouseWheel) def OnSlider(self, evt): self.spin_min.SetValue(evt.minimun) @@ -419,23 +464,23 @@ class GradientCtrl(wx.Panel): self._GenerateEvent(myEVT_THRESHOLD_CHANGED) def OnMinMouseWheel(self, e): - """ + """ When the user wheel the mouse over min texbox """ - v = self.GetMinValue() + e.GetWheelRotation()/e.GetWheelDelta() + v = self.spin_min.GetValue() self.SetMinValue(v) self._GenerateEvent(myEVT_THRESHOLD_CHANGING) def OnMaxMouseWheel(self, e): - """ + """ When the user wheel the mouse over max texbox """ - v = self.GetMaxValue() + e.GetWheelRotation()/e.GetWheelDelta() + v = self.spin_max.GetValue() self.SetMaxValue(v) self._GenerateEvent(myEVT_THRESHOLD_CHANGING) def SetColour(self, colour): - colour = list(colour[:3]) + [90,] + colour = list(colour[:3]) + [90] self.colour = colour self.gradient_slider.SetColour(colour) self.gradient_slider.Refresh() @@ -443,24 +488,40 @@ class GradientCtrl(wx.Panel): def SetMaxRange(self, value): self.spin_min.SetMax(value) self.spin_max.SetMax(value) + self.spin_min.CalcSizeFromTextSize() + self.spin_max.CalcSizeFromTextSize() self.gradient_slider.SetMaxRange(value) self.max_range = value if value > self.max_range: value = self.max_range + self.spin_min.CalcSizeFromTextSize() + self.spin_max.CalcSizeFromTextSize() + self.Layout() + def SetMinRange(self, value): self.spin_min.SetMin(value) self.spin_max.SetMin(value) + self.spin_min.CalcSizeFromTextSize() + self.spin_max.CalcSizeFromTextSize() self.gradient_slider.SetMinRange(value) self.min_range = value if value < self.min_range: value = self.min_range + self.spin_min.CalcSizeFromTextSize() + self.spin_max.CalcSizeFromTextSize() + self.Layout() + def SetMaxValue(self, value): if value is not None: value = int(value) if value > self.max_range: value = int(self.max_range) + if value < self.min_range: + value = int(self.min_range) + if value < self.minimun: + value = int(self.minimun) self.spin_max.SetValue(value) self.gradient_slider.SetMaximun(value) self.maximun = value @@ -470,6 +531,10 @@ class GradientCtrl(wx.Panel): value = int(value) if value < self.min_range: value = int(self.min_range) + if value > self.max_range: + value = int(self.max_range) + if value > self.maximun: + value = int(self.maximun) self.spin_min.SetValue(value) self.gradient_slider.SetMinimun(value) self.minimun = value @@ -497,9 +562,15 @@ class GradientCtrl(wx.Panel): def _GenerateEvent(self, event): if event == myEVT_THRESHOLD_CHANGING: self.changed = True - elif event == myEVT_THRESHOLD_CHANGED : + elif event == myEVT_THRESHOLD_CHANGED: self.changed = False - evt = SliderEvent(event, self.GetId(), self.min_range, - self.max_range, self.minimun, self.maximun) + evt = SliderEvent( + event, + self.GetId(), + self.min_range, + self.max_range, + self.minimun, + self.maximun, + ) self.GetEventHandler().ProcessEvent(evt) diff --git a/invesalius/gui/widgets/inv_spinctrl.py b/invesalius/gui/widgets/inv_spinctrl.py new file mode 100644 index 0000000..e594389 --- /dev/null +++ b/invesalius/gui/widgets/inv_spinctrl.py @@ -0,0 +1,331 @@ +# -------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +# -------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +# -------------------------------------------------------------------------- +import decimal + +import wx + + +class InvSpinCtrl(wx.Panel): + def __init__( + self, + parent, + id=wx.ID_ANY, + value=0, + min_value=1, + max_value=100, + increment=1, + spin_button=True, + size=wx.DefaultSize, + style=wx.TE_RIGHT, + ): + super().__init__(parent, id, size=size) + + self._textctrl = wx.TextCtrl(self, -1, style=style) + if spin_button and wx.Platform != "__WXGTK__": + self._spinbtn = wx.SpinButton(self, -1) + else: + self._spinbtn = None + + self._value = 0 + self._last_value = 0 + self._min_value = 0 + self._max_value = 100 + self._increment = 1 + + self.SetMin(min_value) + self.SetMax(max_value) + self.SetValue(value) + self.SetIncrement(increment) + + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self._textctrl, 1, wx.EXPAND) + if self._spinbtn: + sizer.Add(self._spinbtn, 0, wx.EXPAND) + + self.SetSizer(sizer) + sizer.Fit(self) + + self.__bind_events() + + def __bind_events(self): + self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) + self._textctrl.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) + if self._spinbtn: + self._spinbtn.Bind(wx.EVT_SPIN_UP, self.OnSpinUp) + self._spinbtn.Bind(wx.EVT_SPIN_DOWN, self.OnSpinDown) + + def SetIncrement(self, increment): + self._increment = increment + + def SetMin(self, min_value): + self._min_value = min_value + self.SetValue(self._value) + + def SetMax(self, max_value): + self._max_value = max_value + self.SetValue(self._value) + + def SetRange(self, min_value, max_value): + self.SetMin(min_value) + self.SetMax(max_value) + + def GetValue(self): + return self._value + + def SetValue(self, value): + try: + value = int(value) + except ValueError: + value = self._last_value + + if value < self._min_value: + value = self._min_value + + if value > self._max_value: + value = self._max_value + + self._value = value + self._textctrl.SetValue("{}".format(self._value)) + self._last_value = self._value + + def CalcSizeFromTextSize(self, text=None): + # To calculate best width to spinctrl + if text is None: + text = "{}".format( + max(len(str(self._max_value)), len(str(self._min_value))) * "M" + ) + + dc = wx.WindowDC(self) + dc.SetFont(self.GetFont()) + width, height = dc.GetTextExtent(text) + + if self._spinbtn: + spin = wx.SpinCtrl(self, -1) + spin_width, spin_height = spin.GetBestSize() + spin.Destroy() + + spinb = wx.SpinButton(self, -1) + spinb_width, spinb_height = spinb.GetBestSize() + spinb.Destroy() + + width += spinb_width + if wx.Platform == "__WXMAC": + height = max(height, spin_height, spinb_height) + else: + height = spin_height + else: + height = -1 + + self.SetMinSize((width, height)) + self.Layout() + + def OnMouseWheel(self, evt): + r = evt.GetWheelRotation() + if r > 0: + self.SetValue(self.GetValue() + self._increment) + else: + self.SetValue(self.GetValue() - self._increment) + self.raise_event() + evt.Skip() + + def OnKillFocus(self, evt): + value = self._textctrl.GetValue() + self.SetValue(value) + self.raise_event() + evt.Skip() + + def OnSpinDown(self, evt): + self.SetValue(self.GetValue() - self._increment) + self.raise_event() + evt.Skip() + + def OnSpinUp(self, evt): + self.SetValue(self.GetValue() + self._increment) + self.raise_event() + evt.Skip() + + def raise_event(self): + event = wx.PyCommandEvent(wx.EVT_SPINCTRL.typeId, self.GetId()) + self.GetEventHandler().ProcessEvent(event) + + +class InvFloatSpinCtrl(wx.Panel): + def __init__( + self, + parent, + id=wx.ID_ANY, + value=0.0, + min_value=1.0, + max_value=100.0, + increment=0.1, + digits=1, + spin_button=True, + size=wx.DefaultSize, + style=wx.TE_RIGHT, + ): + super().__init__(parent, id, size=size) + + self._textctrl = wx.TextCtrl(self, -1, style=style) + if spin_button and wx.Platform != "__WXGTK__": + self._spinbtn = wx.SpinButton(self, -1) + else: + self._spinbtn = None + + self._digits = digits + self._dec_context = decimal.Context(prec=digits) + + self._value = decimal.Decimal("0", self._dec_context) + self._last_value = self._value + self._min_value = decimal.Decimal("0", self._dec_context) + self._max_value = decimal.Decimal("100", self._dec_context) + self._increment = decimal.Decimal("0.1", self._dec_context) + + self.SetIncrement(increment) + self.SetMin(min_value) + self.SetMax(max_value) + self.SetValue(value) + + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self._textctrl, 1, wx.EXPAND) + if self._spinbtn: + sizer.Add(self._spinbtn, 0, wx.EXPAND) + + self.SetSizer(sizer) + sizer.Fit(self) + + self.__bind_events() + + def __bind_events(self): + self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) + self._textctrl.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) + if self._spinbtn: + self._spinbtn.Bind(wx.EVT_SPIN_UP, self.OnSpinUp) + self._spinbtn.Bind(wx.EVT_SPIN_DOWN, self.OnSpinDown) + + def _to_decimal(self, value): + if not isinstance(value, str): + value = "{:.{digits}f}".format(value, digits=self._digits) + return decimal.Decimal(value, self._dec_context) + + def SetDigits(self, digits): + self._digits = digits + self._dec_context = decimal.Context(prec=digits) + + self.SetIncrement(self._increment) + self.SetMin(self._min_value) + self.SetMax(self._max_value) + self.SetValue(self._value) + + def SetIncrement(self, increment): + self._increment = self._to_decimal(increment) + + def SetMin(self, min_value): + self._min_value = self._to_decimal(min_value) + self.SetValue(self._value) + + def SetMax(self, max_value): + self._max_value = self._to_decimal(max_value) + self.SetValue(self._value) + + def SetRange(self, min_value, max_value): + self.SetMin(min_value) + self.SetMax(max_value) + + def GetValue(self): + return float(self._value) + + def SetValue(self, value): + try: + value = self._to_decimal(value) + except decimal.InvalidOperation: + value = self._last_value + + if value < self._min_value: + value = self._min_value + + if value > self._max_value: + value = self._max_value + + self._value = value + self._textctrl.SetValue("{}".format(self._value)) + self._last_value = self._value + + def CalcSizeFromTextSize(self, text=None): + # To calculate best width to spinctrl + if text is None: + text = "{}".format( + max(len(str(self._max_value)), len(str(self._min_value))) * "M" + ) + + dc = wx.WindowDC(self) + dc.SetFont(self.GetFont()) + width, height = dc.GetTextExtent(text) + + spin = wx.SpinCtrl(self, -1) + spin_width, spin_height = spin.GetBestSize() + spin.Destroy() + + if self._spinbtn: + spin = wx.SpinCtrl(self, -1) + spin_width, spin_height = spin.GetBestSize() + spin.Destroy() + + spinb = wx.SpinButton(self, -1) + spinb_width, spinb_height = spinb.GetBestSize() + spinb.Destroy() + + width += spinb_width + if wx.Platform == "__WXMAC": + height = max(height, spin_height, spinb_height) + else: + height = spin_height + else: + height = -1 + + self.SetMinSize((width, height)) + self.Layout() + + def OnMouseWheel(self, evt): + r = evt.GetWheelRotation() + if r > 0: + self.SetValue(self._value + self._increment) + else: + self.SetValue(self._value - self._increment) + self.raise_event() + evt.Skip() + + def OnKillFocus(self, evt): + value = self._textctrl.GetValue() + self.SetValue(value) + self.raise_event() + evt.Skip() + + def OnSpinDown(self, evt): + self.SetValue(self._value - self._increment) + self.raise_event() + evt.Skip() + + def OnSpinUp(self, evt): + self.SetValue(self._value + self._increment) + self.raise_event() + evt.Skip() + + def raise_event(self): + event = wx.PyCommandEvent(wx.EVT_SPINCTRL.typeId, self.GetId()) + self.GetEventHandler().ProcessEvent(event) diff --git a/invesalius/gui/widgets/listctrl.py b/invesalius/gui/widgets/listctrl.py index 0960ae2..d072999 100644 --- a/invesalius/gui/widgets/listctrl.py +++ b/invesalius/gui/widgets/listctrl.py @@ -739,7 +739,7 @@ class TextEditMixin: # data source self.SetVirtualData(self.curRow, self.curCol, text) else: - self.SetStringItem(self.curRow, self.curCol, text) + self.SetItem(self.curRow, self.curCol, text) self.RefreshItem(self.curRow) def _SelectIndex(self, row): diff --git a/invesalius/gui/widgets/slice_menu.py b/invesalius/gui/widgets/slice_menu.py index 737be02..78c88ff 100644 --- a/invesalius/gui/widgets/slice_menu.py +++ b/invesalius/gui/widgets/slice_menu.py @@ -57,14 +57,14 @@ class SliceMenu(wx.Menu): new_id = self.id_wl_first = wx.NewId() wl_item = wx.MenuItem(submenu_wl, new_id,\ _('Default'), kind=wx.ITEM_RADIO) - submenu_wl.AppendItem(wl_item) + submenu_wl.Append(wl_item) self.ID_TO_TOOL_ITEM[new_id] = wl_item #Case the user change window and level new_id = self.other_wl_id = wx.NewId() wl_item = wx.MenuItem(submenu_wl, new_id,\ _('Manual'), kind=wx.ITEM_RADIO) - submenu_wl.AppendItem(wl_item) + submenu_wl.Append(wl_item) self.ID_TO_TOOL_ITEM[new_id] = wl_item for name in sorted(const.WINDOW_LEVEL): @@ -72,7 +72,7 @@ class SliceMenu(wx.Menu): new_id = wx.NewId() wl_item = wx.MenuItem(submenu_wl, new_id,\ name, kind=wx.ITEM_RADIO) - submenu_wl.AppendItem(wl_item) + submenu_wl.Append(wl_item) self.ID_TO_TOOL_ITEM[new_id] = wl_item #----------- Sub menu of the save and load options --------- @@ -84,7 +84,7 @@ class SliceMenu(wx.Menu): # new_id = wx.NewId() # wl_item = wx.MenuItem(submenu_wl, new_id,\ # name) - # submenu_wl.AppendItem(wl_item) + # submenu_wl.Append(wl_item) # self.ID_TO_TOOL_ITEM[new_id] = wl_item @@ -100,7 +100,7 @@ class SliceMenu(wx.Menu): new_id = self.id_pseudo_first = wx.NewId() color_item = wx.MenuItem(submenu_pseudo_colours, new_id,\ _("Default "), kind=mkind) - submenu_pseudo_colours.AppendItem(color_item) + submenu_pseudo_colours.Append(color_item) color_item.Check(1) self.ID_TO_TOOL_ITEM[new_id] = color_item self.pseudo_color_items[new_id] = color_item @@ -110,7 +110,7 @@ class SliceMenu(wx.Menu): new_id = wx.NewId() color_item = wx.MenuItem(submenu_wl, new_id,\ name, kind=mkind) - submenu_pseudo_colours.AppendItem(color_item) + submenu_pseudo_colours.Append(color_item) self.ID_TO_TOOL_ITEM[new_id] = color_item self.pseudo_color_items[new_id] = color_item @@ -119,14 +119,14 @@ class SliceMenu(wx.Menu): new_id = wx.NewId() color_item = wx.MenuItem(submenu_wl, new_id, name, kind=mkind) - submenu_pseudo_colours.AppendItem(color_item) + submenu_pseudo_colours.Append(color_item) self.ID_TO_TOOL_ITEM[new_id] = color_item self.pseudo_color_items[new_id] = color_item new_id = wx.NewId() color_item = wx.MenuItem(submenu_wl, new_id, _('Custom'), kind=mkind) - submenu_pseudo_colours.AppendItem(color_item) + submenu_pseudo_colours.Append(color_item) self.ID_TO_TOOL_ITEM[new_id] = color_item self.pseudo_color_items[new_id] = color_item @@ -137,7 +137,7 @@ class SliceMenu(wx.Menu): new_id = wx.NewId() projection_item = wx.MenuItem(submenu_projection, new_id, name, kind=wx.ITEM_RADIO) - submenu_projection.AppendItem(projection_item) + submenu_projection.Append(projection_item) self.ID_TO_TOOL_ITEM[new_id] = projection_item self.projection_items[PROJECTIONS_ID[name]] = projection_item @@ -148,7 +148,7 @@ class SliceMenu(wx.Menu): new_id = wx.NewId() image_tiling_item = wx.MenuItem(submenu_image_tiling, new_id,\ name, kind=wx.ITEM_RADIO) - submenu_image_tiling.AppendItem(image_tiling_item) + submenu_image_tiling.Append(image_tiling_item) self.ID_TO_TOOL_ITEM[new_id] = image_tiling_item #Save first id item @@ -157,10 +157,10 @@ class SliceMenu(wx.Menu): flag_tiling = True # Add sub itens in the menu - self.AppendMenu(-1, _("Window width and level"), submenu_wl) - self.AppendMenu(-1, _("Pseudo color"), submenu_pseudo_colours) - self.AppendMenu(-1, _("Projection type"), submenu_projection) - ###self.AppendMenu(-1, _("Image Tiling"), submenu_image_tiling) + self.Append(-1, _("Window width and level"), submenu_wl) + self.Append(-1, _("Pseudo color"), submenu_pseudo_colours) + self.Append(-1, _("Projection type"), submenu_projection) + ###self.Append(-1, _("Image Tiling"), submenu_image_tiling) # It doesn't work in Linux self.Bind(wx.EVT_MENU, self.OnPopup) -- libgit2 0.21.2