diff --git a/app.py b/app.py index a76ba5f..a62cf6c 100755 --- a/app.py +++ b/app.py @@ -29,10 +29,11 @@ if sys.platform == 'win32': import _winreg else: if sys.platform != 'darwin': - import wxversion + pass + # import wxversion #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True) #wxversion.select('2.8-unicode', optionsRequired=True) - wxversion.ensureMinimal('3.0') + # wxversion.ensureMinimal('3.0') import wx #from wx.lib.pubsub import setupv1 #new wx @@ -48,6 +49,11 @@ from wx.lib.pubsub import pub as Publisher # if sys.platform != 'darwin': # _SplashScreen = wx.SplashScreen +try: + from wx.adv import SplashScreen as _SplashScreen +except ImportError: + from wx import SplashScreen as _SplashScreen + import invesalius.gui.language_dialog as lang_dlg import invesalius.i18n as i18n @@ -92,7 +98,7 @@ class InVesalius(wx.App): # ------------------------------------------------------------------ -class SplashScreen(wx.SplashScreen): +class SplashScreen(_SplashScreen): """ Splash screen to be shown in InVesalius initialization. """ @@ -175,8 +181,12 @@ class SplashScreen(wx.SplashScreen): bmp = wx.Image(path).ConvertToBitmap() - style = wx.SPLASH_TIMEOUT | wx.SPLASH_CENTRE_ON_SCREEN - wx.SplashScreen.__init__(self, + try: + style = wx.SPLASH_TIMEOUT | wx.SPLASH_CENTRE_ON_SCREEN + except AttributeError: + style = wx.adv.SPLASH_TIMEOUT | wx.adv.SPLASH_CENTRE_ON_SCREEN + + _SplashScreen.__init__(self, bitmap=bmp, splashStyle=style, milliseconds=1500, diff --git a/invesalius/data/viewer_slice.py b/invesalius/data/viewer_slice.py index f92bd30..c71bdff 100755 --- a/invesalius/data/viewer_slice.py +++ b/invesalius/data/viewer_slice.py @@ -26,7 +26,8 @@ import tempfile import numpy as np import vtk -from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor +from invesalius.data.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor +# from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor import invesalius.data.styles as styles import wx @@ -95,10 +96,10 @@ 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.AddSpacer((10, 0)) + sizer.AddSpacer(10) sizer.Add(self.txt_mip_border, 0, wx.EXPAND | wx.ALL, 2) sizer.Add(self.border_spin, 0, wx.EXPAND) - sizer.AddSpacer((10, 0)) + sizer.AddSpacer(10) sizer.Add(self.inverted, 0, wx.EXPAND) self.SetSizer(sizer) sizer.Fit(self) @@ -196,7 +197,7 @@ class CanvasRendererCTX: self.alpha = np.zeros((h, w, 1), dtype=np.uint8) self.bitmap = wx.EmptyBitmapRGBA(w, h) - self.image = wx.ImageFromBuffer(w, h, self.rgb, self.alpha) + self.image = wx.ImageFromBuffer(w, h, self.rgb, self.alpha.data) def _resize_canvas(self, w, h): self._array = np.zeros((h, w, 4), dtype=np.uint8) @@ -208,7 +209,7 @@ class CanvasRendererCTX: self.alpha = np.zeros((h, w, 1), dtype=np.uint8) self.bitmap = wx.EmptyBitmapRGBA(w, h) - self.image = wx.ImageFromBuffer(w, h, self.rgb, self.alpha) + self.image = wx.ImageFromBuffer(w, h, self.rgb, self.alpha.data) self.modified = True @@ -582,7 +583,7 @@ class Viewer(wx.Panel): sizer.Add(scroll, 0, wx.EXPAND|wx.GROW) background_sizer = wx.BoxSizer(wx.VERTICAL) - background_sizer.AddSizer(sizer, 1, wx.EXPAND|wx.GROW|wx.ALL, 2) + background_sizer.Add(sizer, 1, wx.EXPAND|wx.GROW|wx.ALL, 2) #background_sizer.Add(self.mip_ctrls, 0, wx.EXPAND|wx.GROW|wx.ALL, 2) self.SetSizer(background_sizer) background_sizer.Fit(self) diff --git a/invesalius/data/viewer_volume.py b/invesalius/data/viewer_volume.py index dfd3602..5613fa7 100755 --- a/invesalius/data/viewer_volume.py +++ b/invesalius/data/viewer_volume.py @@ -26,7 +26,8 @@ import numpy as np from numpy.core.umath_tests import inner1d import wx import vtk -from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor +# from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor +from invesalius.data.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor from wx.lib.pubsub import pub as Publisher import invesalius.constants as const diff --git a/invesalius/data/wxVTKRenderWindowInteractor.py b/invesalius/data/wxVTKRenderWindowInteractor.py new file mode 100644 index 0000000..3b7c838 --- /dev/null +++ b/invesalius/data/wxVTKRenderWindowInteractor.py @@ -0,0 +1,706 @@ +""" + +A VTK RenderWindowInteractor widget for wxPython. + +Find wxPython info at http://wxPython.org + +Created by Prabhu Ramachandran, April 2002 +Based on wxVTKRenderWindow.py + +Fixes and updates by Charl P. Botha 2003-2008 + +Updated to new wx namespace and some cleaning up by Andrea Gavana, +December 2006 +""" + +""" +Please see the example at the end of this file. + +---------------------------------------- +Creation: + + wxVTKRenderWindowInteractor(parent, ID, stereo=0, [wx keywords]): + + You should create a wx.App(False) or some other wx.App subclass + before creating the window. + +Behaviour: + + Uses __getattr__ to make the wxVTKRenderWindowInteractor behave just + like a vtkGenericRenderWindowInteractor. + +---------------------------------------- + +""" + +# import usual libraries +import math, os, sys +import wx +import vtk + +# a few configuration items, see what works best on your system + +# Use GLCanvas as base class instead of wx.Window. +# This is sometimes necessary under wxGTK or the image is blank. +# (in wxWindows 2.3.1 and earlier, the GLCanvas had scroll bars) +baseClass = wx.Window +if wx.Platform == "__WXGTK__": + import wx.glcanvas + baseClass = wx.glcanvas.GLCanvas + +# Keep capturing mouse after mouse is dragged out of window +# (in wxGTK 2.3.2 there is a bug that keeps this from working, +# but it is only relevant in wxGTK if there are multiple windows) +_useCapture = (wx.Platform == "__WXMSW__") + +# end of configuration items + + +class EventTimer(wx.Timer): + """Simple wx.Timer class. + """ + + def __init__(self, iren): + """Default class constructor. + @param iren: current render window + """ + wx.Timer.__init__(self) + self.iren = iren + + + def Notify(self): + """ The timer has expired. + """ + self.iren.TimerEvent() + + +class wxVTKRenderWindowInteractor(baseClass): + """ + A wxRenderWindow for wxPython. + Use GetRenderWindow() to get the vtkRenderWindow. + Create with the keyword stereo=1 in order to + generate a stereo-capable window. + """ + + # class variable that can also be used to request instances that use + # stereo; this is overridden by the stereo=1/0 parameter. If you set + # it to True, the NEXT instantiated object will attempt to allocate a + # stereo visual. E.g.: + # wxVTKRenderWindowInteractor.USE_STEREO = True + # myRWI = wxVTKRenderWindowInteractor(parent, -1) + USE_STEREO = False + + def __init__(self, parent, ID, *args, **kw): + """Default class constructor. + @param parent: parent window + @param ID: window id + @param **kw: wxPython keywords (position, size, style) plus the + 'stereo' keyword + """ + # private attributes + self.__RenderWhenDisabled = 0 + + # First do special handling of some keywords: + # stereo, position, size, width, height, style + + try: + stereo = bool(kw['stereo']) + del kw['stereo'] + except KeyError: + stereo = False + + try: + position = kw['position'] + del kw['position'] + except KeyError: + position = wx.DefaultPosition + + try: + size = kw['size'] + del kw['size'] + except KeyError: + try: + size = parent.GetSize() + except AttributeError: + size = wx.DefaultSize + + # wx.WANTS_CHARS says to give us e.g. TAB + # wx.NO_FULL_REPAINT_ON_RESIZE cuts down resize flicker under GTK + style = wx.WANTS_CHARS | wx.NO_FULL_REPAINT_ON_RESIZE + + try: + style = style | kw['style'] + del kw['style'] + except KeyError: + pass + + # the enclosing frame must be shown under GTK or the windows + # don't connect together properly + if wx.Platform != '__WXMSW__': + l = [] + p = parent + while p: # make a list of all parents + l.append(p) + p = p.GetParent() + l.reverse() # sort list into descending order + for p in l: + p.Show(1) + + if baseClass.__name__ == 'GLCanvas': + # code added by cpbotha to enable stereo and double + # buffering correctly where the user requests this; remember + # that the glXContext in this case is NOT allocated by VTK, + # but by WX, hence all of this. + + # Initialize GLCanvas with correct attriblist + attribList = [wx.glcanvas.WX_GL_RGBA, + wx.glcanvas.WX_GL_MIN_RED, 1, + wx.glcanvas.WX_GL_MIN_GREEN, 1, + wx.glcanvas.WX_GL_MIN_BLUE, 1, + wx.glcanvas.WX_GL_DEPTH_SIZE, 16, + wx.glcanvas.WX_GL_DOUBLEBUFFER] + if stereo: + attribList.append(wx.glcanvas.WX_GL_STEREO) + + try: + baseClass.__init__(self, parent, ID, pos=position, size=size, + style=style, + attribList=attribList) + except wx.PyAssertionError: + # visual couldn't be allocated, so we go back to default + baseClass.__init__(self, parent, ID, pos=position, size=size, + style=style) + if stereo: + # and make sure everyone knows that the stereo + # visual wasn't set. + stereo = 0 + + else: + baseClass.__init__(self, parent, ID, pos=position, size=size, + style=style) + + # create the RenderWindow and initialize it + self._Iren = vtk.vtkGenericRenderWindowInteractor() + self._Iren.SetRenderWindow( vtk.vtkRenderWindow() ) + self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer) + self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer) + self._Iren.GetRenderWindow().AddObserver('CursorChangedEvent', + self.CursorChangedEvent) + + try: + self._Iren.GetRenderWindow().SetSize(size.width, size.height) + except AttributeError: + self._Iren.GetRenderWindow().SetSize(size[0], size[1]) + + if stereo: + self._Iren.GetRenderWindow().StereoCapableWindowOn() + self._Iren.GetRenderWindow().SetStereoTypeToCrystalEyes() + + self.__handle = None + + self.BindEvents() + + # with this, we can make sure that the reparenting logic in + # Render() isn't called before the first OnPaint() has + # successfully been run (and set up the VTK/WX display links) + self.__has_painted = False + + # set when we have captured the mouse. + self._own_mouse = False + # used to store WHICH mouse button led to mouse capture + self._mouse_capture_button = 0 + + # A mapping for cursor changes. + self._cursor_map = {0: wx.CURSOR_ARROW, # VTK_CURSOR_DEFAULT + 1: wx.CURSOR_ARROW, # VTK_CURSOR_ARROW + 2: wx.CURSOR_SIZENESW, # VTK_CURSOR_SIZENE + 3: wx.CURSOR_SIZENWSE, # VTK_CURSOR_SIZENWSE + 4: wx.CURSOR_SIZENESW, # VTK_CURSOR_SIZESW + 5: wx.CURSOR_SIZENWSE, # VTK_CURSOR_SIZESE + 6: wx.CURSOR_SIZENS, # VTK_CURSOR_SIZENS + 7: wx.CURSOR_SIZEWE, # VTK_CURSOR_SIZEWE + 8: wx.CURSOR_SIZING, # VTK_CURSOR_SIZEALL + 9: wx.CURSOR_HAND, # VTK_CURSOR_HAND + 10: wx.CURSOR_CROSS, # VTK_CURSOR_CROSSHAIR + } + + def BindEvents(self): + """Binds all the necessary events for navigation, sizing, + drawing. + """ + # refresh window by doing a Render + self.Bind(wx.EVT_PAINT, self.OnPaint) + # turn off background erase to reduce flicker + self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) + + # Bind the events to the event converters + self.Bind(wx.EVT_RIGHT_DOWN, self.OnButtonDown) + self.Bind(wx.EVT_LEFT_DOWN, self.OnButtonDown) + self.Bind(wx.EVT_MIDDLE_DOWN, self.OnButtonDown) + self.Bind(wx.EVT_RIGHT_UP, self.OnButtonUp) + self.Bind(wx.EVT_LEFT_UP, self.OnButtonUp) + self.Bind(wx.EVT_MIDDLE_UP, self.OnButtonUp) + self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) + self.Bind(wx.EVT_MOTION, self.OnMotion) + + self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) + self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) + + # If we use EVT_KEY_DOWN instead of EVT_CHAR, capital versions + # of all characters are always returned. EVT_CHAR also performs + # other necessary keyboard-dependent translations. + self.Bind(wx.EVT_CHAR, self.OnKeyDown) + self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) + + self.Bind(wx.EVT_SIZE, self.OnSize) + + # the wx 2.8.7.1 documentation states that you HAVE to handle + # this event if you make use of CaptureMouse, which we do. + if _useCapture and hasattr(wx, 'EVT_MOUSE_CAPTURE_LOST'): + self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, + self.OnMouseCaptureLost) + + + def __getattr__(self, attr): + """Makes the object behave like a + vtkGenericRenderWindowInteractor. + """ + if attr == '__vtk__': + return lambda t=self._Iren: t + elif hasattr(self._Iren, attr): + return getattr(self._Iren, attr) + else: + raise AttributeError(self.__class__.__name__ + + " has no attribute named " + attr) + + def CreateTimer(self, obj, evt): + """ Creates a timer. + """ + self._timer = EventTimer(self) + self._timer.Start(10, True) + + def DestroyTimer(self, obj, evt): + """The timer is a one shot timer so will expire automatically. + """ + return 1 + + def _CursorChangedEvent(self, obj, evt): + """Change the wx cursor if the renderwindow's cursor was + changed. + """ + cur = self._cursor_map[obj.GetCurrentCursor()] + c = wx.StockCursor(cur) + self.SetCursor(c) + + def CursorChangedEvent(self, obj, evt): + """Called when the CursorChangedEvent fires on the render + window.""" + # This indirection is needed since when the event fires, the + # current cursor is not yet set so we defer this by which time + # the current cursor should have been set. + wx.CallAfter(self._CursorChangedEvent, obj, evt) + + def HideCursor(self): + """Hides the cursor.""" + c = wx.StockCursor(wx.CURSOR_BLANK) + self.SetCursor(c) + + def ShowCursor(self): + """Shows the cursor.""" + rw = self._Iren.GetRenderWindow() + cur = self._cursor_map[rw.GetCurrentCursor()] + c = wx.StockCursor(cur) + self.SetCursor(c) + + def GetDisplayId(self): + """Function to get X11 Display ID from WX and return it in a format + that can be used by VTK Python. + + We query the X11 Display with a new call that was added in wxPython + 2.6.0.1. The call returns a SWIG object which we can query for the + address and subsequently turn into an old-style SWIG-mangled string + representation to pass to VTK. + """ + d = None + + try: + d = wx.GetXDisplay() + + except AttributeError: + # wx.GetXDisplay was added by Robin Dunn in wxPython 2.6.0.1 + # if it's not available, we can't pass it. In general, + # things will still work; on some setups, it'll break. + pass + + else: + # wx returns None on platforms where wx.GetXDisplay is not relevant + if d: + d = hex(d) + # On wxPython-2.6.3.2 and above there is no leading '0x'. + if not d.startswith('0x'): + d = '0x' + d + + # VTK wants it as: _xxxxxxxx_p_void (SWIG pointer) + d = '_%s_%s\0' % (d[2:], 'p_void') + + return d + + def OnMouseCaptureLost(self, event): + """This is signalled when we lose mouse capture due to an + external event, such as when a dialog box is shown. See the + wx documentation. + """ + + # the documentation seems to imply that by this time we've + # already lost capture. I have to assume that we don't need + # to call ReleaseMouse ourselves. + if _useCapture and self._own_mouse: + self._own_mouse = False + + def OnPaint(self,event): + """Handles the wx.EVT_PAINT event for + wxVTKRenderWindowInteractor. + """ + + # wx should continue event processing after this handler. + # We call this BEFORE Render(), so that if Render() raises + # an exception, wx doesn't re-call OnPaint repeatedly. + event.Skip() + + dc = wx.PaintDC(self) + + # make sure the RenderWindow is sized correctly + self._Iren.GetRenderWindow().SetSize(self.GetSize()) + + # Tell the RenderWindow to render inside the wx.Window. + if not self.__handle: + + # on relevant platforms, set the X11 Display ID + d = self.GetDisplayId() + if d and self.__has_painted: + self._Iren.GetRenderWindow().SetDisplayId(d) + + # store the handle + self.__handle = self.GetHandle() + # and give it to VTK + self._Iren.GetRenderWindow().SetWindowInfo(str(self.__handle)) + + # now that we've painted once, the Render() reparenting logic + # is safe + self.__has_painted = True + + self.Render() + + def OnSize(self,event): + """Handles the wx.EVT_SIZE event for + wxVTKRenderWindowInteractor. + """ + + # event processing should continue (we call this before the + # Render(), in case it raises an exception) + event.Skip() + + try: + width, height = event.GetSize() + except: + width = event.GetSize().width + height = event.GetSize().height + self._Iren.SetSize(width, height) + self._Iren.ConfigureEvent() + + # this will check for __handle + self.Render() + + def OnMotion(self,event): + """Handles the wx.EVT_MOTION event for + wxVTKRenderWindowInteractor. + """ + + # event processing should continue + # we call this early in case any of the VTK code raises an + # exception. + event.Skip() + + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(), + event.ControlDown(), + event.ShiftDown(), + chr(0), 0, None) + self._Iren.MouseMoveEvent() + + def OnEnter(self,event): + """Handles the wx.EVT_ENTER_WINDOW event for + wxVTKRenderWindowInteractor. + """ + + # event processing should continue + event.Skip() + + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(), + event.ControlDown(), + event.ShiftDown(), + chr(0), 0, None) + self._Iren.EnterEvent() + + + def OnLeave(self,event): + """Handles the wx.EVT_LEAVE_WINDOW event for + wxVTKRenderWindowInteractor. + """ + + # event processing should continue + event.Skip() + + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(), + event.ControlDown(), + event.ShiftDown(), + chr(0), 0, None) + self._Iren.LeaveEvent() + + + def OnButtonDown(self,event): + """Handles the wx.EVT_LEFT/RIGHT/MIDDLE_DOWN events for + wxVTKRenderWindowInteractor. + """ + + # allow wx event processing to continue + # on wxPython 2.6.0.1, omitting this will cause problems with + # the initial focus, resulting in the wxVTKRWI ignoring keypresses + # until we focus elsewhere and then refocus the wxVTKRWI frame + # we do it this early in case any of the following VTK code + # raises an exception. + event.Skip() + + ctrl, shift = event.ControlDown(), event.ShiftDown() + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(), + ctrl, shift, chr(0), 0, None) + + button = 0 + if event.RightDown(): + self._Iren.RightButtonPressEvent() + button = 'Right' + elif event.LeftDown(): + self._Iren.LeftButtonPressEvent() + button = 'Left' + elif event.MiddleDown(): + self._Iren.MiddleButtonPressEvent() + button = 'Middle' + + # save the button and capture mouse until the button is released + # we only capture the mouse if it hasn't already been captured + if _useCapture and not self._own_mouse: + self._own_mouse = True + self._mouse_capture_button = button + self.CaptureMouse() + + + def OnButtonUp(self,event): + """Handles the wx.EVT_LEFT/RIGHT/MIDDLE_UP events for + wxVTKRenderWindowInteractor. + """ + + # event processing should continue + event.Skip() + + button = 0 + if event.RightUp(): + button = 'Right' + elif event.LeftUp(): + button = 'Left' + elif event.MiddleUp(): + button = 'Middle' + + # if the same button is released that captured the mouse, and + # we have the mouse, release it. + # (we need to get rid of this as soon as possible; if we don't + # and one of the event handlers raises an exception, mouse + # is never released.) + if _useCapture and self._own_mouse and \ + button==self._mouse_capture_button: + self.ReleaseMouse() + self._own_mouse = False + + ctrl, shift = event.ControlDown(), event.ShiftDown() + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(), + ctrl, shift, chr(0), 0, None) + + if button == 'Right': + self._Iren.RightButtonReleaseEvent() + elif button == 'Left': + self._Iren.LeftButtonReleaseEvent() + elif button == 'Middle': + self._Iren.MiddleButtonReleaseEvent() + + + def OnMouseWheel(self,event): + """Handles the wx.EVT_MOUSEWHEEL event for + wxVTKRenderWindowInteractor. + """ + + # event processing should continue + event.Skip() + + ctrl, shift = event.ControlDown(), event.ShiftDown() + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(), + ctrl, shift, chr(0), 0, None) + if event.GetWheelRotation() > 0: + self._Iren.MouseWheelForwardEvent() + else: + self._Iren.MouseWheelBackwardEvent() + + + def OnKeyDown(self,event): + """Handles the wx.EVT_KEY_DOWN event for + wxVTKRenderWindowInteractor. + """ + + # event processing should continue + event.Skip() + + ctrl, shift = event.ControlDown(), event.ShiftDown() + keycode, keysym = event.GetKeyCode(), None + key = chr(0) + if keycode < 256: + key = chr(keycode) + + # wxPython 2.6.0.1 does not return a valid event.Get{X,Y}() + # for this event, so we use the cached position. + (x,y)= self._Iren.GetEventPosition() + self._Iren.SetEventInformation(x, y, + ctrl, shift, key, 0, + keysym) + + self._Iren.KeyPressEvent() + self._Iren.CharEvent() + + + def OnKeyUp(self,event): + """Handles the wx.EVT_KEY_UP event for + wxVTKRenderWindowInteractor. + """ + + # event processing should continue + event.Skip() + + ctrl, shift = event.ControlDown(), event.ShiftDown() + keycode, keysym = event.GetKeyCode(), None + key = chr(0) + if keycode < 256: + key = chr(keycode) + + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(), + ctrl, shift, key, 0, + keysym) + self._Iren.KeyReleaseEvent() + + + def GetRenderWindow(self): + """Returns the render window (vtkRenderWindow). + """ + return self._Iren.GetRenderWindow() + + def Render(self): + """Actually renders the VTK scene on screen. + """ + RenderAllowed = 1 + + if not self.__RenderWhenDisabled: + # the user doesn't want us to render when the toplevel frame + # is disabled - first find the top level parent + topParent = wx.GetTopLevelParent(self) + if topParent: + # if it exists, check whether it's enabled + # if it's not enabeld, RenderAllowed will be false + RenderAllowed = topParent.IsEnabled() + + if RenderAllowed: + if self.__handle and self.__handle == self.GetHandle(): + self._Iren.GetRenderWindow().Render() + + elif self.GetHandle() and self.__has_painted: + # this means the user has reparented us; let's adapt to the + # new situation by doing the WindowRemap dance + self._Iren.GetRenderWindow().SetNextWindowInfo( + str(self.GetHandle())) + + # make sure the DisplayId is also set correctly + d = self.GetDisplayId() + if d: + self._Iren.GetRenderWindow().SetDisplayId(d) + + # do the actual remap with the new parent information + self._Iren.GetRenderWindow().WindowRemap() + + # store the new situation + self.__handle = self.GetHandle() + self._Iren.GetRenderWindow().Render() + + def SetRenderWhenDisabled(self, newValue): + """Change value of __RenderWhenDisabled ivar. + + If __RenderWhenDisabled is false (the default), this widget will not + call Render() on the RenderWindow if the top level frame (i.e. the + containing frame) has been disabled. + + This prevents recursive rendering during wx.SafeYield() calls. + wx.SafeYield() can be called during the ProgressMethod() callback of + a VTK object to have progress bars and other GUI elements updated - + it does this by disabling all windows (disallowing user-input to + prevent re-entrancy of code) and then handling all outstanding + GUI events. + + However, this often triggers an OnPaint() method for wxVTKRWIs, + resulting in a Render(), resulting in Update() being called whilst + still in progress. + """ + self.__RenderWhenDisabled = bool(newValue) + + +#-------------------------------------------------------------------- +def wxVTKRenderWindowInteractorConeExample(): + """Like it says, just a simple example + """ + # every wx app needs an app + app = wx.App(False) + + # create the top-level frame, sizer and wxVTKRWI + frame = wx.Frame(None, -1, "wxVTKRenderWindowInteractor", size=(400,400)) + widget = wxVTKRenderWindowInteractor(frame, -1) + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(widget, 1, wx.EXPAND) + frame.SetSizer(sizer) + frame.Layout() + + # It would be more correct (API-wise) to call widget.Initialize() and + # widget.Start() here, but Initialize() calls RenderWindow.Render(). + # That Render() call will get through before we can setup the + # RenderWindow() to render via the wxWidgets-created context; this + # causes flashing on some platforms and downright breaks things on + # other platforms. Instead, we call widget.Enable(). This means + # that the RWI::Initialized ivar is not set, but in THIS SPECIFIC CASE, + # that doesn't matter. + widget.Enable(1) + + widget.AddObserver("ExitEvent", lambda o,e,f=frame: f.Close()) + + ren = vtk.vtkRenderer() + widget.GetRenderWindow().AddRenderer(ren) + + cone = vtk.vtkConeSource() + cone.SetResolution(8) + + coneMapper = vtk.vtkPolyDataMapper() + coneMapper.SetInputConnection(cone.GetOutputPort()) + + coneActor = vtk.vtkActor() + coneActor.SetMapper(coneMapper) + + ren.AddActor(coneActor) + + # show the window + frame.Show() + + app.MainLoop() + +if __name__ == "__main__": + wxVTKRenderWindowInteractorConeExample() + diff --git a/invesalius/gui/data_notebook.py b/invesalius/gui/data_notebook.py index 3e96a24..70941ea 100644 --- a/invesalius/gui/data_notebook.py +++ b/invesalius/gui/data_notebook.py @@ -29,7 +29,10 @@ except ImportError: import wx import wx.grid -import wx.lib.flatnotebook as fnb +try: + from wx.lib.agw import flatnotebook as fnb +except ImportError: + import wx.lib.flatnotebook as fnb import wx.lib.platebtn as pbtn from wx.lib.pubsub import pub as Publisher diff --git a/invesalius/gui/default_tasks.py b/invesalius/gui/default_tasks.py index babb733..3b7e8c1 100644 --- a/invesalius/gui/default_tasks.py +++ b/invesalius/gui/default_tasks.py @@ -18,7 +18,11 @@ #-------------------------------------------------------------------------- import wx -import wx.lib.foldpanelbar as fpb +try: + from wx.lib.agw import foldpanelbar as fpb +except ImportError: + import wx.lib.foldpanelbar as fpb + from wx.lib.pubsub import pub as Publisher import invesalius.constants as const diff --git a/invesalius/gui/dialogs.py b/invesalius/gui/dialogs.py index bc77dce..b21670e 100644 --- a/invesalius/gui/dialogs.py +++ b/invesalius/gui/dialogs.py @@ -24,7 +24,10 @@ import sys import vtk import wx -import wx.combo +try: + from wx.adv import BitmapComboBox +except ImportError: + from wx.combo import BitmapComboBox from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor from wx.lib import masked @@ -1792,7 +1795,7 @@ class MaskBooleanDialog(wx.Dialog): (_(u"Difference"), const.BOOLEAN_DIFF, 'bool_difference.png'), (_(u"Intersection"), const.BOOLEAN_AND, 'bool_intersection.png'), (_(u"Exclusive disjunction"), const.BOOLEAN_XOR, 'bool_disjunction.png')) - self.op_boolean = wx.combo.BitmapComboBox(self, -1, op_choices[0][0], choices=[]) + self.op_boolean = BitmapComboBox(self, -1, op_choices[0][0], choices=[]) for n, i, f in op_choices: bmp = wx.Bitmap(os.path.join(icon_folder, f), wx.BITMAP_TYPE_PNG) diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index 7f3e0b1..626cd95 100644 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -29,6 +29,11 @@ from wx.lib.pubsub import pub as Publisher import wx.lib.agw.toasterbox as TB import wx.lib.popupctl as pc +try: + from wx.adv import TaskBarIcon as _TaskBarIcon +except ImportError: + from wx import TaskBarIcon as _TaskBarIcon + from wx.lib.agw.aui.auibar import AuiToolBar, AUI_TB_PLAIN_BACKGROUND import invesalius.constants as const @@ -176,23 +181,23 @@ class Frame(wx.Frame): Name("Data").Position(1)) # This is the DICOM import panel. When the two panels above as dicom # are shown, this should be hiden - caption = _("Preview medical data to be reconstructed") - aui_manager.AddPane(imp.Panel(self), wx.aui.AuiPaneInfo(). - Name("Import").CloseButton(False).Centre().Hide(). - MaximizeButton(False).Floatable(True). - Caption(caption).CaptionVisible(True)) - - caption = _("Preview bitmap to be reconstructed") - aui_manager.AddPane(imp_bmp.Panel(self), wx.aui.AuiPaneInfo(). - Name("ImportBMP").CloseButton(False).Centre().Hide(). - MaximizeButton(False).Floatable(True). - Caption(caption).CaptionVisible(True)) - - ncaption = _("Retrieve DICOM from PACS") - aui_manager.AddPane(imp_net.Panel(self), wx.aui.AuiPaneInfo(). - Name("Retrieve").Centre().Hide(). - MaximizeButton(True).Floatable(True). - Caption(ncaption).CaptionVisible(True)) + # caption = _("Preview medical data to be reconstructed") + # aui_manager.AddPane(imp.Panel(self), wx.aui.AuiPaneInfo(). + # Name("Import").CloseButton(False).Centre().Hide(). + # MaximizeButton(False).Floatable(True). + # Caption(caption).CaptionVisible(True)) + + # caption = _("Preview bitmap to be reconstructed") + # aui_manager.AddPane(imp_bmp.Panel(self), wx.aui.AuiPaneInfo(). + # Name("ImportBMP").CloseButton(False).Centre().Hide(). + # MaximizeButton(False).Floatable(True). + # Caption(caption).CaptionVisible(True)) + + # ncaption = _("Retrieve DICOM from PACS") + # aui_manager.AddPane(imp_net.Panel(self), wx.aui.AuiPaneInfo(). + # Name("Retrieve").Centre().Hide(). + # MaximizeButton(True).Floatable(True). + # Caption(ncaption).CaptionVisible(True)) # Add toolbars to manager # This is pretty tricky -- order on win32 is inverted when @@ -1078,7 +1083,7 @@ class StatusBar(wx.StatusBar): # ------------------------------------------------------------------ # ------------------------------------------------------------------ -class TaskBarIcon(wx.TaskBarIcon): +class TaskBarIcon(_TaskBarIcon): """ TaskBarIcon has different behaviours according to the platform: - win32: Show icon on "Notification Area" (near clock) @@ -1086,7 +1091,7 @@ class TaskBarIcon(wx.TaskBarIcon): - linux2: Show icon on "Notification Area" (near clock) """ def __init__(self, parent=None): - wx.TaskBarIcon.__init__(self) + _TaskBarIcon.__init__(self) self.frame = parent icon = wx.Icon(os.path.join(const.ICON_DIR, "invesalius.ico"), diff --git a/invesalius/gui/import_bitmap_panel.py b/invesalius/gui/import_bitmap_panel.py index 2a7cd3b..022e2b5 100644 --- a/invesalius/gui/import_bitmap_panel.py +++ b/invesalius/gui/import_bitmap_panel.py @@ -17,7 +17,10 @@ # detalhes. #-------------------------------------------------------------------------- import wx -import wx.gizmos as gizmos +try: + from wx.adv import EditableListBox as EditableListBox +except ImportError: + from wx.gizmos import TreeListCtrl from wx.lib.pubsub import pub as Publisher import wx.lib.splitter as spl @@ -188,15 +191,15 @@ class TextPanel(wx.Panel): self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyPress) def __init_gui(self): - tree = gizmos.TreeListCtrl(self, -1, style = - wx.TR_DEFAULT_STYLE - | wx.TR_HIDE_ROOT - | wx.TR_ROW_LINES - | wx.TR_COLUMN_LINES - | wx.TR_FULL_ROW_HIGHLIGHT - | wx.TR_MULTIPLE - | wx.TR_HIDE_ROOT - ) + tree = TreeListCtrl(self, -1, style = + wx.TR_DEFAULT_STYLE + | wx.TR_HIDE_ROOT + | wx.TR_ROW_LINES + | wx.TR_COLUMN_LINES + | wx.TR_FULL_ROW_HIGHLIGHT + | wx.TR_MULTIPLE + | wx.TR_HIDE_ROOT + ) tree.AddColumn(_("Path")) diff --git a/invesalius/gui/import_network_panel.py b/invesalius/gui/import_network_panel.py index 38086ff..d7011f4 100644 --- a/invesalius/gui/import_network_panel.py +++ b/invesalius/gui/import_network_panel.py @@ -18,7 +18,10 @@ #-------------------------------------------------------------------------- import wx import sys -import wx.gizmos as gizmos +try: + from wx.adv import EditableListBox as EditableListBox +except ImportError: + from wx.gizmos import TreeListCtrl from wx.lib.pubsub import pub as Publisher import wx.lib.splitter as spl @@ -226,15 +229,14 @@ class TextPanel(wx.Panel): self.Bind(wx.EVT_SIZE, self.OnSize) def __init_gui(self): - tree = gizmos.TreeListCtrl(self, -1, style = - wx.TR_DEFAULT_STYLE - | wx.TR_HIDE_ROOT - | wx.TR_ROW_LINES - | wx.TR_COLUMN_LINES - | wx.TR_FULL_ROW_HIGHLIGHT - | wx.TR_SINGLE - ) - + tree = TreeListCtrl(self, -1, style = + wx.TR_DEFAULT_STYLE + | wx.TR_HIDE_ROOT + | wx.TR_ROW_LINES + | wx.TR_COLUMN_LINES + | wx.TR_FULL_ROW_HIGHLIGHT + | wx.TR_SINGLE + ) tree.AddColumn(_("Patient name")) tree.AddColumn(_("Patient ID")) diff --git a/invesalius/gui/import_panel.py b/invesalius/gui/import_panel.py index 2125f1a..25c0632 100644 --- a/invesalius/gui/import_panel.py +++ b/invesalius/gui/import_panel.py @@ -17,7 +17,11 @@ # detalhes. #-------------------------------------------------------------------------- import wx -import wx.gizmos as gizmos + +try: + from wx.dataview import TreeListCtrl +except ImportError: + from wx.gizmos import TreeListCtrl from wx.lib.pubsub import pub as Publisher import wx.lib.splitter as spl @@ -103,7 +107,7 @@ class InnerPanel(wx.Panel): self.combo_interval.SetSelection(0) inner_sizer = wx.BoxSizer(wx.HORIZONTAL) - inner_sizer.AddSizer(btnsizer, 0, wx.LEFT|wx.TOP, 5) + inner_sizer.Add(btnsizer, 0, wx.LEFT|wx.TOP, 5) inner_sizer.Add(self.combo_interval, 0, wx.LEFT|wx.RIGHT|wx.TOP, 5) panel.SetSizer(inner_sizer) inner_sizer.Fit(panel) @@ -211,30 +215,47 @@ class TextPanel(wx.Panel): self.Bind(wx.EVT_SIZE, self.OnSize) def __init_gui(self): - tree = gizmos.TreeListCtrl(self, -1, style = - wx.TR_DEFAULT_STYLE - | wx.TR_HIDE_ROOT - | wx.TR_ROW_LINES - | wx.TR_COLUMN_LINES - | wx.TR_FULL_ROW_HIGHLIGHT - | wx.TR_SINGLE - ) - - - tree.AddColumn(_("Patient name")) - tree.AddColumn(_("Patient ID")) - tree.AddColumn(_("Age")) - tree.AddColumn(_("Gender")) - tree.AddColumn(_("Study description")) - tree.AddColumn(_("Modality")) - tree.AddColumn(_("Date acquired")) - tree.AddColumn(_("# Images")) - tree.AddColumn(_("Institution")) - tree.AddColumn(_("Date of birth")) - tree.AddColumn(_("Accession Number")) - tree.AddColumn(_("Referring physician")) - - tree.SetMainColumn(0) # the one with the tree in it... + tree = TreeListCtrl(self, -1, style = + wx.TR_DEFAULT_STYLE + | wx.TR_HIDE_ROOT + | wx.TR_ROW_LINES + # | wx.TR_COLUMN_LINES + | wx.TR_FULL_ROW_HIGHLIGHT + | wx.TR_SINGLE + ) + + + try: + tree.AppendColumn(_("Patient name")) + tree.AppendColumn(_("Patient ID")) + tree.AppendColumn(_("Age")) + tree.AppendColumn(_("Gender")) + tree.AppendColumn(_("Study description")) + tree.AppendColumn(_("Modality")) + tree.AppendColumn(_("Date acquired")) + tree.AppendColumn(_("# Images")) + tree.AppendColumn(_("Institution")) + tree.AppendColumn(_("Date of birth")) + tree.AppendColumn(_("Accession Number")) + tree.AppendColumn(_("Referring physician")) + except AttributeError: + tree.AddColumn(_("Patient name")) + tree.AddColumn(_("Patient ID")) + tree.AddColumn(_("Age")) + tree.AddColumn(_("Gender")) + tree.AddColumn(_("Study description")) + tree.AddColumn(_("Modality")) + tree.AddColumn(_("Date acquired")) + tree.AddColumn(_("# Images")) + tree.AddColumn(_("Institution")) + tree.AddColumn(_("Date of birth")) + tree.AddColumn(_("Accession Number")) + tree.AddColumn(_("Referring physician")) + + try: + tree.SetMainColumn(0) # the one with the tree in it... + except AttributeError: + pass tree.SetColumnWidth(0, 280) # Patient name tree.SetColumnWidth(1, 110) # Patient ID tree.SetColumnWidth(2, 40) # Age @@ -248,7 +269,7 @@ class TextPanel(wx.Panel): tree.SetColumnWidth(10, 140) # Accession Number tree.SetColumnWidth(11, 160) # Referring physician - self.root = tree.AddRoot(_("InVesalius Database")) + # self.root = tree.AddRoot(_("InVesalius Database")) self.tree = tree def SelectSeries(self, pubsub_evt): diff --git a/invesalius/gui/language_dialog.py b/invesalius/gui/language_dialog.py index 9d9d153..3bc7f8d 100644 --- a/invesalius/gui/language_dialog.py +++ b/invesalius/gui/language_dialog.py @@ -20,7 +20,10 @@ import os import sys import wx -import wx.combo +try: + from wx.adv import BitmapComboBox +except ImportError: + from wx.combo import BitmapComboBox import invesalius.i18n as i18n @@ -62,7 +65,7 @@ class ComboBoxLanguage: selection = self.locales_key.index('en') # Create bitmap combo - self.bitmapCmb = bitmapCmb = wx.combo.BitmapComboBox(parent, style=wx.CB_READONLY) + self.bitmapCmb = bitmapCmb = BitmapComboBox(parent, style=wx.CB_READONLY) for key in self.locales_key: # Based on composed flag filename, get bitmap filepath = os.path.join(ICON_DIR, "%s.bmp"%(key)) @@ -114,7 +117,7 @@ class LanguageDialog(wx.Dialog): # selection = self.locales_key.index('en') # # Create bitmap combo - # self.bitmapCmb = bitmapCmb = wx.combo.BitmapComboBox(self, style=wx.CB_READONLY) + # self.bitmapCmb = bitmapCmb = BitmapComboBox(self, style=wx.CB_READONLY) # for key in self.locales_key: # # Based on composed flag filename, get bitmap # filepath = os.path.join(ICON_DIR, "%s.bmp"%(key)) diff --git a/invesalius/gui/preferences.py b/invesalius/gui/preferences.py index 4ea1696..d8f0e42 100644 --- a/invesalius/gui/preferences.py +++ b/invesalius/gui/preferences.py @@ -17,11 +17,15 @@ class Preferences(wx.Dialog): def __init__( self, parent, id = ID, title = _("Preferences"), size=wx.DefaultSize,\ pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE): - pre = wx.PreDialog() - pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) - pre.Create(parent, ID, title, pos, size, style) - - self.PostCreate(pre) + 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) + self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) + self.Create(parent, ID, title, pos, size, style) sizer = wx.BoxSizer(wx.VERTICAL) @@ -55,7 +59,7 @@ class Preferences(wx.Dialog): btnsizer.Realize() - sizer.AddSizer(btnsizer, 10, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP|wx.BOTTOM, 5) + sizer.Add(btnsizer, 10, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP|wx.BOTTOM, 5) self.SetSizer(sizer) sizer.Fit(self) diff --git a/invesalius/gui/task_exporter.py b/invesalius/gui/task_exporter.py index 5fa28cc..5a25960 100644 --- a/invesalius/gui/task_exporter.py +++ b/invesalius/gui/task_exporter.py @@ -21,7 +21,10 @@ import os import sys import wx -import wx.lib.hyperlink as hl +try: + from wx.lib.agw import hyperlink as hl +except ImportError: + import wx.lib.hyperlink as hl import wx.lib.platebtn as pbtn from wx.lib.pubsub import pub as Publisher diff --git a/invesalius/gui/task_importer.py b/invesalius/gui/task_importer.py index ecd1903..23366b1 100644 --- a/invesalius/gui/task_importer.py +++ b/invesalius/gui/task_importer.py @@ -20,7 +20,10 @@ import os import sys import wx -import wx.lib.hyperlink as hl +try: + from wx.lib.agw import hyperlink as hl +except ImportError: + import wx.lib.hyperlink as hl import wx.lib.platebtn as pbtn from wx.lib.pubsub import pub as Publisher diff --git a/invesalius/gui/task_navigator.py b/invesalius/gui/task_navigator.py index c0ca456..f0a2210 100644 --- a/invesalius/gui/task_navigator.py +++ b/invesalius/gui/task_navigator.py @@ -22,7 +22,10 @@ import sys import numpy as np import wx -import wx.lib.hyperlink as hl +try: + from wx.lib.agw import hyperlink as hl +except ImportError: + import wx.lib.hyperlink as hl import wx.lib.masked.numctrl from wx.lib.pubsub import pub as Publisher diff --git a/invesalius/gui/task_slice.py b/invesalius/gui/task_slice.py index ff79f55..a01d603 100644 --- a/invesalius/gui/task_slice.py +++ b/invesalius/gui/task_slice.py @@ -21,10 +21,18 @@ import sys import os import wx -import wx.lib.hyperlink as hl +try: + from wx.lib.agw import hyperlink as hl +except ImportError: + import wx.lib.hyperlink as hl import wx.lib.platebtn as pbtn from wx.lib.pubsub import pub as Publisher +try: + SystemSettings_GetColour = wx.SystemSettings.GetColour +except AttributeError: + SystemSettings_GetColour = wx.SystemSettings_GetColour + import invesalius.data.mask as mask import invesalius.data.slice_ as slice_ import invesalius.constants as const @@ -108,7 +116,7 @@ class InnerTaskPanel(wx.Panel): #print wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) #print wx.SystemSettings_GetColour(wx.SYS_COLOUR_SCROLLBAR) #print wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUHILIGHT) - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) fold_panel = FoldPanel(self) fold_panel.SetBackgroundColour(default_colour) self.fold_panel = fold_panel @@ -134,7 +142,7 @@ class InnerTaskPanel(wx.Panel): main_sizer = wx.BoxSizer(wx.VERTICAL) main_sizer.Add(line_new, 0,wx.GROW|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5) main_sizer.Add(fold_panel, 1, wx.GROW|wx.EXPAND|wx.ALL, 5) - main_sizer.AddSizer(line_sizer, 0, wx.GROW|wx.EXPAND) + main_sizer.Add(line_sizer, 0, wx.GROW|wx.EXPAND) main_sizer.AddSpacer(5) main_sizer.Fit(self) @@ -229,7 +237,7 @@ class FoldPanel(wx.Panel): class InnerFoldPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) self.SetBackgroundColour(default_colour) # Fold panel and its style settings @@ -643,7 +651,7 @@ class MaskProperties(wx.Panel): class EditionTools(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) self.SetBackgroundColour(default_colour) ## LINE 1 @@ -807,7 +815,7 @@ class EditionTools(wx.Panel): class WatershedTool(EditionTools): def __init__(self, parent): wx.Panel.__init__(self, parent) - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) self.SetBackgroundColour(default_colour) ## LINE 1 diff --git a/invesalius/gui/task_surface.py b/invesalius/gui/task_surface.py index 9ae7f89..69b007f 100644 --- a/invesalius/gui/task_surface.py +++ b/invesalius/gui/task_surface.py @@ -20,9 +20,17 @@ import sys import os import wx -import wx.lib.hyperlink as hl +try: + from wx.lib.agw import hyperlink as hl +except ImportError: + import wx.lib.hyperlink as hl from wx.lib.pubsub import pub as Publisher +try: + SystemSettings_GetColour = wx.SystemSettings.GetColour +except AttributeError: + SystemSettings_GetColour = wx.SystemSettings_GetColour + import invesalius.constants as const import invesalius.data.slice_ as slice_ import invesalius.gui.dialogs as dlg @@ -195,7 +203,7 @@ class FoldPanel(wx.Panel): class InnerFoldPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) self.SetBackgroundColour(default_colour) # Fold panel and its style settings @@ -264,7 +272,7 @@ BTN_SEEDS = wx.NewId() class SurfaceTools(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) self.SetBackgroundColour(default_colour) #self.SetBackgroundColour(wx.Colour(255,255,255)) @@ -398,7 +406,7 @@ class SurfaceTools(wx.Panel): class SurfaceProperties(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) self.SetBackgroundColour(default_colour) self.surface_list = [] @@ -559,7 +567,7 @@ class QualityAdjustment(wx.Panel): def __init__(self, parent): import invesalius.constants as const wx.Panel.__init__(self, parent) - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) self.SetBackgroundColour(default_colour) # LINE 1 diff --git a/invesalius/gui/task_tools.py b/invesalius/gui/task_tools.py index d3d4bb4..7218b05 100644 --- a/invesalius/gui/task_tools.py +++ b/invesalius/gui/task_tools.py @@ -20,7 +20,10 @@ import wx import os import wx.lib.embeddedimage as emb -import wx.lib.hyperlink as hl +try: + from wx.lib.agw import hyperlink as hl +except ImportError: + import wx.lib.hyperlink as hl import wx.lib.platebtn as pbtn from wx.lib.pubsub import pub as Publisher diff --git a/invesalius/gui/widgets/gradient.py b/invesalius/gui/widgets/gradient.py index e93dd95..b07f1c8 100755 --- a/invesalius/gui/widgets/gradient.py +++ b/invesalius/gui/widgets/gradient.py @@ -121,8 +121,11 @@ class GradientSlider(wx.Panel): dc.GradientFillLinear((x_init_gradient, y_init_gradient, width_gradient, height_gradient), (0, 0, 0), (255,255, 255)) - - n = wx.RendererNative_Get() + + try: + n = wx.RendererNative.Get() + except AttributeError: + n = wx.RendererNative_Get() # Drawing the push buttons n.DrawPushButton(self, dc, (x_init_push1, 0, PUSH_WIDTH, h)) -- libgit2 0.21.2