diff --git a/invesalius/gui/dicom_preview_panel.py b/invesalius/gui/dicom_preview_panel.py index 0a7c15e..1c77750 100755 --- a/invesalius/gui/dicom_preview_panel.py +++ b/invesalius/gui/dicom_preview_panel.py @@ -9,6 +9,13 @@ import vtkgdcm from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor from reader import dicom_reader + + +NROWS = 3 +NCOLS = 6 +MAX_VALUE = NCOLS*NROWS + + myEVT_SELECT = wx.NewEventType() # This event occurs when the user select a preview EVT_SELECT = wx.PyEventBinder(myEVT_SELECT, 1) @@ -40,39 +47,67 @@ class Preview(wx.Panel): super(Preview, self).__init__(parent) # Will it be white? self.SetBackgroundColour((255, 255, 255)) - self.sizer = wx.BoxSizer(wx.VERTICAL) - self.SetSizer(self.sizer) self._init_ui() self._init_vtk() self._bind_events() def _init_ui(self): + self.title = wx.StaticText(self, -1, "Image", style=wx.ALIGN_CENTER) self.subtitle = wx.StaticText(self, -1, "Image", style=wx.ALIGN_CENTER) - self.interactor = wxVTKRenderWindowInteractor(self, -1, size=(70, 70)) + self.panel = wx.Panel(self, -1) + + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.sizer.AddSpacer(2) + self.sizer.Add(self.title, 1, wx.GROW|wx.EXPAND) + self.sizer.Add(self.subtitle, 1, wx.GROW|wx.EXPAND) + self.sizer.Add(self.panel, 5, wx.GROW|wx.EXPAND|wx.ALL, 4) + self.sizer.Fit(self) + + + self.SetSizer(self.sizer) + + + self.Layout() + self.Update() + self.Fit() + self.SetAutoLayout(1) - self.sizer.Add(self.title, 0, wx.ALIGN_CENTER_HORIZONTAL) - self.sizer.Add(self.subtitle, 0, wx.ALIGN_CENTER_HORIZONTAL) - self.sizer.Add(self.interactor, 0, wx.ALIGN_CENTER_HORIZONTAL\ - | wx.ALL, 5) def _init_vtk(self): + + self.interactor = wxVTKRenderWindowInteractor(self.panel, -1, size=(70, 70)) + + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.interactor, 1, wx.GROW|wx.EXPAND) + sizer.Fit(self.panel) + + self.panel.SetSizer(sizer) + + self.panel.Layout() + self.panel.Update() + self.panel.SetAutoLayout(1) + self.actor = vtk.vtkImageActor() self.render = vtk.vtkRenderer() + self.render.AddActor(self.actor) self.interactor.SetInteractorStyle(None) self.interactor.GetRenderWindow().AddRenderer(self.render) - self.render.AddActor(self.actor) - def _bind_events(self): self.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) + self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) + self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) + self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) + self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) + def OnSelect(self, evt): evt = PreviewEvent(myEVT_SELECT, self.GetId()) @@ -91,6 +126,10 @@ class Preview(wx.Panel): """ self.SetTitle(image_file[3]) self.SetSubtitle(image_file[4]) + + self.Layout() + self.Update() + self.ID = image_file[5] image_reader = vtkgdcm.vtkGDCMImageReader() @@ -117,7 +156,9 @@ class Preview(wx.Panel): cast.SetLevel(level) self.actor.SetInput(cast.GetOutput()) self.render.ResetCamera() - #self.interactor.Render() + self.interactor.Render() + + class DicomPreviewSeries(wx.Panel): @@ -126,28 +167,46 @@ class DicomPreviewSeries(wx.Panel): super(DicomPreviewSeries, self).__init__(parent) # TODO: 3 pixels between the previews is a good idea? # I have to test. - self.sizer = wx.BoxSizer(wx.HORIZONTAL) - self.SetSizer(self.sizer) + #self.sizer = wx.BoxSizer(wx.HORIZONTAL) + #self.SetSizer(self.sizer) self.displayed_position = 0 - self.files = [] + self.nhidden_last_display = 0 self._init_ui() def _init_ui(self): - self.scroll = wx.ScrollBar(self, style=wx.SB_VERTICAL) - self.grid = wx.GridSizer(rows=3, cols=5, vgap=3, hgap=3) - self.sizer.Add(self.grid) - self.sizer.Add(self.scroll, 0, wx.EXPAND) + + scroll = wx.ScrollBar(self, -1, style=wx.SB_VERTICAL) + self.scroll = scroll + + self.grid = wx.GridSizer(rows=NROWS, cols=NCOLS, vgap=3, hgap=3) + + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.AddSizer(self.grid, 1, wx.EXPAND|wx.GROW|wx.ALL, 2) + + background_sizer = wx.BoxSizer(wx.HORIZONTAL) + background_sizer.AddSizer(sizer, 1, wx.EXPAND|wx.GROW|wx.ALL, 2) + background_sizer.Add(scroll, 0, wx.EXPAND|wx.GROW) + self.SetSizer(background_sizer) + background_sizer.Fit(self) + + + self.Layout() + self.Update() + self.SetAutoLayout(1) + + self.sizer = background_sizer + self._Add_Panels_Preview() self._bind_events() def _Add_Panels_Preview(self): self.previews = [] - for i in xrange(3): - for j in xrange(5): + for i in xrange(NROWS): + for j in xrange(NCOLS): p = Preview(self) - p.Hide() + #p.Hide() self.previews.append(p) - self.grid.Add(p, i, j) + self.grid.Add(p, 1, flag=wx.EXPAND) def _bind_events(self): # When the user scrolls the window @@ -160,7 +219,11 @@ class DicomPreviewSeries(wx.Panel): self.GetEventHandler().ProcessEvent(my_evt) def SetPatientGroups(self, patient): + self.files = [] + self.displayed_position = 0 + self.nhidden_last_display = 0 group_list = patient.GetGroups() + print "LEN:", len(group_list) n = 0 for group in group_list: info = (group.dicom.image.file, @@ -172,47 +235,50 @@ class DicomPreviewSeries(wx.Panel): self.files.append(info) n+=1 - scroll_range = len(self.files)/5 - if scroll_range * 5 < len(self.files): + scroll_range = len(self.files)/NCOLS + if scroll_range * NCOLS < len(self.files): scroll_range +=1 - self.scroll.SetScrollbar(0, 3, scroll_range, 5) + self.scroll.SetScrollbar(0, NROWS, scroll_range, NCOLS) + self._display_previews() + + def _display_previews(self): + initial = self.displayed_position * NCOLS + final = initial + MAX_VALUE + print "len:", len(self.files) + + if len(self.files) < final: + for i in xrange(final-len(self.files)): + print "hide ", i + try: + self.previews[-i-1].Hide() + except IndexError: + #print "doesn't exist!" + pass + self.nhidden_last_display = final-len(self.files) + else: + if self.nhidden_last_display: + for i in xrange(self.nhidden_last_display): + try: + self.previews[-i-1].Show() + except IndexError: + #print "doesn't exist!" + pass + self.nhidden_last_display = 0 - self._Display_Previews() - def SetDicomDirectoryOld(self, directory): - import time - a = time.time() - self.directory = directory - self.series = dicom_reader.GetSeries(directory)[0] - b = time.time() - # TODO: I need to improve this - self.files = [(self.series[i][0][0][8], # Filename - self.series[i][0][0][12], # Window Level - self.series[i][0][0][13], # Window Width - "Serie %d" % (n + 1), # Title - "%d Images" % len(self.series[i][0]), # Subtitle - n) for n, i in enumerate(self.series)] - - scroll_range = len(self.files)/5 - if scroll_range * 5 < len(self.files): - scroll_range +=1 - self.scroll.SetScrollbar(0, 3, scroll_range, 5) - - self._Display_Previews() - - def _Display_Previews(self): - initial = self.displayed_position * 5 - final = initial + 15 for f, p in zip(self.files[initial:final], self.previews): p.SetImage(f) + #p.interactor.Render() + + for f, p in zip(self.files[initial:final], self.previews): p.Show() - def OnScroll(self, evt): - self.displayed_position = evt.GetPosition() - [i.Hide() for i in self.previews] - self._Display_Previews() + def OnScroll(self, evt): + if self.displayed_position != evt.GetPosition(): + self.displayed_position = evt.GetPosition() + self._display_previews() class DicomPreview(wx.Panel): """A dicom preview panel""" @@ -220,28 +286,44 @@ class DicomPreview(wx.Panel): super(DicomPreview, self).__init__(parent) # TODO: 3 pixels between the previews is a good idea? # I have to test. - self.sizer = wx.BoxSizer(wx.HORIZONTAL) - self.SetSizer(self.sizer) self.displayed_position = 0 - self.files = [] + self.nhidden_last_display = 0 self._init_ui() + def _init_ui(self): - self.scroll = wx.ScrollBar(self, style=wx.SB_VERTICAL) - self.grid = wx.GridSizer(rows=3, cols=5, vgap=3, hgap=3) - self.sizer.Add(self.grid) - self.sizer.Add(self.scroll, 0, wx.EXPAND) + scroll = wx.ScrollBar(self, -1, style=wx.SB_VERTICAL) + self.scroll = scroll + + self.grid = wx.GridSizer(rows=NROWS, cols=NCOLS, vgap=3, hgap=3) + + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.AddSizer(self.grid, 1, wx.EXPAND|wx.GROW|wx.ALL, 2) + + background_sizer = wx.BoxSizer(wx.HORIZONTAL) + background_sizer.AddSizer(sizer, 1, wx.EXPAND|wx.GROW|wx.ALL, 2) + background_sizer.Add(scroll, 0, wx.EXPAND|wx.GROW) + self.SetSizer(background_sizer) + background_sizer.Fit(self) + + + self.Layout() + self.Update() + self.SetAutoLayout(1) + + self.sizer = background_sizer + self._Add_Panels_Preview() self._bind_events() def _Add_Panels_Preview(self): self.previews = [] - for i in xrange(3): - for j in xrange(5): + for i in xrange(NROWS): + for j in xrange(NCOLS): p = Preview(self) - p.Hide() + #p.Hide() self.previews.append(p) - self.grid.Add(p, i, j) + self.grid.Add(p, 1, flag=wx.EXPAND) def _bind_events(self): # When the user scrolls the window @@ -255,6 +337,9 @@ class DicomPreview(wx.Panel): self.group_list = patient.GetGroups() def SetDicomSerie(self, pos): + self.files = [] + self.displayed_position = 0 + self.nhidden_last_display = 0 group = self.group_list[pos] #dicom_files = group.GetList() dicom_files = group.GetHandSortedList() @@ -269,37 +354,71 @@ class DicomPreview(wx.Panel): self.files.append(info) n+=1 - scroll_range = len(self.files)/5 - if scroll_range * 5 < len(self.files): + scroll_range = len(self.files)/NCOLS + if scroll_range * NCOLS < len(self.files): scroll_range +=1 - self.scroll.SetScrollbar(0, 3, scroll_range, 5) - self._Display_Previews() - - def SetDicomSerieOld(self, serie): - k = self.series.keys()[serie] - self.files = [(i[8], - i[12], - i[13], - "Serie %d" % (n + 1), # Title - "%d Images" % n, # Subtitle - n)for n, i in enumerate(self.series[k][0])] - scroll_range = len(self.files)/5 - if scroll_range * 5 < len(self.files): + self.scroll.SetScrollbar(0, NROWS, scroll_range, NCOLS) + + self._display_previews() + + def SetDicomGroup(self, group): + self.files = [] + self.displayed_position = 0 + self.nhidden_last_display = 0 + #dicom_files = group.GetList() + dicom_files = group.GetHandSortedList() + n = 0 + for dicom in dicom_files: + info = (dicom.image.file, + dicom.image.window, + dicom.image.level, + "Image %d" % (dicom.image.number), + "%.2f" % (dicom.image.position[2]), + n) + self.files.append(info) + n+=1 + + scroll_range = len(self.files)/NCOLS + if scroll_range * NCOLS < len(self.files): scroll_range +=1 - self.scroll.SetScrollbar(0, 3, scroll_range, 5) - self._Display_Previews() + self.scroll.SetScrollbar(0, NROWS, scroll_range, NCOLS) + + self._display_previews() + + + def _display_previews(self): + initial = self.displayed_position * NCOLS + final = initial + MAX_VALUE + print "len:", len(self.files) + + if len(self.files) < final: + for i in xrange(final-len(self.files)): + print "hide ", i + try: + self.previews[-i-1].Hide() + except IndexError: + #print "doesn't exist!" + pass + self.nhidden_last_display = final-len(self.files) + else: + if self.nhidden_last_display: + for i in xrange(self.nhidden_last_display): + try: + self.previews[-i-1].Show() + except IndexError: + #print "doesn't exist!" + pass + self.nhidden_last_display = 0 - def _Display_Previews(self): - initial = self.displayed_position * 5 - final = initial + 15 for f, p in zip(self.files[initial:final], self.previews): p.SetImage(f) + #p.interactor.Render() + + for f, p in zip(self.files[initial:final], self.previews): p.Show() - def OnScroll(self, evt): - self.displayed_position = evt.GetPosition() - [i.Hide() for i in self.previews] - self._Display_Previews() - self.Update() - self.Update() + def OnScroll(self, evt): + if self.displayed_position != evt.GetPosition(): + self.displayed_position = evt.GetPosition() + self._display_previews() diff --git a/invesalius/gui/import_panel.py b/invesalius/gui/import_panel.py index 589af41..7d99622 100644 --- a/invesalius/gui/import_panel.py +++ b/invesalius/gui/import_panel.py @@ -4,21 +4,29 @@ import wx.lib.pubsub as ps import wx.lib.splitter as spl import dicom_preview_panel as dpp +import reader.dicom_grouper as dcm class Panel(wx.Panel): def __init__(self, parent): - wx.Panel.__init__(self, parent, pos=wx.Point(5, 5), - size=wx.Size(280, 656)) + wx.Panel.__init__(self, parent, pos=wx.Point(5, 5))#, + #size=wx.Size(280, 656)) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(InnerPanel(self), 1, wx.EXPAND|wx.GROW|wx.ALL, 5) + self.SetSizer(sizer) + sizer.Fit(self) + + self.Layout() + self.Update() + self.SetAutoLayout(1) + # Inner fold panel class InnerPanel(wx.Panel): def __init__(self, parent): - wx.Panel.__init__(self, parent, pos=wx.Point(5, 5), - size=wx.Size(680, 656)) + wx.Panel.__init__(self, parent, pos=wx.Point(5, 5))#, + #size=wx.Size(680, 656)) splitter = spl.MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) splitter.SetOrientation(wx.VERTICAL) @@ -26,8 +34,14 @@ class InnerPanel(wx.Panel): sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(splitter, 1, wx.EXPAND) + self.SetSizer(sizer) - + sizer.Fit(self) + + self.Layout() + self.Update() + self.SetAutoLayout(1) + self.text_panel = TextPanel(splitter) splitter.AppendWindow(self.text_panel, 250) @@ -105,10 +119,10 @@ class TextPanel(wx.Panel): parent = tree.AppendItem(self.root, title) if not first: - tree.SelectItem(parent) + parent_select = parent first += 1 - + tree.SetItemPyData(parent, patient) tree.SetItemText(parent, str(dicom.patient.id), 1) tree.SetItemText(parent, str(dicom.patient.age), 2) tree.SetItemText(parent, str(dicom.patient.gender), 3) @@ -136,17 +150,37 @@ class TextPanel(wx.Panel): tree.Expand(self.root) + tree.SelectItem(parent_select) + tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate) + tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged) + + + def OnSelChanged(self, evt): + print "OnLeftUp" + item = self.tree.GetSelection() + group = self.tree.GetItemPyData(item) + if isinstance(group, dcm.DicomGroup): + print " :)" + ps.Publisher().sendMessage('Load group into import panel', + group) + elif isinstance(group, dcm.PatientGroup): + print " :) patient" + ps.Publisher().sendMessage('Load patient into import panel', + group) + + else: + print " :(" + + def OnActivate(self, evt): print "OnActivate" item = evt.GetItem() group = self.tree.GetItemPyData(item) - if group: - print "send" + if isinstance(group, dcm.DicomGroup): ps.Publisher().sendMessage('Open DICOM group', group) - else: if self.tree.IsExpanded(item): self.tree.Collapse(item) @@ -155,7 +189,10 @@ class TextPanel(wx.Panel): def OnSize(self, evt): self.tree.SetSize(self.GetSize()) - + + + + class ImagePanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, -1) @@ -174,6 +211,14 @@ class ImagePanel(wx.Panel): self.image_panel = SlicePanel(splitter) splitter.AppendWindow(self.image_panel, 250) + + + self.SetSizer(sizer) + sizer.Fit(self) + + self.Layout() + self.Update() + self.SetAutoLayout(1) class SeriesPanel(wx.Panel): def __init__(self, parent): @@ -184,31 +229,58 @@ class SeriesPanel(wx.Panel): self.dicom_preview = dpp.DicomPreview(self) self.dicom_preview.Show(0) - self.sizer = wx.BoxSizer(wx.VERTICAL) + self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.sizer.Add(self.serie_preview, 1, wx.EXPAND | wx.ALL, 5) self.sizer.Add(self.dicom_preview, 1, wx.EXPAND | wx.ALL, 5) self.sizer.Fit(self) + self.SetSizer(self.sizer) - self.SetAutoLayout(True) - self.Show() + self.Layout() + self.Update() + self.SetAutoLayout(1) + self.__bind_evt() self._bind_gui_evt() def __bind_evt(self): - ps.Publisher().subscribe(self.ShowDicomSeries, "Load dicom preview") + ps.Publisher().subscribe(self.ShowDicomSeries, 'Load dicom preview') + ps.Publisher().subscribe(self.SetDicomSeries, 'Load group into import panel') + ps.Publisher().subscribe(self.SetPatientSeries, 'Load patient into import panel') def _bind_gui_evt(self): self.Bind(dpp.EVT_SELECT_SERIE, self.OnSelectSerie) + def SetDicomSeries(self, pubsub_evt): + group = pubsub_evt.data + print "X" + self.dicom_preview.Show(1) + self.serie_preview.Show(0) + self.dicom_preview.SetDicomGroup(group) + self.Update() + + + def SetPatientSeries(self, pubsub_evt): + print "Z" + patient = pubsub_evt.data + + self.dicom_preview.Show(0) + self.serie_preview.Show(1) + + + self.serie_preview.SetPatientGroups(patient) + self.dicom_preview.SetPatientGroups(patient) + + self.Update() + + def OnSelectSerie(self, evt): serie = evt.GetSelectID() self.dicom_preview.SetDicomSerie(serie) self.dicom_preview.Show(1) - #self.sizer.Detach(self.serie_preview) self.serie_preview.Show(0) self.sizer.Layout() #self.Show() @@ -217,9 +289,9 @@ class SeriesPanel(wx.Panel): def ShowDicomSeries(self, pubsub_evt): print "---- ShowDicomSeries ----" - first_patient = pubsub_evt.data - self.serie_preview.SetPatientGroups(first_patient) - self.dicom_preview.SetPatientGroups(first_patient) + patient = pubsub_evt.data + self.serie_preview.SetPatientGroups(patient) + self.dicom_preview.SetPatientGroups(patient) diff --git a/invesalius/reader/dicom_grouper.py b/invesalius/reader/dicom_grouper.py index ae541d4..b519991 100644 --- a/invesalius/reader/dicom_grouper.py +++ b/invesalius/reader/dicom_grouper.py @@ -125,7 +125,8 @@ class DicomGroup: list_ = self.slices_dict.values() dicom = list_[0] axis = ORIENT_MAP[dicom.image.orientation_label] - list_ = sorted(list_, key = lambda dicom:dicom.image.position[axis]) + #list_ = sorted(list_, key = lambda dicom:dicom.image.position[axis]) + list_ = sorted(list_, key = lambda dicom:dicom.image.number) return list_ def UpdateZSpacing(self): -- libgit2 0.21.2