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.

237 lines
7.2 KiB

  1. from functools import partial
  2. import wx
  3. from gooey.gui.util import wx_util
  4. from gooey.gui.widgets import widget_pack
  5. class BaseGuiComponent(object):
  6. widget_class = None
  7. def __init__(self, parent, title, msg, choices=None):
  8. '''
  9. :param data: field info (title, help, etc..)
  10. :param widget_pack: internal wxWidgets to render
  11. '''
  12. # parent
  13. self.parent = parent
  14. # Widgets
  15. self.title = None
  16. self.help_msg = None
  17. self.choices = choices
  18. # Internal WidgetPack set in subclasses
  19. self.do_layout(parent, title, msg)
  20. def do_layout(self, parent, title, msg):
  21. self.panel = wx.Panel(parent)
  22. self.widget_pack = self.widget_class()
  23. self.title = self.format_title(self.panel, title)
  24. self.help_msg = self.format_help_msg(self.panel, msg)
  25. self.help_msg.SetMinSize((0, -1))
  26. core_widget_set = self.widget_pack.build(self.panel, {}, self.choices)
  27. vertical_container = wx.BoxSizer(wx.VERTICAL)
  28. vertical_container.Add(self.title)
  29. vertical_container.AddSpacer(2)
  30. if self.help_msg.GetLabelText():
  31. vertical_container.Add(self.help_msg, 1, wx.EXPAND)
  32. vertical_container.AddSpacer(2)
  33. else:
  34. vertical_container.AddStretchSpacer(1)
  35. vertical_container.Add(core_widget_set, 0, wx.EXPAND)
  36. self.panel.SetSizer(vertical_container)
  37. return self.panel
  38. def bind(self, *args, **kwargs):
  39. print self.widget_pack.widget.Bind(*args, **kwargs)
  40. def get_title(self):
  41. return self.title.GetLabel()
  42. def set_title(self, text):
  43. self.title.SetLabel(text)
  44. def get_help_msg(self):
  45. return self.help_msg.GetLabelText()
  46. def set_label_text(self, text):
  47. self.help_msg.SetLabel(text)
  48. def format_help_msg(self, parent, msg):
  49. base_text = wx.StaticText(parent, label=msg or '')
  50. wx_util.dark_grey(base_text)
  51. return base_text
  52. def format_title(self, parent, title):
  53. text = wx.StaticText(parent, label=title)
  54. wx_util.make_bold(text)
  55. return text
  56. def onResize(self, evt):
  57. # handle internal widgets
  58. # self.panel.Freeze()
  59. self._onResize(evt)
  60. # propagate event to child widgets
  61. self.widget_pack.onResize(evt)
  62. evt.Skip()
  63. # self.panel.Thaw()
  64. def _onResize(self, evt):
  65. if not self.help_msg:
  66. return
  67. self.panel.Size = evt.GetSize()
  68. container_width, _ = self.panel.Size
  69. text_width, _ = self.help_msg.Size
  70. if text_width != container_width:
  71. self.help_msg.SetLabel(self.help_msg.GetLabelText().replace('\n', ' '))
  72. self.help_msg.Wrap(container_width)
  73. evt.Skip()
  74. def get_value(self):
  75. return self.widget_pack.get_value()
  76. def set_value(self, val):
  77. if val:
  78. self.widget_pack.widget.SetValue(unicode(val))
  79. def __repr__(self):
  80. return self.__class__.__name__
  81. class CheckBox(BaseGuiComponent):
  82. def __init__(self, parent, title, msg, choices=None):
  83. BaseGuiComponent.__init__(self, parent, title, msg)
  84. def do_layout(self, parent, title, msg):
  85. self.panel = wx.Panel(parent)
  86. self.widget = wx.CheckBox(self.panel)
  87. # self.widget.SetValue(self.default_value)
  88. self.title = self.format_title(self.panel, title)
  89. self.help_msg = self.format_help_msg(self.panel, msg)
  90. self.help_msg.SetMinSize((0, -1))
  91. # self.help_msg.Bind(wx.EVT_LEFT_UP, lambda event: self.widget.SetValue(not self.widget.GetValue()))
  92. vertical_container = wx.BoxSizer(wx.VERTICAL)
  93. vertical_container.Add(self.title)
  94. horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
  95. horizontal_sizer.Add(self.widget, 0, wx.EXPAND | wx.RIGHT, 10)
  96. horizontal_sizer.Add(self.help_msg, 1, wx.EXPAND)
  97. vertical_container.Add(horizontal_sizer, 0, wx.EXPAND)
  98. self.panel.SetSizer(vertical_container)
  99. self.panel.Bind(wx.EVT_SIZE, self.onResize)
  100. return self.panel
  101. def onResize(self, evt):
  102. msg = self.help_msg
  103. container_width, _ = self.panel.Size
  104. text_width, _ = msg.Size
  105. if text_width != container_width:
  106. msg.SetLabel(msg.GetLabelText().replace('\n', ' '))
  107. msg.Wrap(container_width)
  108. evt.Skip()
  109. def get_value(self):
  110. return self.widget.GetValue()
  111. def set_value(self, val):
  112. self.widget.SetValue(val)
  113. class RadioGroup(object):
  114. def __init__(self, parent, title, msg, choices=None):
  115. self.panel = None
  116. self.radio_buttons = []
  117. self.option_strings = []
  118. self.help_msgs = []
  119. self.btn_names = []
  120. self.do_layout(parent, title, msg)
  121. def do_layout(self, parent, titles, msgs):
  122. self.panel = wx.Panel(parent)
  123. self.radio_buttons = [wx.RadioButton(self.panel, -1) for _ in titles]
  124. self.btn_names = [wx.StaticText(self.panel, label=title.title()) for title in titles]
  125. self.help_msgs = [wx.StaticText(self.panel, label=msg.title()) for msg in msgs]
  126. # box = wx.StaticBox(self.panel, -1, label=self.data['group_name'])
  127. box = wx.StaticBox(self.panel, -1, label='')
  128. vertical_container = wx.StaticBoxSizer(box, wx.VERTICAL)
  129. for button, name, help in zip(self.radio_buttons, self.btn_names, self.help_msgs):
  130. hbox = wx.BoxSizer(wx.HORIZONTAL)
  131. hbox.Add(button, 0, wx.ALIGN_TOP | wx.ALIGN_LEFT)
  132. hbox.Add(name, 0, wx.LEFT, 10)
  133. vertical_container.Add(hbox, 0, wx.EXPAND)
  134. vertical_container.Add(help, 1, wx.EXPAND | wx.LEFT, 25)
  135. vertical_container.AddSpacer(5)
  136. self.panel.SetSizer(vertical_container)
  137. self.panel.Bind(wx.EVT_SIZE, self.onResize)
  138. self.panel.Bind(wx.EVT_RADIOBUTTON, self.showz)
  139. return self.panel
  140. def showz(self, evt):
  141. print evt
  142. for i in self.radio_buttons:
  143. print i.GetValue()
  144. def onResize(self, evt):
  145. msg = self.help_msgs[0]
  146. container_width, _ = self.panel.Size
  147. text_width, _ = msg.Size
  148. if text_width != container_width:
  149. msg.SetLabel(msg.GetLabelText().replace('\n', ' '))
  150. msg.Wrap(container_width)
  151. evt.Skip()
  152. def get_value(self):
  153. return [button.GetValue() for button in self.radio_buttons]
  154. def set_value(self, val):
  155. pass
  156. def build_subclass(name, widget_class):
  157. # this seemed faster than typing class X a bunch
  158. return type(name, (BaseGuiComponent,), {'widget_class': widget_class})
  159. FileChooser = build_subclass('FileChooser', widget_pack.FileChooserPayload)
  160. MultiFileChooser = build_subclass('MultiFileChooser', widget_pack.MultiFileSaverPayload)
  161. DirChooser = build_subclass('DirChooser', widget_pack.DirChooserPayload)
  162. FileSaver = build_subclass('FileSaver', widget_pack.FileSaverPayload)
  163. DateChooser = build_subclass('DateChooser', widget_pack.DateChooserPayload)
  164. TextField = build_subclass('TextField', widget_pack.TextInputPayload)
  165. Textarea = build_subclass('TextField', widget_pack.TextAreaPayload)
  166. CommandField = build_subclass('CommandField', widget_pack.TextInputPayload(no_quoting=True))
  167. Dropdown = build_subclass('Dropdown', widget_pack.DropdownPayload)
  168. Counter = build_subclass('Counter', widget_pack.CounterPayload)
  169. MultiDirChooser = build_subclass('MultiDirChooser', widget_pack.MultiDirChooserPayload)
  170. PasswordField = build_subclass('PasswordField', widget_pack.PasswordInputPayload)