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.
237 lines
7.2 KiB
237 lines
7.2 KiB
from functools import partial
|
|
|
|
import wx
|
|
|
|
from gooey.gui.util import wx_util
|
|
from gooey.gui.widgets import widget_pack
|
|
|
|
|
|
class BaseGuiComponent(object):
|
|
|
|
widget_class = None
|
|
|
|
def __init__(self, parent, title, msg, choices=None):
|
|
'''
|
|
:param data: field info (title, help, etc..)
|
|
:param widget_pack: internal wxWidgets to render
|
|
'''
|
|
# parent
|
|
self.parent = parent
|
|
|
|
# Widgets
|
|
self.title = None
|
|
self.help_msg = None
|
|
self.choices = choices
|
|
|
|
# Internal WidgetPack set in subclasses
|
|
|
|
self.do_layout(parent, title, msg)
|
|
|
|
def do_layout(self, parent, title, msg):
|
|
self.panel = wx.Panel(parent)
|
|
|
|
self.widget_pack = self.widget_class()
|
|
|
|
self.title = self.format_title(self.panel, title)
|
|
self.help_msg = self.format_help_msg(self.panel, msg)
|
|
self.help_msg.SetMinSize((0, -1))
|
|
core_widget_set = self.widget_pack.build(self.panel, {}, self.choices)
|
|
|
|
vertical_container = wx.BoxSizer(wx.VERTICAL)
|
|
|
|
vertical_container.Add(self.title)
|
|
vertical_container.AddSpacer(2)
|
|
|
|
if self.help_msg.GetLabelText():
|
|
vertical_container.Add(self.help_msg, 1, wx.EXPAND)
|
|
vertical_container.AddSpacer(2)
|
|
else:
|
|
vertical_container.AddStretchSpacer(1)
|
|
|
|
vertical_container.Add(core_widget_set, 0, wx.EXPAND)
|
|
self.panel.SetSizer(vertical_container)
|
|
|
|
return self.panel
|
|
|
|
def bind(self, *args, **kwargs):
|
|
print(self.widget_pack.widget.Bind(*args, **kwargs))
|
|
|
|
def get_title(self):
|
|
return self.title.GetLabel()
|
|
|
|
def set_title(self, text):
|
|
self.title.SetLabel(text)
|
|
|
|
def get_help_msg(self):
|
|
return self.help_msg.GetLabelText()
|
|
|
|
def set_label_text(self, text):
|
|
self.help_msg.SetLabel(text)
|
|
|
|
def format_help_msg(self, parent, msg):
|
|
base_text = wx.StaticText(parent, label=msg or '')
|
|
wx_util.dark_grey(base_text)
|
|
return base_text
|
|
|
|
def format_title(self, parent, title):
|
|
text = wx.StaticText(parent, label=title)
|
|
wx_util.make_bold(text)
|
|
return text
|
|
|
|
def onResize(self, evt):
|
|
# handle internal widgets
|
|
# self.panel.Freeze()
|
|
self._onResize(evt)
|
|
# propagate event to child widgets
|
|
self.widget_pack.onResize(evt)
|
|
evt.Skip()
|
|
# self.panel.Thaw()
|
|
|
|
def _onResize(self, evt):
|
|
if not self.help_msg:
|
|
return
|
|
self.panel.Size = evt.GetSize()
|
|
container_width, _ = self.panel.Size
|
|
text_width, _ = self.help_msg.Size
|
|
|
|
if text_width != container_width:
|
|
self.help_msg.SetLabel(self.help_msg.GetLabelText().replace('\n', ' '))
|
|
self.help_msg.Wrap(container_width)
|
|
evt.Skip()
|
|
|
|
def get_value(self):
|
|
return self.widget_pack.get_value()
|
|
|
|
def set_value(self, val):
|
|
if val:
|
|
self.widget_pack.widget.SetValue(str(val))
|
|
|
|
def __repr__(self):
|
|
return self.__class__.__name__
|
|
|
|
|
|
class CheckBox(BaseGuiComponent):
|
|
|
|
def __init__(self, parent, title, msg, choices=None):
|
|
BaseGuiComponent.__init__(self, parent, title, msg)
|
|
|
|
def do_layout(self, parent, title, msg):
|
|
self.panel = wx.Panel(parent)
|
|
|
|
self.widget = wx.CheckBox(self.panel)
|
|
# self.widget.SetValue(self.default_value)
|
|
self.title = self.format_title(self.panel, title)
|
|
self.help_msg = self.format_help_msg(self.panel, msg)
|
|
self.help_msg.SetMinSize((0, -1))
|
|
|
|
# self.help_msg.Bind(wx.EVT_LEFT_UP, lambda event: self.widget.SetValue(not self.widget.GetValue()))
|
|
|
|
vertical_container = wx.BoxSizer(wx.VERTICAL)
|
|
vertical_container.Add(self.title)
|
|
|
|
horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
|
horizontal_sizer.Add(self.widget, 0, wx.EXPAND | wx.RIGHT, 10)
|
|
horizontal_sizer.Add(self.help_msg, 1, wx.EXPAND)
|
|
|
|
vertical_container.Add(horizontal_sizer, 0, wx.EXPAND)
|
|
|
|
self.panel.SetSizer(vertical_container)
|
|
self.panel.Bind(wx.EVT_SIZE, self.onResize)
|
|
return self.panel
|
|
|
|
def onResize(self, evt):
|
|
msg = self.help_msg
|
|
container_width, _ = self.panel.Size
|
|
text_width, _ = msg.Size
|
|
|
|
if text_width != container_width:
|
|
msg.SetLabel(msg.GetLabelText().replace('\n', ' '))
|
|
msg.Wrap(container_width)
|
|
evt.Skip()
|
|
|
|
def get_value(self):
|
|
return self.widget.GetValue()
|
|
|
|
def set_value(self, val):
|
|
self.widget.SetValue(val)
|
|
|
|
|
|
class RadioGroup(object):
|
|
def __init__(self, parent, title, msg, choices=None):
|
|
self.panel = None
|
|
|
|
self.radio_buttons = []
|
|
self.option_strings = []
|
|
self.help_msgs = []
|
|
self.btn_names = []
|
|
|
|
self.do_layout(parent, title, msg)
|
|
|
|
def do_layout(self, parent, titles, msgs):
|
|
self.panel = wx.Panel(parent)
|
|
|
|
self.radio_buttons = [wx.RadioButton(self.panel, -1) for _ in titles]
|
|
self.btn_names = [wx.StaticText(self.panel, label=title.title()) for title in titles]
|
|
self.help_msgs = [wx.StaticText(self.panel, label=msg.title()) for msg in msgs]
|
|
|
|
# box = wx.StaticBox(self.panel, -1, label=self.data['group_name'])
|
|
box = wx.StaticBox(self.panel, -1, label='')
|
|
vertical_container = wx.StaticBoxSizer(box, wx.VERTICAL)
|
|
|
|
for button, name, help in zip(self.radio_buttons, self.btn_names, self.help_msgs):
|
|
|
|
hbox = wx.BoxSizer(wx.HORIZONTAL)
|
|
|
|
hbox.Add(button, 0, wx.ALIGN_TOP | wx.ALIGN_LEFT)
|
|
hbox.Add(name, 0, wx.LEFT, 10)
|
|
|
|
vertical_container.Add(hbox, 0, wx.EXPAND)
|
|
|
|
vertical_container.Add(help, 1, wx.EXPAND | wx.LEFT, 25)
|
|
vertical_container.AddSpacer(5)
|
|
|
|
self.panel.SetSizer(vertical_container)
|
|
self.panel.Bind(wx.EVT_SIZE, self.onResize)
|
|
self.panel.Bind(wx.EVT_RADIOBUTTON, self.showz)
|
|
return self.panel
|
|
|
|
def showz(self, evt):
|
|
print(evt)
|
|
for i in self.radio_buttons:
|
|
print(i.GetValue())
|
|
|
|
def onResize(self, evt):
|
|
msg = self.help_msgs[0]
|
|
container_width, _ = self.panel.Size
|
|
text_width, _ = msg.Size
|
|
|
|
if text_width != container_width:
|
|
msg.SetLabel(msg.GetLabelText().replace('\n', ' '))
|
|
msg.Wrap(container_width)
|
|
evt.Skip()
|
|
|
|
def get_value(self):
|
|
return [button.GetValue() for button in self.radio_buttons]
|
|
|
|
def set_value(self, val):
|
|
pass
|
|
|
|
|
|
|
|
def build_subclass(name, widget_class):
|
|
# this seemed faster than typing class X a bunch
|
|
return type(name, (BaseGuiComponent,), {'widget_class': widget_class})
|
|
|
|
|
|
FileChooser = build_subclass('FileChooser', widget_pack.FileChooserPayload)
|
|
MultiFileChooser = build_subclass('MultiFileChooser', widget_pack.MultiFileSaverPayload)
|
|
DirChooser = build_subclass('DirChooser', widget_pack.DirChooserPayload)
|
|
FileSaver = build_subclass('FileSaver', widget_pack.FileSaverPayload)
|
|
DateChooser = build_subclass('DateChooser', widget_pack.DateChooserPayload)
|
|
TextField = build_subclass('TextField', widget_pack.TextInputPayload)
|
|
Textarea = build_subclass('TextField', widget_pack.TextAreaPayload)
|
|
CommandField = build_subclass('CommandField', widget_pack.TextInputPayload(no_quoting=True))
|
|
Dropdown = build_subclass('Dropdown', widget_pack.DropdownPayload)
|
|
Counter = build_subclass('Counter', widget_pack.CounterPayload)
|
|
MultiDirChooser = build_subclass('MultiDirChooser', widget_pack.MultiDirChooserPayload)
|
|
PasswordField = build_subclass('PasswordField', widget_pack.PasswordInputPayload)
|