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.

180 lines
5.9 KiB

  1. from functools import reduce
  2. import wx
  3. from gooey.gui import formatters, events
  4. from gooey.gui.util import wx_util
  5. from gooey.util.functional import getin, ifPresent
  6. from gooey.gui.validators import runValidator
  7. from gooey.gui.components.util.wrapped_static_text import AutoWrappedStaticText
  8. class BaseWidget(wx.Panel):
  9. widget_class = None
  10. def arrange(self, label, text):
  11. raise NotImplementedError
  12. def getWidget(self, parent, **options):
  13. return self.widget_class(parent, **options)
  14. def connectSignal(self):
  15. raise NotImplementedError
  16. def getSublayout(self, *args, **kwargs):
  17. raise NotImplementedError
  18. def setValue(self, value):
  19. raise NotImplementedError
  20. def receiveChange(self, *args, **kwargs):
  21. raise NotImplementedError
  22. def dispatchChange(self, value, **kwargs):
  23. raise NotImplementedError
  24. def formatOutput(self, metatdata, value):
  25. raise NotImplementedError
  26. class TextContainer(BaseWidget):
  27. widget_class = None
  28. def __init__(self, parent, widgetInfo, *args, **kwargs):
  29. super(TextContainer, self).__init__(parent, *args, **kwargs)
  30. self.info = widgetInfo
  31. self._id = widgetInfo['id']
  32. self._meta = widgetInfo['data']
  33. self._options = widgetInfo['options']
  34. self.label = wx.StaticText(self, label=widgetInfo['data']['display_name'])
  35. self.help_text = AutoWrappedStaticText(self, label=widgetInfo['data']['help'] or '')
  36. self.error = AutoWrappedStaticText(self, label='')
  37. self.error.Hide()
  38. self.widget = self.getWidget(self)
  39. self.layout = self.arrange(*args, **kwargs)
  40. self.setColors()
  41. self.SetSizer(self.layout)
  42. self.Bind(wx.EVT_SIZE, self.onSize)
  43. # Checking for None instead of truthiness means False-evaluaded defaults can be used.
  44. if self._meta['default'] is not None:
  45. self.setValue(self._meta['default'])
  46. def arrange(self, *args, **kwargs):
  47. wx_util.make_bold(self.label)
  48. wx_util.withColor(self.label, self._options['label_color'])
  49. wx_util.withColor(self.help_text, self._options['help_color'])
  50. wx_util.withColor(self.error, self._options['error_color'])
  51. self.help_text.SetMinSize((0,-1))
  52. layout = wx.BoxSizer(wx.VERTICAL)
  53. if self._options.get('show_label', True):
  54. layout.Add(self.label, 0, wx.EXPAND)
  55. else:
  56. self.label.Show(False)
  57. layout.AddStretchSpacer(1)
  58. layout.AddSpacer(2)
  59. if self.help_text and self._options.get('show_help', True):
  60. layout.Add(self.help_text, 1, wx.EXPAND)
  61. layout.AddSpacer(2)
  62. else:
  63. self.help_text.Show(False)
  64. layout.AddStretchSpacer(1)
  65. layout.Add(self.getSublayout(), 0, wx.EXPAND)
  66. layout.Add(self.error, 1, wx.EXPAND)
  67. self.error.Hide()
  68. return layout
  69. def setColors(self):
  70. wx_util.make_bold(self.label)
  71. wx_util.withColor(self.label, self._options['label_color'])
  72. wx_util.withColor(self.help_text, self._options['help_color'])
  73. wx_util.withColor(self.error, self._options['error_color'])
  74. if self._options.get('label_bg_color'):
  75. self.label.SetBackgroundColour(self._options.get('label_bg_color'))
  76. if self._options.get('help_bg_color'):
  77. self.help_text.SetBackgroundColour(self._options.get('help_bg_color'))
  78. if self._options.get('error_bg_color'):
  79. self.error.SetBackgroundColour(self._options.get('error_bg_color'))
  80. def getWidget(self, *args, **options):
  81. return self.widget_class(*args, **options)
  82. def getWidgetValue(self):
  83. raise NotImplementedError
  84. def getSublayout(self, *args, **kwargs):
  85. layout = wx.BoxSizer(wx.HORIZONTAL)
  86. layout.Add(self.widget, 1, wx.EXPAND)
  87. return layout
  88. def onSize(self, event):
  89. # print(self.GetSize())
  90. # self.error.Wrap(self.GetSize().width)
  91. # self.help_text.Wrap(500)
  92. # self.Layout()
  93. event.Skip()
  94. def getValue(self):
  95. userValidator = getin(self._options, ['validator', 'test'], 'True')
  96. message = getin(self._options, ['validator', 'message'], '')
  97. testFunc = eval('lambda user_input: bool(%s)' % userValidator)
  98. satisfies = testFunc if self._meta['required'] else ifPresent(testFunc)
  99. value = self.getWidgetValue()
  100. return {
  101. 'id': self._id,
  102. 'cmd': self.formatOutput(self._meta, value),
  103. 'rawValue': value,
  104. 'test': runValidator(satisfies, value),
  105. 'error': None if runValidator(satisfies, value) else message,
  106. 'clitype': 'positional'
  107. if self._meta['required'] and not self._meta['commands']
  108. else 'optional'
  109. }
  110. def setValue(self, value):
  111. self.widget.SetValue(value)
  112. def setErrorString(self, message):
  113. self.error.SetLabel(message)
  114. self.error.Wrap(self.Size.width)
  115. self.Layout()
  116. def showErrorString(self, b):
  117. self.error.Wrap(self.Size.width)
  118. self.error.Show(b)
  119. def setOptions(self, values):
  120. return None
  121. def receiveChange(self, metatdata, value):
  122. raise NotImplementedError
  123. def dispatchChange(self, value, **kwargs):
  124. raise NotImplementedError
  125. def formatOutput(self, metadata, value):
  126. raise NotImplementedError
  127. class BaseChooser(TextContainer):
  128. """ Base Class for the Chooser widget types """
  129. def setValue(self, value):
  130. self.widget.setValue(value)
  131. def getWidgetValue(self):
  132. return self.widget.getValue()
  133. def formatOutput(self, metatdata, value):
  134. return formatters.general(metatdata, value)