Browse Source

Refactored to pubsub

subparsing
chriskiehl 9 years ago
parent
commit
c0c7462a33
4 changed files with 93 additions and 82 deletions
  1. 94
      gooey/gui/controller.py
  2. 18
      gooey/gui/events.py
  3. 4
      gooey/gui/windows/base_window.py
  4. 59
      gooey/gui/windows/footer.py

94
gooey/gui/controller.py

@ -7,7 +7,11 @@ Created on Dec 22, 2013
import wx
import sys
import subprocess
from wx.lib.pubsub import pub
from multiprocessing.dummy import Pool
from gooey.gui import events
from gooey.gui.lang import i18n
@ -31,7 +35,23 @@ class Controller(object):
self.core_gui = base_frame
self.build_spec = build_spec
def OnCancelButton(self, widget, event):
# wire up all the observers
pub.subscribe(self.on_cancel, events.WINDOW_CANCEL)
pub.subscribe(self.on_start, events.WINDOW_START)
pub.subscribe(self.on_restart, events.WINDOW_RESTART)
pub.subscribe(self.on_close, events.WINDOW_CLOSE)
def on_close(self):
self.core_gui.Destroy()
sys.exit()
def on_restart(self):
self.on_start()
def manual_restart(self):
self.on_start()
def on_cancel(self):
msg = i18n._('sure_you_want_to_exit')
dlg = wx.MessageDialog(None, msg, i18n._('close_program'), wx.YES_NO)
result = dlg.ShowModal()
@ -41,61 +61,51 @@ class Controller(object):
sys.exit()
dlg.Destroy()
def OnStartButton(self, widget, event):
cmd_line_args = self.core_gui.GetOptions()
if not self.build_spec['manual_start']:
_required = self.core_gui.GetRequiredArgs()
if _required and any(req == '' for req in _required):
self.ShowDialog(i18n._('error_title'), "Must fill in all fields in the Required section!", wx.ICON_ERROR)
return
def on_start(self):
if not self.skipping_config() and not self.required_section_complete():
return self.show_dialog(i18n._('error_title'), i18n._('error_required_fields'), wx.ICON_ERROR)
cmd_line_args = self.core_gui.GetOptions()
command = '{0} {1}'.format(self.build_spec['target'], cmd_line_args)
self.core_gui.NextPage()
self.RunClientCode(command)
def RunClientCode(self, command):
def doInBackground(process, callback):
while True:
line = process.stdout.readline()
if not line:
break
wx.CallAfter(self.core_gui.PublishConsoleMsg, line)
wx.CallAfter(callback, process)
p = subprocess.Popen(command, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
_pool = Pool(1)
_pool.apply_async(doInBackground, (p, self.HandleResult))
self.run_client_code(command)
def HandleResult(self, process):
def run_client_code(self, command):
p = subprocess.Popen(command, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pool = Pool(1)
pool.apply_async(self.read_stdout, (p, self.process_result))
def read_stdout(self, process, callback):
while True:
line = process.stdout.readline()
if not line:
break
wx.CallAfter(self.core_gui.PublishConsoleMsg, line)
wx.CallAfter(callback, process)
def process_result(self, process):
_stdout, _stderr = process.communicate()
if process.returncode == 0:
self.core_gui.NextPage()
self.ShowGoodFinishedDialog()
self.success_dialog()
else:
self.core_gui.NextPage()
self.ShowBadFinishedDialog(_stderr)
self.error_dialog(_stderr)
def OnRestartButton(self, widget, event):
self.OnStartButton(None, event)
def ManualStart(self):
self.OnStartButton(None, None)
def OnCloseButton(self, widget, event):
self.core_gui.Destroy()
sys.exit()
def skipping_config(self):
return self.build_spec['manual_start']
def ShowGoodFinishedDialog(self):
self.ShowDialog(i18n._("execution_finished"),
i18n._('success_message'),
wx.ICON_INFORMATION)
def required_section_complete(self):
_required = self.core_gui.GetRequiredArgs()
return _required and not any(req == '' for req in _required)
def ShowBadFinishedDialog(self, error_msg):
msg = i18n._('uh_oh').format(error_msg)
self.ShowDialog(i18n._('error_title'), msg, wx.ICON_ERROR)
def success_dialog(self):
self.show_dialog(i18n._("execution_finished"), i18n._('success_message'), wx.ICON_INFORMATION)
def error_dialog(self, error_msg):
self.show_dialog(i18n._('error_title'), i18n._('uh_oh').format(error_msg), wx.ICON_ERROR)
def ShowDialog(self, title, content, style):
def show_dialog(self, title, content, style):
a = wx.MessageDialog(None, content, title, style)
a.ShowModal()
a.Destroy()

18
gooey/gui/events.py

@ -0,0 +1,18 @@
"""
App wide event registry
Everything in the application is communitcated via pubsub. These are the events that
tie everythign together.
"""
import wx
new_id = lambda: str(wx.NewId())
WINDOW_STOP = new_id()
WINDOW_CANCEL = new_id()
WINDOW_CLOSE = new_id()
WINDOW_START = new_id()
WINDOW_RESTART = new_id()

4
gooey/gui/windows/base_window.py

@ -56,7 +56,7 @@ class BaseWindow(wx.Frame):
parent=self)
self.config_panel = AdvancedConfigPanel(self, self.build_spec)
self.runtime_display = RuntimeDisplay(self)
self.foot_panel = footer.Footer(self, self._controller)
self.foot_panel = footer.Footer(self)
self.panels = [self.head_panel, self.config_panel, self.foot_panel]
def _do_layout(self):
@ -117,7 +117,7 @@ class BaseWindow(wx.Frame):
self.Layout()
def ManualStart(self):
self._controller.ManualStart()
self._controller.manual_restart()
def onResize(self, evt):
evt.Skip()

59
gooey/gui/windows/footer.py

@ -7,8 +7,10 @@ Created on Dec 23, 2013
import wx
import wx.animate
from gooey.gui import imageutil, image_repository
from wx.lib.pubsub import pub
from gooey.gui.lang import i18n
from gooey.gui import imageutil, image_repository, events
class AbstractFooter(wx.Panel):
@ -29,6 +31,7 @@ class AbstractFooter(wx.Panel):
self.close_button = None
self.stop_button = None
self.restart_button = None
self.buttons = None
self._init_components()
self._init_pages()
@ -36,19 +39,14 @@ class AbstractFooter(wx.Panel):
def _init_components(self):
'''
initialize all of the gui used in the footer
TODO:
Add Checkmark image for when the program has finished running.
Refactor image tools into their own module. The resize code is
getting spread around a bit.
'''
self.cancel_button = self._Button(i18n._('cancel'), wx.ID_CANCEL)
self.start_button = self._Button(i18n._('start'), wx.ID_OK)
self.running_animation = wx.animate.GIFAnimationCtrl(self, -1, image_repository.loader)
self.close_button = self._Button(i18n._("close"), wx.ID_OK)
self.stop_button = self._Button('Stop', wx.ID_OK) # TODO: i18n
self.restart_button = self._Button('Restart', wx.ID_OK) # TODO: i18n
self.cancel_button = self.button(i18n._('cancel'), wx.ID_CANCEL, event_id=int(events.WINDOW_CANCEL))
self.stop_button = self.button(i18n._('stop'), wx.ID_OK, event_id=int(events.WINDOW_STOP))
self.start_button = self.button(i18n._('start'), wx.ID_OK, event_id=int(events.WINDOW_START))
self.close_button = self.button(i18n._("close"), wx.ID_OK, event_id=int(events.WINDOW_CLOSE))
self.restart_button = self.button(i18n._('restart'), wx.ID_OK, event_id=int(events.WINDOW_RESTART))
self.running_animation = wx.animate.GIFAnimationCtrl(self, -1, image_repository.loader)
self.buttons = [self.cancel_button, self.start_button, self.stop_button, self.close_button, self.restart_button]
def _init_pages(self):
if self.restart_button.IsShown(): self.restart_button.Hide()
@ -96,10 +94,10 @@ class AbstractFooter(wx.Panel):
v_sizer.AddStretchSpacer(1)
self.SetSizer(v_sizer)
def _Button(self, label=None, style=None):
def button(self, label=None, style=None, event_id=-1):
return wx.Button(
parent=self,
id=-1,
id=event_id,
size=(90, 24),
label=label,
style=style)
@ -116,10 +114,7 @@ class AbstractFooter(wx.Panel):
next(self._pages)()
def _load_image(self, img_path, height=70):
return imageutil.resize_bitmap(
self,
imageutil._load_image(img_path),
height)
return imageutil.resize_bitmap(self, imageutil._load_image(img_path), height)
class Footer(AbstractFooter):
@ -132,27 +127,15 @@ class Footer(AbstractFooter):
controller: controller class used in delagating all the commands
'''
def __init__(self, parent, controller, **kwargs):
def __init__(self, parent, **kwargs):
AbstractFooter.__init__(self, parent, **kwargs)
for button in self.buttons:
print button.GetId()
self.Bind(wx.EVT_BUTTON, self.dispatch_click, button)
self.Bind(wx.EVT_BUTTON, self.OnCancelButton, self.cancel_button)
self.Bind(wx.EVT_BUTTON, self.OnStartButton, self.start_button)
self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.close_button)
self.Bind(wx.EVT_BUTTON, self.OnRestartButton, self.restart_button)
def OnCancelButton(self, event):
self._controller.OnCancelButton(self, event)
def dispatch_click(self, event):
pub.sendMessage(str(event.GetId()))
event.Skip()
def OnCloseButton(self, event):
self._controller.OnCloseButton(self, event)
event.Skip()
def OnStartButton(self, event):
self._controller.OnStartButton(event, self)
event.Skip()
def OnRestartButton(self, event):
self._controller.OnStartButton(event, self)
event.Skip()
Loading…
Cancel
Save