Browse Source

Refactored to pubsub

subparsing
chriskiehl 10 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 wx
import sys import sys
import subprocess import subprocess
from wx.lib.pubsub import pub
from multiprocessing.dummy import Pool from multiprocessing.dummy import Pool
from gooey.gui import events
from gooey.gui.lang import i18n from gooey.gui.lang import i18n
@ -31,7 +35,23 @@ class Controller(object):
self.core_gui = base_frame self.core_gui = base_frame
self.build_spec = build_spec 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') msg = i18n._('sure_you_want_to_exit')
dlg = wx.MessageDialog(None, msg, i18n._('close_program'), wx.YES_NO) dlg = wx.MessageDialog(None, msg, i18n._('close_program'), wx.YES_NO)
result = dlg.ShowModal() result = dlg.ShowModal()
@ -41,61 +61,51 @@ class Controller(object):
sys.exit() sys.exit()
dlg.Destroy() 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) command = '{0} {1}'.format(self.build_spec['target'], cmd_line_args)
self.core_gui.NextPage() 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() _stdout, _stderr = process.communicate()
if process.returncode == 0: if process.returncode == 0:
self.core_gui.NextPage() self.core_gui.NextPage()
self.ShowGoodFinishedDialog()
self.success_dialog()
else: else:
self.core_gui.NextPage() 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 = wx.MessageDialog(None, content, title, style)
a.ShowModal() a.ShowModal()
a.Destroy() 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) parent=self)
self.config_panel = AdvancedConfigPanel(self, self.build_spec) self.config_panel = AdvancedConfigPanel(self, self.build_spec)
self.runtime_display = RuntimeDisplay(self) 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] self.panels = [self.head_panel, self.config_panel, self.foot_panel]
def _do_layout(self): def _do_layout(self):
@ -117,7 +117,7 @@ class BaseWindow(wx.Frame):
self.Layout() self.Layout()
def ManualStart(self): def ManualStart(self):
self._controller.ManualStart()
self._controller.manual_restart()
def onResize(self, evt): def onResize(self, evt):
evt.Skip() evt.Skip()

59
gooey/gui/windows/footer.py

@ -7,8 +7,10 @@ Created on Dec 23, 2013
import wx import wx
import wx.animate 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.lang import i18n
from gooey.gui import imageutil, image_repository, events
class AbstractFooter(wx.Panel): class AbstractFooter(wx.Panel):
@ -29,6 +31,7 @@ class AbstractFooter(wx.Panel):
self.close_button = None self.close_button = None
self.stop_button = None self.stop_button = None
self.restart_button = None self.restart_button = None
self.buttons = None
self._init_components() self._init_components()
self._init_pages() self._init_pages()
@ -36,19 +39,14 @@ class AbstractFooter(wx.Panel):
def _init_components(self): 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): def _init_pages(self):
if self.restart_button.IsShown(): self.restart_button.Hide() if self.restart_button.IsShown(): self.restart_button.Hide()
@ -96,10 +94,10 @@ class AbstractFooter(wx.Panel):
v_sizer.AddStretchSpacer(1) v_sizer.AddStretchSpacer(1)
self.SetSizer(v_sizer) self.SetSizer(v_sizer)
def _Button(self, label=None, style=None):
def button(self, label=None, style=None, event_id=-1):
return wx.Button( return wx.Button(
parent=self, parent=self,
id=-1,
id=event_id,
size=(90, 24), size=(90, 24),
label=label, label=label,
style=style) style=style)
@ -116,10 +114,7 @@ class AbstractFooter(wx.Panel):
next(self._pages)() next(self._pages)()
def _load_image(self, img_path, height=70): 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): class Footer(AbstractFooter):
@ -132,27 +127,15 @@ class Footer(AbstractFooter):
controller: controller class used in delagating all the commands 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) 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() 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