Browse Source

Replaced duplicated code with utility funcs in styling.py

pull/1/head
chriskiehl 10 years ago
parent
commit
20bc3f0d50
16 changed files with 91 additions and 105 deletions
  1. 1
      gooey/TODO.txt
  2. 2
      gooey/__init__.py
  3. 22
      gooey/gooey_decorator.py
  4. 37
      gooey/gui/advanced_config.py
  5. 4
      gooey/gui/advanced_config_unittest.py
  6. 29
      gooey/gui/base_window.py
  7. 12
      gooey/gui/basic_config_panel.py
  8. 8
      gooey/gui/client_app.py
  9. 4
      gooey/gui/components.py
  10. 26
      gooey/gui/controller.py
  11. 6
      gooey/gui/styling.py
  12. 5
      gooey/mockapplications/example_argparse_souce_in_main.py
  13. 26
      gooey/mockapplications/example_argparse_souce_in_try.py
  14. 2
      gooey/mockapplications/mockapp.py
  15. 0
      gooey/themes/__init__.py
  16. 12
      gooey/themes/thm.py

1
gooey/TODO.txt

@ -2,7 +2,6 @@
TODO:
- Need to catch imports as well, I believe
- support giving the GUI a specific name
- system for supplying custom widgets to the GUI -- e.g. a FileChooser, rather than just a TextBox

2
gooey/__init__.py

@ -1 +1 @@
from gooey_decorator import Gooey

22
gooey/gooey_decorator.py

@ -7,11 +7,12 @@ Created on Jan 24, 2014
from functools import partial
import wx
from gooey.gui.component_factory import ComponentFactory
import i18n_config
import source_parser
from gooey.gui.config_model import ConfigModel
from gooey.gui.config_model import EmptyConfigModel
from gooey.gui.client_app import ClientApp
from gooey.gui.client_app import EmptyClientApp
from gooey.gui.base_window import BaseWindow
from gooey.gui.advanced_config import AdvancedConfigPanel
from gooey.gui.basic_config_panel import BasicConfigPanel
@ -31,7 +32,7 @@ def Gooey(f=None, advanced=True,
params = locals()
def build(f):
def build(payload):
def inner():
module_path = get_caller_path()
@ -42,33 +43,32 @@ def Gooey(f=None, advanced=True,
if config:
parser = get_parser(module_path)
model = ConfigModel(parser)
client_app = ClientApp(parser, payload)
if advanced:
BodyPanel = partial(AdvancedConfigPanel, model=model)
BodyPanel = partial(AdvancedConfigPanel, action_groups=client_app.action_groups)
else:
BodyPanel = BasicConfigPanel
# User doesn't want to display configuration screen
# Just jump straight to the run panel
else:
BodyPanel = BasicConfigPanel
model = EmptyConfigModel()
client_app = EmptyClientApp()
frame = BaseWindow(BodyPanel, client_app, params)
frame = BaseWindow(BodyPanel, model, f, params)
if not config:
# gah, hacky.. not sure how else to go
# about it without rewriting a *bunch* of other stuff
frame.ManualStart()
frame.Show(True)
app.MainLoop()
inner.__name__ = f.__name__
inner.__name__ = payload.__name__
return inner
if callable(f):
return build(f)
return build
def get_parser(module_path):
try:
return source_parser.extract_parser(module_path)

37
gooey/gui/advanced_config.py

@ -9,6 +9,7 @@ from wx.lib.scrolledpanel import ScrolledPanel
from gooey.gui.component_factory import ComponentFactory
from gooey.gui.option_reader import OptionReader
import styling
PADDING = 10
@ -19,12 +20,16 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader):
Abstract class for the Footer panels.
"""
def __init__(self, parent, model=None, **kwargs):
def __init__(self, parent, action_groups=None, **kwargs):
ScrolledPanel.__init__(self, parent, **kwargs)
self.SetupScrolling()
self._model = model
self.components = ComponentFactory(model.action_groups)
self._action_groups = action_groups
self._positionals = len(action_groups._positionals) > 0
self.components = ComponentFactory(action_groups)
self._msg_req_args = None
self._msg_opt_args = None
self._controller = None
@ -34,18 +39,20 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader):
def _init_components(self):
self._msg_req_args = (self.BuildHeaderMsg("Required Arguments")
if self._model.HasPositionals() else None)
self._msg_opt_args = self.BuildHeaderMsg("Optional Arguments")
self._msg_req_args = (styling.H1(self, "Required Arguments")
if self._positionals else None)
self._msg_opt_args = styling.H1(self, "Optional Arguments")
def _do_layout(self):
STD_LAYOUT = (0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING)
container = wx.BoxSizer(wx.VERTICAL)
container.AddSpacer(15)
if self._model.HasPositionals():
if self._positionals:
container.Add(self._msg_req_args, 0, wx.LEFT | wx.RIGHT, PADDING)
container.AddSpacer(5)
container.Add(self._draw_horizontal_line(), *STD_LAYOUT)
container.Add(styling.HorizontalRule(self), *STD_LAYOUT)
container.AddSpacer(20)
self.AddWidgets(container, self.components.required_args, add_space=True)
@ -55,7 +62,7 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader):
container.AddSpacer(10)
container.Add(self._msg_opt_args, 0, wx.LEFT | wx.RIGHT, PADDING)
container.AddSpacer(5)
container.Add(self._draw_horizontal_line(), *STD_LAYOUT)
container.Add(styling.HorizontalRule(self), *STD_LAYOUT)
container.AddSpacer(20)
flag_grids = self.CreateComponentGrid(self.components.flags, cols=3, vgap=15)
@ -66,13 +73,6 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader):
self.SetSizer(container)
def BuildHeaderMsg(self, label):
_msg = wx.StaticText(self, label=label)
font_size = _msg.GetFont().GetPointSize()
bold = wx.Font(font_size * 1.2, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
_msg.SetFont(bold)
return _msg
def AddWidgets(self, sizer, components, add_space=False, padding=PADDING):
for component in components:
widget_group = component.Build(parent=self)
@ -85,11 +85,6 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader):
self.AddWidgets(gridsizer, components)
return gridsizer
def _draw_horizontal_line(self):
line = wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL)
line.SetSize((10, 10))
return line
def OnResize(self, evt):
for component in self.components:
component.Update(evt.m_size)

4
gooey/gui/advanced_config_unittest.py

@ -11,7 +11,7 @@ import unittest
import wx
import advanced_config
from gooey.gui.config_model import ConfigModel
from gooey.gui.client_app import ClientApp
from gooey.gui import argparse_test_data
@ -24,7 +24,7 @@ class TestAdvancedConfigPanel(unittest.TestCase):
module_name = os.path.split(sys.argv[0])[-1]
frame = wx.Frame(None, -1, module_name, size=(640, 480))
panel = advanced_config.AdvancedConfigPanel(frame, ConfigModel(self.parser))
panel = advanced_config.AdvancedConfigPanel(frame, ClientApp(self.parser))
frame.Show()
app.MainLoop()

29
gooey/gui/base_window.py

@ -20,15 +20,15 @@ from gooey.gui import footer
from gooey import image_repository
from gooey.gui.controller import Controller
from gooey.gui.runtime_display_panel import RuntimeDisplay
import styling
class BaseWindow(wx.Frame):
def __init__(self, BodyPanel, model, payload, params):
def __init__(self, BodyPanel, client_app, params):
wx.Frame.__init__(self, parent=None, id=-1)
self._params = params
self._model = model
self._payload = payload
self._client_app = client_app
self._controller = None
@ -62,7 +62,7 @@ class BaseWindow(wx.Frame):
# init gui
self.head_panel = header.FrameHeader(
heading=i18n.translate("settings_title"),
subheading=self._model.description,
subheading=self._client_app.description,
parent=self)
self.config_panel = BodyPanel(self)
self.runtime_display = RuntimeDisplay(self)
@ -72,31 +72,26 @@ class BaseWindow(wx.Frame):
def _do_layout(self):
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.head_panel, 0, wx.EXPAND)
self._draw_horizontal_line(sizer)
sizer.Add(styling.HorizontalRule(self), 0, wx.EXPAND)
sizer.Add(self.config_panel, 1, wx.EXPAND)
self.runtime_display.Hide()
sizer.Add(self.runtime_display, 1, wx.EXPAND)
self._draw_horizontal_line(sizer)
sizer.Add(styling.HorizontalRule(self), 0, wx.EXPAND)
sizer.Add(self.foot_panel, 0, wx.EXPAND)
self.SetSizer(sizer)
def _draw_horizontal_line(self, sizer):
line = wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL)
line.SetSize((10, 10))
sizer.Add(line, 0, wx.EXPAND)
def _init_controller(self):
self._controller = Controller(
base_frame=self,
head_panel=self.head_panel,
body_panel=self.config_panel,
footer_panel=self.foot_panel,
model=self._model)
client_app=self._client_app)
def registerControllers(self):
for panel in self.panels:
panel.RegisterController(self._controller)
def GetOptions(self):
return self.config_panel.GetOptions()
def NextPage(self):
self.head_panel.NextPage()
self.foot_panel.NextPage()
@ -104,8 +99,8 @@ class BaseWindow(wx.Frame):
self.runtime_display.Show()
self.Layout()
def AttachPayload(self, payload):
self._payload = payload
# def AttachPayload(self, payload):
# self._payload = payload
def ManualStart(self):
self._controller.ManualStart()

12
gooey/gui/basic_config_panel.py

@ -11,17 +11,18 @@ from gooey.gui.option_reader import OptionReader
from gooey import i18n
class BasicConfigPanel(wx.Panel, OptionReader):
def __init__(self, parent, params, **kwargs):
def __init__(self, parent, **kwargs):
wx.Panel.__init__(self, parent, **kwargs)
self._translator = I18N(params['language'])
self.header_msg = None
self.cmd_textbox = None
self._init_properties()
self._init_components()
self._do_layout()
def _init_components(self):
self.header_msg = self._bold_static_text(self._translator['simple_config'])
self.header_msg = self._bold_static_text(i18n.translate('simple_config'))
self.cmd_textbox = wx.TextCtrl(self, -1, "")
def _init_properties(self):
@ -48,7 +49,4 @@ class BasicConfigPanel(wx.Panel, OptionReader):
return self.cmd_textbox.GetValue()
def RegisterController(self, controller):
pass
pass

gooey/gui/config_model.py → gooey/gui/client_app.py

@ -10,12 +10,12 @@ from gooey.monkey_parser import ArgumentError
from gooey.gui.action_sorter import ActionSorter
class ConfigModel(object):
def __init__(self, parser):
class ClientApp(object):
def __init__(self, parser, payload):
self._parser = parser
self.description = parser.description
self.action_groups = ActionSorter(self._parser._actions)
self._payload = None
self.payload = payload
def HasPositionals(self):
if self.action_groups._positionals:
@ -48,7 +48,7 @@ class ConfigModel(object):
sys.argv.extend(arg_string.split())
class EmptyConfigModel(object):
class EmptyClientApp(object):
def __init__(self):
'''
initializes a BlankModel object

4
gooey/gui/components.py

@ -64,7 +64,7 @@ class AbstractComponent(object):
def CreateHelpMsgWidget(self, parent, action):
base_text = wx.StaticText(parent, label=action.help)
if self.HasNargs(action):
base_text += self.CreateNargsMsg(action)
base_text.SetLabelText(base_text.GetLabelText() + self.CreateNargsMsg(action))
styling.MakeDarkGrey(base_text)
return base_text
@ -72,7 +72,7 @@ class AbstractComponent(object):
return action.nargs == '+' or action.nargs == '?'
def CreateNargsMsg(self, action):
return ' (Note: at least 1 or more arguments are required'
return ' (Note: at least 1 or more arguments are required)'
def CreateNameLabelWidget(self, parent, action):
label = str(action.dest).title()

26
gooey/gui/controller.py

@ -30,21 +30,14 @@ class Controller(object):
translator = instance of the I18N class
'''
def __init__(
self, base_frame, head_panel, body_panel,
footer_panel, model):
def __init__(self, base_frame, client_app):
self._base = base_frame
self._head = head_panel
self._body = body_panel
self._foot = footer_panel
self._model = model
self._client_app = client_app
self._payload_runner = Process(target=self.RunClientCode)
def OnCancelButton(self, widget, event):
msg = i18n.translate('sure_you_want_to_exit')
dlg = wx.MessageDialog(None, msg,
i18n.translate('close_program'), wx.YES_NO)
dlg = wx.MessageDialog(None, msg, i18n.translate('close_program'), wx.YES_NO)
result = dlg.ShowModal()
print result
if result == YES:
@ -54,12 +47,12 @@ class Controller(object):
dlg.Destroy()
def OnStartButton(self, widget, event):
cmd_line_args = self._body.GetOptions()
if not self._model.IsValidArgString(cmd_line_args):
error_msg = self._model.GetErrorMsg(cmd_line_args)
cmd_line_args = self._base.GetOptions()
if not self._client_app.IsValidArgString(cmd_line_args):
error_msg = self._client_app.GetErrorMsg(cmd_line_args)
self.ShowDialog(i18n.translate('error_title'), error_msg, wx.ICON_ERROR)
return
self._model.AddToArgv(cmd_line_args)
self._client_app.AddToArgv(cmd_line_args)
self._base.NextPage()
self._payload_runner.start()
@ -75,9 +68,8 @@ class Controller(object):
def RunClientCode(self):
pool = Pool(1)
try:
pool.apply(self._base._payload)
self._head.NextPage()
self._foot.NextPage()
pool.apply(self._client_app.payload)
self._base.NextPage()
self.ShowGoodFinishedDialog()
except:
self.ShowBadFinishedDialog(traceback.format_exc())

6
gooey/gui/styling.py

@ -22,6 +22,7 @@ def _bold_static_text(parent, text_label):
text.SetFont(bold)
return text
def H1(parent, label):
text = wx.StaticText(parent, label=label)
font_size = text.GetFont().GetPointSize()
@ -29,6 +30,11 @@ def H1(parent, label):
text.SetFont(font)
return text
def HorizontalRule(parent):
line = wx.StaticLine(parent, -1, style=wx.LI_HORIZONTAL)
line.SetSize((10, 10))
return line
def MakeDarkGrey(statictext):
darkgray = (54, 54, 54)
statictext.SetForegroundColour(darkgray)

5
gooey/mockapplications/example_argparse_souce_in_main.py

@ -22,13 +22,14 @@ import os
from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
from gooey.gooey_decorator import Gooey
__all__ = []
__version__ = 0.1
__date__ = '2013-12-13'
__updated__ = '2013-12-13'
DEBUG = 1
DEBUG = 0
TESTRUN = 0
PROFILE = 0
@ -47,7 +48,7 @@ class CLIError(Exception):
def __unicode__(self):
return self.msg
@Gooey
def main(argv=None): # IGNORE:C0111
'''Command line options.'''

26
gooey/mockapplications/example_argparse_souce_in_try.py

@ -23,12 +23,14 @@ import os
from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
from gooey.gooey_decorator import Gooey
__all__ = []
__version__ = 0.1
__date__ = '2013-12-13'
__updated__ = '2013-12-13'
DEBUG = 1
DEBUG = 0
TESTRUN = 0
PROFILE = 0
@ -47,6 +49,7 @@ class CLIError(Exception):
return self.msg
@Gooey
def main(argv=None): # IGNORE:C0111
'''Command line options.'''
@ -62,14 +65,14 @@ def main(argv=None): # IGNORE:C0111
program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
program_license = '''%s
Created by user_name on %s.
Copyright 2013 organization_name. All rights reserved.
Created by user_name on %s.
Copyright 2013 organization_name. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
''' % (program_shortdesc, str(__date__))
@ -77,19 +80,28 @@ USAGE
try:
# Setup argument parser
parser = ArgumentParser(description='Example Argparse Program', formatter_class=RawDescriptionHelpFormatter)
parser.add_argument("filename", help="filename")
parser.add_argument("-r", "--recursive", dest="recurse", action="store_true",
help="recurse into subfolders [default: %(default)s]")
parser.add_argument("-v", "--verbose", dest="verbose", action="count",
help="set verbosity level [default: %(default)s]")
parser.add_argument("-i", "--include", action="append",
help="only include paths matching this regex pattern. Note: exclude is given preference over include. [default: %(default)s]",
metavar="RE")
parser.add_argument("-m", "--mycoolargument", help="mycoolargument")
parser.add_argument("-e", "--exclude", dest="exclude",
help="exclude paths matching this regex pattern. [default: %(default)s]", metavar="RE")
parser.add_argument('-V', '--version', action='version')
parser.add_argument('-T', '--tester', choices=['yes', 'no'])
parser.add_argument(dest="paths", help="paths to folder(s) with source file(s) [default: %(default)s]",
metavar="path", nargs='+')

2
gooey/mockapplications/mockapp.py

@ -9,7 +9,7 @@ from time import time as _time
from time import sleep as _sleep
from argparse import ArgumentParser
from gooey.gooey_decorator import Gooey
from gooey import Gooey
@Gooey

0
gooey/themes/__init__.py

12
gooey/themes/thm.py

@ -1,12 +0,0 @@
'''
Created on Jan 25, 2014
@author: Chris
'''
if __name__ == '__main__':
a = {
'font_size': 8,
'bold_font_family': 'default',
}
Loading…
Cancel
Save