Commit eed9bb86cef64a2954b61b39d1e27d72e693626b

Authored by Paulo Henrique Junqueira Amorim
1 parent e238e3ae

FIX: Color selection problem in win64 FIX:102

.gitattributes
@@ -140,6 +140,7 @@ invesalius/gui/task_surface.py -text @@ -140,6 +140,7 @@ invesalius/gui/task_surface.py -text
140 invesalius/gui/task_tools.py -text 140 invesalius/gui/task_tools.py -text
141 invesalius/gui/widgets/__init__.py -text 141 invesalius/gui/widgets/__init__.py -text
142 invesalius/gui/widgets/clut_raycasting.py -text 142 invesalius/gui/widgets/clut_raycasting.py -text
  143 +invesalius/gui/widgets/colourselect.py -text
143 invesalius/gui/widgets/foldpanelbar.py -text 144 invesalius/gui/widgets/foldpanelbar.py -text
144 invesalius/gui/widgets/gradient.py -text 145 invesalius/gui/widgets/gradient.py -text
145 invesalius/gui/widgets/listctrl.py -text 146 invesalius/gui/widgets/listctrl.py -text
invesalius/gui/default_viewers.py
@@ -301,8 +301,9 @@ class VolumeInteraction(wx.Panel): @@ -301,8 +301,9 @@ class VolumeInteraction(wx.Panel):
301 import wx.lib.platebtn as pbtn 301 import wx.lib.platebtn as pbtn
302 import wx.lib.buttons as btn 302 import wx.lib.buttons as btn
303 import wx.lib.pubsub as ps 303 import wx.lib.pubsub as ps
304 -import wx.lib.colourselect as csel 304 +
305 import constants as const 305 import constants as const
  306 +import widgets.colourselect as csel
306 307
307 [BUTTON_RAYCASTING, BUTTON_VIEW, BUTTON_SLICE_PLANE] = [wx.NewId() for num in xrange(3)] 308 [BUTTON_RAYCASTING, BUTTON_VIEW, BUTTON_SLICE_PLANE] = [wx.NewId() for num in xrange(3)]
308 RAYCASTING_TOOLS = wx.NewId() 309 RAYCASTING_TOOLS = wx.NewId()
@@ -345,7 +346,7 @@ class VolumeToolPanel(wx.Panel): @@ -345,7 +346,7 @@ class VolumeToolPanel(wx.Panel):
345 button_slice_plane = self.button_slice_plane = pbtn.PlateButton(self, BUTTON_SLICE_PLANE,"", 346 button_slice_plane = self.button_slice_plane = pbtn.PlateButton(self, BUTTON_SLICE_PLANE,"",
346 BMP_SLICE_PLANE, style=pbtn.PB_STYLE_SQUARE, 347 BMP_SLICE_PLANE, style=pbtn.PB_STYLE_SQUARE,
347 size=(24,24)) 348 size=(24,24))
348 - 349 +
349 self.button_raycasting = button_raycasting 350 self.button_raycasting = button_raycasting
350 351
351 # VOLUME VIEW ANGLE BUTTON 352 # VOLUME VIEW ANGLE BUTTON
@@ -402,7 +403,7 @@ class VolumeToolPanel(wx.Panel): @@ -402,7 +403,7 @@ class VolumeToolPanel(wx.Panel):
402 403
403 def OnButtonView(self, evt): 404 def OnButtonView(self, evt):
404 self.button_view.PopupMenu(self.menu_view) 405 self.button_view.PopupMenu(self.menu_view)
405 - 406 +
406 def OnButtonSlicePlane(self, evt): 407 def OnButtonSlicePlane(self, evt):
407 self.button_slice_plane.PopupMenu(self.slice_plane_menu) 408 self.button_slice_plane.PopupMenu(self.slice_plane_menu)
408 409
@@ -455,21 +456,21 @@ class VolumeToolPanel(wx.Panel): @@ -455,21 +456,21 @@ class VolumeToolPanel(wx.Panel):
455 menu.AppendItem(item) 456 menu.AppendItem(item)
456 menu.Bind(wx.EVT_MENU, self.OnMenuView) 457 menu.Bind(wx.EVT_MENU, self.OnMenuView)
457 self.menu_view = menu 458 self.menu_view = menu
458 - 459 +
459 #SLICE PLANES BUTTON 460 #SLICE PLANES BUTTON
460 self.slice_plane_menu = slice_plane_menu = wx.Menu() 461 self.slice_plane_menu = slice_plane_menu = wx.Menu()
461 itens = ["Axial", "Coronal", "Sagital"] 462 itens = ["Axial", "Coronal", "Sagital"]
462 - 463 +
463 for value in itens: 464 for value in itens:
464 new_id = wx.NewId() 465 new_id = wx.NewId()
465 -  
466 - item = wx.MenuItem(slice_plane_menu, new_id, value, 466 +
  467 + item = wx.MenuItem(slice_plane_menu, new_id, value,
467 kind = wx.ITEM_CHECK) 468 kind = wx.ITEM_CHECK)
468 ID_TO_ITEMSLICEMENU[new_id] = item 469 ID_TO_ITEMSLICEMENU[new_id] = item
469 slice_plane_menu.AppendItem(item) 470 slice_plane_menu.AppendItem(item)
470 - 471 +
471 slice_plane_menu.Bind(wx.EVT_MENU, self.OnMenuPlaneSlice) 472 slice_plane_menu.Bind(wx.EVT_MENU, self.OnMenuPlaneSlice)
472 - 473 +
473 self.Fit() 474 self.Fit()
474 self.Update() 475 self.Update()
475 476
@@ -479,20 +480,20 @@ class VolumeToolPanel(wx.Panel): @@ -479,20 +480,20 @@ class VolumeToolPanel(wx.Panel):
479 presets += [filename.split(".")[0] for filename in 480 presets += [filename.split(".")[0] for filename in
480 os.listdir(folder) if 481 os.listdir(folder) if
481 os.path.isfile(os.path.join(folder,filename))] 482 os.path.isfile(os.path.join(folder,filename))]
482 - 483 +
483 def OnMenuPlaneSlice(self, evt): 484 def OnMenuPlaneSlice(self, evt):
484 - 485 +
485 id = evt.GetId() 486 id = evt.GetId()
486 item = ID_TO_ITEMSLICEMENU[id] 487 item = ID_TO_ITEMSLICEMENU[id]
487 checked = item.IsChecked() 488 checked = item.IsChecked()
488 label = item.GetLabel() 489 label = item.GetLabel()
489 - 490 +
490 if not (checked): 491 if not (checked):
491 ps.Publisher().sendMessage('Disable plane', label) 492 ps.Publisher().sendMessage('Disable plane', label)
492 else: 493 else:
493 ps.Publisher().sendMessage('Enable plane', label) 494 ps.Publisher().sendMessage('Enable plane', label)
494 495
495 - 496 +
496 def ChangeButtonColour(self, pubsub_evt): 497 def ChangeButtonColour(self, pubsub_evt):
497 colour = [i*255 for i in pubsub_evt.data] 498 colour = [i*255 for i in pubsub_evt.data]
498 self.button_colour.SetColour(colour) 499 self.button_colour.SetColour(colour)
invesalius/gui/task_slice.py
@@ -20,7 +20,6 @@ @@ -20,7 +20,6 @@
20 import sys 20 import sys
21 21
22 import wx 22 import wx
23 -import wx.lib.colourselect as csel  
24 import wx.lib.hyperlink as hl 23 import wx.lib.hyperlink as hl
25 import wx.lib.platebtn as pbtn 24 import wx.lib.platebtn as pbtn
26 import wx.lib.pubsub as ps 25 import wx.lib.pubsub as ps
@@ -29,6 +28,8 @@ import data.mask as mask @@ -29,6 +28,8 @@ import data.mask as mask
29 import constants as const 28 import constants as const
30 import gui.widgets.gradient as grad 29 import gui.widgets.gradient as grad
31 import gui.widgets.foldpanelbar as fpb 30 import gui.widgets.foldpanelbar as fpb
  31 +import widgets.colourselect as csel
  32 +
32 from project import Project 33 from project import Project
33 34
34 BTN_NEW = wx.NewId() 35 BTN_NEW = wx.NewId()
@@ -207,7 +208,7 @@ class InnerFoldPanel(wx.Panel): @@ -207,7 +208,7 @@ class InnerFoldPanel(wx.Panel):
207 leftSpacing=0, rightSpacing=0) 208 leftSpacing=0, rightSpacing=0)
208 self.__id_editor = item.GetId() 209 self.__id_editor = item.GetId()
209 self.last_panel_opened = None 210 self.last_panel_opened = None
210 - 211 +
211 #fold_panel.Expand(fold_panel.GetFoldPanel(1)) 212 #fold_panel.Expand(fold_panel.GetFoldPanel(1))
212 213
213 # Panel sizer to expand fold panel 214 # Panel sizer to expand fold panel
@@ -226,15 +227,15 @@ class InnerFoldPanel(wx.Panel): @@ -226,15 +227,15 @@ class InnerFoldPanel(wx.Panel):
226 227
227 def __bind_evt(self): 228 def __bind_evt(self):
228 self.fold_panel.Bind(fpb.EVT_CAPTIONBAR, self.OnFoldPressCaption) 229 self.fold_panel.Bind(fpb.EVT_CAPTIONBAR, self.OnFoldPressCaption)
229 - 230 +
230 def __bind_pubsub_evt(self): 231 def __bind_pubsub_evt(self):
231 ps.Publisher().subscribe(self.OnRetrieveStyle, 'Retrieve task slice style') 232 ps.Publisher().subscribe(self.OnRetrieveStyle, 'Retrieve task slice style')
232 ps.Publisher().subscribe(self.OnDisableStyle, 'Disable task slice style') 233 ps.Publisher().subscribe(self.OnDisableStyle, 'Disable task slice style')
233 - 234 +
234 def OnFoldPressCaption(self, evt): 235 def OnFoldPressCaption(self, evt):
235 id = evt.GetTag().GetId() 236 id = evt.GetTag().GetId()
236 closed = evt.GetFoldStatus() 237 closed = evt.GetFoldStatus()
237 - 238 +
238 if self.__id_editor == id: 239 if self.__id_editor == id:
239 if closed: 240 if closed:
240 ps.Publisher().sendMessage('Disable style', const.SLICE_STATE_EDITOR) 241 ps.Publisher().sendMessage('Disable style', const.SLICE_STATE_EDITOR)
@@ -245,7 +246,7 @@ class InnerFoldPanel(wx.Panel): @@ -245,7 +246,7 @@ class InnerFoldPanel(wx.Panel):
245 else: 246 else:
246 ps.Publisher().sendMessage('Disable style', const.SLICE_STATE_EDITOR) 247 ps.Publisher().sendMessage('Disable style', const.SLICE_STATE_EDITOR)
247 self.last_style = None 248 self.last_style = None
248 - 249 +
249 evt.Skip() 250 evt.Skip()
250 251
251 def OnRetrieveStyle(self, pubsub_evt): 252 def OnRetrieveStyle(self, pubsub_evt):
@@ -344,7 +345,7 @@ class MaskProperties(wx.Panel): @@ -344,7 +345,7 @@ class MaskProperties(wx.Panel):
344 n = self.combo_thresh.GetCount() 345 n = self.combo_thresh.GetCount()
345 for i in xrange(n-1, -1, -1): 346 for i in xrange(n-1, -1, -1):
346 self.combo_thresh.Delete(i) 347 self.combo_thresh.Delete(i)
347 - 348 +
348 349
349 def __bind_events_wx(self): 350 def __bind_events_wx(self):
350 self.Bind(grad.EVT_THRESHOLD_CHANGE, self.OnSlideChanged, self.gradient) 351 self.Bind(grad.EVT_THRESHOLD_CHANGE, self.OnSlideChanged, self.gradient)
@@ -397,7 +398,7 @@ class MaskProperties(wx.Panel): @@ -397,7 +398,7 @@ class MaskProperties(wx.Panel):
397 else: 398 else:
398 self.combo_thresh.SetSelection(3) 399 self.combo_thresh.SetSelection(3)
399 thresh_min, thresh_max = default_thresh 400 thresh_min, thresh_max = default_thresh
400 - 401 +
401 self.gradient.SetMinValue(thresh_min) 402 self.gradient.SetMinValue(thresh_min)
402 self.gradient.SetMaxValue(thresh_max) 403 self.gradient.SetMaxValue(thresh_max)
403 404
invesalius/gui/task_surface.py
@@ -19,12 +19,12 @@ @@ -19,12 +19,12 @@
19 import sys 19 import sys
20 20
21 import wx 21 import wx
22 -import wx.lib.colourselect as csel  
23 import wx.lib.hyperlink as hl 22 import wx.lib.hyperlink as hl
24 import wx.lib.platebtn as pbtn 23 import wx.lib.platebtn as pbtn
25 import wx.lib.pubsub as ps 24 import wx.lib.pubsub as ps
26 25
27 import gui.widgets.foldpanelbar as fpb 26 import gui.widgets.foldpanelbar as fpb
  27 +import widgets.colourselect as csel
28 28
29 #INTERPOLATION_MODE_LIST = ["Cubic", "Linear", "NearestNeighbor"] 29 #INTERPOLATION_MODE_LIST = ["Cubic", "Linear", "NearestNeighbor"]
30 QUALITY_LIST = [_("Low"), _("Medium"), _("High"), _("Optimal *"), _("Custom")] 30 QUALITY_LIST = [_("Low"), _("Medium"), _("High"), _("Optimal *"), _("Custom")]
invesalius/gui/widgets/colourselect.py 0 → 100644
@@ -0,0 +1,176 @@ @@ -0,0 +1,176 @@
  1 +#----------------------------------------------------------------------------
  2 +# Name: ColourSelect.py
  3 +# Purpose: Colour Box Selection Control
  4 +#
  5 +# Author: Lorne White, Lorne.White@telusplanet.net
  6 +#
  7 +# Created: Feb 25, 2001
  8 +# Licence: wxWindows license
  9 +#----------------------------------------------------------------------------
  10 +
  11 +# creates a colour wxButton with selectable color
  12 +# button click provides a colour selection box
  13 +# button colour will change to new colour
  14 +# GetColour method to get the selected colour
  15 +
  16 +# Updates:
  17 +# call back to function if changes made
  18 +
  19 +# Cliff Wells, logiplexsoftware@earthlink.net:
  20 +# - Made ColourSelect into "is a button" rather than "has a button"
  21 +# - Added label parameter and logic to adjust the label colour according to the background
  22 +# colour
  23 +# - Added id argument
  24 +# - Rearranged arguments to more closely follow wx conventions
  25 +# - Simplified some of the code
  26 +
  27 +# Cliff Wells, 2002/02/07
  28 +# - Added ColourSelect Event
  29 +
  30 +# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net)
  31 +#
  32 +# o Updated for 2.5 compatability.
  33 +#
  34 +
  35 +"""
  36 +Provides a `ColourSelect` button that, when clicked, will display a
  37 +colour selection dialog. The selected colour is displayed on the
  38 +button itself.
  39 +"""
  40 +
  41 +#----------------------------------------------------------------------------
  42 +
  43 +import wx
  44 +
  45 +#----------------------------------------------------------------------------
  46 +
  47 +wxEVT_COMMAND_COLOURSELECT = wx.NewEventType()
  48 +
  49 +class ColourSelectEvent(wx.PyCommandEvent):
  50 + def __init__(self, id, value):
  51 + wx.PyCommandEvent.__init__(self, id = id)
  52 + self.SetEventType(wxEVT_COMMAND_COLOURSELECT)
  53 + self.value = value
  54 +
  55 + def GetValue(self):
  56 + return self.value
  57 +
  58 +EVT_COLOURSELECT = wx.PyEventBinder(wxEVT_COMMAND_COLOURSELECT, 1)
  59 +
  60 +#----------------------------------------------------------------------------
  61 +
  62 +class ColourSelect(wx.BitmapButton):
  63 + def __init__(self, parent, id=wx.ID_ANY, label="", colour=wx.BLACK,
  64 + pos=wx.DefaultPosition, size=wx.DefaultSize,
  65 + callback=None, style=0):
  66 + if label:
  67 + w, h = parent.GetTextExtent(label)
  68 + w += 6
  69 + h += 6
  70 + else:
  71 + w, h = 20, 20
  72 + wx.BitmapButton.__init__(self, parent, id, wx.EmptyBitmap(w,h),
  73 + pos=pos, size=size, style=style|wx.BU_AUTODRAW)
  74 +
  75 + if type(colour) == type( () ):
  76 + colour = wx.Colour(*colour)
  77 + self.colour = colour
  78 + self.SetLabel(label)
  79 + self.callback = callback
  80 + bmp = self.MakeBitmap()
  81 + self.SetBitmap(bmp)
  82 + parent.Bind(wx.EVT_BUTTON, self.OnClick, self)
  83 +
  84 +
  85 + def GetColour(self):
  86 + return self.colour
  87 +
  88 + def GetValue(self):
  89 + return self.colour
  90 +
  91 + def SetValue(self, colour):
  92 + self.SetColour(colour)
  93 +
  94 + def SetColour(self, colour):
  95 + if type(colour) == tuple:
  96 + colour = wx.Colour(*colour)
  97 + if type(colour) == str:
  98 + colour = wx.NamedColour(colour)
  99 +
  100 + self.colour = colour
  101 + bmp = self.MakeBitmap()
  102 + self.SetBitmap(bmp)
  103 +
  104 +
  105 + def SetLabel(self, label):
  106 + self.label = label
  107 +
  108 + def GetLabel(self):
  109 + return self.label
  110 +
  111 +
  112 + def MakeBitmap(self):
  113 + bdr = 8
  114 + width, height = self.GetSize()
  115 +
  116 + # yes, this is weird, but it appears to work around a bug in wxMac
  117 + if "wxMac" in wx.PlatformInfo and width == height:
  118 + height -= 1
  119 +
  120 + bmp = wx.EmptyBitmap(width-bdr, height-bdr)
  121 + dc = wx.MemoryDC()
  122 + dc.SelectObject(bmp)
  123 + dc.SetFont(self.GetFont())
  124 + label = self.GetLabel()
  125 + # Just make a little colored bitmap
  126 + dc.SetBackground(wx.Brush(self.colour))
  127 + dc.Clear()
  128 +
  129 + if label:
  130 + # Add a label to it
  131 + avg = reduce(lambda a, b: a + b, self.colour.Get()) / 3
  132 + fcolour = avg > 128 and wx.BLACK or wx.WHITE
  133 + dc.SetTextForeground(fcolour)
  134 + dc.DrawLabel(label, (0,0, width-bdr, height-bdr),
  135 + wx.ALIGN_CENTER)
  136 +
  137 + dc.SelectObject(wx.NullBitmap)
  138 + return bmp
  139 +
  140 +
  141 + def SetBitmap(self, bmp):
  142 + self.SetBitmapLabel(bmp)
  143 + #self.SetBitmapSelected(bmp)
  144 + #self.SetBitmapDisabled(bmp)
  145 + #self.SetBitmapFocus(bmp)
  146 + #self.SetBitmapSelected(bmp)
  147 + self.Refresh()
  148 +
  149 +
  150 + def OnChange(self):
  151 + evt = ColourSelectEvent(self.GetId(), self.GetValue())
  152 + evt.SetEventObject(self)
  153 + wx.PostEvent(self, evt)
  154 + if self.callback is not None:
  155 + self.callback()
  156 +
  157 + def OnClick(self, event):
  158 + data = wx.ColourData()
  159 + data.SetChooseFull(True)
  160 + data.SetColour(self.colour)
  161 + dlg = wx.ColourDialog(wx.GetTopLevelParent(self), data)
  162 +
  163 + try:
  164 + changed = dlg.ShowModal() == wx.ID_OK
  165 + except(wx._core.PyAssertionError):
  166 + changed = True
  167 +
  168 + if changed:
  169 + data = dlg.GetColourData()
  170 + self.SetColour(data.GetColour())
  171 + dlg.Destroy()
  172 +
  173 + # moved after dlg.Destroy, since who knows what the callback will do...
  174 + if changed:
  175 + self.OnChange()
  176 +