Mercurial > fife-parpg
diff engine/extensions/pychan/dialogs.py @ 205:54bfd1015b35
* PyChan event handling rework (part I)
** Unified listeners
** ...hopefully more robust attach/detach code.
* Added compat, layout and also the new autopsition feature.
* Documentation
* Minor style fixes in core.
author | phoku@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sat, 14 Mar 2009 12:13:29 +0000 |
parents | |
children | 51cc05d862f2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/extensions/pychan/dialogs.py Sat Mar 14 12:13:29 2009 +0000 @@ -0,0 +1,197 @@ +# coding: utf-8 + +from pychan import loadXML +import pychan.tools +import widgets +from internal import get_manager, screen_width, screen_height +from StringIO import StringIO + +OK,YES,NO,CANCEL = True,True,False,None + +def print_event(**kwargs): + print kwargs + +class XMLDialog(object): + def __init__(self, xml, ok_field = None, cancel_field = None,initial_data={},data={}): + self.gui = loadXML(xml) + self.ok_field = ok_field + self.cancel_field = cancel_field + self.initial_data= initial_data + self.data= data + self.max_size=None + self.min_size=None + self.gui.capture(print_event,"mouseEntered") + + def execute(self): + self.gui.distributeInitialData(self.initial_data) + self.gui.distributeData(self.data) + + screen_w, screen_h = screen_width(), screen_height() + if self.max_size is None: + self.max_size = screen_w/2, screen_h/3 + if self.min_size is None: + self.min_size = screen_w/2, screen_h/4 + self.gui.max_size = self.max_size + self.gui.min_size = self.min_size + + resultMap = {} + if self.gui.findChild(name="okButton"): + resultMap["okButton"] = OK + + if self.gui.findChild(name="cancelButton"): + resultMap["cancelButton"] = CANCEL + + if self.gui.findChild(name="yesButton"): + resultMap["noButton"] = NO + + if self.gui.findChild(name="yesButton"): + resultMap["yesButton"] = YES + + ok = self.gui.execute(resultMap) + if ok: + return self.getOkResult() + return self.getCancelResult() + + def getOkResult(self): + if self.ok_field: + return self.gui.collectData(self.ok_field) + return True + + def getCancelResult(self): + if self.cancel_field: + return self.gui.collectData(self.cancel_field) + return False + +MESSAGE_BOX_XML = """\ +<Window name="window" title="Message"> +<ScrollArea> +<Label wrap_text="1" text="$MESSAGE" name="message" vexpanding="1"/> +</ScrollArea> +<HBox> +<Spacer/><Button min_width="50" name="okButton" text="OK"/> +</HBox> +</Window> +""" + +YESNO_BOX_XML = """\ +<Window name="window" title="Question"> +<ScrollArea> +<Label wrap_text="1" text="$MESSAGE" name="message" vexpanding="1"/> +</ScrollArea> +<HBox> +<Spacer/> +<Button min_width="50" name="yesButton" text="Yes"/> +<Button min_width="50" name="noButton" text="No"/> +</HBox> +</Window> +""" + +YESNOCANCEL_BOX_XML = """\ +<Window name="window" title="Question"> +<ScrollArea> +<Label wrap_text="1" text="$MESSAGE" name="message" vexpanding="1"/> +</ScrollArea> +<HBox> +<Spacer/> +<Button min_width="50" name="yesButton" text="Yes"/> +<Button min_width="50" name="noButton" text="No"/> +<Button min_width="50" name="cancelButton" text="Cancel"/> +</HBox> +</Window> +""" + +SELECT_BOX_XML = """\ +<Window name="window" title="Select"> +<Label wrap_text="1" text="$MESSAGE" name="message"/> +<ScrollArea> +<ListBox name="selection"> +</ListBox> +</ScrollArea> +<HBox> +<Spacer/> +<Button min_width="50" name="okButton" text="Select"/> +<Button min_width="50" name="cancelButton" text="Cancel"/> +</HBox> +</Window> +""" + +EXCEPTION_CATCHER_XML="""\ +<Window name="window" title="An exception occurred - what now?"> + <VBox hexpanding="1"> + <Label wrap_text="1" max_width="400" text="$MESSAGE" name="message"/> + <ScrollArea> + <Label text="$MESSAGE" name="traceback"/> + </ScrollArea> + </VBox> + <HBox> + <Spacer/> + <Button name="yesButton" text="Retry"/> + <Button name="noButton" text="Ignore"/> + <Button name="cancelButton" text="Reraise"/> + </HBox> +</Window> +""" + +def _make_text(message): + if callable(message): + message = message() + if hasattr(message,"read"): + message = message.read() + return message + +def message(message="",caption="Message"): + text = _make_text(message) + dialog = XMLDialog(StringIO(MESSAGE_BOX_XML), + initial_data={'message':text,'window':caption}) + dialog.gui.findChild(name="message").max_width = screen_width()/2 - 50 + dialog.execute() + +def yesNo(message="",caption="Message"): + text = _make_text(message) + dialog = XMLDialog(StringIO(YESNO_BOX_XML), + initial_data={'message':text,'window':caption}) + dialog.gui.findChild(name="message").max_width = screen_width()/2 - 50 + return dialog.execute() + +def yesNoCancel(message="",caption="Message"): + text = _make_text(message) + dialog = XMLDialog(StringIO(YESNOCANCEL_BOX_XML), + initial_data={'message':text,'window':caption}) + dialog.gui.findChild(name="message").max_width = screen_width()/2 - 50 + return dialog.execute() + +def select(message="",options=[],caption="Message"): + text = _make_text(message) + dialog = XMLDialog(StringIO(SELECT_BOX_XML), + initial_data={'message':text,'window':caption}) + dialog.size = screen_width()/3, 2*screen_height()/3 + + dialog.gui.findChild(name="message").max_width = screen_width()/2 - 50 + listbox = dialog.gui.findChild(name="selection") + listbox.items = options + if dialog.execute(): + return listbox.selected_item + return None + +def trace(f): + import sys, traceback + def new_f(*args,**kwargs): + try: + return pychan.tools.applyOnlySuitable(f,*args,**kwargs) + + except Exception, e: + dialog = XMLDialog(StringIO(EXCEPTION_CATCHER_XML), + initial_data={'message':str(e)} + ) + tb = traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) + dialog.gui.findChild(name="traceback").text = "".join(tb) + dialog.min_size = screen_width()/2,3*screen_height()/4 + dialog.max_size = screen_width()/2,3*screen_height()/4 + result = dialog.execute() + if result == YES: + return new_f(*args,**kwargs) + elif result == NO: + return + raise + return new_f +