mirror of https://github.com/chriskiehl/Gooey.git
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.
84 lines
2.9 KiB
84 lines
2.9 KiB
from contextlib import contextmanager
|
|
|
|
from gooey.gui.components.widgets.bases import TextContainer
|
|
import wx # type: ignore
|
|
|
|
from gooey.gui import formatters
|
|
from gooey.gui.lang.i18n import _
|
|
from gooey.python_bindings import types as t
|
|
from gooey.python_bindings.types import FormField
|
|
|
|
|
|
class Dropdown(TextContainer):
|
|
_gooey_options = {
|
|
'placeholder': str,
|
|
'readonly': bool,
|
|
'enable_autocomplete': bool
|
|
}
|
|
def getWidget(self, parent, *args, **options):
|
|
default = _('select_option')
|
|
return wx.ComboBox(
|
|
parent=parent,
|
|
id=-1,
|
|
# str conversion allows using stringyfiable values in addition to pure strings
|
|
value=str(default),
|
|
choices=[str(default)] + [str(choice) for choice in self._meta['choices']],
|
|
style=wx.CB_DROPDOWN)
|
|
|
|
def setOptions(self, options):
|
|
with self.retainSelection():
|
|
self.widget.Clear()
|
|
self.widget.SetItems([_('select_option')] + options)
|
|
|
|
def setValue(self, value):
|
|
## +1 to offset the default placeholder value
|
|
index = self._meta['choices'].index(value) + 1
|
|
self.widget.SetSelection(index)
|
|
|
|
def getWidgetValue(self):
|
|
value = self.widget.GetValue()
|
|
# filter out the extra default option that's
|
|
# appended during creation
|
|
if value == _('select_option'):
|
|
return None
|
|
return value
|
|
|
|
def formatOutput(self, metadata, value):
|
|
return formatters.dropdown(metadata, value)
|
|
|
|
|
|
def syncUiState(self, state: FormField):
|
|
self.setOptions(state['choices']) # type: ignore
|
|
if state['selected'] is not None: # type: ignore
|
|
self.setValue(state['selected']) # type: ignore
|
|
self.error.SetLabel(state['error'] or '')
|
|
self.error.Show(state['error'] is not None and state['error'] is not '')
|
|
|
|
def getUiState(self) -> t.FormField:
|
|
widget: wx.ComboBox = self.widget
|
|
return t.Dropdown(
|
|
id=self._id,
|
|
type=self.widgetInfo['type'],
|
|
selected=self.getWidgetValue(),
|
|
choices=widget.GetStrings(),
|
|
error=self.error.GetLabel() or None,
|
|
enabled=self.IsEnabled(),
|
|
visible=self.IsShown()
|
|
)
|
|
|
|
@contextmanager
|
|
def retainSelection(self):
|
|
""""
|
|
Retains the selected dropdown option (when possible)
|
|
across mutations due to dynamic updates.
|
|
"""
|
|
prevSelection = self.widget.GetSelection()
|
|
prevValue = self.widget.GetValue()
|
|
try:
|
|
yield
|
|
finally:
|
|
current_at_index = self.widget.GetString(prevSelection)
|
|
if prevValue == current_at_index:
|
|
self.widget.SetSelection(prevSelection)
|
|
else:
|
|
self.widget.SetSelection(0)
|