Commit 0b283dbe808e29124751cdf64c2455338c169595

Authored by Thiago Franco de Moraes
1 parent 4773dbbf
Exists in phoenix

Adapting InVesalius to Phoenix (new wxpython version)

app.py
... ... @@ -29,10 +29,11 @@ if sys.platform == 'win32':
29 29 import _winreg
30 30 else:
31 31 if sys.platform != 'darwin':
32   - import wxversion
  32 + pass
  33 + # import wxversion
33 34 #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True)
34 35 #wxversion.select('2.8-unicode', optionsRequired=True)
35   - wxversion.ensureMinimal('3.0')
  36 + # wxversion.ensureMinimal('3.0')
36 37  
37 38 import wx
38 39 #from wx.lib.pubsub import setupv1 #new wx
... ... @@ -48,6 +49,11 @@ from wx.lib.pubsub import pub as Publisher
48 49 # if sys.platform != 'darwin':
49 50 # _SplashScreen = wx.SplashScreen
50 51  
  52 +try:
  53 + from wx.adv import SplashScreen as _SplashScreen
  54 +except ImportError:
  55 + from wx import SplashScreen as _SplashScreen
  56 +
51 57  
52 58 import invesalius.gui.language_dialog as lang_dlg
53 59 import invesalius.i18n as i18n
... ... @@ -92,7 +98,7 @@ class InVesalius(wx.App):
92 98  
93 99 # ------------------------------------------------------------------
94 100  
95   -class SplashScreen(wx.SplashScreen):
  101 +class SplashScreen(_SplashScreen):
96 102 """
97 103 Splash screen to be shown in InVesalius initialization.
98 104 """
... ... @@ -175,8 +181,12 @@ class SplashScreen(wx.SplashScreen):
175 181  
176 182 bmp = wx.Image(path).ConvertToBitmap()
177 183  
178   - style = wx.SPLASH_TIMEOUT | wx.SPLASH_CENTRE_ON_SCREEN
179   - wx.SplashScreen.__init__(self,
  184 + try:
  185 + style = wx.SPLASH_TIMEOUT | wx.SPLASH_CENTRE_ON_SCREEN
  186 + except AttributeError:
  187 + style = wx.adv.SPLASH_TIMEOUT | wx.adv.SPLASH_CENTRE_ON_SCREEN
  188 +
  189 + _SplashScreen.__init__(self,
180 190 bitmap=bmp,
181 191 splashStyle=style,
182 192 milliseconds=1500,
... ...
invesalius/data/viewer_slice.py
... ... @@ -26,7 +26,8 @@ import tempfile
26 26 import numpy as np
27 27  
28 28 import vtk
29   -from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
  29 +from invesalius.data.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
  30 +# from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
30 31  
31 32 import invesalius.data.styles as styles
32 33 import wx
... ... @@ -95,10 +96,10 @@ class ContourMIPConfig(wx.Panel):
95 96 sizer = wx.BoxSizer(wx.HORIZONTAL)
96 97 sizer.Add(txt_mip_size, 0, wx.EXPAND | wx.ALL, 2)
97 98 sizer.Add(self.mip_size_spin, 0, wx.EXPAND)
98   - sizer.AddSpacer((10, 0))
  99 + sizer.AddSpacer(10)
99 100 sizer.Add(self.txt_mip_border, 0, wx.EXPAND | wx.ALL, 2)
100 101 sizer.Add(self.border_spin, 0, wx.EXPAND)
101   - sizer.AddSpacer((10, 0))
  102 + sizer.AddSpacer(10)
102 103 sizer.Add(self.inverted, 0, wx.EXPAND)
103 104 self.SetSizer(sizer)
104 105 sizer.Fit(self)
... ... @@ -196,7 +197,7 @@ class CanvasRendererCTX:
196 197 self.alpha = np.zeros((h, w, 1), dtype=np.uint8)
197 198  
198 199 self.bitmap = wx.EmptyBitmapRGBA(w, h)
199   - self.image = wx.ImageFromBuffer(w, h, self.rgb, self.alpha)
  200 + self.image = wx.ImageFromBuffer(w, h, self.rgb, self.alpha.data)
200 201  
201 202 def _resize_canvas(self, w, h):
202 203 self._array = np.zeros((h, w, 4), dtype=np.uint8)
... ... @@ -208,7 +209,7 @@ class CanvasRendererCTX:
208 209 self.alpha = np.zeros((h, w, 1), dtype=np.uint8)
209 210  
210 211 self.bitmap = wx.EmptyBitmapRGBA(w, h)
211   - self.image = wx.ImageFromBuffer(w, h, self.rgb, self.alpha)
  212 + self.image = wx.ImageFromBuffer(w, h, self.rgb, self.alpha.data)
212 213  
213 214 self.modified = True
214 215  
... ... @@ -582,7 +583,7 @@ class Viewer(wx.Panel):
582 583 sizer.Add(scroll, 0, wx.EXPAND|wx.GROW)
583 584  
584 585 background_sizer = wx.BoxSizer(wx.VERTICAL)
585   - background_sizer.AddSizer(sizer, 1, wx.EXPAND|wx.GROW|wx.ALL, 2)
  586 + background_sizer.Add(sizer, 1, wx.EXPAND|wx.GROW|wx.ALL, 2)
586 587 #background_sizer.Add(self.mip_ctrls, 0, wx.EXPAND|wx.GROW|wx.ALL, 2)
587 588 self.SetSizer(background_sizer)
588 589 background_sizer.Fit(self)
... ...
invesalius/data/viewer_volume.py
... ... @@ -26,7 +26,8 @@ import numpy as np
26 26 from numpy.core.umath_tests import inner1d
27 27 import wx
28 28 import vtk
29   -from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
  29 +# from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
  30 +from invesalius.data.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
30 31 from wx.lib.pubsub import pub as Publisher
31 32  
32 33 import invesalius.constants as const
... ...
invesalius/data/wxVTKRenderWindowInteractor.py 0 → 100644
... ... @@ -0,0 +1,706 @@
  1 +"""
  2 +
  3 +A VTK RenderWindowInteractor widget for wxPython.
  4 +
  5 +Find wxPython info at http://wxPython.org
  6 +
  7 +Created by Prabhu Ramachandran, April 2002
  8 +Based on wxVTKRenderWindow.py
  9 +
  10 +Fixes and updates by Charl P. Botha 2003-2008
  11 +
  12 +Updated to new wx namespace and some cleaning up by Andrea Gavana,
  13 +December 2006
  14 +"""
  15 +
  16 +"""
  17 +Please see the example at the end of this file.
  18 +
  19 +----------------------------------------
  20 +Creation:
  21 +
  22 + wxVTKRenderWindowInteractor(parent, ID, stereo=0, [wx keywords]):
  23 +
  24 + You should create a wx.App(False) or some other wx.App subclass
  25 + before creating the window.
  26 +
  27 +Behaviour:
  28 +
  29 + Uses __getattr__ to make the wxVTKRenderWindowInteractor behave just
  30 + like a vtkGenericRenderWindowInteractor.
  31 +
  32 +----------------------------------------
  33 +
  34 +"""
  35 +
  36 +# import usual libraries
  37 +import math, os, sys
  38 +import wx
  39 +import vtk
  40 +
  41 +# a few configuration items, see what works best on your system
  42 +
  43 +# Use GLCanvas as base class instead of wx.Window.
  44 +# This is sometimes necessary under wxGTK or the image is blank.
  45 +# (in wxWindows 2.3.1 and earlier, the GLCanvas had scroll bars)
  46 +baseClass = wx.Window
  47 +if wx.Platform == "__WXGTK__":
  48 + import wx.glcanvas
  49 + baseClass = wx.glcanvas.GLCanvas
  50 +
  51 +# Keep capturing mouse after mouse is dragged out of window
  52 +# (in wxGTK 2.3.2 there is a bug that keeps this from working,
  53 +# but it is only relevant in wxGTK if there are multiple windows)
  54 +_useCapture = (wx.Platform == "__WXMSW__")
  55 +
  56 +# end of configuration items
  57 +
  58 +
  59 +class EventTimer(wx.Timer):
  60 + """Simple wx.Timer class.
  61 + """
  62 +
  63 + def __init__(self, iren):
  64 + """Default class constructor.
  65 + @param iren: current render window
  66 + """
  67 + wx.Timer.__init__(self)
  68 + self.iren = iren
  69 +
  70 +
  71 + def Notify(self):
  72 + """ The timer has expired.
  73 + """
  74 + self.iren.TimerEvent()
  75 +
  76 +
  77 +class wxVTKRenderWindowInteractor(baseClass):
  78 + """
  79 + A wxRenderWindow for wxPython.
  80 + Use GetRenderWindow() to get the vtkRenderWindow.
  81 + Create with the keyword stereo=1 in order to
  82 + generate a stereo-capable window.
  83 + """
  84 +
  85 + # class variable that can also be used to request instances that use
  86 + # stereo; this is overridden by the stereo=1/0 parameter. If you set
  87 + # it to True, the NEXT instantiated object will attempt to allocate a
  88 + # stereo visual. E.g.:
  89 + # wxVTKRenderWindowInteractor.USE_STEREO = True
  90 + # myRWI = wxVTKRenderWindowInteractor(parent, -1)
  91 + USE_STEREO = False
  92 +
  93 + def __init__(self, parent, ID, *args, **kw):
  94 + """Default class constructor.
  95 + @param parent: parent window
  96 + @param ID: window id
  97 + @param **kw: wxPython keywords (position, size, style) plus the
  98 + 'stereo' keyword
  99 + """
  100 + # private attributes
  101 + self.__RenderWhenDisabled = 0
  102 +
  103 + # First do special handling of some keywords:
  104 + # stereo, position, size, width, height, style
  105 +
  106 + try:
  107 + stereo = bool(kw['stereo'])
  108 + del kw['stereo']
  109 + except KeyError:
  110 + stereo = False
  111 +
  112 + try:
  113 + position = kw['position']
  114 + del kw['position']
  115 + except KeyError:
  116 + position = wx.DefaultPosition
  117 +
  118 + try:
  119 + size = kw['size']
  120 + del kw['size']
  121 + except KeyError:
  122 + try:
  123 + size = parent.GetSize()
  124 + except AttributeError:
  125 + size = wx.DefaultSize
  126 +
  127 + # wx.WANTS_CHARS says to give us e.g. TAB
  128 + # wx.NO_FULL_REPAINT_ON_RESIZE cuts down resize flicker under GTK
  129 + style = wx.WANTS_CHARS | wx.NO_FULL_REPAINT_ON_RESIZE
  130 +
  131 + try:
  132 + style = style | kw['style']
  133 + del kw['style']
  134 + except KeyError:
  135 + pass
  136 +
  137 + # the enclosing frame must be shown under GTK or the windows
  138 + # don't connect together properly
  139 + if wx.Platform != '__WXMSW__':
  140 + l = []
  141 + p = parent
  142 + while p: # make a list of all parents
  143 + l.append(p)
  144 + p = p.GetParent()
  145 + l.reverse() # sort list into descending order
  146 + for p in l:
  147 + p.Show(1)
  148 +
  149 + if baseClass.__name__ == 'GLCanvas':
  150 + # code added by cpbotha to enable stereo and double
  151 + # buffering correctly where the user requests this; remember
  152 + # that the glXContext in this case is NOT allocated by VTK,
  153 + # but by WX, hence all of this.
  154 +
  155 + # Initialize GLCanvas with correct attriblist
  156 + attribList = [wx.glcanvas.WX_GL_RGBA,
  157 + wx.glcanvas.WX_GL_MIN_RED, 1,
  158 + wx.glcanvas.WX_GL_MIN_GREEN, 1,
  159 + wx.glcanvas.WX_GL_MIN_BLUE, 1,
  160 + wx.glcanvas.WX_GL_DEPTH_SIZE, 16,
  161 + wx.glcanvas.WX_GL_DOUBLEBUFFER]
  162 + if stereo:
  163 + attribList.append(wx.glcanvas.WX_GL_STEREO)
  164 +
  165 + try:
  166 + baseClass.__init__(self, parent, ID, pos=position, size=size,
  167 + style=style,
  168 + attribList=attribList)
  169 + except wx.PyAssertionError:
  170 + # visual couldn't be allocated, so we go back to default
  171 + baseClass.__init__(self, parent, ID, pos=position, size=size,
  172 + style=style)
  173 + if stereo:
  174 + # and make sure everyone knows that the stereo
  175 + # visual wasn't set.
  176 + stereo = 0
  177 +
  178 + else:
  179 + baseClass.__init__(self, parent, ID, pos=position, size=size,
  180 + style=style)
  181 +
  182 + # create the RenderWindow and initialize it
  183 + self._Iren = vtk.vtkGenericRenderWindowInteractor()
  184 + self._Iren.SetRenderWindow( vtk.vtkRenderWindow() )
  185 + self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer)
  186 + self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer)
  187 + self._Iren.GetRenderWindow().AddObserver('CursorChangedEvent',
  188 + self.CursorChangedEvent)
  189 +
  190 + try:
  191 + self._Iren.GetRenderWindow().SetSize(size.width, size.height)
  192 + except AttributeError:
  193 + self._Iren.GetRenderWindow().SetSize(size[0], size[1])
  194 +
  195 + if stereo:
  196 + self._Iren.GetRenderWindow().StereoCapableWindowOn()
  197 + self._Iren.GetRenderWindow().SetStereoTypeToCrystalEyes()
  198 +
  199 + self.__handle = None
  200 +
  201 + self.BindEvents()
  202 +
  203 + # with this, we can make sure that the reparenting logic in
  204 + # Render() isn't called before the first OnPaint() has
  205 + # successfully been run (and set up the VTK/WX display links)
  206 + self.__has_painted = False
  207 +
  208 + # set when we have captured the mouse.
  209 + self._own_mouse = False
  210 + # used to store WHICH mouse button led to mouse capture
  211 + self._mouse_capture_button = 0
  212 +
  213 + # A mapping for cursor changes.
  214 + self._cursor_map = {0: wx.CURSOR_ARROW, # VTK_CURSOR_DEFAULT
  215 + 1: wx.CURSOR_ARROW, # VTK_CURSOR_ARROW
  216 + 2: wx.CURSOR_SIZENESW, # VTK_CURSOR_SIZENE
  217 + 3: wx.CURSOR_SIZENWSE, # VTK_CURSOR_SIZENWSE
  218 + 4: wx.CURSOR_SIZENESW, # VTK_CURSOR_SIZESW
  219 + 5: wx.CURSOR_SIZENWSE, # VTK_CURSOR_SIZESE
  220 + 6: wx.CURSOR_SIZENS, # VTK_CURSOR_SIZENS
  221 + 7: wx.CURSOR_SIZEWE, # VTK_CURSOR_SIZEWE
  222 + 8: wx.CURSOR_SIZING, # VTK_CURSOR_SIZEALL
  223 + 9: wx.CURSOR_HAND, # VTK_CURSOR_HAND
  224 + 10: wx.CURSOR_CROSS, # VTK_CURSOR_CROSSHAIR
  225 + }
  226 +
  227 + def BindEvents(self):
  228 + """Binds all the necessary events for navigation, sizing,
  229 + drawing.
  230 + """
  231 + # refresh window by doing a Render
  232 + self.Bind(wx.EVT_PAINT, self.OnPaint)
  233 + # turn off background erase to reduce flicker
  234 + self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None)
  235 +
  236 + # Bind the events to the event converters
  237 + self.Bind(wx.EVT_RIGHT_DOWN, self.OnButtonDown)
  238 + self.Bind(wx.EVT_LEFT_DOWN, self.OnButtonDown)
  239 + self.Bind(wx.EVT_MIDDLE_DOWN, self.OnButtonDown)
  240 + self.Bind(wx.EVT_RIGHT_UP, self.OnButtonUp)
  241 + self.Bind(wx.EVT_LEFT_UP, self.OnButtonUp)
  242 + self.Bind(wx.EVT_MIDDLE_UP, self.OnButtonUp)
  243 + self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
  244 + self.Bind(wx.EVT_MOTION, self.OnMotion)
  245 +
  246 + self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
  247 + self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
  248 +
  249 + # If we use EVT_KEY_DOWN instead of EVT_CHAR, capital versions
  250 + # of all characters are always returned. EVT_CHAR also performs
  251 + # other necessary keyboard-dependent translations.
  252 + self.Bind(wx.EVT_CHAR, self.OnKeyDown)
  253 + self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
  254 +
  255 + self.Bind(wx.EVT_SIZE, self.OnSize)
  256 +
  257 + # the wx 2.8.7.1 documentation states that you HAVE to handle
  258 + # this event if you make use of CaptureMouse, which we do.
  259 + if _useCapture and hasattr(wx, 'EVT_MOUSE_CAPTURE_LOST'):
  260 + self.Bind(wx.EVT_MOUSE_CAPTURE_LOST,
  261 + self.OnMouseCaptureLost)
  262 +
  263 +
  264 + def __getattr__(self, attr):
  265 + """Makes the object behave like a
  266 + vtkGenericRenderWindowInteractor.
  267 + """
  268 + if attr == '__vtk__':
  269 + return lambda t=self._Iren: t
  270 + elif hasattr(self._Iren, attr):
  271 + return getattr(self._Iren, attr)
  272 + else:
  273 + raise AttributeError(self.__class__.__name__ +
  274 + " has no attribute named " + attr)
  275 +
  276 + def CreateTimer(self, obj, evt):
  277 + """ Creates a timer.
  278 + """
  279 + self._timer = EventTimer(self)
  280 + self._timer.Start(10, True)
  281 +
  282 + def DestroyTimer(self, obj, evt):
  283 + """The timer is a one shot timer so will expire automatically.
  284 + """
  285 + return 1
  286 +
  287 + def _CursorChangedEvent(self, obj, evt):
  288 + """Change the wx cursor if the renderwindow's cursor was
  289 + changed.
  290 + """
  291 + cur = self._cursor_map[obj.GetCurrentCursor()]
  292 + c = wx.StockCursor(cur)
  293 + self.SetCursor(c)
  294 +
  295 + def CursorChangedEvent(self, obj, evt):
  296 + """Called when the CursorChangedEvent fires on the render
  297 + window."""
  298 + # This indirection is needed since when the event fires, the
  299 + # current cursor is not yet set so we defer this by which time
  300 + # the current cursor should have been set.
  301 + wx.CallAfter(self._CursorChangedEvent, obj, evt)
  302 +
  303 + def HideCursor(self):
  304 + """Hides the cursor."""
  305 + c = wx.StockCursor(wx.CURSOR_BLANK)
  306 + self.SetCursor(c)
  307 +
  308 + def ShowCursor(self):
  309 + """Shows the cursor."""
  310 + rw = self._Iren.GetRenderWindow()
  311 + cur = self._cursor_map[rw.GetCurrentCursor()]
  312 + c = wx.StockCursor(cur)
  313 + self.SetCursor(c)
  314 +
  315 + def GetDisplayId(self):
  316 + """Function to get X11 Display ID from WX and return it in a format
  317 + that can be used by VTK Python.
  318 +
  319 + We query the X11 Display with a new call that was added in wxPython
  320 + 2.6.0.1. The call returns a SWIG object which we can query for the
  321 + address and subsequently turn into an old-style SWIG-mangled string
  322 + representation to pass to VTK.
  323 + """
  324 + d = None
  325 +
  326 + try:
  327 + d = wx.GetXDisplay()
  328 +
  329 + except AttributeError:
  330 + # wx.GetXDisplay was added by Robin Dunn in wxPython 2.6.0.1
  331 + # if it's not available, we can't pass it. In general,
  332 + # things will still work; on some setups, it'll break.
  333 + pass
  334 +
  335 + else:
  336 + # wx returns None on platforms where wx.GetXDisplay is not relevant
  337 + if d:
  338 + d = hex(d)
  339 + # On wxPython-2.6.3.2 and above there is no leading '0x'.
  340 + if not d.startswith('0x'):
  341 + d = '0x' + d
  342 +
  343 + # VTK wants it as: _xxxxxxxx_p_void (SWIG pointer)
  344 + d = '_%s_%s\0' % (d[2:], 'p_void')
  345 +
  346 + return d
  347 +
  348 + def OnMouseCaptureLost(self, event):
  349 + """This is signalled when we lose mouse capture due to an
  350 + external event, such as when a dialog box is shown. See the
  351 + wx documentation.
  352 + """
  353 +
  354 + # the documentation seems to imply that by this time we've
  355 + # already lost capture. I have to assume that we don't need
  356 + # to call ReleaseMouse ourselves.
  357 + if _useCapture and self._own_mouse:
  358 + self._own_mouse = False
  359 +
  360 + def OnPaint(self,event):
  361 + """Handles the wx.EVT_PAINT event for
  362 + wxVTKRenderWindowInteractor.
  363 + """
  364 +
  365 + # wx should continue event processing after this handler.
  366 + # We call this BEFORE Render(), so that if Render() raises
  367 + # an exception, wx doesn't re-call OnPaint repeatedly.
  368 + event.Skip()
  369 +
  370 + dc = wx.PaintDC(self)
  371 +
  372 + # make sure the RenderWindow is sized correctly
  373 + self._Iren.GetRenderWindow().SetSize(self.GetSize())
  374 +
  375 + # Tell the RenderWindow to render inside the wx.Window.
  376 + if not self.__handle:
  377 +
  378 + # on relevant platforms, set the X11 Display ID
  379 + d = self.GetDisplayId()
  380 + if d and self.__has_painted:
  381 + self._Iren.GetRenderWindow().SetDisplayId(d)
  382 +
  383 + # store the handle
  384 + self.__handle = self.GetHandle()
  385 + # and give it to VTK
  386 + self._Iren.GetRenderWindow().SetWindowInfo(str(self.__handle))
  387 +
  388 + # now that we've painted once, the Render() reparenting logic
  389 + # is safe
  390 + self.__has_painted = True
  391 +
  392 + self.Render()
  393 +
  394 + def OnSize(self,event):
  395 + """Handles the wx.EVT_SIZE event for
  396 + wxVTKRenderWindowInteractor.
  397 + """
  398 +
  399 + # event processing should continue (we call this before the
  400 + # Render(), in case it raises an exception)
  401 + event.Skip()
  402 +
  403 + try:
  404 + width, height = event.GetSize()
  405 + except:
  406 + width = event.GetSize().width
  407 + height = event.GetSize().height
  408 + self._Iren.SetSize(width, height)
  409 + self._Iren.ConfigureEvent()
  410 +
  411 + # this will check for __handle
  412 + self.Render()
  413 +
  414 + def OnMotion(self,event):
  415 + """Handles the wx.EVT_MOTION event for
  416 + wxVTKRenderWindowInteractor.
  417 + """
  418 +
  419 + # event processing should continue
  420 + # we call this early in case any of the VTK code raises an
  421 + # exception.
  422 + event.Skip()
  423 +
  424 + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(),
  425 + event.ControlDown(),
  426 + event.ShiftDown(),
  427 + chr(0), 0, None)
  428 + self._Iren.MouseMoveEvent()
  429 +
  430 + def OnEnter(self,event):
  431 + """Handles the wx.EVT_ENTER_WINDOW event for
  432 + wxVTKRenderWindowInteractor.
  433 + """
  434 +
  435 + # event processing should continue
  436 + event.Skip()
  437 +
  438 + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(),
  439 + event.ControlDown(),
  440 + event.ShiftDown(),
  441 + chr(0), 0, None)
  442 + self._Iren.EnterEvent()
  443 +
  444 +
  445 + def OnLeave(self,event):
  446 + """Handles the wx.EVT_LEAVE_WINDOW event for
  447 + wxVTKRenderWindowInteractor.
  448 + """
  449 +
  450 + # event processing should continue
  451 + event.Skip()
  452 +
  453 + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(),
  454 + event.ControlDown(),
  455 + event.ShiftDown(),
  456 + chr(0), 0, None)
  457 + self._Iren.LeaveEvent()
  458 +
  459 +
  460 + def OnButtonDown(self,event):
  461 + """Handles the wx.EVT_LEFT/RIGHT/MIDDLE_DOWN events for
  462 + wxVTKRenderWindowInteractor.
  463 + """
  464 +
  465 + # allow wx event processing to continue
  466 + # on wxPython 2.6.0.1, omitting this will cause problems with
  467 + # the initial focus, resulting in the wxVTKRWI ignoring keypresses
  468 + # until we focus elsewhere and then refocus the wxVTKRWI frame
  469 + # we do it this early in case any of the following VTK code
  470 + # raises an exception.
  471 + event.Skip()
  472 +
  473 + ctrl, shift = event.ControlDown(), event.ShiftDown()
  474 + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(),
  475 + ctrl, shift, chr(0), 0, None)
  476 +
  477 + button = 0
  478 + if event.RightDown():
  479 + self._Iren.RightButtonPressEvent()
  480 + button = 'Right'
  481 + elif event.LeftDown():
  482 + self._Iren.LeftButtonPressEvent()
  483 + button = 'Left'
  484 + elif event.MiddleDown():
  485 + self._Iren.MiddleButtonPressEvent()
  486 + button = 'Middle'
  487 +
  488 + # save the button and capture mouse until the button is released
  489 + # we only capture the mouse if it hasn't already been captured
  490 + if _useCapture and not self._own_mouse:
  491 + self._own_mouse = True
  492 + self._mouse_capture_button = button
  493 + self.CaptureMouse()
  494 +
  495 +
  496 + def OnButtonUp(self,event):
  497 + """Handles the wx.EVT_LEFT/RIGHT/MIDDLE_UP events for
  498 + wxVTKRenderWindowInteractor.
  499 + """
  500 +
  501 + # event processing should continue
  502 + event.Skip()
  503 +
  504 + button = 0
  505 + if event.RightUp():
  506 + button = 'Right'
  507 + elif event.LeftUp():
  508 + button = 'Left'
  509 + elif event.MiddleUp():
  510 + button = 'Middle'
  511 +
  512 + # if the same button is released that captured the mouse, and
  513 + # we have the mouse, release it.
  514 + # (we need to get rid of this as soon as possible; if we don't
  515 + # and one of the event handlers raises an exception, mouse
  516 + # is never released.)
  517 + if _useCapture and self._own_mouse and \
  518 + button==self._mouse_capture_button:
  519 + self.ReleaseMouse()
  520 + self._own_mouse = False
  521 +
  522 + ctrl, shift = event.ControlDown(), event.ShiftDown()
  523 + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(),
  524 + ctrl, shift, chr(0), 0, None)
  525 +
  526 + if button == 'Right':
  527 + self._Iren.RightButtonReleaseEvent()
  528 + elif button == 'Left':
  529 + self._Iren.LeftButtonReleaseEvent()
  530 + elif button == 'Middle':
  531 + self._Iren.MiddleButtonReleaseEvent()
  532 +
  533 +
  534 + def OnMouseWheel(self,event):
  535 + """Handles the wx.EVT_MOUSEWHEEL event for
  536 + wxVTKRenderWindowInteractor.
  537 + """
  538 +
  539 + # event processing should continue
  540 + event.Skip()
  541 +
  542 + ctrl, shift = event.ControlDown(), event.ShiftDown()
  543 + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(),
  544 + ctrl, shift, chr(0), 0, None)
  545 + if event.GetWheelRotation() > 0:
  546 + self._Iren.MouseWheelForwardEvent()
  547 + else:
  548 + self._Iren.MouseWheelBackwardEvent()
  549 +
  550 +
  551 + def OnKeyDown(self,event):
  552 + """Handles the wx.EVT_KEY_DOWN event for
  553 + wxVTKRenderWindowInteractor.
  554 + """
  555 +
  556 + # event processing should continue
  557 + event.Skip()
  558 +
  559 + ctrl, shift = event.ControlDown(), event.ShiftDown()
  560 + keycode, keysym = event.GetKeyCode(), None
  561 + key = chr(0)
  562 + if keycode < 256:
  563 + key = chr(keycode)
  564 +
  565 + # wxPython 2.6.0.1 does not return a valid event.Get{X,Y}()
  566 + # for this event, so we use the cached position.
  567 + (x,y)= self._Iren.GetEventPosition()
  568 + self._Iren.SetEventInformation(x, y,
  569 + ctrl, shift, key, 0,
  570 + keysym)
  571 +
  572 + self._Iren.KeyPressEvent()
  573 + self._Iren.CharEvent()
  574 +
  575 +
  576 + def OnKeyUp(self,event):
  577 + """Handles the wx.EVT_KEY_UP event for
  578 + wxVTKRenderWindowInteractor.
  579 + """
  580 +
  581 + # event processing should continue
  582 + event.Skip()
  583 +
  584 + ctrl, shift = event.ControlDown(), event.ShiftDown()
  585 + keycode, keysym = event.GetKeyCode(), None
  586 + key = chr(0)
  587 + if keycode < 256:
  588 + key = chr(keycode)
  589 +
  590 + self._Iren.SetEventInformationFlipY(event.GetX(), event.GetY(),
  591 + ctrl, shift, key, 0,
  592 + keysym)
  593 + self._Iren.KeyReleaseEvent()
  594 +
  595 +
  596 + def GetRenderWindow(self):
  597 + """Returns the render window (vtkRenderWindow).
  598 + """
  599 + return self._Iren.GetRenderWindow()
  600 +
  601 + def Render(self):
  602 + """Actually renders the VTK scene on screen.
  603 + """
  604 + RenderAllowed = 1
  605 +
  606 + if not self.__RenderWhenDisabled:
  607 + # the user doesn't want us to render when the toplevel frame
  608 + # is disabled - first find the top level parent
  609 + topParent = wx.GetTopLevelParent(self)
  610 + if topParent:
  611 + # if it exists, check whether it's enabled
  612 + # if it's not enabeld, RenderAllowed will be false
  613 + RenderAllowed = topParent.IsEnabled()
  614 +
  615 + if RenderAllowed:
  616 + if self.__handle and self.__handle == self.GetHandle():
  617 + self._Iren.GetRenderWindow().Render()
  618 +
  619 + elif self.GetHandle() and self.__has_painted:
  620 + # this means the user has reparented us; let's adapt to the
  621 + # new situation by doing the WindowRemap dance
  622 + self._Iren.GetRenderWindow().SetNextWindowInfo(
  623 + str(self.GetHandle()))
  624 +
  625 + # make sure the DisplayId is also set correctly
  626 + d = self.GetDisplayId()
  627 + if d:
  628 + self._Iren.GetRenderWindow().SetDisplayId(d)
  629 +
  630 + # do the actual remap with the new parent information
  631 + self._Iren.GetRenderWindow().WindowRemap()
  632 +
  633 + # store the new situation
  634 + self.__handle = self.GetHandle()
  635 + self._Iren.GetRenderWindow().Render()
  636 +
  637 + def SetRenderWhenDisabled(self, newValue):
  638 + """Change value of __RenderWhenDisabled ivar.
  639 +
  640 + If __RenderWhenDisabled is false (the default), this widget will not
  641 + call Render() on the RenderWindow if the top level frame (i.e. the
  642 + containing frame) has been disabled.
  643 +
  644 + This prevents recursive rendering during wx.SafeYield() calls.
  645 + wx.SafeYield() can be called during the ProgressMethod() callback of
  646 + a VTK object to have progress bars and other GUI elements updated -
  647 + it does this by disabling all windows (disallowing user-input to
  648 + prevent re-entrancy of code) and then handling all outstanding
  649 + GUI events.
  650 +
  651 + However, this often triggers an OnPaint() method for wxVTKRWIs,
  652 + resulting in a Render(), resulting in Update() being called whilst
  653 + still in progress.
  654 + """
  655 + self.__RenderWhenDisabled = bool(newValue)
  656 +
  657 +
  658 +#--------------------------------------------------------------------
  659 +def wxVTKRenderWindowInteractorConeExample():
  660 + """Like it says, just a simple example
  661 + """
  662 + # every wx app needs an app
  663 + app = wx.App(False)
  664 +
  665 + # create the top-level frame, sizer and wxVTKRWI
  666 + frame = wx.Frame(None, -1, "wxVTKRenderWindowInteractor", size=(400,400))
  667 + widget = wxVTKRenderWindowInteractor(frame, -1)
  668 + sizer = wx.BoxSizer(wx.VERTICAL)
  669 + sizer.Add(widget, 1, wx.EXPAND)
  670 + frame.SetSizer(sizer)
  671 + frame.Layout()
  672 +
  673 + # It would be more correct (API-wise) to call widget.Initialize() and
  674 + # widget.Start() here, but Initialize() calls RenderWindow.Render().
  675 + # That Render() call will get through before we can setup the
  676 + # RenderWindow() to render via the wxWidgets-created context; this
  677 + # causes flashing on some platforms and downright breaks things on
  678 + # other platforms. Instead, we call widget.Enable(). This means
  679 + # that the RWI::Initialized ivar is not set, but in THIS SPECIFIC CASE,
  680 + # that doesn't matter.
  681 + widget.Enable(1)
  682 +
  683 + widget.AddObserver("ExitEvent", lambda o,e,f=frame: f.Close())
  684 +
  685 + ren = vtk.vtkRenderer()
  686 + widget.GetRenderWindow().AddRenderer(ren)
  687 +
  688 + cone = vtk.vtkConeSource()
  689 + cone.SetResolution(8)
  690 +
  691 + coneMapper = vtk.vtkPolyDataMapper()
  692 + coneMapper.SetInputConnection(cone.GetOutputPort())
  693 +
  694 + coneActor = vtk.vtkActor()
  695 + coneActor.SetMapper(coneMapper)
  696 +
  697 + ren.AddActor(coneActor)
  698 +
  699 + # show the window
  700 + frame.Show()
  701 +
  702 + app.MainLoop()
  703 +
  704 +if __name__ == "__main__":
  705 + wxVTKRenderWindowInteractorConeExample()
  706 +
... ...
invesalius/gui/data_notebook.py
... ... @@ -29,7 +29,10 @@ except ImportError:
29 29  
30 30 import wx
31 31 import wx.grid
32   -import wx.lib.flatnotebook as fnb
  32 +try:
  33 + from wx.lib.agw import flatnotebook as fnb
  34 +except ImportError:
  35 + import wx.lib.flatnotebook as fnb
33 36 import wx.lib.platebtn as pbtn
34 37 from wx.lib.pubsub import pub as Publisher
35 38  
... ...
invesalius/gui/default_tasks.py
... ... @@ -18,7 +18,11 @@
18 18 #--------------------------------------------------------------------------
19 19  
20 20 import wx
21   -import wx.lib.foldpanelbar as fpb
  21 +try:
  22 + from wx.lib.agw import foldpanelbar as fpb
  23 +except ImportError:
  24 + import wx.lib.foldpanelbar as fpb
  25 +
22 26 from wx.lib.pubsub import pub as Publisher
23 27  
24 28 import invesalius.constants as const
... ...
invesalius/gui/dialogs.py
... ... @@ -24,7 +24,10 @@ import sys
24 24  
25 25 import vtk
26 26 import wx
27   -import wx.combo
  27 +try:
  28 + from wx.adv import BitmapComboBox
  29 +except ImportError:
  30 + from wx.combo import BitmapComboBox
28 31  
29 32 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
30 33 from wx.lib import masked
... ... @@ -1792,7 +1795,7 @@ class MaskBooleanDialog(wx.Dialog):
1792 1795 (_(u"Difference"), const.BOOLEAN_DIFF, 'bool_difference.png'),
1793 1796 (_(u"Intersection"), const.BOOLEAN_AND, 'bool_intersection.png'),
1794 1797 (_(u"Exclusive disjunction"), const.BOOLEAN_XOR, 'bool_disjunction.png'))
1795   - self.op_boolean = wx.combo.BitmapComboBox(self, -1, op_choices[0][0], choices=[])
  1798 + self.op_boolean = BitmapComboBox(self, -1, op_choices[0][0], choices=[])
1796 1799  
1797 1800 for n, i, f in op_choices:
1798 1801 bmp = wx.Bitmap(os.path.join(icon_folder, f), wx.BITMAP_TYPE_PNG)
... ...
invesalius/gui/frame.py
... ... @@ -29,6 +29,11 @@ from wx.lib.pubsub import pub as Publisher
29 29 import wx.lib.agw.toasterbox as TB
30 30 import wx.lib.popupctl as pc
31 31  
  32 +try:
  33 + from wx.adv import TaskBarIcon as _TaskBarIcon
  34 +except ImportError:
  35 + from wx import TaskBarIcon as _TaskBarIcon
  36 +
32 37 from wx.lib.agw.aui.auibar import AuiToolBar, AUI_TB_PLAIN_BACKGROUND
33 38  
34 39 import invesalius.constants as const
... ... @@ -176,23 +181,23 @@ class Frame(wx.Frame):
176 181 Name("Data").Position(1))
177 182  
178 183 # This is the DICOM import panel. When the two panels above as dicom # are shown, this should be hiden
179   - caption = _("Preview medical data to be reconstructed")
180   - aui_manager.AddPane(imp.Panel(self), wx.aui.AuiPaneInfo().
181   - Name("Import").CloseButton(False).Centre().Hide().
182   - MaximizeButton(False).Floatable(True).
183   - Caption(caption).CaptionVisible(True))
184   -
185   - caption = _("Preview bitmap to be reconstructed")
186   - aui_manager.AddPane(imp_bmp.Panel(self), wx.aui.AuiPaneInfo().
187   - Name("ImportBMP").CloseButton(False).Centre().Hide().
188   - MaximizeButton(False).Floatable(True).
189   - Caption(caption).CaptionVisible(True))
190   -
191   - ncaption = _("Retrieve DICOM from PACS")
192   - aui_manager.AddPane(imp_net.Panel(self), wx.aui.AuiPaneInfo().
193   - Name("Retrieve").Centre().Hide().
194   - MaximizeButton(True).Floatable(True).
195   - Caption(ncaption).CaptionVisible(True))
  184 + # caption = _("Preview medical data to be reconstructed")
  185 + # aui_manager.AddPane(imp.Panel(self), wx.aui.AuiPaneInfo().
  186 + # Name("Import").CloseButton(False).Centre().Hide().
  187 + # MaximizeButton(False).Floatable(True).
  188 + # Caption(caption).CaptionVisible(True))
  189 +
  190 + # caption = _("Preview bitmap to be reconstructed")
  191 + # aui_manager.AddPane(imp_bmp.Panel(self), wx.aui.AuiPaneInfo().
  192 + # Name("ImportBMP").CloseButton(False).Centre().Hide().
  193 + # MaximizeButton(False).Floatable(True).
  194 + # Caption(caption).CaptionVisible(True))
  195 +
  196 + # ncaption = _("Retrieve DICOM from PACS")
  197 + # aui_manager.AddPane(imp_net.Panel(self), wx.aui.AuiPaneInfo().
  198 + # Name("Retrieve").Centre().Hide().
  199 + # MaximizeButton(True).Floatable(True).
  200 + # Caption(ncaption).CaptionVisible(True))
196 201  
197 202 # Add toolbars to manager
198 203 # This is pretty tricky -- order on win32 is inverted when
... ... @@ -1078,7 +1083,7 @@ class StatusBar(wx.StatusBar):
1078 1083 # ------------------------------------------------------------------
1079 1084 # ------------------------------------------------------------------
1080 1085  
1081   -class TaskBarIcon(wx.TaskBarIcon):
  1086 +class TaskBarIcon(_TaskBarIcon):
1082 1087 """
1083 1088 TaskBarIcon has different behaviours according to the platform:
1084 1089 - win32: Show icon on "Notification Area" (near clock)
... ... @@ -1086,7 +1091,7 @@ class TaskBarIcon(wx.TaskBarIcon):
1086 1091 - linux2: Show icon on "Notification Area" (near clock)
1087 1092 """
1088 1093 def __init__(self, parent=None):
1089   - wx.TaskBarIcon.__init__(self)
  1094 + _TaskBarIcon.__init__(self)
1090 1095 self.frame = parent
1091 1096  
1092 1097 icon = wx.Icon(os.path.join(const.ICON_DIR, "invesalius.ico"),
... ...
invesalius/gui/import_bitmap_panel.py
... ... @@ -17,7 +17,10 @@
17 17 # detalhes.
18 18 #--------------------------------------------------------------------------
19 19 import wx
20   -import wx.gizmos as gizmos
  20 +try:
  21 + from wx.adv import EditableListBox as EditableListBox
  22 +except ImportError:
  23 + from wx.gizmos import TreeListCtrl
21 24 from wx.lib.pubsub import pub as Publisher
22 25 import wx.lib.splitter as spl
23 26  
... ... @@ -188,15 +191,15 @@ class TextPanel(wx.Panel):
188 191 self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyPress)
189 192  
190 193 def __init_gui(self):
191   - tree = gizmos.TreeListCtrl(self, -1, style =
192   - wx.TR_DEFAULT_STYLE
193   - | wx.TR_HIDE_ROOT
194   - | wx.TR_ROW_LINES
195   - | wx.TR_COLUMN_LINES
196   - | wx.TR_FULL_ROW_HIGHLIGHT
197   - | wx.TR_MULTIPLE
198   - | wx.TR_HIDE_ROOT
199   - )
  194 + tree = TreeListCtrl(self, -1, style =
  195 + wx.TR_DEFAULT_STYLE
  196 + | wx.TR_HIDE_ROOT
  197 + | wx.TR_ROW_LINES
  198 + | wx.TR_COLUMN_LINES
  199 + | wx.TR_FULL_ROW_HIGHLIGHT
  200 + | wx.TR_MULTIPLE
  201 + | wx.TR_HIDE_ROOT
  202 + )
200 203  
201 204  
202 205 tree.AddColumn(_("Path"))
... ...
invesalius/gui/import_network_panel.py
... ... @@ -18,7 +18,10 @@
18 18 #--------------------------------------------------------------------------
19 19 import wx
20 20 import sys
21   -import wx.gizmos as gizmos
  21 +try:
  22 + from wx.adv import EditableListBox as EditableListBox
  23 +except ImportError:
  24 + from wx.gizmos import TreeListCtrl
22 25 from wx.lib.pubsub import pub as Publisher
23 26 import wx.lib.splitter as spl
24 27  
... ... @@ -226,15 +229,14 @@ class TextPanel(wx.Panel):
226 229 self.Bind(wx.EVT_SIZE, self.OnSize)
227 230  
228 231 def __init_gui(self):
229   - tree = gizmos.TreeListCtrl(self, -1, style =
230   - wx.TR_DEFAULT_STYLE
231   - | wx.TR_HIDE_ROOT
232   - | wx.TR_ROW_LINES
233   - | wx.TR_COLUMN_LINES
234   - | wx.TR_FULL_ROW_HIGHLIGHT
235   - | wx.TR_SINGLE
236   - )
237   -
  232 + tree = TreeListCtrl(self, -1, style =
  233 + wx.TR_DEFAULT_STYLE
  234 + | wx.TR_HIDE_ROOT
  235 + | wx.TR_ROW_LINES
  236 + | wx.TR_COLUMN_LINES
  237 + | wx.TR_FULL_ROW_HIGHLIGHT
  238 + | wx.TR_SINGLE
  239 + )
238 240  
239 241 tree.AddColumn(_("Patient name"))
240 242 tree.AddColumn(_("Patient ID"))
... ...
invesalius/gui/import_panel.py
... ... @@ -17,7 +17,11 @@
17 17 # detalhes.
18 18 #--------------------------------------------------------------------------
19 19 import wx
20   -import wx.gizmos as gizmos
  20 +
  21 +try:
  22 + from wx.dataview import TreeListCtrl
  23 +except ImportError:
  24 + from wx.gizmos import TreeListCtrl
21 25 from wx.lib.pubsub import pub as Publisher
22 26 import wx.lib.splitter as spl
23 27  
... ... @@ -103,7 +107,7 @@ class InnerPanel(wx.Panel):
103 107 self.combo_interval.SetSelection(0)
104 108  
105 109 inner_sizer = wx.BoxSizer(wx.HORIZONTAL)
106   - inner_sizer.AddSizer(btnsizer, 0, wx.LEFT|wx.TOP, 5)
  110 + inner_sizer.Add(btnsizer, 0, wx.LEFT|wx.TOP, 5)
107 111 inner_sizer.Add(self.combo_interval, 0, wx.LEFT|wx.RIGHT|wx.TOP, 5)
108 112 panel.SetSizer(inner_sizer)
109 113 inner_sizer.Fit(panel)
... ... @@ -211,30 +215,47 @@ class TextPanel(wx.Panel):
211 215 self.Bind(wx.EVT_SIZE, self.OnSize)
212 216  
213 217 def __init_gui(self):
214   - tree = gizmos.TreeListCtrl(self, -1, style =
215   - wx.TR_DEFAULT_STYLE
216   - | wx.TR_HIDE_ROOT
217   - | wx.TR_ROW_LINES
218   - | wx.TR_COLUMN_LINES
219   - | wx.TR_FULL_ROW_HIGHLIGHT
220   - | wx.TR_SINGLE
221   - )
222   -
223   -
224   - tree.AddColumn(_("Patient name"))
225   - tree.AddColumn(_("Patient ID"))
226   - tree.AddColumn(_("Age"))
227   - tree.AddColumn(_("Gender"))
228   - tree.AddColumn(_("Study description"))
229   - tree.AddColumn(_("Modality"))
230   - tree.AddColumn(_("Date acquired"))
231   - tree.AddColumn(_("# Images"))
232   - tree.AddColumn(_("Institution"))
233   - tree.AddColumn(_("Date of birth"))
234   - tree.AddColumn(_("Accession Number"))
235   - tree.AddColumn(_("Referring physician"))
236   -
237   - tree.SetMainColumn(0) # the one with the tree in it...
  218 + tree = TreeListCtrl(self, -1, style =
  219 + wx.TR_DEFAULT_STYLE
  220 + | wx.TR_HIDE_ROOT
  221 + | wx.TR_ROW_LINES
  222 + # | wx.TR_COLUMN_LINES
  223 + | wx.TR_FULL_ROW_HIGHLIGHT
  224 + | wx.TR_SINGLE
  225 + )
  226 +
  227 +
  228 + try:
  229 + tree.AppendColumn(_("Patient name"))
  230 + tree.AppendColumn(_("Patient ID"))
  231 + tree.AppendColumn(_("Age"))
  232 + tree.AppendColumn(_("Gender"))
  233 + tree.AppendColumn(_("Study description"))
  234 + tree.AppendColumn(_("Modality"))
  235 + tree.AppendColumn(_("Date acquired"))
  236 + tree.AppendColumn(_("# Images"))
  237 + tree.AppendColumn(_("Institution"))
  238 + tree.AppendColumn(_("Date of birth"))
  239 + tree.AppendColumn(_("Accession Number"))
  240 + tree.AppendColumn(_("Referring physician"))
  241 + except AttributeError:
  242 + tree.AddColumn(_("Patient name"))
  243 + tree.AddColumn(_("Patient ID"))
  244 + tree.AddColumn(_("Age"))
  245 + tree.AddColumn(_("Gender"))
  246 + tree.AddColumn(_("Study description"))
  247 + tree.AddColumn(_("Modality"))
  248 + tree.AddColumn(_("Date acquired"))
  249 + tree.AddColumn(_("# Images"))
  250 + tree.AddColumn(_("Institution"))
  251 + tree.AddColumn(_("Date of birth"))
  252 + tree.AddColumn(_("Accession Number"))
  253 + tree.AddColumn(_("Referring physician"))
  254 +
  255 + try:
  256 + tree.SetMainColumn(0) # the one with the tree in it...
  257 + except AttributeError:
  258 + pass
238 259 tree.SetColumnWidth(0, 280) # Patient name
239 260 tree.SetColumnWidth(1, 110) # Patient ID
240 261 tree.SetColumnWidth(2, 40) # Age
... ... @@ -248,7 +269,7 @@ class TextPanel(wx.Panel):
248 269 tree.SetColumnWidth(10, 140) # Accession Number
249 270 tree.SetColumnWidth(11, 160) # Referring physician
250 271  
251   - self.root = tree.AddRoot(_("InVesalius Database"))
  272 + # self.root = tree.AddRoot(_("InVesalius Database"))
252 273 self.tree = tree
253 274  
254 275 def SelectSeries(self, pubsub_evt):
... ...
invesalius/gui/language_dialog.py
... ... @@ -20,7 +20,10 @@
20 20 import os
21 21 import sys
22 22 import wx
23   -import wx.combo
  23 +try:
  24 + from wx.adv import BitmapComboBox
  25 +except ImportError:
  26 + from wx.combo import BitmapComboBox
24 27  
25 28 import invesalius.i18n as i18n
26 29  
... ... @@ -62,7 +65,7 @@ class ComboBoxLanguage:
62 65 selection = self.locales_key.index('en')
63 66  
64 67 # Create bitmap combo
65   - self.bitmapCmb = bitmapCmb = wx.combo.BitmapComboBox(parent, style=wx.CB_READONLY)
  68 + self.bitmapCmb = bitmapCmb = BitmapComboBox(parent, style=wx.CB_READONLY)
66 69 for key in self.locales_key:
67 70 # Based on composed flag filename, get bitmap
68 71 filepath = os.path.join(ICON_DIR, "%s.bmp"%(key))
... ... @@ -114,7 +117,7 @@ class LanguageDialog(wx.Dialog):
114 117 # selection = self.locales_key.index('en')
115 118  
116 119 # # Create bitmap combo
117   - # self.bitmapCmb = bitmapCmb = wx.combo.BitmapComboBox(self, style=wx.CB_READONLY)
  120 + # self.bitmapCmb = bitmapCmb = BitmapComboBox(self, style=wx.CB_READONLY)
118 121 # for key in self.locales_key:
119 122 # # Based on composed flag filename, get bitmap
120 123 # filepath = os.path.join(ICON_DIR, "%s.bmp"%(key))
... ...
invesalius/gui/preferences.py
... ... @@ -17,11 +17,15 @@ class Preferences(wx.Dialog):
17 17 def __init__( self, parent, id = ID, title = _("Preferences"), size=wx.DefaultSize,\
18 18 pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE):
19 19  
20   - pre = wx.PreDialog()
21   - pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
22   - pre.Create(parent, ID, title, pos, size, style)
23   -
24   - self.PostCreate(pre)
  20 + try:
  21 + pre = wx.PreDialog()
  22 + pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
  23 + pre.Create(parent, ID, title, pos, size, style)
  24 + self.PostCreate(pre)
  25 + except AttributeError:
  26 + wx.Dialog.__init__(self)
  27 + self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
  28 + self.Create(parent, ID, title, pos, size, style)
25 29  
26 30 sizer = wx.BoxSizer(wx.VERTICAL)
27 31  
... ... @@ -55,7 +59,7 @@ class Preferences(wx.Dialog):
55 59  
56 60 btnsizer.Realize()
57 61  
58   - sizer.AddSizer(btnsizer, 10, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP|wx.BOTTOM, 5)
  62 + sizer.Add(btnsizer, 10, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP|wx.BOTTOM, 5)
59 63  
60 64 self.SetSizer(sizer)
61 65 sizer.Fit(self)
... ...
invesalius/gui/task_exporter.py
... ... @@ -21,7 +21,10 @@ import os
21 21 import sys
22 22  
23 23 import wx
24   -import wx.lib.hyperlink as hl
  24 +try:
  25 + from wx.lib.agw import hyperlink as hl
  26 +except ImportError:
  27 + import wx.lib.hyperlink as hl
25 28 import wx.lib.platebtn as pbtn
26 29 from wx.lib.pubsub import pub as Publisher
27 30  
... ...
invesalius/gui/task_importer.py
... ... @@ -20,7 +20,10 @@ import os
20 20 import sys
21 21  
22 22 import wx
23   -import wx.lib.hyperlink as hl
  23 +try:
  24 + from wx.lib.agw import hyperlink as hl
  25 +except ImportError:
  26 + import wx.lib.hyperlink as hl
24 27 import wx.lib.platebtn as pbtn
25 28 from wx.lib.pubsub import pub as Publisher
26 29  
... ...
invesalius/gui/task_navigator.py
... ... @@ -22,7 +22,10 @@ import sys
22 22  
23 23 import numpy as np
24 24 import wx
25   -import wx.lib.hyperlink as hl
  25 +try:
  26 + from wx.lib.agw import hyperlink as hl
  27 +except ImportError:
  28 + import wx.lib.hyperlink as hl
26 29 import wx.lib.masked.numctrl
27 30 from wx.lib.pubsub import pub as Publisher
28 31  
... ...
invesalius/gui/task_slice.py
... ... @@ -21,10 +21,18 @@ import sys
21 21 import os
22 22  
23 23 import wx
24   -import wx.lib.hyperlink as hl
  24 +try:
  25 + from wx.lib.agw import hyperlink as hl
  26 +except ImportError:
  27 + import wx.lib.hyperlink as hl
25 28 import wx.lib.platebtn as pbtn
26 29 from wx.lib.pubsub import pub as Publisher
27 30  
  31 +try:
  32 + SystemSettings_GetColour = wx.SystemSettings.GetColour
  33 +except AttributeError:
  34 + SystemSettings_GetColour = wx.SystemSettings_GetColour
  35 +
28 36 import invesalius.data.mask as mask
29 37 import invesalius.data.slice_ as slice_
30 38 import invesalius.constants as const
... ... @@ -108,7 +116,7 @@ class InnerTaskPanel(wx.Panel):
108 116 #print wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
109 117 #print wx.SystemSettings_GetColour(wx.SYS_COLOUR_SCROLLBAR)
110 118 #print wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUHILIGHT)
111   - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
  119 + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
112 120 fold_panel = FoldPanel(self)
113 121 fold_panel.SetBackgroundColour(default_colour)
114 122 self.fold_panel = fold_panel
... ... @@ -134,7 +142,7 @@ class InnerTaskPanel(wx.Panel):
134 142 main_sizer = wx.BoxSizer(wx.VERTICAL)
135 143 main_sizer.Add(line_new, 0,wx.GROW|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5)
136 144 main_sizer.Add(fold_panel, 1, wx.GROW|wx.EXPAND|wx.ALL, 5)
137   - main_sizer.AddSizer(line_sizer, 0, wx.GROW|wx.EXPAND)
  145 + main_sizer.Add(line_sizer, 0, wx.GROW|wx.EXPAND)
138 146 main_sizer.AddSpacer(5)
139 147 main_sizer.Fit(self)
140 148  
... ... @@ -229,7 +237,7 @@ class FoldPanel(wx.Panel):
229 237 class InnerFoldPanel(wx.Panel):
230 238 def __init__(self, parent):
231 239 wx.Panel.__init__(self, parent)
232   - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
  240 + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
233 241 self.SetBackgroundColour(default_colour)
234 242  
235 243 # Fold panel and its style settings
... ... @@ -643,7 +651,7 @@ class MaskProperties(wx.Panel):
643 651 class EditionTools(wx.Panel):
644 652 def __init__(self, parent):
645 653 wx.Panel.__init__(self, parent)
646   - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
  654 + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
647 655 self.SetBackgroundColour(default_colour)
648 656  
649 657 ## LINE 1
... ... @@ -807,7 +815,7 @@ class EditionTools(wx.Panel):
807 815 class WatershedTool(EditionTools):
808 816 def __init__(self, parent):
809 817 wx.Panel.__init__(self, parent)
810   - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
  818 + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
811 819 self.SetBackgroundColour(default_colour)
812 820  
813 821 ## LINE 1
... ...
invesalius/gui/task_surface.py
... ... @@ -20,9 +20,17 @@ import sys
20 20 import os
21 21  
22 22 import wx
23   -import wx.lib.hyperlink as hl
  23 +try:
  24 + from wx.lib.agw import hyperlink as hl
  25 +except ImportError:
  26 + import wx.lib.hyperlink as hl
24 27 from wx.lib.pubsub import pub as Publisher
25 28  
  29 +try:
  30 + SystemSettings_GetColour = wx.SystemSettings.GetColour
  31 +except AttributeError:
  32 + SystemSettings_GetColour = wx.SystemSettings_GetColour
  33 +
26 34 import invesalius.constants as const
27 35 import invesalius.data.slice_ as slice_
28 36 import invesalius.gui.dialogs as dlg
... ... @@ -195,7 +203,7 @@ class FoldPanel(wx.Panel):
195 203 class InnerFoldPanel(wx.Panel):
196 204 def __init__(self, parent):
197 205 wx.Panel.__init__(self, parent)
198   - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
  206 + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
199 207 self.SetBackgroundColour(default_colour)
200 208  
201 209 # Fold panel and its style settings
... ... @@ -264,7 +272,7 @@ BTN_SEEDS = wx.NewId()
264 272 class SurfaceTools(wx.Panel):
265 273 def __init__(self, parent):
266 274 wx.Panel.__init__(self, parent)
267   - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
  275 + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
268 276 self.SetBackgroundColour(default_colour)
269 277  
270 278 #self.SetBackgroundColour(wx.Colour(255,255,255))
... ... @@ -398,7 +406,7 @@ class SurfaceTools(wx.Panel):
398 406 class SurfaceProperties(wx.Panel):
399 407 def __init__(self, parent):
400 408 wx.Panel.__init__(self, parent)
401   - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
  409 + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
402 410 self.SetBackgroundColour(default_colour)
403 411  
404 412 self.surface_list = []
... ... @@ -559,7 +567,7 @@ class QualityAdjustment(wx.Panel):
559 567 def __init__(self, parent):
560 568 import invesalius.constants as const
561 569 wx.Panel.__init__(self, parent)
562   - default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
  570 + default_colour = SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR)
563 571 self.SetBackgroundColour(default_colour)
564 572  
565 573 # LINE 1
... ...
invesalius/gui/task_tools.py
... ... @@ -20,7 +20,10 @@
20 20 import wx
21 21 import os
22 22 import wx.lib.embeddedimage as emb
23   -import wx.lib.hyperlink as hl
  23 +try:
  24 + from wx.lib.agw import hyperlink as hl
  25 +except ImportError:
  26 + import wx.lib.hyperlink as hl
24 27 import wx.lib.platebtn as pbtn
25 28 from wx.lib.pubsub import pub as Publisher
26 29  
... ...
invesalius/gui/widgets/gradient.py
... ... @@ -121,8 +121,11 @@ class GradientSlider(wx.Panel):
121 121 dc.GradientFillLinear((x_init_gradient, y_init_gradient,
122 122 width_gradient, height_gradient),
123 123 (0, 0, 0), (255,255, 255))
124   -
125   - n = wx.RendererNative_Get()
  124 +
  125 + try:
  126 + n = wx.RendererNative.Get()
  127 + except AttributeError:
  128 + n = wx.RendererNative_Get()
126 129  
127 130 # Drawing the push buttons
128 131 n.DrawPushButton(self, dc, (x_init_push1, 0, PUSH_WIDTH, h))
... ...