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.

113 lines
3.5 KiB

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