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.6 KiB

9 years ago
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. 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 import component_builder
  11. from gooey.gui.option_reader import OptionReader
  12. PADDING = 10
  13. class ConfigPanel(ScrolledPanel, OptionReader):
  14. def __init__(self, parent, widgets=None, req_cols=1, opt_cols=3, title=None, **kwargs):
  15. ScrolledPanel.__init__(self, parent, **kwargs)
  16. self.SetupScrolling(scroll_x=False, scrollToTop=False)
  17. self.SetDoubleBuffered(True)
  18. self.title = title
  19. self.widgets = component_builder.build_components(widgets)
  20. self._num_req_cols = req_cols
  21. self._num_opt_cols = opt_cols
  22. self._controller = None
  23. self._do_layout()
  24. self.Bind(wx.EVT_SIZE, self.OnResize)
  25. def _do_layout(self):
  26. STD_LAYOUT = (0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING)
  27. container = wx.BoxSizer(wx.VERTICAL)
  28. container.AddSpacer(15)
  29. if self.title:
  30. container.Add(wx_util.h0(self, self.title), 0, wx.LEFT | wx.RIGHT, PADDING)
  31. container.AddSpacer(30)
  32. if self.widgets.required_args:
  33. container.Add(wx_util.h1(self, i18n._("required_args_msg")), 0, wx.LEFT | wx.RIGHT, PADDING)
  34. container.AddSpacer(5)
  35. container.Add(wx_util.horizontal_rule(self), *STD_LAYOUT)
  36. container.AddSpacer(20)
  37. self.CreateComponentGrid(container, self.widgets.required_args, cols=self._num_req_cols)
  38. container.AddSpacer(10)
  39. if self.widgets.optional_args:
  40. # container.AddSpacer(10)
  41. container.Add(wx_util.h1(self, i18n._("optional_args_msg")), 0, wx.LEFT | wx.RIGHT, PADDING)
  42. container.AddSpacer(5)
  43. container.Add(wx_util.horizontal_rule(self), *STD_LAYOUT)
  44. container.AddSpacer(20)
  45. self.CreateComponentGrid(container, self.widgets.optional_args, cols=self._num_opt_cols)
  46. self.SetSizer(container)
  47. def CreateComponentGrid(self, parent_sizer, components, cols=2):
  48. for row in self.chunk(components, cols):
  49. hsizer = wx.BoxSizer(wx.HORIZONTAL)
  50. for widget in filter(None, row):
  51. hsizer.Add(widget.build(self), 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
  52. # hsizer.FitInside(parent_sizer)
  53. parent_sizer.Add(hsizer, 0, wx.EXPAND)
  54. parent_sizer.AddSpacer(20)
  55. def OnResize(self, evt):
  56. self.SetupScrolling(scroll_x=False, scrollToTop=False)
  57. evt.Skip()
  58. def RegisterController(self, controller):
  59. if self._controller is None:
  60. self._controller = controller
  61. def GetOptions(self):
  62. """
  63. returns the collective values from all of the
  64. widgets contained in the panel"""
  65. _f = lambda lst: [x for x in lst if x is not None]
  66. optional_args = _f([c.GetValue() for c in self.widgets.optional_args])
  67. required_args = _f([c.GetValue() for c in self.widgets.required_args if c.HasOptionString()])
  68. position_args = _f([c.GetValue() for c in self.widgets.required_args if not c.HasOptionString()])
  69. if position_args: position_args.insert(0, "--")
  70. return ' '.join(chain(required_args, optional_args, position_args))
  71. def GetRequiredArgs(self):
  72. return [arg.GetValue() for arg in self.widgets.required_args]
  73. def chunk(self, iterable, n, fillvalue=None):
  74. "itertools recipe: Collect data into fixed-length chunks or blocks"
  75. # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
  76. args = [iter(iterable)] * n
  77. return izip_longest(fillvalue=fillvalue, *args)
  78. if __name__ == '__main__':
  79. pass