Commit 16a741dedefd74ed919a4e7c1aa1edb501002079

Authored by tfmoraes
1 parent 1a0875bc

ENH: Starting the sync between the treecontrol and preview

invesalius/gui/dicom_preview_panel.py
... ... @@ -47,6 +47,49 @@ STR_LOCAL = _("Location: %.2f")
47 47 STR_PATIENT = "%s\n%s"
48 48 STR_ACQ = _("%s %s\nMade in InVesalius")
49 49  
  50 +myEVT_PREVIEW_CLICK = wx.NewEventType()
  51 +EVT_PREVIEW_CLICK = wx.PyEventBinder(myEVT_PREVIEW_CLICK, 1)
  52 +
  53 +myEVT_PREVIEW_DBLCLICK = wx.NewEventType()
  54 +EVT_PREVIEW_DBLCLICK = wx.PyEventBinder(myEVT_PREVIEW_DBLCLICK, 1)
  55 +
  56 +myEVT_CLICK_SLICE = wx.NewEventType()
  57 +# This event occurs when the user select a preview
  58 +EVT_CLICK_SLICE = wx.PyEventBinder(myEVT_CLICK_SLICE, 1)
  59 +
  60 +myEVT_CLICK_SERIE = wx.NewEventType()
  61 +# This event occurs when the user select a preview
  62 +EVT_CLICK_SERIE = wx.PyEventBinder(myEVT_CLICK_SERIE, 1)
  63 +
  64 +myEVT_CLICK = wx.NewEventType()
  65 +EVT_CLICK = wx.PyEventBinder(myEVT_CLICK, 1)
  66 +
  67 +class SelectionEvent(wx.PyCommandEvent):
  68 + pass
  69 +
  70 +
  71 +class PreviewEvent(wx.PyCommandEvent):
  72 + def __init__(self , evtType, id):
  73 + super(PreviewEvent, self).__init__(evtType, id)
  74 +
  75 + def GetSelectID(self):
  76 + return self.SelectedID
  77 +
  78 + def SetSelectedID(self, id):
  79 + self.SelectedID = id
  80 +
  81 + def GetItemData(self):
  82 + return self.data
  83 +
  84 + def SetItemData(self, data):
  85 + self.data = data
  86 +
  87 +
  88 +class SerieEvent(PreviewEvent):
  89 + def __init__(self , evtType, id):
  90 + super(SerieEvent, self).__init__(evtType, id)
  91 +
  92 +
50 93 class DicomInfo(object):
51 94 """
52 95 Keep the informations and the image used by preview.
... ... @@ -57,25 +100,14 @@ class DicomInfo(object):
57 100 self.title = title
58 101 self.subtitle = subtitle
59 102 self._preview = None
60   - self._size = (70, 70)
61 103 self.selected = False
62   - self.resized = False
63   -
64   - @property
65   - def size(self):
66   - return self._size
67   -
68   - @size.setter
69   - def size(self, size):
70   - if size != self._size:
71   - self._size = size
72   - self.resized = True
73 104  
74 105 @property
75 106 def preview(self):
76 107 if self._preview:
77 108 return self._preview
78 109 else:
  110 + print "First time!"
79 111 colorer = vtk.vtkImageMapToWindowLevelColors()
80 112 colorer.SetInput(self.dicom.image.imagedata)
81 113 colorer.SetWindow(float(self.dicom.image.window))
... ... @@ -118,7 +150,6 @@ class DicomPaintPanel(wx.Panel):
118 150 else:
119 151 return image.Scale(*self.last_size)
120 152  
121   -
122 153 def SetImage(self, image):
123 154 self.image = image
124 155 r_img = self._image_resize(image)
... ... @@ -193,10 +224,9 @@ class Preview(wx.Panel):
193 224 #self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
194 225  
195 226 self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
196   - #self.interactor.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
197   - #self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
198   - #self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
199   - #self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
  227 + self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
  228 + self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
  229 + self.image_viewer.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
200 230  
201 231 #self.Bind(wx.EVT_SIZE, self.OnSize)
202 232  
... ... @@ -252,6 +282,13 @@ class Preview(wx.Panel):
252 282 #self.SetBackgroundColour(c)
253 283 self.Select()
254 284  
  285 + # Generating a EVT_PREVIEW_CLICK event
  286 + my_evt = SerieEvent(myEVT_PREVIEW_CLICK, self.GetId())
  287 + my_evt.SetSelectedID(self.dicom_info.id)
  288 + my_evt.SetItemData(self.dicom_info.dicom)
  289 + print "patient", self.dicom_info.dicom.patient
  290 + self.GetEventHandler().ProcessEvent(my_evt)
  291 +
255 292 def OnSize(self, evt):
256 293 if self.dicom_info:
257 294 self.SetDicomToPreview(self.dicom_info)
... ... @@ -266,313 +303,10 @@ class Preview(wx.Panel):
266 303 self.Refresh()
267 304  
268 305 def OnDClick(self, evt):
269   - evt = PreviewEvent(myEVT_SELECT, self.GetId())
270   - evt.SetSelectedID(self.ID)
271   - evt.SetItemData(self.data)
272   - self.GetEventHandler().ProcessEvent(evt)
273   -
274   - def ShowShadow(self):
275   - self._nImgSize = 16
276   - nPadding = 4
277   - print "ShowShadow"
278   - dc = wx.BufferedPaintDC(self)
279   - style = self.GetParent().GetWindowStyleFlag()
280   -
281   - backBrush = wx.WHITE_BRUSH
282   - if 1: #style & INB_BORDER:
283   - borderPen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW))
284   - #else:
285   - # borderPen = wx.TRANSPARENT_PEN
286   -
287   - size = self.GetSize()
288   -
289   - # Background
290   - dc.SetBrush(backBrush)
291   -
292   - borderPen.SetWidth(1)
293   - dc.SetPen(borderPen)
294   - dc.DrawRectangle(0, 0, size.x, size.y)
295   - #bUsePin = (style & INB_USE_PIN_BUTTON and [True] or [False])[0]
296   -
297   - borderPen = wx.BLACK_PEN
298   - borderPen.SetWidth(1)
299   - dc.SetPen(borderPen)
300   - dc.DrawLine(0, size.y, size.x, size.y)
301   - dc.DrawPoint(0, size.y)
302   -
303   - clientSize = 0
304   - #bUseYcoord = (style & INB_RIGHT or style & INB_LEFT)
305   - bUseYcoord = 1
306   -
307   - if bUseYcoord:
308   - clientSize = size.GetHeight()
309   - else:
310   - clientSize = size.GetWidth()
311   -
312   - if 1:
313   - # Default values for the surronounding rectangle
314   - # around a button
315   - rectWidth = self._nImgSize * 2 # To avoid the recangle to 'touch' the borders
316   - rectHeight = self._nImgSize * 2
317   -
318   - # Incase the style requires non-fixed button (fit to text)
319   - # recalc the rectangle width
320   - if 1:
321   - #if style & INB_FIT_BUTTON and \
322   - # not ((style & INB_LEFT) or (style & INB_RIGHT)) and \
323   - # not self._pagesInfoVec[i].GetCaption() == "" and \
324   - # not (style & INB_SHOW_ONLY_IMAGES):
325   -
326   -
327   - #rectWidth = ((textWidth + nPadding * 2) > rectWidth and [nPadding * 2 + textWidth] or [rectWidth])[0]
328   -
329   - rectWidth = ((nPadding * 2) > rectWidth and [nPadding * 2] or [rectWidth])[0]
330   - # Make the width an even number
331   - if rectWidth % 2 != 0:
332   - rectWidth += 1
333   -
334   - # If Pin button is used, consider its space as well (applicable for top/botton style)
335   - # since in the left/right, its size is already considered in 'pos'
336   - #pinBtnSize = (bUsePin and [20] or [0])[0]
337   -
338   - #if pos + rectWidth + pinBtnSize > clientSize:
339   - # break
340   -
341   - # Calculate the button rectangle
342   - modRectWidth = rectWidth - 2# or [rectWidth])[0]
343   - modRectHeight = rectHeight# or [rectHeight - 2])[0]
344   -
345   - pos = rectWidth
346   -
347   - if bUseYcoord:
348   - buttonRect = wx.Rect(1, pos, modRectWidth, modRectHeight)
349   - else:
350   - buttonRect = wx.Rect(pos , 1, modRectWidth, modRectHeight)
351   -
352   - def ShowShadow2(self):
353   - pass
354   -
355   -
356   -class SingleImagePreview(wx.Panel):
357   - def __init__(self, parent):
358   - wx.Panel.__init__(self, parent, -1)
359   - self.__init_gui()
360   - self.__init_vtk()
361   - self.__bind_evt_gui()
362   - self.dicom_list = []
363   - self.nimages = 1
364   - self.current_index = 0
365   - self.window_width = const.WINDOW_LEVEL[_("Bone")][0]
366   - self.window_level = const.WINDOW_LEVEL[_("Bone")][1]
367   -
368   - def __init_vtk(self):
369   - actor = vtk.vtkImageActor()
370   - self.actor = actor
371   -
372   - text_image_size = vtku.Text()
373   - text_image_size.SetPosition(const.TEXT_POS_LEFT_UP)
374   - text_image_size.SetValue(_("image size"))
375   - self.text_image_size = text_image_size
376   -
377   - text_image_location = vtku.Text()
378   - text_image_location.SetVerticalJustificationToBottom()
379   - text_image_location.SetPosition(const.TEXT_POS_LEFT_DOWN)
380   - text_image_location.SetValue("localization")
381   - self.text_image_location = text_image_location
382   -
383   - value = _("id\nprotocol")
384   - text_patient = vtku.Text()
385   - text_patient.SetJustificationToRight()
386   - text_patient.SetPosition(const.TEXT_POS_RIGHT_UP)
387   - text_patient.SetValue(value)
388   - self.text_patient = text_patient
389   -
390   - value = _("date time\n Made in InVesalius")
391   - text_acquisition = vtku.Text()
392   - text_acquisition.SetJustificationToRight()
393   - text_acquisition.SetVerticalJustificationToBottom()
394   - text_acquisition.SetPosition(const.TEXT_POS_RIGHT_DOWN)
395   - text_acquisition.SetValue(value)
396   - self.text_acquisition = text_acquisition
397   -
398   - renderer = vtk.vtkRenderer()
399   - renderer.AddActor(actor)
400   - renderer.AddActor(text_image_size.actor)
401   - renderer.AddActor(text_image_location.actor)
402   - renderer.AddActor(text_patient.actor)
403   - renderer.AddActor(text_acquisition.actor)
404   - self.renderer = renderer
405   -
406   - style = vtk.vtkInteractorStyleImage()
407   -
408   - interactor = wxVTKRenderWindowInteractor(self.panel, -1,
409   - size=wx.Size(340,340))
410   - interactor.GetRenderWindow().AddRenderer(renderer)
411   - interactor.SetInteractorStyle(style)
412   - interactor.Render()
413   - self.interactor = interactor
414   -
415   - sizer = wx.BoxSizer(wx.VERTICAL)
416   - sizer.Add(interactor, 1, wx.GROW|wx.EXPAND)
417   - sizer.Fit(self.panel)
418   - self.panel.SetSizer(sizer)
419   - self.Layout()
420   - self.Update()
421   -
422   -
423   - def __init_gui(self):
424   - self.panel = wx.Panel(self, -1)
425   -
426   - slider = wx.Slider(self,
427   - id=-1,
428   - value=0,
429   - minValue=0,
430   - maxValue=99,
431   - style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS)
432   - slider.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
433   - slider.SetTickFreq(1, 1)
434   - self.slider = slider
435   -
436   - checkbox = wx.CheckBox(self, -1, _("Auto-play"))
437   - self.checkbox = checkbox
438   -
439   - in_sizer = wx.BoxSizer(wx.HORIZONTAL)
440   - in_sizer.Add(slider, 1, wx.GROW|wx.EXPAND)
441   - in_sizer.Add(checkbox, 0)
442   -
443   - sizer = wx.BoxSizer(wx.VERTICAL)
444   - sizer.Add(self.panel, 20, wx.GROW|wx.EXPAND)
445   - sizer.Add(in_sizer, 1, wx.GROW|wx.EXPAND)
446   - sizer.Fit(self)
447   -
448   - self.SetSizer(sizer)
449   - self.Layout()
450   - self.Update()
451   - self.SetAutoLayout(1)
452   -
453   - def __bind_evt_gui(self):
454   - self.slider.Bind(wx.EVT_SLIDER, self.OnSlider)
455   - self.checkbox.Bind(wx.EVT_CHECKBOX, self.OnCheckBox)
456   -
457   - def OnSlider(self, evt):
458   - pos = evt.GetInt()
459   - self.ShowSlice(pos)
460   - evt.Skip()
461   -
462   - def OnCheckBox(self, evt):
463   - self.ischecked = evt.IsChecked()
464   - if evt.IsChecked():
465   - wx.CallAfter(self.OnRun)
466   - evt.Skip()
467   -
468   - def OnRun(self):
469   - pos = self.slider.GetValue()
470   - pos += 1
471   - if not (self.nimages- pos):
472   - pos = 0
473   - self.slider.SetValue(pos)
474   - self.ShowSlice(pos)
475   - time.sleep(0.2)
476   - if self.ischecked:
477   - try:
478   - wx.Yield()
479   - #TODO: temporary fix necessary in the Windows XP 64 Bits
480   - #BUG in wxWidgets http://trac.wxwidgets.org/ticket/10896
481   - except(wx._core.PyAssertionError):
482   - print "wx._core.PyAssertionError"
483   - finally:
484   - wx.CallAfter(self.OnRun)
485   -
486   - def SetDicomGroup(self, group):
487   - self.dicom_list = group.GetHandSortedList()
488   - self.current_index = 0
489   - self.nimages = len(self.dicom_list)
490   - # GUI
491   - self.slider.SetMax(self.nimages-1)
492   - print self.nimages
493   - self.slider.SetValue(0)
494   - self.ShowSlice()
495   -
496   - def ShowSlice(self, index = 0):
497   - print "ShowSlice"
498   - dicom = self.dicom_list[index]
499   -
500   - # UPDATE GUI
501   - ## Text related to size
502   - value = STR_SIZE %(dicom.image.size[0], dicom.image.size[1])
503   - self.text_image_size.SetValue(value)
504   -
505   - ## Text related to slice position
506   - value1 = STR_SPC %(dicom.image.spacing[2])
507   - value2 = STR_LOCAL %(dicom.image.position[2])
508   - value = "%s\n%s" %(value1, value2)
509   - self.text_image_location.SetValue(value)
510   -
511   - ## Text related to patient/ acquisiiton data
512   - value = STR_PATIENT %(dicom.patient.id,\
513   - dicom.acquisition.protocol_name)
514   - self.text_patient.SetValue(value)
515   -
516   - ## Text related to acquisition date and time
517   - value = STR_ACQ % (dicom.acquisition.date,
518   - dicom.acquisition.time)
519   - self.text_acquisition.SetValue(value)
520   -
521   - # READ FILE
522   - #filename = dicom.image.file
523   - #reader = vtkgdcm.vtkGDCMImageReader()
524   - #reader.SetFileName(filename)
525   -
526   - # ADJUST CONTRAST
527   - window_level = dicom.image.level
528   - window_width = dicom.image.window
529   - colorer = vtk.vtkImageMapToWindowLevelColors()
530   - colorer.SetInput(dicom.image.imagedata)
531   - colorer.SetWindow(float(window_width))
532   - colorer.SetLevel(float(window_level))
533   -
534   - # PLOT IMAGE INTO VIEWER
535   - self.actor.SetInput(colorer.GetOutput())
536   - self.renderer.ResetCamera()
537   - self.interactor.Render()
538   -
539   - def __del__(self):
540   - print "---------> morri"
541   -
542   -
543   -
544   -myEVT_SELECT = wx.NewEventType()
545   -# This event occurs when the user select a preview
546   -EVT_SELECT = wx.PyEventBinder(myEVT_SELECT, 1)
547   -
548   -myEVT_SELECT_SERIE = wx.NewEventType()
549   -# This event occurs when the user select a preview
550   -EVT_SELECT_SERIE = wx.PyEventBinder(myEVT_SELECT_SERIE, 1)
551   -
552   -myEVT_CLICK = wx.NewEventType()
553   -EVT_CLICK = wx.PyEventBinder(myEVT_CLICK, 1)
554   -
555   -class PreviewEvent(wx.PyCommandEvent):
556   - def __init__(self , evtType, id):
557   - wx.PyCommandEvent.__init__(self, evtType, id)
558   -
559   - def GetSelectID(self):
560   - return self.SelectedID
561   -
562   - def SetSelectedID(self, id):
563   - self.SelectedID = id
564   -
565   - def GetItemData(self):
566   - return self.data
567   -
568   - def SetItemData(self, data):
569   - self.data = data
570   -
571   -
572   -class SerieEvent(PreviewEvent):
573   - def __init__(self , evtType, id):
574   - super(SerieEvent, self).__init__(evtType, id)
575   -
  306 + my_evt = SerieEvent(myEVT_PREVIEW_DBLCLICK, self.GetId())
  307 + my_evt.SetSelectedID(self.dicom_info.id)
  308 + my_evt.SetItemData(self.dicom_info.dicom)
  309 + self.GetEventHandler().ProcessEvent(my_evt)
576 310  
577 311  
578 312 class DicomPreviewSeries(wx.Panel):
... ... @@ -588,7 +322,6 @@ class DicomPreviewSeries(wx.Panel):
588 322 self._init_ui()
589 323  
590 324 def _init_ui(self):
591   -
592 325 scroll = wx.ScrollBar(self, -1, style=wx.SB_VERTICAL)
593 326 self.scroll = scroll
594 327  
... ... @@ -603,7 +336,6 @@ class DicomPreviewSeries(wx.Panel):
603 336 self.SetSizer(background_sizer)
604 337 background_sizer.Fit(self)
605 338  
606   -
607 339 self.Layout()
608 340 self.Update()
609 341 self.SetAutoLayout(1)
... ... @@ -618,6 +350,7 @@ class DicomPreviewSeries(wx.Panel):
618 350 for i in xrange(NROWS):
619 351 for j in xrange(NCOLS):
620 352 p = Preview(self)
  353 + p.Bind(EVT_PREVIEW_CLICK, self.OnSelect)
621 354 #if (i == j == 0):
622 355 #self._show_shadow(p)
623 356 #p.Hide()
... ... @@ -627,16 +360,15 @@ class DicomPreviewSeries(wx.Panel):
627 360 #def _show_shadow(self, preview):
628 361 # preview.ShowShadow()
629 362  
630   -
631 363 def _bind_events(self):
632 364 # When the user scrolls the window
633 365 self.Bind(wx.EVT_SCROLL, self.OnScroll)
634   - self.Bind(EVT_SELECT, self.OnSelect)
635 366  
636 367 def OnSelect(self, evt):
637   - my_evt = SerieEvent(myEVT_SELECT_SERIE, self.GetId())
  368 + print dir(evt)
  369 + my_evt = SerieEvent(myEVT_CLICK_SERIE, self.GetId())
638 370 my_evt.SetSelectedID(evt.GetSelectID())
639   - my_evt.SetItemData(self.group_list)
  371 + my_evt.SetItemData(evt.GetItemData())
640 372 self.GetEventHandler().ProcessEvent(my_evt)
641 373  
642 374 def SetPatientGroups(self, patient):
... ... @@ -647,14 +379,6 @@ class DicomPreviewSeries(wx.Panel):
647 379 self.group_list = group_list
648 380 n = 0
649 381 for group in group_list:
650   - #info = (group.dicom.image,
651   - # float(group.dicom.image.window),
652   - # float(group.dicom.image.level),
653   - # group.title,
654   - # _("%d Images") %(group.nslices),
655   - # n,
656   - # group_list,
657   - # group.dicom)
658 382 info = DicomInfo(n, group.dicom,
659 383 group.title,
660 384 _("%d Images") %(group.nslices),
... ... @@ -690,8 +414,6 @@ class DicomPreviewSeries(wx.Panel):
690 414 pass
691 415 self.nhidden_last_display = 0
692 416  
693   -
694   -
695 417 for f, p in zip(self.files[initial:final], self.previews):
696 418 #print "f", f
697 419 p.SetDicomToPreview(f)
... ... @@ -700,23 +422,22 @@ class DicomPreviewSeries(wx.Panel):
700 422 for f, p in zip(self.files[initial:final], self.previews):
701 423 p.Show()
702 424  
703   -
704 425 def OnScroll(self, evt):
705 426 if self.displayed_position != evt.GetPosition():
706 427 self.displayed_position = evt.GetPosition()
707 428 self._display_previews()
708 429  
709   -class DicomPreview(wx.Panel):
  430 +
  431 +class DicomPreviewSlice(wx.Panel):
710 432 """A dicom preview panel"""
711 433 def __init__(self, parent):
712   - super(DicomPreview, self).__init__(parent)
  434 + super(DicomPreviewSlice, self).__init__(parent)
713 435 # TODO: 3 pixels between the previews is a good idea?
714 436 # I have to test.
715 437 self.displayed_position = 0
716 438 self.nhidden_last_display = 0
717 439 self._init_ui()
718 440  
719   -
720 441 def _init_ui(self):
721 442 scroll = wx.ScrollBar(self, -1, style=wx.SB_VERTICAL)
722 443 self.scroll = scroll
... ... @@ -732,7 +453,6 @@ class DicomPreview(wx.Panel):
732 453 self.SetSizer(background_sizer)
733 454 background_sizer.Fit(self)
734 455  
735   -
736 456 self.Layout()
737 457 self.Update()
738 458 self.SetAutoLayout(1)
... ... @@ -747,6 +467,7 @@ class DicomPreview(wx.Panel):
747 467 for i in xrange(NROWS):
748 468 for j in xrange(NCOLS):
749 469 p = Preview(self)
  470 + p.Bind(EVT_PREVIEW_CLICK, self.OnPreviewClick)
750 471 #p.Hide()
751 472 self.previews.append(p)
752 473 self.grid.Add(p, 1, flag=wx.EXPAND)
... ... @@ -839,8 +560,201 @@ class DicomPreview(wx.Panel):
839 560 for f, p in zip(self.files[initial:final], self.previews):
840 561 p.Show()
841 562  
842   -
843 563 def OnScroll(self, evt):
844 564 if self.displayed_position != evt.GetPosition():
845 565 self.displayed_position = evt.GetPosition()
846 566 self._display_previews()
  567 +
  568 + def OnPreviewClick(self, evt):
  569 + print "Hey man, you've clicked over me"
  570 + my_evt = SerieEvent(myEVT_CLICK_SLICE, self.GetId())
  571 + my_evt.SetSelectedID(evt.GetSelectID())
  572 + my_evt.SetItemData(evt.GetItemData())
  573 + self.GetEventHandler().ProcessEvent(my_evt)
  574 +
  575 +
  576 +class SingleImagePreview(wx.Panel):
  577 + def __init__(self, parent):
  578 + wx.Panel.__init__(self, parent, -1)
  579 + self.__init_gui()
  580 + self.__init_vtk()
  581 + self.__bind_evt_gui()
  582 + self.dicom_list = []
  583 + self.nimages = 1
  584 + self.current_index = 0
  585 + self.window_width = const.WINDOW_LEVEL[_("Bone")][0]
  586 + self.window_level = const.WINDOW_LEVEL[_("Bone")][1]
  587 +
  588 + def __init_vtk(self):
  589 + actor = vtk.vtkImageActor()
  590 + self.actor = actor
  591 +
  592 + text_image_size = vtku.Text()
  593 + text_image_size.SetPosition(const.TEXT_POS_LEFT_UP)
  594 + text_image_size.SetValue(_("image size"))
  595 + self.text_image_size = text_image_size
  596 +
  597 + text_image_location = vtku.Text()
  598 + text_image_location.SetVerticalJustificationToBottom()
  599 + text_image_location.SetPosition(const.TEXT_POS_LEFT_DOWN)
  600 + text_image_location.SetValue("localization")
  601 + self.text_image_location = text_image_location
  602 +
  603 + value = _("id\nprotocol")
  604 + text_patient = vtku.Text()
  605 + text_patient.SetJustificationToRight()
  606 + text_patient.SetPosition(const.TEXT_POS_RIGHT_UP)
  607 + text_patient.SetValue(value)
  608 + self.text_patient = text_patient
  609 +
  610 + value = _("date time\n Made in InVesalius")
  611 + text_acquisition = vtku.Text()
  612 + text_acquisition.SetJustificationToRight()
  613 + text_acquisition.SetVerticalJustificationToBottom()
  614 + text_acquisition.SetPosition(const.TEXT_POS_RIGHT_DOWN)
  615 + text_acquisition.SetValue(value)
  616 + self.text_acquisition = text_acquisition
  617 +
  618 + renderer = vtk.vtkRenderer()
  619 + renderer.AddActor(actor)
  620 + renderer.AddActor(text_image_size.actor)
  621 + renderer.AddActor(text_image_location.actor)
  622 + renderer.AddActor(text_patient.actor)
  623 + renderer.AddActor(text_acquisition.actor)
  624 + self.renderer = renderer
  625 +
  626 + style = vtk.vtkInteractorStyleImage()
  627 +
  628 + interactor = wxVTKRenderWindowInteractor(self.panel, -1,
  629 + size=wx.Size(340,340))
  630 + interactor.GetRenderWindow().AddRenderer(renderer)
  631 + interactor.SetInteractorStyle(style)
  632 + interactor.Render()
  633 + self.interactor = interactor
  634 +
  635 + sizer = wx.BoxSizer(wx.VERTICAL)
  636 + sizer.Add(interactor, 1, wx.GROW|wx.EXPAND)
  637 + sizer.Fit(self.panel)
  638 + self.panel.SetSizer(sizer)
  639 + self.Layout()
  640 + self.Update()
  641 +
  642 + def __init_gui(self):
  643 + self.panel = wx.Panel(self, -1)
  644 +
  645 + slider = wx.Slider(self,
  646 + id=-1,
  647 + value=0,
  648 + minValue=0,
  649 + maxValue=99,
  650 + style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS)
  651 + slider.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
  652 + slider.SetTickFreq(1, 1)
  653 + self.slider = slider
  654 +
  655 + checkbox = wx.CheckBox(self, -1, _("Auto-play"))
  656 + self.checkbox = checkbox
  657 +
  658 + in_sizer = wx.BoxSizer(wx.HORIZONTAL)
  659 + in_sizer.Add(slider, 1, wx.GROW|wx.EXPAND)
  660 + in_sizer.Add(checkbox, 0)
  661 +
  662 + sizer = wx.BoxSizer(wx.VERTICAL)
  663 + sizer.Add(self.panel, 20, wx.GROW|wx.EXPAND)
  664 + sizer.Add(in_sizer, 1, wx.GROW|wx.EXPAND)
  665 + sizer.Fit(self)
  666 +
  667 + self.SetSizer(sizer)
  668 + self.Layout()
  669 + self.Update()
  670 + self.SetAutoLayout(1)
  671 +
  672 + def __bind_evt_gui(self):
  673 + self.slider.Bind(wx.EVT_SLIDER, self.OnSlider)
  674 + self.checkbox.Bind(wx.EVT_CHECKBOX, self.OnCheckBox)
  675 +
  676 + def OnSlider(self, evt):
  677 + pos = evt.GetInt()
  678 + self.ShowSlice(pos)
  679 + evt.Skip()
  680 +
  681 + def OnCheckBox(self, evt):
  682 + self.ischecked = evt.IsChecked()
  683 + if evt.IsChecked():
  684 + wx.CallAfter(self.OnRun)
  685 + evt.Skip()
  686 +
  687 + def OnRun(self):
  688 + pos = self.slider.GetValue()
  689 + pos += 1
  690 + if not (self.nimages- pos):
  691 + pos = 0
  692 + self.slider.SetValue(pos)
  693 + self.ShowSlice(pos)
  694 + time.sleep(0.2)
  695 + if self.ischecked:
  696 + try:
  697 + wx.Yield()
  698 + #TODO: temporary fix necessary in the Windows XP 64 Bits
  699 + #BUG in wxWidgets http://trac.wxwidgets.org/ticket/10896
  700 + except(wx._core.PyAssertionError):
  701 + print "wx._core.PyAssertionError"
  702 + finally:
  703 + wx.CallAfter(self.OnRun)
  704 +
  705 + def SetDicomGroup(self, group):
  706 + self.dicom_list = group.GetHandSortedList()
  707 + self.current_index = 0
  708 + self.nimages = len(self.dicom_list)
  709 + # GUI
  710 + self.slider.SetMax(self.nimages-1)
  711 + print self.nimages
  712 + self.slider.SetValue(0)
  713 + self.ShowSlice()
  714 +
  715 + def ShowSlice(self, index = 0):
  716 + print "ShowSlice"
  717 + dicom = self.dicom_list[index]
  718 +
  719 + # UPDATE GUI
  720 + ## Text related to size
  721 + value = STR_SIZE %(dicom.image.size[0], dicom.image.size[1])
  722 + self.text_image_size.SetValue(value)
  723 +
  724 + ## Text related to slice position
  725 + value1 = STR_SPC %(dicom.image.spacing[2])
  726 + value2 = STR_LOCAL %(dicom.image.position[2])
  727 + value = "%s\n%s" %(value1, value2)
  728 + self.text_image_location.SetValue(value)
  729 +
  730 + ## Text related to patient/ acquisiiton data
  731 + value = STR_PATIENT %(dicom.patient.id,\
  732 + dicom.acquisition.protocol_name)
  733 + self.text_patient.SetValue(value)
  734 +
  735 + ## Text related to acquisition date and time
  736 + value = STR_ACQ % (dicom.acquisition.date,
  737 + dicom.acquisition.time)
  738 + self.text_acquisition.SetValue(value)
  739 +
  740 + # READ FILE
  741 + #filename = dicom.image.file
  742 + #reader = vtkgdcm.vtkGDCMImageReader()
  743 + #reader.SetFileName(filename)
  744 +
  745 + # ADJUST CONTRAST
  746 + window_level = dicom.image.level
  747 + window_width = dicom.image.window
  748 + colorer = vtk.vtkImageMapToWindowLevelColors()
  749 + colorer.SetInput(dicom.image.imagedata)
  750 + colorer.SetWindow(float(window_width))
  751 + colorer.SetLevel(float(window_level))
  752 +
  753 + # PLOT IMAGE INTO VIEWER
  754 + self.actor.SetInput(colorer.GetOutput())
  755 + self.renderer.ResetCamera()
  756 + self.interactor.Render()
  757 +
  758 + def __del__(self):
  759 + print "---------> morri"
  760 +
... ...
invesalius/gui/import_panel.py
... ... @@ -24,6 +24,29 @@ import wx.lib.splitter as spl
24 24 import dicom_preview_panel as dpp
25 25 import reader.dicom_grouper as dcm
26 26  
  27 +myEVT_SELECT_SERIE = wx.NewEventType()
  28 +EVT_SELECT_SERIE = wx.PyEventBinder(myEVT_SELECT_SERIE, 1)
  29 +
  30 +myEVT_SELECT_SLICE = wx.NewEventType()
  31 +EVT_SELECT_SLICE = wx.PyEventBinder(myEVT_SELECT_SLICE, 1)
  32 +
  33 +class SelectEvent(wx.PyCommandEvent):
  34 + def __init__(self , evtType, id):
  35 + super(SelectEvent, self).__init__(evtType, id)
  36 +
  37 + def GetSelectID(self):
  38 + return self.SelectedID
  39 +
  40 + def SetSelectedID(self, id):
  41 + self.SelectedID = id
  42 +
  43 + def GetItemData(self):
  44 + return self.data
  45 +
  46 + def SetItemData(self, data):
  47 + self.data = data
  48 +
  49 +
27 50 class Panel(wx.Panel):
28 51 def __init__(self, parent):
29 52 wx.Panel.__init__(self, parent, pos=wx.Point(5, 5))#,
... ... @@ -74,14 +97,25 @@ class InnerPanel(wx.Panel):
74 97 self.image_panel = ImagePanel(splitter)
75 98 splitter.AppendWindow(self.image_panel, 250)
76 99  
77   - self.__bind_evt()
  100 + self._bind_events()
  101 + self._bind_pubsubevt()
78 102  
79   - def __bind_evt(self):
  103 + def _bind_pubsubevt(self):
80 104 ps.Publisher().subscribe(self.ShowDicomPreview, "Load import panel")
  105 +
  106 + def _bind_events(self):
  107 + self.Bind(EVT_SELECT_SERIE, self.OnSelectSerie)
  108 + self.Bind(EVT_SELECT_SLICE, self.OnSelectSlice)
81 109  
82 110 def ShowDicomPreview(self, pubsub_evt):
83 111 dicom_groups = pubsub_evt.data
84 112 self.text_panel.Populate(dicom_groups)
  113 +
  114 + def OnSelectSerie(self, evt):
  115 + print "You've selected the serie", evt.GetSelectID()
  116 +
  117 + def OnSelectSlice(self, evt):
  118 + print "You've selected the slice", evt.GetSelectID()
85 119  
86 120  
87 121 class TextPanel(wx.Panel):
... ... @@ -141,6 +175,7 @@ class TextPanel(wx.Panel):
141 175  
142 176 def Populate(self, patient_list):
143 177 tree = self.tree
  178 + self.idserie_treeitem = {}
144 179  
145 180 first = 0
146 181 for patient in patient_list:
... ... @@ -172,7 +207,7 @@ class TextPanel(wx.Panel):
172 207 tree.SetItemText(parent, "%s" % dicom.patient.physician, 11)
173 208  
174 209 group_list = patient.GetGroups()
175   - for group in group_list:
  210 + for n, group in enumerate(group_list):
176 211 dicom = group.GetDicomSample()
177 212  
178 213 child = tree.AppendItem(parent, group.title)
... ... @@ -184,14 +219,16 @@ class TextPanel(wx.Panel):
184 219 tree.SetItemText(child, "%s" % date_time, 6)
185 220 tree.SetItemText(child, "%s" % group.nslices, 7)
186 221  
  222 + self.idserie_treeitem[n] = child
  223 +
187 224 tree.Expand(self.root)
188 225  
189 226 tree.SelectItem(parent_select)
  227 + print "parent select", parent_select
190 228  
191 229 tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate)
192 230 tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged)
193 231  
194   -
195 232 def OnSelChanged(self, evt):
196 233 item = self.tree.GetSelection()
197 234 group = self.tree.GetItemPyData(item)
... ... @@ -202,7 +239,6 @@ class TextPanel(wx.Panel):
202 239 ps.Publisher().sendMessage('Load patient into import panel',
203 240 group)
204 241  
205   -
206 242 def OnActivate(self, evt):
207 243 item = evt.GetItem()
208 244 group = self.tree.GetItemPyData(item)
... ... @@ -218,15 +254,23 @@ class TextPanel(wx.Panel):
218 254 def OnSize(self, evt):
219 255 self.tree.SetSize(self.GetSize())
220 256  
  257 + def SelectSerie(self, serie):
  258 + item = self.idserie_treeitem[serie]
  259 + self.tree.SelectItem(item)
  260 +
221 261  
222 262 class ImagePanel(wx.Panel):
223 263 def __init__(self, parent):
224 264 wx.Panel.__init__(self, parent, -1)
225   - #self.SetBackgroundColour((0,255,0))
226   -
  265 + self._init_ui()
  266 + self._bind_events()
  267 +
  268 + def _init_ui(self):
227 269 splitter = spl.MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE)
228 270 splitter.SetOrientation(wx.HORIZONTAL)
229 271 self.splitter = splitter
  272 +
  273 + splitter.ContainingSizer = wx.BoxSizer(wx.HORIZONTAL)
230 274  
231 275 sizer = wx.BoxSizer(wx.HORIZONTAL)
232 276 sizer.Add(splitter, 1, wx.EXPAND)
... ... @@ -238,13 +282,27 @@ class ImagePanel(wx.Panel):
238 282 self.image_panel = SlicePanel(splitter)
239 283 splitter.AppendWindow(self.image_panel, 250)
240 284  
241   -
242 285 self.SetSizer(sizer)
243 286 sizer.Fit(self)
244 287  
245 288 self.Layout()
246 289 self.Update()
247 290 self.SetAutoLayout(1)
  291 +
  292 + def _bind_events(self):
  293 + self.text_panel.Bind(EVT_SELECT_SERIE, self.OnSelectSerie)
  294 + self.text_panel.Bind(EVT_SELECT_SLICE, self.OnSelectSlice)
  295 +
  296 + def OnSelectSerie(self, evt):
  297 + print "Hi, You selected Serie"
  298 + evt.Skip()
  299 +
  300 + def OnSelectSlice(self, evt):
  301 + print "Hi, You selected slice"
  302 + print "Selected ID", evt.GetSelectID()
  303 + self.image_panel.dicom_preview.ShowSlice(evt.GetSelectID())
  304 + evt.Skip()
  305 +
248 306  
249 307 class SeriesPanel(wx.Panel):
250 308 def __init__(self, parent):
... ... @@ -252,7 +310,7 @@ class SeriesPanel(wx.Panel):
252 310 #self.SetBackgroundColour((0,0,0))
253 311  
254 312 self.serie_preview = dpp.DicomPreviewSeries(self)
255   - self.dicom_preview = dpp.DicomPreview(self)
  313 + self.dicom_preview = dpp.DicomPreviewSlice(self)
256 314 self.dicom_preview.Show(0)
257 315  
258 316 self.sizer = wx.BoxSizer(wx.HORIZONTAL)
... ... @@ -260,10 +318,8 @@ class SeriesPanel(wx.Panel):
260 318 self.sizer.Add(self.dicom_preview, 1, wx.EXPAND | wx.ALL, 5)
261 319 self.sizer.Fit(self)
262 320  
263   -
264 321 self.SetSizer(self.sizer)
265 322  
266   -
267 323 self.Layout()
268 324 self.Update()
269 325 self.SetAutoLayout(1)
... ... @@ -277,7 +333,8 @@ class SeriesPanel(wx.Panel):
277 333 ps.Publisher().subscribe(self.SetPatientSeries, 'Load patient into import panel')
278 334  
279 335 def _bind_gui_evt(self):
280   - self.Bind(dpp.EVT_SELECT_SERIE, self.OnSelectSerie)
  336 + self.serie_preview.Bind(dpp.EVT_CLICK_SERIE, self.OnSelectSerie)
  337 + self.dicom_preview.Bind(dpp.EVT_CLICK_SLICE, self.OnSelectSlice)
281 338  
282 339 def SetDicomSeries(self, pubsub_evt):
283 340 group = pubsub_evt.data
... ... @@ -286,7 +343,6 @@ class SeriesPanel(wx.Panel):
286 343 self.serie_preview.Show(0)
287 344 self.sizer.Layout()
288 345 self.Update()
289   -
290 346  
291 347 def SetPatientSeries(self, pubsub_evt):
292 348 patient = pubsub_evt.data
... ... @@ -299,26 +355,36 @@ class SeriesPanel(wx.Panel):
299 355  
300 356 self.Update()
301 357  
302   -
303 358 def OnSelectSerie(self, evt):
304   - serie = evt.GetSelectID()
305   - self.dicom_preview.SetDicomSerie(serie)
306   -
  359 + print "Hey, You selected a serie"
  360 + serie = evt.GetItemData()
307 361 data = evt.GetItemData()
308 362  
  363 + my_evt = SelectEvent(myEVT_SELECT_SERIE, self.GetId())
  364 + my_evt.SetSelectedID(evt.GetSelectID())
  365 + my_evt.SetItemData(evt.GetItemData())
  366 + self.GetEventHandler().ProcessEvent(my_evt)
  367 +
  368 + self.dicom_preview.SetDicomSerie(serie)
309 369 self.dicom_preview.Show(1)
310 370 self.serie_preview.Show(0)
311 371 self.sizer.Layout()
312 372 #self.Show()
313 373 self.Update()
314 374  
  375 + def OnSelectSlice(self, evt):
  376 + print "Hey, Ho, Let's go", evt.GetSelectID()
  377 +
  378 + my_evt = SelectEvent(myEVT_SELECT_SLICE, self.GetId())
  379 + my_evt.SetSelectedID(evt.GetSelectID())
  380 + my_evt.SetItemData(evt.GetItemData())
  381 + self.GetEventHandler().ProcessEvent(my_evt)
315 382  
316 383 def ShowDicomSeries(self, pubsub_evt):
317 384 patient = pubsub_evt.data
318 385 if isinstance(patient, dcm.PatientGroup):
319 386 self.serie_preview.SetPatientGroups(patient)
320 387 self.dicom_preview.SetPatientGroups(patient)
321   -
322 388  
323 389  
324 390 class SlicePanel(wx.Panel):
... ... @@ -352,15 +418,13 @@ class SlicePanel(wx.Panel):
352 418 self.dicom_preview.SetDicomGroup(group)
353 419 self.sizer.Layout()
354 420 self.Update()
355   -
356 421  
357   - def SetDicomSeries(self, pubsub_evt):
358   - group = pubsub_evt.data
  422 + def SetDicomSeries(self, evt):
  423 + group = evt.data
359 424 self.dicom_preview.SetDicomGroup(group)
360 425 self.sizer.Layout()
361 426 self.Update()
362 427  
363   -
364 428 def ShowDicomSeries(self, pubsub_evt):
365 429 patient = pubsub_evt.data
366 430 group = patient.GetGroups()[0]
... ...