Browse Source

wip

dynamic-values
Chris 2 years ago
parent
commit
23ad809774
9 changed files with 173 additions and 113 deletions
  1. 8
      gooey/gui/components/config.py
  2. 14
      gooey/gui/components/widgets/bases.py
  3. 83
      gooey/gui/components/widgets/beep_boop.py
  4. 1
      gooey/gui/components/widgets/commands.py
  5. 11
      gooey/gui/components/widgets/radio_group.py
  6. 21
      gooey/gui/containers/application.py
  7. 4
      gooey/gui/state.py
  8. 3
      gooey/python_bindings/argparse_to_json.py
  9. 141
      gooey/python_bindings/types.py

8
gooey/gui/components/config.py

@ -65,14 +65,16 @@ class ConfigPage(ScrolledPanel):
if widget.info['cli_type'] != 'positional']
def getFormState(self):
return {
''
}
return [widget.getValue()
for widget in self.reifiedWidgets]
def isValid(self):
return not any(self.getErrors())
def syncFromState(self, state):
pass
def getErrors(self):
states = [widget.getValue() for widget in self.reifiedWidgets]
return {state['meta']['dest']: state['error'] for state in states

14
gooey/gui/components/widgets/bases.py

@ -11,7 +11,7 @@ from gooey.util.functional import getin, ifPresent
from gooey.gui.validators import runValidator
from gooey.gui.components.util.wrapped_static_text import AutoWrappedStaticText
from gooey.gui.components.mouse import notifyMouseEvent
from gooey.python_bindings.types import FieldValue
from gooey.python_bindings.types import FieldValue, FormField, TextField
class BaseWidget(wx.Panel):
@ -70,6 +70,7 @@ class TextContainer(BaseWidget):
self.info = widgetInfo
self._id = widgetInfo['id']
self.widgetInfo = widgetInfo
self._meta = widgetInfo['data']
self._options = widgetInfo['options']
self.label = wx.StaticText(self, label=widgetInfo['data']['display_name'])
@ -169,6 +170,14 @@ class TextContainer(BaseWidget):
# self.Layout()
event.Skip()
def getUiState(self) -> FormField:
return TextField(
id=self._id,
type=self.widgetInfo['type'],
value=self.getWidgetValue(),
enabled=self.Enabled,
visible=self.Shown
)
def getValue(self) -> FieldValue:
regexFunc: Callable[[str], bool] = lambda x: bool(re.match(userValidator, x))
@ -186,6 +195,9 @@ class TextContainer(BaseWidget):
cmd=self.formatOutput(self._meta, value),
meta=self._meta,
rawValue= value,
type=self.info['type'],
enabled=self.Enabled,
visible=self.Shown,
test= runValidator(satisfies, value),
error=None if runValidator(satisfies, value) else message,
clitype=('positional'

83
gooey/gui/components/widgets/beep_boop.py

@ -1,83 +0,0 @@
import wx # type: ignore
import wx.lib.inspection
from gooey.gui.components.widgets.textfield import TextField
from gooey.gui.components.widgets.textarea import Textarea
from gooey.gui.components.widgets.password import PasswordField
from gooey.gui.components.widgets.choosers import FileChooser, FileSaver, DirChooser, DateChooser
from gooey.gui.components.widgets.dropdown import Dropdown
from gooey.gui.components.widgets.listbox import Listbox
class CCC(wx.Frame):
def __init__(self, *args, **kwargs):
super(CCC, self).__init__(*args, **kwargs)
x = {'data':{'choices':['one', 'tw'], 'display_name': 'foo', 'help': 'bar', 'commands': ['-t']}, 'id': 1, 'options': {}}
a = TextField(self, x)
c = Textarea(self, x)
b = PasswordField(self, x)
d = DirChooser(self, x)
e = FileChooser(self,x)
f = FileSaver(self, x)
g = DateChooser(self, x)
h = Dropdown(self, x)
i = Listbox(self, x)
s = wx.BoxSizer(wx.VERTICAL)
s.Add(a, 0, wx.EXPAND)
s.Add(b, 0, wx.EXPAND)
s.Add(c, 0, wx.EXPAND)
s.Add(d, 0, wx.EXPAND)
s.Add(e, 0, wx.EXPAND)
s.Add(f, 0, wx.EXPAND)
s.Add(g, 0, wx.EXPAND)
s.Add(h, 0, wx.EXPAND)
s.Add(i, 0, wx.EXPAND)
self.SetSizer(s)
app = wx.App()
frame = CCC(None, -1, 'simple.py')
frame.Show()
app.MainLoop()
# import wx
#
# class MainWindow(wx.Frame):
# def __init__(self, *args, **kwargs):
# wx.Frame.__init__(self, *args, **kwargs)
#
# self.panel = wx.Panel(self)
#
# self.label = wx.StaticText(self.panel, label="Label")
# self.text = wx.TextCtrl(self.panel)
# self.button = wx.Button(self.panel, label="Test")
#
# self.button1 = wx.Button(self.panel, label="ABOVE")
# self.button2 = wx.Button(self.panel, label="BELOW")
#
# self.horizontal = wx.BoxSizer()
# self.horizontal.Add(self.label, flag=wx.CENTER)
# self.horizontal.Add(self.text, proportion=1, flag=wx.CENTER)
# self.horizontal.Add(self.button, flag=wx.CENTER)
#
# self.vertical = wx.BoxSizer(wx.VERTICAL)
# self.vertical.Add(self.button1, flag=wx.EXPAND)
# self.vertical.Add(self.horizontal, proportion=1, flag=wx.EXPAND)
# self.vertical.Add(self.button2, flag=wx.EXPAND)
#
# self.panel.SetSizerAndFit(self.vertical)
# self.Show()
#
#
# app = wx.App(False)
# win = MainWindow(None)
# app.MainLoop()

1
gooey/gui/components/widgets/commands.py

@ -1 +0,0 @@

11
gooey/gui/components/widgets/radio_group.py

@ -4,7 +4,7 @@ from gooey.gui.lang.i18n import _
from gooey.gui.util import wx_util
from gooey.gui.components.widgets import CheckBox
from gooey.util.functional import getin, findfirst, merge
from gooey.python_bindings import types as t
class RadioGroup(BaseWidget):
"""
@ -46,6 +46,15 @@ class RadioGroup(BaseWidget):
# not active so that the expected interface is satisfied
return self.widgets[0].getValue()
def getUiState(self):
return t.RadioGroup(
id=self._id,
type=self.widgetInfo['type'],
selected=findfirst(lambda x: x.GetValue(), self.radioButtons),
options=[x.getUiState() for x in self.widgets]
)
def setErrorString(self, message):
for button, widget in zip(self.radioButtons, self.widgets):
if button.GetValue(): # is Checked

21
gooey/gui/containers/application.py

@ -588,8 +588,9 @@ def RSidebar(props):
'min_size': (1, -1)}],
*[[ConfigPage, {'flag': wx.EXPAND,
'proportion': 3,
'config': config,
'show': i == props['activeSelection']}]
for i in range(3)]
for i, config in enumerate(props['config'].values())]
]
)
@ -620,8 +621,6 @@ class RGooey(Component):
'image_uri': state['image'],
'image_size': (six.MAXSIZE, self.buildSpec['header_height'] - 10)}
state = form_page(initial_state(self.buildSpec))
self.fprops = lambda state: {
'buttons': state['buttons'],
'progress': state['progress'],
@ -775,6 +774,7 @@ class RGooey(Component):
'show': self.state['screen'] == 'FORM',
'activeSelection': self.state['activeSelection'],
'on_change': self.handle_select_action,
'config': self.buildSpec['widgets'],
'flag': wx.EXPAND,
'proportion': 1}],
# [c.Notebook, {'flag': wx.EXPAND, 'proportion': 1, 'on_change': self.handle_tab},
@ -839,20 +839,7 @@ class TitleText(Component):
@mount.register(ConfigPage)
def config(element, parent):
xxx = {'command': 'range', 'name': 'range', 'help': None, 'description': '', 'contents': [
{'name': 'optional_args_msg', 'items': [
{'id': '--length', 'type': 'TextField', 'cli_type': 'optional', 'required': False,
'data': {'display_name': 'length', 'help': None, 'required': False, 'nargs': '',
'commands': ['--length'], 'choices': [], 'default': 10, 'dest': 'length'},
'options': {'error_color': '#ea7878', 'label_color': '#000000',
'help_color': '#363636', 'full_width': False,
'validator': {'type': 'ExpressionValidator', 'test': 'True',
'message': ''}, 'external_validator': {'cmd': ''}}}],
'groups': [], 'description': None,
'options': {'label_color': '#000000', 'description_color': '#363636',
'legacy': {'required_cols': 2, 'optional_cols': 2}, 'columns': 2,
'padding': 10, 'show_border': False}}]}
return update(element, ConfigPage(parent, xxx, {'contents': []}))
return update(element, ConfigPage(parent, element['props']['config'], {'contents': []}))
@update.register(ConfigPage)

4
gooey/gui/state.py

@ -102,9 +102,8 @@ def initial_state(params: GooeyParams):
'elapsed_time': None,
'estimatedRemaining': None,
},
'activeSelection': 1,
'activeSelection': 0,
'forms': {}
}
def header_props(state, params):
@ -195,4 +194,3 @@ def present_time(timer):
return f'{elapsed_time_value}<{estimate_time_remaining}'
else:
return f'{elapsed_time_value}'

3
gooey/python_bindings/argparse_to_json.py

@ -417,8 +417,9 @@ def choose_name(name, subparser):
def build_radio_group(mutex_group, widget_group, options):
dests = [action.dest for action in mutex_group._group_actions]
return {
'id': str(uuid4()),
'id': 'radio-group-' + '-'.join(dests),
'type': 'RadioGroup',
'cli_type': 'optional',
'group_name': 'Choose Option',

141
gooey/python_bindings/types.py

@ -1,4 +1,4 @@
from typing import Optional, Tuple, List, Union, Mapping, Any, TypeVar, Callable, Generic
from typing import Optional, Tuple, List, Union, Mapping, Any, TypeVar, Callable, Generic, Dict
from dataclasses import dataclass
from typing_extensions import TypedDict, TypeAlias
@ -129,6 +129,82 @@ class GooeyParams(TypedDict):
# widgets: str
class GooeyField(TypedDict):
id: str
type: str
error: Optional[str]
enabled: bool
visible: bool
class Dropdown(TypedDict):
id: str
choices: List[str]
selected: str
class Chooser(TypedDict):
id: str
type: str
label: str
value: str
placeholder: str
error: str
class Command(TypedDict):
id: str
type: str
value: str
placeholder: str
error: str
class Counter(TypedDict):
id: str
type: str
selected: str
choices: List[str]
error: str
class DropdownFilterable(TypedDict):
id: str
type: str
value: str
choices: List[str]
class ListBox(TypedDict):
id: str
type: str
choices: List[str]
selected: List[int]
class IntegerField(TypedDict):
id: str
type: str
value: str
min: int
max: int
class DecimalField(TypedDict):
id: str
type: str
value: float
min: float
max: float
class Slider(TypedDict):
id: str
type: str
value: float
min: float
max: float
class Textarea(TypedDict):
id: str
type: str
value: float
height: int
class FieldValue(TypedDict):
"""
The current value of a widget in the UI.
@ -139,6 +215,11 @@ class FieldValue(TypedDict):
id: str
cmd: Optional[str]
rawValue: str
placeholder: str
positional: bool
required: bool
enabled: bool
visible: bool
test: bool
error: Optional[str]
clitype: str
@ -146,16 +227,70 @@ class FieldValue(TypedDict):
## TODO: dynamic types
class TextField(TypedDict):
value: str
error: Optional[str]
enabled: bool
visible: bool
class Checkbox(TypedDict):
id: str
type: str
checked: bool
error: str
class RadioGroup(TypedDict):
id: str
type: str
selected: Optional[int]
options: List['FormField']
FormField = Union[Dropdown, Chooser, FieldValue, RadioGroup]
class Group(TypedDict):
name: str
items: List[Any]
groups: List['Group']
description: str
options: Dict[Any, Any]
class Item(TypedDict):
id: str
type: str
cli_type: str
group_name: str
required: bool
options: Dict[Any, Any]
data: 'ItemData'
ItemData = Union['StandardData', 'RadioData']
class StandardData(TypedDict):
display_name: str
help: str
required: bool
nargs: str
commands: List[str]
choices: List[str]
default: Union[str, List[str]]
dest: str
class RadioData(TypedDict):
commands: List[List[str]]
widgets: List[Item]
A = TypeVar('A')
## TODO: dynamic types
@dataclass(frozen=True, eq=True)
class CommandDetails:
target: str

Loading…
Cancel
Save