You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.4 KiB

8 years ago
  1. """
  2. Managed the internal layout for configuration options
  3. @author: Chris
  4. """
  5. import wx
  6. from wx.lib.scrolledpanel import ScrolledPanel
  7. from itertools import chain, izip_longest
  8. from gooey.gui.util import wx_util
  9. from gooey.gui.lang import i18n
  10. from gooey.gui.widgets import components
  11. PADDING = 10
  12. class WidgetContainer(wx.Panel):
  13. '''
  14. Collection of widgets
  15. '''
  16. def __init__(self, parent, section_name, *args, **kwargs):
  17. wx.Panel.__init__(self, parent, *args, **kwargs)
  18. self.section_name = section_name
  19. self.title = None
  20. self.widgets = []
  21. self.container = wx.BoxSizer(wx.VERTICAL)
  22. self.SetSizer(self.container)
  23. def layout(self, num_columns):
  24. STD_LAYOUT = (0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING)
  25. if self.title:
  26. self.container.Add(wx_util.h0(self, self.title), 0, wx.LEFT | wx.RIGHT, PADDING)
  27. self.container.AddSpacer(30)
  28. if self.widgets:
  29. self.container.Add(wx_util.h1(self, self.section_name), 0, wx.LEFT | wx.RIGHT, PADDING)
  30. self.container.AddSpacer(5)
  31. self.container.Add(wx_util.horizontal_rule(self), *STD_LAYOUT)
  32. self.container.AddSpacer(20)
  33. self.create_component_grid(self.container, self.widgets, cols=num_columns)
  34. self.container.AddSpacer(10)
  35. def populate(self, widgets, num_columns):
  36. for index, widget in enumerate(widgets):
  37. widget_class = getattr(components, widget.type)
  38. widget_instance = widget_class(self, widget.title, widget.help, widget.choices)
  39. self.widgets.append(widget_instance)
  40. self.layout(num_columns)
  41. def get_values(self):
  42. return [x.get_value() for x in self.widgets]
  43. def clear(self):
  44. self.container.Clear(True)
  45. self.widgets = []
  46. def create_component_grid(self, parent_sizer, components, cols=2):
  47. for row in self.chunk(components, cols):
  48. hsizer = wx.BoxSizer(wx.HORIZONTAL)
  49. for widget in filter(None, row):
  50. hsizer.Add(widget.panel, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
  51. parent_sizer.Add(hsizer, 0, wx.EXPAND)
  52. parent_sizer.AddSpacer(20)
  53. def chunk(self, iterable, n, fillvalue=None):
  54. "itertools recipe: Collect data into fixed-length chunks or blocks"
  55. args = [iter(iterable)] * n
  56. return izip_longest(fillvalue=fillvalue, *args)
  57. def __iter__(self):
  58. return iter(self.widgets)
  59. class ConfigPanel(ScrolledPanel):
  60. def __init__(self, parent, req_cols=1, opt_cols=3, title=None, **kwargs):
  61. ScrolledPanel.__init__(self, parent, **kwargs)
  62. self.SetupScrolling(scroll_x=False, scrollToTop=False)
  63. self.SetDoubleBuffered(True)
  64. self.title = title
  65. self._num_req_cols = req_cols
  66. self._num_opt_cols = opt_cols
  67. self.required_section = WidgetContainer(self, i18n._("required_args_msg"))
  68. self.optional_section = WidgetContainer(self, i18n._("optional_args_msg"))
  69. self._do_layout()
  70. self.Bind(wx.EVT_SIZE, self.OnResize)
  71. def _do_layout(self):
  72. STD_LAYOUT = (0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING)
  73. container = wx.BoxSizer(wx.VERTICAL)
  74. container.AddSpacer(15)
  75. container.Add(self.required_section, *STD_LAYOUT)
  76. container.Add(self.optional_section, *STD_LAYOUT)
  77. self.SetSizer(container)
  78. def OnResize(self, evt):
  79. self.SetupScrolling(scroll_x=False, scrollToTop=False)
  80. evt.Skip()
  81. def clear(self):
  82. self.required_section.clear()
  83. self.optional_section.clear()