Commit 37109ae4ed9cf09bbc145de953b5df8b4ac6f247

Authored by Thiago Franco de Moraes
Committed by GitHub
1 parent 5af919ac
Exists in master

Improvements to GUI of FFill tools (#54)

Close button on remove parts, fill holes and region growing segmentation.
Cancel and Ok button on the select parts.
invesalius/data/styles.py
@@ -1904,20 +1904,28 @@ class SelectMaskPartsInteractorStyle(DefaultInteractorStyle): @@ -1904,20 +1904,28 @@ class SelectMaskPartsInteractorStyle(DefaultInteractorStyle):
1904 self.dlg.Show() 1904 self.dlg.Show()
1905 1905
1906 def CleanUp(self): 1906 def CleanUp(self):
1907 - if (self.dlg is not None) and (self.config.dlg_visible): 1907 + if self.dlg is None:
  1908 + return
  1909 +
  1910 + dialog_return = self.dlg.GetReturnCode()
  1911 +
  1912 + if self.config.dlg_visible:
1908 self.config.dlg_visible = False 1913 self.config.dlg_visible = False
1909 self.dlg.Destroy() 1914 self.dlg.Destroy()
1910 self.dlg = None 1915 self.dlg = None
1911 1916
1912 if self.config.mask: 1917 if self.config.mask:
1913 - self.config.mask.name = self.config.mask_name  
1914 - self.viewer.slice_._add_mask_into_proj(self.config.mask)  
1915 - self.viewer.slice_.SelectCurrentMask(self.config.mask.index)  
1916 - Publisher.sendMessage('Change mask selected', self.config.mask.index)  
1917 - self.config.mask = None 1918 + if dialog_return == wx.OK:
  1919 + self.config.mask.name = self.config.mask_name
  1920 + self.viewer.slice_._add_mask_into_proj(self.config.mask)
  1921 + self.viewer.slice_.SelectCurrentMask(self.config.mask.index)
  1922 + Publisher.sendMessage('Change mask selected', self.config.mask.index)
  1923 +
1918 del self.viewer.slice_.aux_matrices['SELECT'] 1924 del self.viewer.slice_.aux_matrices['SELECT']
1919 self.viewer.slice_.to_show_aux = '' 1925 self.viewer.slice_.to_show_aux = ''
1920 Publisher.sendMessage('Reload actual slice') 1926 Publisher.sendMessage('Reload actual slice')
  1927 + self.config.mask = None
  1928 +
1921 1929
1922 def OnSelect(self, obj, evt): 1930 def OnSelect(self, obj, evt):
1923 if (self.viewer.slice_.buffer_slices[self.orientation].mask is None): 1931 if (self.viewer.slice_.buffer_slices[self.orientation].mask is None):
@@ -1969,7 +1977,7 @@ class FFillSegmentationConfig(object): @@ -1969,7 +1977,7 @@ class FFillSegmentationConfig(object):
1969 1977
1970 self.fill_value = 254 1978 self.fill_value = 254
1971 1979
1972 - self.method = 'threshold' 1980 + self.method = 'dynamic'
1973 1981
1974 self.dev_min = 25 1982 self.dev_min = 25
1975 self.dev_max = 25 1983 self.dev_max = 25
@@ -1991,7 +1999,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): @@ -1991,7 +1999,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle):
1991 self.config = FFillSegmentationConfig() 1999 self.config = FFillSegmentationConfig()
1992 self.dlg_ffill = None 2000 self.dlg_ffill = None
1993 2001
1994 - self._progr_title = _(u"Floodfill segmentation") 2002 + self._progr_title = _(u"Region growing")
1995 self._progr_msg = _(u"Segmenting ...") 2003 self._progr_msg = _(u"Segmenting ...")
1996 2004
1997 self.AddObserver("LeftButtonPressEvent", self.OnFFClick) 2005 self.AddObserver("LeftButtonPressEvent", self.OnFFClick)
invesalius/gui/dialogs.py
@@ -1840,6 +1840,164 @@ def BitmapNotSameSize(): @@ -1840,6 +1840,164 @@ def BitmapNotSameSize():
1840 dlg.Destroy() 1840 dlg.Destroy()
1841 1841
1842 1842
  1843 +class PanelTargeFFill(wx.Panel):
  1844 + def __init__(self, parent, ID=-1, style=wx.TAB_TRAVERSAL|wx.NO_BORDER):
  1845 + wx.Panel.__init__(self, parent, ID, style=style)
  1846 + self._init_gui()
  1847 +
  1848 + def _init_gui(self):
  1849 + self.target_2d = wx.RadioButton(self, -1, _(u"2D - Actual slice"), style=wx.RB_GROUP)
  1850 + self.target_3d = wx.RadioButton(self, -1, _(u"3D - All slices"))
  1851 +
  1852 + sizer = wx.GridBagSizer(5, 5)
  1853 +
  1854 + sizer.AddStretchSpacer((0, 0))
  1855 + sizer.Add(self.target_2d, (1, 0), (1, 6), flag=wx.LEFT, border=5)
  1856 + sizer.Add(self.target_3d, (2, 0), (1, 6), flag=wx.LEFT, border=5)
  1857 + sizer.AddStretchSpacer((3, 0))
  1858 +
  1859 + self.SetSizer(sizer)
  1860 + sizer.Fit(self)
  1861 + self.Layout()
  1862 +
  1863 +class Panel2DConnectivity(wx.Panel):
  1864 + def __init__(self, parent, ID=-1, style=wx.TAB_TRAVERSAL|wx.NO_BORDER):
  1865 + wx.Panel.__init__(self, parent, ID, style=style)
  1866 + self._init_gui()
  1867 +
  1868 + def _init_gui(self):
  1869 + self.conect2D_4 = wx.RadioButton(self, -1, "4", style=wx.RB_GROUP)
  1870 + self.conect2D_8 = wx.RadioButton(self, -1, "8")
  1871 +
  1872 + sizer = wx.GridBagSizer(5, 5)
  1873 +
  1874 + sizer.AddStretchSpacer((0, 0))
  1875 + sizer.Add(wx.StaticText(self, -1, _(u"2D Connectivity")), (1, 0), (1, 6), flag=wx.LEFT, border=5)
  1876 + sizer.Add(self.conect2D_4, (2, 0), flag=wx.LEFT, border=7)
  1877 + sizer.Add(self.conect2D_8, (2, 1), flag=wx.LEFT, border=7)
  1878 + sizer.AddStretchSpacer((3, 0))
  1879 +
  1880 + self.SetSizer(sizer)
  1881 + sizer.Fit(self)
  1882 + self.Layout()
  1883 +
  1884 +
  1885 +class Panel3DConnectivity(wx.Panel):
  1886 + def __init__(self, parent, ID=-1, style=wx.TAB_TRAVERSAL|wx.NO_BORDER):
  1887 + wx.Panel.__init__(self, parent, ID, style=style)
  1888 + self._init_gui()
  1889 +
  1890 + def _init_gui(self):
  1891 + self.conect3D_6 = wx.RadioButton(self, -1, "6", style=wx.RB_GROUP)
  1892 + self.conect3D_18 = wx.RadioButton(self, -1, "18")
  1893 + self.conect3D_26 = wx.RadioButton(self, -1, "26")
  1894 +
  1895 + sizer = wx.GridBagSizer(5, 5)
  1896 +
  1897 + sizer.AddStretchSpacer((0, 0))
  1898 + sizer.Add(wx.StaticText(self, -1, _(u"3D Connectivity")), (1, 0), (1, 6), flag=wx.LEFT, border=5)
  1899 + sizer.Add(self.conect3D_6, (2, 0), flag=wx.LEFT, border=9)
  1900 + sizer.Add(self.conect3D_18, (2, 1), flag=wx.LEFT, border=9)
  1901 + sizer.Add(self.conect3D_26, (2, 2), flag=wx.LEFT, border=9)
  1902 + sizer.AddStretchSpacer((3, 0))
  1903 +
  1904 + self.SetSizer(sizer)
  1905 + sizer.Fit(self)
  1906 + self.Layout()
  1907 +
  1908 +
  1909 +class PanelFFillThreshold(wx.Panel):
  1910 + def __init__(self, parent, config, ID=-1, style=wx.TAB_TRAVERSAL|wx.NO_BORDER):
  1911 + wx.Panel.__init__(self, parent, ID, style=style)
  1912 +
  1913 + self.config = config
  1914 +
  1915 + self._init_gui()
  1916 +
  1917 + def _init_gui(self):
  1918 + import project as prj
  1919 +
  1920 + project = prj.Project()
  1921 + bound_min, bound_max = project.threshold_range
  1922 + colour = [i*255 for i in const.MASK_COLOUR[0]]
  1923 + colour.append(100)
  1924 +
  1925 + self.threshold = grad.GradientCtrl(self, -1, int(bound_min),
  1926 + int(bound_max), self.config.t0,
  1927 + self.config.t1, colour)
  1928 +
  1929 + # sizer
  1930 + sizer = wx.BoxSizer(wx.VERTICAL)
  1931 + sizer.AddSpacer(5)
  1932 + sizer.Add(self.threshold, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
  1933 + sizer.AddSpacer(5)
  1934 +
  1935 + self.SetSizer(sizer)
  1936 + sizer.Fit(self)
  1937 + self.Layout()
  1938 +
  1939 + self.Bind(grad.EVT_THRESHOLD_CHANGING, self.OnSlideChanged, self.threshold)
  1940 + self.Bind(grad.EVT_THRESHOLD_CHANGED, self.OnSlideChanged, self.threshold)
  1941 +
  1942 + def OnSlideChanged(self, evt):
  1943 + self.config.t0 = int(self.threshold.GetMinValue())
  1944 + self.config.t1 = int(self.threshold.GetMaxValue())
  1945 + print self.config.t0, self.config.t1
  1946 +
  1947 +
  1948 +class PanelFFillDynamic(wx.Panel):
  1949 + def __init__(self, parent, config, ID=-1, style=wx.TAB_TRAVERSAL|wx.NO_BORDER):
  1950 + wx.Panel.__init__(self, parent, ID, style=style)
  1951 +
  1952 + self.config = config
  1953 +
  1954 + self._init_gui()
  1955 +
  1956 + def _init_gui(self):
  1957 + self.use_ww_wl = wx.CheckBox(self, -1, _(u"Use WW&WL"))
  1958 + self.use_ww_wl.SetValue(self.config.use_ww_wl)
  1959 +
  1960 + self.deviation_min = wx.SpinCtrl(self, -1, value='%d' % self.config.dev_min, min=0, max=10000)
  1961 + w, h = self.deviation_min.GetTextExtent('M')
  1962 + self.deviation_min.SetMinSize((w*5, -1))
  1963 +
  1964 + self.deviation_max = wx.SpinCtrl(self, -1, value='%d' % self.config.dev_max, min=0, max=10000)
  1965 + self.deviation_max.SetMinSize((w*5, -1))
  1966 +
  1967 + sizer = wx.GridBagSizer(5, 5)
  1968 +
  1969 + sizer.AddStretchSpacer((0, 0))
  1970 +
  1971 + sizer.Add(self.use_ww_wl, (1, 0), (1, 6), flag=wx.LEFT, border=5)
  1972 +
  1973 + sizer.AddStretchSpacer((2, 0))
  1974 +
  1975 + sizer.Add(wx.StaticText(self, -1, _(u"Deviation")), (3, 0), (1, 6), flag=wx.LEFT, border=5)
  1976 +
  1977 + sizer.Add(wx.StaticText(self, -1, _(u"Min:")), (4, 0), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border=9)
  1978 + sizer.Add(self.deviation_min, (4, 1))
  1979 +
  1980 + sizer.Add(wx.StaticText(self, -1, _(u"Max:")), (4, 2), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border=9)
  1981 + sizer.Add(self.deviation_max, (4, 3))
  1982 +
  1983 + sizer.AddStretchSpacer((5, 0))
  1984 +
  1985 + self.SetSizer(sizer)
  1986 + sizer.Fit(self)
  1987 + self.Layout()
  1988 +
  1989 + self.use_ww_wl.Bind(wx.EVT_CHECKBOX, self.OnSetUseWWWL)
  1990 + self.deviation_min.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation)
  1991 + self.deviation_max.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation)
  1992 +
  1993 + def OnSetUseWWWL(self, evt):
  1994 + self.config.use_ww_wl = self.use_ww_wl.GetValue()
  1995 +
  1996 + def OnSetDeviation(self, evt):
  1997 + self.config.dev_max = self.deviation_max.GetValue()
  1998 + self.config.dev_min = self.deviation_min.GetValue()
  1999 +
  2000 +
1843 class FFillOptionsDialog(wx.Dialog): 2001 class FFillOptionsDialog(wx.Dialog):
1844 def __init__(self, title, config): 2002 def __init__(self, title, config):
1845 pre = wx.PreDialog() 2003 pre = wx.PreDialog()
@@ -1854,88 +2012,96 @@ class FFillOptionsDialog(wx.Dialog): @@ -1854,88 +2012,96 @@ class FFillOptionsDialog(wx.Dialog):
1854 """ 2012 """
1855 Create the widgets. 2013 Create the widgets.
1856 """ 2014 """
  2015 +
1857 # Target 2016 # Target
1858 - self.target_2d = wx.RadioButton(self, -1, _(u"2D - Actual slice"), style=wx.RB_GROUP)  
1859 - self.target_3d = wx.RadioButton(self, -1, _(u"3D - All slices")) 2017 + if sys.platform == "win32":
  2018 + border_style = wx.SIMPLE_BORDER
  2019 + else:
  2020 + border_style = wx.SUNKEN_BORDER
  2021 +
  2022 + self.panel_target = PanelTargeFFill(self, style=border_style|wx.TAB_TRAVERSAL)
  2023 + self.panel2dcon = Panel2DConnectivity(self, style=border_style|wx.TAB_TRAVERSAL)
  2024 + self.panel3dcon = Panel3DConnectivity(self, style=border_style|wx.TAB_TRAVERSAL)
1860 2025
1861 if self.config.target == "2D": 2026 if self.config.target == "2D":
1862 - self.target_2d.SetValue(1) 2027 + self.panel_target.target_2d.SetValue(1)
  2028 + self.panel2dcon.Enable(1)
  2029 + self.panel3dcon.Enable(0)
1863 else: 2030 else:
1864 - self.target_3d.SetValue(1) 2031 + self.panel_target.target_3d.SetValue(1)
  2032 + self.panel3dcon.Enable(1)
  2033 + self.panel2dcon.Enable(0)
1865 2034
1866 # Connectivity 2D 2035 # Connectivity 2D
1867 - self.conect2D_4 = wx.RadioButton(self, -1, "4", style=wx.RB_GROUP)  
1868 - self.conect2D_8 = wx.RadioButton(self, -1, "8")  
1869 -  
1870 if self.config.con_2d == 8: 2036 if self.config.con_2d == 8:
1871 - self.conect2D_8.SetValue(1) 2037 + self.panel2dcon.conect2D_8.SetValue(1)
1872 else: 2038 else:
1873 - self.conect2D_4.SetValue(1) 2039 + self.panel2dcon.conect2D_4.SetValue(1)
1874 self.config.con_2d = 4 2040 self.config.con_2d = 4
1875 2041
1876 # Connectivity 3D 2042 # Connectivity 3D
1877 - self.conect3D_6 = wx.RadioButton(self, -1, "6", style=wx.RB_GROUP)  
1878 - self.conect3D_18 = wx.RadioButton(self, -1, "18")  
1879 - self.conect3D_26 = wx.RadioButton(self, -1, "26")  
1880 -  
1881 if self.config.con_3d == 18: 2043 if self.config.con_3d == 18:
1882 - self.conect3D_18.SetValue(1) 2044 + self.panel3dcon.conect3D_18.SetValue(1)
1883 elif self.config.con_3d == 26: 2045 elif self.config.con_3d == 26:
1884 - self.conect3D_26.SetValue(1) 2046 + self.panel3dcon.conect3D_26.SetValue(1)
1885 else: 2047 else:
1886 - self.conect3D_6.SetValue(1) 2048 + self.panel3dcon.conect3D_6.SetValue(1)
1887 2049
1888 - # Sizer  
1889 - sizer = wx.GridBagSizer(11, 6)  
1890 - sizer.AddStretchSpacer((0, 0))  
1891 -  
1892 - sizer.Add(wx.StaticText(self, -1, _(u"Parameters")), (1, 0), (1, 6), flag=wx.LEFT, border=7)  
1893 - sizer.Add(self.target_2d, (2, 0), (1, 6), flag=wx.LEFT, border=9)  
1894 - sizer.Add(self.target_3d, (3, 0), (1, 6), flag=wx.LEFT, border=9) 2050 + self.close_btn = wx.Button(self, wx.ID_CLOSE)
1895 2051
1896 - sizer.AddStretchSpacer((4, 0))  
1897 -  
1898 - sizer.Add(wx.StaticText(self, -1, _(u"2D Connectivity")), (5, 0), (1, 6), flag=wx.LEFT, border=9)  
1899 - sizer.Add(self.conect2D_4, (6, 0), flag=wx.LEFT, border=9)  
1900 - sizer.Add(self.conect2D_8, (6, 1), flag=wx.LEFT, border=9)  
1901 -  
1902 - sizer.AddStretchSpacer((7, 0)) 2052 + # Sizer
  2053 + sizer = wx.BoxSizer(wx.VERTICAL)
1903 2054
1904 - sizer.Add(wx.StaticText(self, -1, _(u"3D Connectivity")), (8, 0), (1, 6), flag=wx.LEFT, border=9)  
1905 - sizer.Add(self.conect3D_6, (9, 0), flag=wx.LEFT, border=9)  
1906 - sizer.Add(self.conect3D_18, (9, 1), flag=wx.LEFT, border=9)  
1907 - sizer.Add(self.conect3D_26, (9, 2), flag=wx.LEFT, border=9)  
1908 - sizer.AddStretchSpacer((10, 0)) 2055 + sizer.AddSpacer(5)
  2056 + sizer.Add(wx.StaticText(self, -1, _(u"Parameters")), flag=wx.LEFT, border=5)
  2057 + sizer.AddSpacer(5)
  2058 + sizer.Add(self.panel_target, flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
  2059 + sizer.AddSpacer(5)
  2060 + sizer.Add(self.panel2dcon, flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
  2061 + sizer.AddSpacer(5)
  2062 + sizer.Add(self.panel3dcon, flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
  2063 + sizer.AddSpacer(5)
  2064 + sizer.Add(self.close_btn, 0, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=7)
  2065 + sizer.AddSpacer(5)
1909 2066
1910 self.SetSizer(sizer) 2067 self.SetSizer(sizer)
1911 sizer.Fit(self) 2068 sizer.Fit(self)
1912 self.Layout() 2069 self.Layout()
1913 2070
  2071 + self.close_btn.Bind(wx.EVT_BUTTON, self.OnBtnClose)
1914 self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) 2072 self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio)
1915 self.Bind(wx.EVT_CLOSE, self.OnClose) 2073 self.Bind(wx.EVT_CLOSE, self.OnClose)
1916 2074
  2075 + def OnBtnClose(self, evt):
  2076 + self.Close()
  2077 +
1917 def OnSetRadio(self, evt): 2078 def OnSetRadio(self, evt):
1918 # Target 2079 # Target
1919 - if self.target_2d.GetValue(): 2080 + if self.panel_target.target_2d.GetValue():
1920 self.config.target = "2D" 2081 self.config.target = "2D"
  2082 + self.panel2dcon.Enable(1)
  2083 + self.panel3dcon.Enable(0)
1921 else: 2084 else:
1922 self.config.target = "3D" 2085 self.config.target = "3D"
  2086 + self.panel3dcon.Enable(1)
  2087 + self.panel2dcon.Enable(0)
1923 2088
1924 # 2D 2089 # 2D
1925 - if self.conect2D_4.GetValue(): 2090 + if self.panel2dcon.conect2D_4.GetValue():
1926 self.config.con_2d = 4 2091 self.config.con_2d = 4
1927 - elif self.conect2D_8.GetValue(): 2092 + elif self.panel2dcon.conect2D_8.GetValue():
1928 self.config.con_2d = 8 2093 self.config.con_2d = 8
1929 2094
1930 # 3D 2095 # 3D
1931 - if self.conect3D_6.GetValue(): 2096 + if self.panel3dcon.conect3D_6.GetValue():
1932 self.config.con_3d = 6 2097 self.config.con_3d = 6
1933 - elif self.conect3D_18.GetValue(): 2098 + elif self.panel3dcon.conect3D_18.GetValue():
1934 self.config.con_3d = 18 2099 self.config.con_3d = 18
1935 - elif self.conect3D_26.GetValue(): 2100 + elif self.panel3dcon.conect3D_26.GetValue():
1936 self.config.con_3d = 26 2101 self.config.con_3d = 26
1937 2102
1938 def OnClose(self, evt): 2103 def OnClose(self, evt):
  2104 + print "ONCLOSE"
1939 if self.config.dlg_visible: 2105 if self.config.dlg_visible:
1940 Publisher.sendMessage('Disable style', const.SLICE_STATE_MASK_FFILL) 2106 Publisher.sendMessage('Disable style', const.SLICE_STATE_MASK_FFILL)
1941 evt.Skip() 2107 evt.Skip()
@@ -1950,6 +2116,8 @@ class SelectPartsOptionsDialog(wx.Dialog): @@ -1950,6 +2116,8 @@ class SelectPartsOptionsDialog(wx.Dialog):
1950 2116
1951 self.config = config 2117 self.config = config
1952 2118
  2119 + self.SetReturnCode(wx.CANCEL)
  2120 +
1953 self._init_gui() 2121 self._init_gui()
1954 2122
1955 def _init_gui(self): 2123 def _init_gui(self):
@@ -1957,73 +2125,63 @@ class SelectPartsOptionsDialog(wx.Dialog): @@ -1957,73 +2125,63 @@ class SelectPartsOptionsDialog(wx.Dialog):
1957 self.target_name.SetValue(self.config.mask_name) 2125 self.target_name.SetValue(self.config.mask_name)
1958 2126
1959 # Connectivity 3D 2127 # Connectivity 3D
1960 - self.conect3D_6 = wx.RadioButton(self, -1, "6", style=wx.RB_GROUP)  
1961 - self.conect3D_18 = wx.RadioButton(self, -1, "18")  
1962 - self.conect3D_26 = wx.RadioButton(self, -1, "26")  
1963 - 2128 + self.panel3dcon = Panel3DConnectivity(self)
1964 if self.config.con_3d == 18: 2129 if self.config.con_3d == 18:
1965 - self.conect3D_18.SetValue(1) 2130 + self.panel3dcon.conect3D_18.SetValue(1)
1966 elif self.config.con_3d == 26: 2131 elif self.config.con_3d == 26:
1967 - self.conect3D_26.SetValue(1) 2132 + self.panel3dcon.conect3D_26.SetValue(1)
1968 else: 2133 else:
1969 - self.conect3D_6.SetValue(1)  
1970 -  
1971 - sizer_t = wx.BoxSizer(wx.HORIZONTAL)  
1972 - sizer_t.AddSpacer(7)  
1973 - sizer_t.Add(wx.StaticText(self, -1, _(u"Target mask name")), 1, wx.ALIGN_CENTRE_VERTICAL)  
1974 - sizer_t.AddSpacer(7)  
1975 - sizer_t.Add(self.target_name, 1, wx.EXPAND)  
1976 - sizer_t.AddSpacer(7)  
1977 -  
1978 - sizer_c = wx.BoxSizer(wx.HORIZONTAL)  
1979 - sizer_c.AddSpacer(7)  
1980 - sizer_c.Add(self.conect3D_6)  
1981 - sizer_c.AddSpacer(7)  
1982 - sizer_c.Add(self.conect3D_18)  
1983 - sizer_c.AddSpacer(7)  
1984 - sizer_c.Add(self.conect3D_26) 2134 + self.panel3dcon.conect3D_6.SetValue(1)
1985 2135
1986 - sizer = wx.BoxSizer(wx.VERTICAL)  
1987 - sizer.AddSpacer(7)  
1988 - sizer.Add(sizer_t, 1, wx.EXPAND)  
1989 - sizer.AddSpacer(7)  
1990 - sizer.Add(wx.StaticText(self, -1, _(u"3D Connectivity")), 0, wx.LEFT, 7)  
1991 - sizer.AddSpacer(5)  
1992 - sizer.Add(sizer_c)  
1993 - sizer.AddSpacer(7) 2136 + self.btn_ok = wx.Button(self, wx.ID_OK)
  2137 + self.btn_cancel = wx.Button(self, wx.ID_CANCEL)
1994 2138
1995 - # sizer = wx.GridBagSizer(11, 6)  
1996 - # sizer.AddStretchSpacer((0, 0)) 2139 + sizer = wx.BoxSizer(wx.VERTICAL)
1997 2140
1998 - # sizer.Add(wx.StaticText(self, -1, _(u"Target mask name")), (1, 0), (1, 6), flag=wx.LEFT|wx.ALIGN_BOTTOM|wx.EXPAND, border=7)  
1999 - # sizer.Add(self.target_name, (2, 0), (1, 6), flag=wx.LEFT|wx.EXPAND|wx.RIGHT|wx.ALIGN_TOP, border=9) 2141 + sizer.AddSpacer(5)
  2142 + sizer.Add(wx.StaticText(self, -1, _(u"Target mask name")), flag=wx.LEFT, border=5)
  2143 + sizer.AddSpacer(5)
  2144 + sizer.Add(self.target_name, flag=wx.LEFT|wx.EXPAND|wx.RIGHT, border=9)
  2145 + sizer.AddSpacer(5)
  2146 + sizer.Add(self.panel3dcon, flag=wx.LEFT|wx.RIGHT|wx.EXPAND)
  2147 + sizer.AddSpacer(5)
2000 2148
2001 - # # sizer.AddStretchSpacer((3, 0)) 2149 + btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
  2150 + btn_sizer.Add(self.btn_ok, 0, flag=wx.ALIGN_RIGHT, border=5)
  2151 + btn_sizer.Add(self.btn_cancel, 0, flag=wx.LEFT|wx.ALIGN_RIGHT, border=5)
2002 2152
2003 - # sizer.Add(wx.StaticText(self, -1, _(u"3D Connectivity")), (3, 0), (1, 6), flag=wx.LEFT, border=7)  
2004 - # sizer.Add(self.conect3D_6, (4, 0), flag=wx.LEFT, border=9)  
2005 - # sizer.Add(self.conect3D_18, (4, 1), flag=wx.LEFT, border=9)  
2006 - # sizer.Add(self.conect3D_26, (4, 2), flag=wx.LEFT, border=9)  
2007 - # sizer.AddStretchSpacer((5, 0)) 2153 + sizer.AddSizer(btn_sizer, 0, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT, border=5)
  2154 + sizer.AddSpacer(5)
2008 2155
2009 self.SetSizer(sizer) 2156 self.SetSizer(sizer)
2010 sizer.Fit(self) 2157 sizer.Fit(self)
2011 self.Layout() 2158 self.Layout()
2012 2159
  2160 + self.btn_ok.Bind(wx.EVT_BUTTON, self.OnOk)
  2161 + self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  2162 +
2013 self.target_name.Bind(wx.EVT_CHAR, self.OnChar) 2163 self.target_name.Bind(wx.EVT_CHAR, self.OnChar)
2014 self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) 2164 self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio)
2015 self.Bind(wx.EVT_CLOSE, self.OnClose) 2165 self.Bind(wx.EVT_CLOSE, self.OnClose)
2016 2166
  2167 + def OnOk(self, evt):
  2168 + self.SetReturnCode(wx.OK)
  2169 + self.Close()
  2170 +
  2171 + def OnCancel(self, evt):
  2172 + self.SetReturnCode(wx.CANCEL)
  2173 + self.Close()
  2174 +
2017 def OnChar(self, evt): 2175 def OnChar(self, evt):
2018 evt.Skip() 2176 evt.Skip()
2019 self.config.mask_name = self.target_name.GetValue() 2177 self.config.mask_name = self.target_name.GetValue()
2020 2178
2021 def OnSetRadio(self, evt): 2179 def OnSetRadio(self, evt):
2022 - if self.conect3D_6.GetValue(): 2180 + if self.panel3dcon.conect3D_6.GetValue():
2023 self.config.con_3d = 6 2181 self.config.con_3d = 6
2024 - elif self.conect3D_18.GetValue(): 2182 + elif self.panel3dcon.conect3D_18.GetValue():
2025 self.config.con_3d = 18 2183 self.config.con_3d = 18
2026 - elif self.conect3D_26.GetValue(): 2184 + elif self.panel3dcon.conect3D_26.GetValue():
2027 self.config.con_3d = 26 2185 self.config.con_3d = 26
2028 2186
2029 def OnClose(self, evt): 2187 def OnClose(self, evt):
@@ -2035,7 +2193,7 @@ class SelectPartsOptionsDialog(wx.Dialog): @@ -2035,7 +2193,7 @@ class SelectPartsOptionsDialog(wx.Dialog):
2035 class FFillSegmentationOptionsDialog(wx.Dialog): 2193 class FFillSegmentationOptionsDialog(wx.Dialog):
2036 def __init__(self, config): 2194 def __init__(self, config):
2037 pre = wx.PreDialog() 2195 pre = wx.PreDialog()
2038 - pre.Create(wx.GetApp().GetTopWindow(), -1, _(u"Floodfill Segmentation"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT) 2196 + pre.Create(wx.GetApp().GetTopWindow(), -1, _(u"Region growing"), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT)
2039 self.PostCreate(pre) 2197 self.PostCreate(pre)
2040 2198
2041 self.config = config 2199 self.config = config
@@ -2047,157 +2205,142 @@ class FFillSegmentationOptionsDialog(wx.Dialog): @@ -2047,157 +2205,142 @@ class FFillSegmentationOptionsDialog(wx.Dialog):
2047 Create the widgets. 2205 Create the widgets.
2048 """ 2206 """
2049 import project as prj 2207 import project as prj
  2208 +
2050 # Target 2209 # Target
2051 - self.target_2d = wx.RadioButton(self, -1, _(u"2D - Actual slice"), style=wx.RB_GROUP)  
2052 - self.target_3d = wx.RadioButton(self, -1, _(u"3D - All slices")) 2210 + if sys.platform == "win32":
  2211 + border_style = wx.SIMPLE_BORDER
  2212 + else:
  2213 + border_style = wx.SUNKEN_BORDER
  2214 +
  2215 + self.panel_target = PanelTargeFFill(self, style=border_style|wx.TAB_TRAVERSAL)
  2216 + self.panel2dcon = Panel2DConnectivity(self, style=border_style|wx.TAB_TRAVERSAL)
  2217 + self.panel3dcon = Panel3DConnectivity(self, style=border_style|wx.TAB_TRAVERSAL)
2053 2218
2054 if self.config.target == "2D": 2219 if self.config.target == "2D":
2055 - self.target_2d.SetValue(1) 2220 + self.panel_target.target_2d.SetValue(1)
  2221 + self.panel2dcon.Enable(1)
  2222 + self.panel3dcon.Enable(0)
2056 else: 2223 else:
2057 - self.target_3d.SetValue(1) 2224 + self.panel_target.target_3d.SetValue(1)
  2225 + self.panel3dcon.Enable(1)
  2226 + self.panel2dcon.Enable(0)
2058 2227
2059 # Connectivity 2D 2228 # Connectivity 2D
2060 - self.conect2D_4 = wx.RadioButton(self, -1, "4", style=wx.RB_GROUP)  
2061 - self.conect2D_8 = wx.RadioButton(self, -1, "8")  
2062 -  
2063 if self.config.con_2d == 8: 2229 if self.config.con_2d == 8:
2064 - self.conect2D_8.SetValue(1) 2230 + self.panel2dcon.conect2D_8.SetValue(1)
2065 else: 2231 else:
2066 - self.conect2D_4.SetValue(1) 2232 + self.panel2dcon.conect2D_4.SetValue(1)
2067 self.config.con_2d = 4 2233 self.config.con_2d = 4
2068 2234
2069 # Connectivity 3D 2235 # Connectivity 3D
2070 - self.conect3D_6 = wx.RadioButton(self, -1, "6", style=wx.RB_GROUP)  
2071 - self.conect3D_18 = wx.RadioButton(self, -1, "18")  
2072 - self.conect3D_26 = wx.RadioButton(self, -1, "26")  
2073 -  
2074 if self.config.con_3d == 18: 2236 if self.config.con_3d == 18:
2075 - self.conect3D_18.SetValue(1) 2237 + self.panel3dcon.conect3D_18.SetValue(1)
2076 elif self.config.con_3d == 26: 2238 elif self.config.con_3d == 26:
2077 - self.conect3D_26.SetValue(1) 2239 + self.panel3dcon.conect3D_26.SetValue(1)
2078 else: 2240 else:
2079 - self.conect3D_6.SetValue(1)  
2080 -  
2081 - project = prj.Project()  
2082 - bound_min, bound_max = project.threshold_range  
2083 - colour = [i*255 for i in const.MASK_COLOUR[0]]  
2084 - colour.append(100)  
2085 - self.threshold = grad.GradientCtrl(self, -1, int(bound_min),  
2086 - int(bound_max), self.config.t0,  
2087 - self.config.t1, colour)  
2088 - self.threshold.SetMinSize((250, -1)) 2241 + self.panel3dcon.conect3D_6.SetValue(1)
2089 2242
2090 - self.method_threshold = wx.RadioButton(self, -1, _(u"Threshold"), style=wx.RB_GROUP)  
2091 - self.method_dynamic = wx.RadioButton(self, -1, _(u"Dynamic")) 2243 + self.cmb_method = wx.ComboBox(self, -1, choices=(_(u"Dynamic"), _(u"Threshold")), style=wx.CB_READONLY)
2092 2244
2093 if self.config.method == 'dynamic': 2245 if self.config.method == 'dynamic':
2094 - self.method_dynamic.SetValue(1) 2246 + self.cmb_method.SetSelection(0)
2095 else: 2247 else:
2096 - self.method_threshold.SetValue(1) 2248 + self.cmb_method.SetSelection(1)
2097 self.config.method = 'threshold' 2249 self.config.method = 'threshold'
2098 2250
2099 - self.use_ww_wl = wx.CheckBox(self, -1, _(u"Use WW\&WL"))  
2100 - self.use_ww_wl.SetValue(self.config.use_ww_wl)  
2101 -  
2102 - self.deviation_min = wx.SpinCtrl(self, -1, value='%d' % self.config.dev_min, min=0, max=10000)  
2103 - self.deviation_max = wx.SpinCtrl(self, -1, value='%d' % self.config.dev_max, min=0, max=10000)  
2104 -  
2105 - # Sizer  
2106 - sizer = wx.BoxSizer(wx.VERTICAL) 2251 + self.panel_ffill_threshold = PanelFFillThreshold(self, self.config, -1, style=border_style|wx.TAB_TRAVERSAL)
  2252 + self.panel_ffill_threshold.SetMinSize((250, -1))
  2253 + self.panel_ffill_threshold.Hide()
2107 2254
2108 - sizer.AddSpacer(7) 2255 + self.panel_ffill_dynamic = PanelFFillDynamic(self, self.config, -1, style=border_style|wx.TAB_TRAVERSAL)
  2256 + self.panel_ffill_dynamic.SetMinSize((250, -1))
  2257 + self.panel_ffill_dynamic.Hide()
2109 2258
2110 - sizer.Add(wx.StaticText(self, -1, _(u"Parameters")), flag=wx.LEFT, border=7)  
2111 - sizer.AddSpacer(5)  
2112 - sizer.Add(self.target_2d, flag=wx.LEFT, border=9)  
2113 - sizer.Add(self.target_3d, flag=wx.LEFT, border=9)  
2114 -  
2115 - sizer.AddSpacer(7) 2259 + self.close_btn = wx.Button(self, wx.ID_CLOSE)
2116 2260
2117 - sizer.Add(wx.StaticText(self, -1, _(u"2D Connectivity")), flag=wx.LEFT, border=9)  
2118 - sizer.AddSpacer(5)  
2119 - sizer_2d = wx.BoxSizer(wx.HORIZONTAL)  
2120 - sizer_2d.Add(self.conect2D_4, flag=wx.LEFT, border=11)  
2121 - sizer_2d.Add(self.conect2D_8, flag=wx.LEFT, border=11)  
2122 - sizer.Add(sizer_2d) 2261 + # Sizer
  2262 + sizer = wx.GridBagSizer(2, 2)
2123 2263
2124 - sizer.AddSpacer(7) 2264 + sizer.AddStretchSpacer((0, 0))
  2265 + sizer.Add(wx.StaticText(self, -1, _(u"Parameters")), (1, 0), (1, 6), flag=wx.LEFT, border=5)
  2266 + sizer.AddStretchSpacer((2, 0))
  2267 + sizer.Add(self.panel_target, (3, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
  2268 + sizer.AddStretchSpacer((4, 0))
  2269 + sizer.Add(self.panel2dcon, (5, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
  2270 + sizer.AddStretchSpacer((6, 0))
  2271 + sizer.Add(self.panel3dcon, (7, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
  2272 + sizer.AddStretchSpacer((8, 0))
2125 2273
2126 - sizer.Add(wx.StaticText(self, -1, _(u"3D Connectivity")), flag=wx.LEFT, border=9)  
2127 - sizer.AddSpacer(5)  
2128 - sizer_3d = wx.BoxSizer(wx.HORIZONTAL)  
2129 - sizer_3d.Add(self.conect3D_6, flag=wx.LEFT, border=11)  
2130 - sizer_3d.Add(self.conect3D_18, flag=wx.LEFT, border=11)  
2131 - sizer_3d.Add(self.conect3D_26, flag=wx.LEFT, border=11)  
2132 - sizer.Add(sizer_3d) 2274 + sizer.Add(wx.StaticText(self, -1, _(u"Method")), (9, 0), (1, 1), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=7)
  2275 + sizer.Add(self.cmb_method, (9, 1), (1, 5), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
2133 2276
2134 - sizer.AddSpacer(7) 2277 + sizer.AddStretchSpacer((10, 0))
2135 2278
2136 - sizer.Add(wx.StaticText(self, -1, _(u"Method")), flag=wx.LEFT, border=9)  
2137 - sizer.AddSpacer(5)  
2138 - sizer.Add(self.method_threshold, flag=wx.LEFT, border=11)  
2139 - sizer.AddSpacer(5)  
2140 - sizer.Add(self.threshold, flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=13)  
2141 - sizer.AddSpacer(5)  
2142 - sizer.Add(self.method_dynamic, flag=wx.LEFT, border=11)  
2143 - sizer.AddSpacer(5)  
2144 - sizer.Add(self.use_ww_wl, flag=wx.LEFT, border=13)  
2145 - sizer.AddSpacer(5)  
2146 - sizer.Add(self.deviation_min, flag=wx.LEFT, border=13)  
2147 - sizer.Add(self.deviation_max, flag=wx.LEFT, border=13) 2279 + if self.config.method == 'dynamic':
  2280 + self.cmb_method.SetSelection(0)
  2281 + self.panel_ffill_dynamic.Show()
  2282 + sizer.Add(self.panel_ffill_dynamic, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
  2283 + else:
  2284 + self.cmb_method.SetSelection(1)
  2285 + self.panel_ffill_threshold.Show()
  2286 + sizer.Add(self.panel_ffill_threshold, (11, 0), (1, 6), flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=7)
  2287 + self.config.method = 'threshold'
2148 2288
2149 - sizer.AddSpacer(7) 2289 + sizer.AddStretchSpacer((12, 0))
  2290 + sizer.Add(self.close_btn, (13, 0), (1, 6), flag=wx.ALIGN_RIGHT|wx.RIGHT, border=5)
  2291 + sizer.AddStretchSpacer((14, 0))
2150 2292
2151 self.SetSizer(sizer) 2293 self.SetSizer(sizer)
2152 sizer.Fit(self) 2294 sizer.Fit(self)
2153 self.Layout() 2295 self.Layout()
2154 2296
2155 self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) 2297 self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio)
2156 - self.Bind(grad.EVT_THRESHOLD_CHANGING, self.OnSlideChanged, self.threshold)  
2157 - self.Bind(grad.EVT_THRESHOLD_CHANGED, self.OnSlideChanged, self.threshold)  
2158 - self.use_ww_wl.Bind(wx.EVT_CHECKBOX, self.OnSetUseWWWL)  
2159 - self.deviation_min.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation)  
2160 - self.deviation_max.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation) 2298 + self.cmb_method.Bind(wx.EVT_COMBOBOX, self.OnSetMethod)
  2299 + self.close_btn.Bind(wx.EVT_BUTTON, self.OnBtnClose)
2161 self.Bind(wx.EVT_CLOSE, self.OnClose) 2300 self.Bind(wx.EVT_CLOSE, self.OnClose)
2162 2301
2163 def OnSetRadio(self, evt): 2302 def OnSetRadio(self, evt):
2164 # Target 2303 # Target
2165 - if self.target_2d.GetValue(): 2304 + if self.panel_target.target_2d.GetValue():
2166 self.config.target = "2D" 2305 self.config.target = "2D"
  2306 + self.panel2dcon.Enable(1)
  2307 + self.panel3dcon.Enable(0)
2167 else: 2308 else:
2168 self.config.target = "3D" 2309 self.config.target = "3D"
  2310 + self.panel3dcon.Enable(1)
  2311 + self.panel2dcon.Enable(0)
2169 2312
2170 # 2D 2313 # 2D
2171 - if self.conect2D_4.GetValue(): 2314 + if self.panel2dcon.conect2D_4.GetValue():
2172 self.config.con_2d = 4 2315 self.config.con_2d = 4
2173 - elif self.conect2D_8.GetValue(): 2316 + elif self.panel2dcon.conect2D_8.GetValue():
2174 self.config.con_2d = 8 2317 self.config.con_2d = 8
2175 2318
2176 # 3D 2319 # 3D
2177 - if self.conect3D_6.GetValue(): 2320 + if self.panel3dcon.conect3D_6.GetValue():
2178 self.config.con_3d = 6 2321 self.config.con_3d = 6
2179 - elif self.conect3D_18.GetValue(): 2322 + elif self.panel3dcon.conect3D_18.GetValue():
2180 self.config.con_3d = 18 2323 self.config.con_3d = 18
2181 - elif self.conect3D_26.GetValue(): 2324 + elif self.panel3dcon.conect3D_26.GetValue():
2182 self.config.con_3d = 26 2325 self.config.con_3d = 26
2183 2326
2184 - # Method  
2185 - if self.method_threshold.GetValue():  
2186 - self.config.method = 'threshold'  
2187 - else: 2327 + def OnSetMethod(self, evt):
  2328 + if self.cmb_method.GetSelection() == 0:
2188 self.config.method = 'dynamic' 2329 self.config.method = 'dynamic'
  2330 + self.panel_ffill_threshold.Hide()
  2331 + self.panel_ffill_dynamic.Show()
  2332 + self.GetSizer().Replace(self.panel_ffill_threshold, self.panel_ffill_dynamic)
  2333 + else:
  2334 + self.config.method = 'threshold'
  2335 + self.panel_ffill_dynamic.Hide()
  2336 + self.panel_ffill_threshold.Show()
  2337 + self.GetSizer().Replace(self.panel_ffill_dynamic, self.panel_ffill_threshold)
2189 2338
2190 - def OnSlideChanged(self, evt):  
2191 - self.config.t0 = int(self.threshold.GetMinValue())  
2192 - self.config.t1 = int(self.threshold.GetMaxValue())  
2193 - print self.config.t0, self.config.t1  
2194 -  
2195 - def OnSetUseWWWL(self, evt):  
2196 - self.config.use_ww_wl = self.use_ww_wl.GetValue() 2339 + self.GetSizer().Fit(self)
  2340 + self.Layout()
2197 2341
2198 - def OnSetDeviation(self, evt):  
2199 - self.config.dev_max = self.deviation_max.GetValue()  
2200 - self.config.dev_min = self.deviation_min.GetValue() 2342 + def OnBtnClose(self, evt):
  2343 + self.Close()
2201 2344
2202 def OnClose(self, evt): 2345 def OnClose(self, evt):
2203 if self.config.dlg_visible: 2346 if self.config.dlg_visible:
@@ -2205,6 +2348,7 @@ class FFillSegmentationOptionsDialog(wx.Dialog): @@ -2205,6 +2348,7 @@ class FFillSegmentationOptionsDialog(wx.Dialog):
2205 evt.Skip() 2348 evt.Skip()
2206 self.Destroy() 2349 self.Destroy()
2207 2350
  2351 +
2208 class CropOptionsDialog(wx.Dialog): 2352 class CropOptionsDialog(wx.Dialog):
2209 2353
2210 def __init__(self, config): 2354 def __init__(self, config):
invesalius/gui/frame.py
@@ -765,7 +765,7 @@ class MenuBar(wx.MenuBar): @@ -765,7 +765,7 @@ class MenuBar(wx.MenuBar):
765 765
766 # Segmentation Menu 766 # Segmentation Menu
767 segmentation_menu = wx.Menu() 767 segmentation_menu = wx.Menu()
768 - self.ffill_segmentation = segmentation_menu.Append(const.ID_FLOODFILL_SEGMENTATION, _(u"Floodfill")) 768 + self.ffill_segmentation = segmentation_menu.Append(const.ID_FLOODFILL_SEGMENTATION, _(u"Region growing"))
769 self.ffill_segmentation.Enable(False) 769 self.ffill_segmentation.Enable(False)
770 770
771 tools_menu.AppendMenu(-1, _("Segmentation"), segmentation_menu) 771 tools_menu.AppendMenu(-1, _("Segmentation"), segmentation_menu)