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.

62 lines
2.0 KiB

  1. from contextlib import contextmanager
  2. from gooey.gui.components.widgets.bases import TextContainer
  3. import wx
  4. from gooey.gui import formatters
  5. from gooey.gui.lang.i18n import _
  6. class Dropdown(TextContainer):
  7. _gooey_options = {
  8. 'placeholder': str,
  9. 'readonly': bool,
  10. 'enable_autocomplete': bool
  11. }
  12. def getWidget(self, parent, *args, **options):
  13. default = _('select_option')
  14. return wx.ComboBox(
  15. parent=parent,
  16. id=-1,
  17. # str conversion allows using stringyfiable values in addition to pure strings
  18. value=str(default),
  19. choices=[str(default)] + [str(choice) for choice in self._meta['choices']],
  20. style=wx.CB_DROPDOWN)
  21. def setOptions(self, options):
  22. with self.retainSelection():
  23. self.widget.Clear()
  24. self.widget.SetItems([_('select_option')] + options)
  25. def setValue(self, value):
  26. ## +1 to offset the default placeholder value
  27. index = self._meta['choices'].index(value) + 1
  28. self.widget.SetSelection(index)
  29. def getWidgetValue(self):
  30. value = self.widget.GetValue()
  31. # filter out the extra default option that's
  32. # appended during creation
  33. if value == _('select_option'):
  34. return None
  35. return value
  36. def formatOutput(self, metadata, value):
  37. return formatters.dropdown(metadata, value)
  38. @contextmanager
  39. def retainSelection(self):
  40. """"
  41. Retains the selected dropdown option (when possible)
  42. across mutations due to dynamic updates.
  43. """
  44. prevSelection = self.widget.GetSelection()
  45. prevValue = self.widget.GetValue()
  46. try:
  47. yield
  48. finally:
  49. current_at_index = self.widget.GetString(prevSelection)
  50. if prevValue == current_at_index:
  51. self.widget.SetSelection(prevSelection)
  52. else:
  53. self.widget.SetSelection(0)