Mercurial > fife-parpg
diff engine/extensions/pychan/internal.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 | 40257a6dc57d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/extensions/pychan/internal.py Sat Mar 14 12:13:29 2009 +0000 @@ -0,0 +1,208 @@ +# coding: utf-8 + +from compat import guichan, in_fife +import widgets +import fonts +from exceptions import * +from traceback import print_exc + +def get_manager(): + """ + Get the manager from inside pychan. + + To avoid cyclic imports write:: + from internal import get_manager + """ + return Manager.manager + +def screen_width(): + return get_manager().hook.screen_width + +def screen_height(): + return get_manager().hook.screen_height + +class Manager(object): + manager = None + + def __init__(self, hook, debug = False): + super(Manager,self).__init__() + self.hook = hook + self.debug = debug + + if in_fife: + if not hook.engine.getEventManager(): + raise InitializationError("No event manager installed.") + if not hook.engine.getGuiManager(): + raise InitializationError("No GUI manager installed.") + + self.fonts = {} + #glyphs = ' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/:();%`\'*#=[]"' + self.fonts['default'] = hook.default_font + + self.styles = {} + self.addStyle('default',DEFAULT_STYLE) + + Manager.manager = self + + # Setup synchronous dialogs + self.mainLoop = None + self.breakFromMainLoop = None + self.can_execute = False + + # Autopos + from autoposition import placeWidget + self.placeWidget = placeWidget + + def setupModalExecution(self,mainLoop,breakFromMainLoop): + """ + Setup synchronous execution of dialogs. + """ + self.mainLoop = mainLoop + self.breakFromMainLoop = breakFromMainLoop + self.can_execute = True + + def show(self,widget): + """ + Shows a widget on screen. Used by L{Widget.show} - do not use directly. + """ + self.placeWidget(widget, widget.position_technique) + self.hook.add_widget( widget.real_widget ) + + def hide(self,widget): + """ + Hides a widget again. Used by L{Widget.hide} - do not use directly. + """ + self.hook.remove_widget( widget.real_widget ) + + def setDefaultFont(self,name): + self.fonts['default'] = self.getFont(name) + + def getFont(self,name): + """ + B{pending deprecation} + + Returns a GuiFont identified by its name. + + @param name: A string identifier from the font definitions in pychans config files. + """ + if in_fife: + font = self.fonts.get(name) + if isinstance(font,guichan.GuiFont): + return font + if hasattr(font,"font") and isinstance(getattr(font,"font"),guichan.GuiFont): + return font.font + return fonts.parseFontSpec(name) + else: + return self.hook.get_font(name) + + def addFont(self,font): + """ + B{deprecated} + + Add a font to the font registry. It's not necessary to call this directly. + But it expects a L{Font} instance and throws an L{InitializationError} + otherwise. + + @param font: A L{Font} instance. + """ + if not isinstance(font,fonts.Font): + raise InitializationError("PyChan Manager expected a fonts.Font instance, not %s." % repr(font)) + self.fonts[font.name] = font + + def addStyle(self,name,style): + style = self._remapStyleKeys(style) + + for k,v in self.styles.get('default',{}).items(): + style[k] = style.get(k,v) + self.styles[name] = style + + def stylize(self,widget, style, **kwargs): + style = self.styles[style] + for k,v in style.get('default',{}).items(): + v = kwargs.get(k,v) + setattr(widget,k,v) + + cls = widget.__class__ + for applicable,specstyle in style.items(): + if not isinstance(applicable,tuple): + applicable = (applicable,) + if cls in applicable: + for k,v in specstyle.items(): + v = kwargs.get(k,v) + setattr(widget,k,v) + + def _remapStyleKeys(self,style): + # Remap class names, create copy: + def _toClass(class_): + if class_ == "default": + return class_ + + if type(class_) == type(widgets.Widget) and issubclass(class_,widgets.Widget): + return class_ + if not widgets.WIDGETS.has_key(str(class_)): + raise InitializationError("Can't resolve %s to a widget class." % repr(class_)) + return widgets.WIDGETS[str(class_)] + + style_copy = {} + for k,v in style.items(): + if isinstance(k,tuple): + new_k = tuple(map(_toClass,k)) + else: + new_k = _toClass(k) + style_copy[new_k] = v + return style_copy + + def loadImage(self,filename): + if not filename: + raise InitializationError("Empty Image file.") + return self.hook.load_image(filename) + +# Default Widget style. + +DEFAULT_STYLE = { + 'default' : { + 'border_size': 0, + 'margins': (0,0), + 'base_color' : guichan.Color(28,28,28), + 'foreground_color' : guichan.Color(255,255,255), + 'background_color' : guichan.Color(50,50,50), + }, + 'Button' : { + 'border_size': 2, + 'margins' : (5,2), + 'min_size' : (15,10), + }, + 'CheckBox' : { + 'border_size': 0, + }, + 'RadioButton' : { + 'border_size': 0, + 'background_color' : guichan.Color(0,0,0), + }, + 'Label' : { + 'border_size': 0, + }, + 'ClickLabel' : { + 'border_size': 0, + }, + 'ListBox' : { + 'border_size': 0, + }, + 'Window' : { + 'border_size': 0, + 'margins': (5,5), + 'opaque' : 1, + 'titlebar_height' : 12, + 'vexpanding' : 1, + #'background_image' : 'gui/backgrounds/background.png', + #'font' : 'samanata_large' + }, + 'TextBox' : { + }, + ('Container','HBox','VBox') : { + 'border_size': 0, + 'margins': (0,0), + 'padding':2, + #'background_image' : 'gui/backgrounds/background.png', + } +} \ No newline at end of file