Mercurial > fife-parpg
comparison 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 |
comparison
equal
deleted
inserted
replaced
204:5816ab527da8 | 205:54bfd1015b35 |
---|---|
1 # coding: utf-8 | |
2 | |
3 from compat import guichan, in_fife | |
4 import widgets | |
5 import fonts | |
6 from exceptions import * | |
7 from traceback import print_exc | |
8 | |
9 def get_manager(): | |
10 """ | |
11 Get the manager from inside pychan. | |
12 | |
13 To avoid cyclic imports write:: | |
14 from internal import get_manager | |
15 """ | |
16 return Manager.manager | |
17 | |
18 def screen_width(): | |
19 return get_manager().hook.screen_width | |
20 | |
21 def screen_height(): | |
22 return get_manager().hook.screen_height | |
23 | |
24 class Manager(object): | |
25 manager = None | |
26 | |
27 def __init__(self, hook, debug = False): | |
28 super(Manager,self).__init__() | |
29 self.hook = hook | |
30 self.debug = debug | |
31 | |
32 if in_fife: | |
33 if not hook.engine.getEventManager(): | |
34 raise InitializationError("No event manager installed.") | |
35 if not hook.engine.getGuiManager(): | |
36 raise InitializationError("No GUI manager installed.") | |
37 | |
38 self.fonts = {} | |
39 #glyphs = ' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/:();%`\'*#=[]"' | |
40 self.fonts['default'] = hook.default_font | |
41 | |
42 self.styles = {} | |
43 self.addStyle('default',DEFAULT_STYLE) | |
44 | |
45 Manager.manager = self | |
46 | |
47 # Setup synchronous dialogs | |
48 self.mainLoop = None | |
49 self.breakFromMainLoop = None | |
50 self.can_execute = False | |
51 | |
52 # Autopos | |
53 from autoposition import placeWidget | |
54 self.placeWidget = placeWidget | |
55 | |
56 def setupModalExecution(self,mainLoop,breakFromMainLoop): | |
57 """ | |
58 Setup synchronous execution of dialogs. | |
59 """ | |
60 self.mainLoop = mainLoop | |
61 self.breakFromMainLoop = breakFromMainLoop | |
62 self.can_execute = True | |
63 | |
64 def show(self,widget): | |
65 """ | |
66 Shows a widget on screen. Used by L{Widget.show} - do not use directly. | |
67 """ | |
68 self.placeWidget(widget, widget.position_technique) | |
69 self.hook.add_widget( widget.real_widget ) | |
70 | |
71 def hide(self,widget): | |
72 """ | |
73 Hides a widget again. Used by L{Widget.hide} - do not use directly. | |
74 """ | |
75 self.hook.remove_widget( widget.real_widget ) | |
76 | |
77 def setDefaultFont(self,name): | |
78 self.fonts['default'] = self.getFont(name) | |
79 | |
80 def getFont(self,name): | |
81 """ | |
82 B{pending deprecation} | |
83 | |
84 Returns a GuiFont identified by its name. | |
85 | |
86 @param name: A string identifier from the font definitions in pychans config files. | |
87 """ | |
88 if in_fife: | |
89 font = self.fonts.get(name) | |
90 if isinstance(font,guichan.GuiFont): | |
91 return font | |
92 if hasattr(font,"font") and isinstance(getattr(font,"font"),guichan.GuiFont): | |
93 return font.font | |
94 return fonts.parseFontSpec(name) | |
95 else: | |
96 return self.hook.get_font(name) | |
97 | |
98 def addFont(self,font): | |
99 """ | |
100 B{deprecated} | |
101 | |
102 Add a font to the font registry. It's not necessary to call this directly. | |
103 But it expects a L{Font} instance and throws an L{InitializationError} | |
104 otherwise. | |
105 | |
106 @param font: A L{Font} instance. | |
107 """ | |
108 if not isinstance(font,fonts.Font): | |
109 raise InitializationError("PyChan Manager expected a fonts.Font instance, not %s." % repr(font)) | |
110 self.fonts[font.name] = font | |
111 | |
112 def addStyle(self,name,style): | |
113 style = self._remapStyleKeys(style) | |
114 | |
115 for k,v in self.styles.get('default',{}).items(): | |
116 style[k] = style.get(k,v) | |
117 self.styles[name] = style | |
118 | |
119 def stylize(self,widget, style, **kwargs): | |
120 style = self.styles[style] | |
121 for k,v in style.get('default',{}).items(): | |
122 v = kwargs.get(k,v) | |
123 setattr(widget,k,v) | |
124 | |
125 cls = widget.__class__ | |
126 for applicable,specstyle in style.items(): | |
127 if not isinstance(applicable,tuple): | |
128 applicable = (applicable,) | |
129 if cls in applicable: | |
130 for k,v in specstyle.items(): | |
131 v = kwargs.get(k,v) | |
132 setattr(widget,k,v) | |
133 | |
134 def _remapStyleKeys(self,style): | |
135 # Remap class names, create copy: | |
136 def _toClass(class_): | |
137 if class_ == "default": | |
138 return class_ | |
139 | |
140 if type(class_) == type(widgets.Widget) and issubclass(class_,widgets.Widget): | |
141 return class_ | |
142 if not widgets.WIDGETS.has_key(str(class_)): | |
143 raise InitializationError("Can't resolve %s to a widget class." % repr(class_)) | |
144 return widgets.WIDGETS[str(class_)] | |
145 | |
146 style_copy = {} | |
147 for k,v in style.items(): | |
148 if isinstance(k,tuple): | |
149 new_k = tuple(map(_toClass,k)) | |
150 else: | |
151 new_k = _toClass(k) | |
152 style_copy[new_k] = v | |
153 return style_copy | |
154 | |
155 def loadImage(self,filename): | |
156 if not filename: | |
157 raise InitializationError("Empty Image file.") | |
158 return self.hook.load_image(filename) | |
159 | |
160 # Default Widget style. | |
161 | |
162 DEFAULT_STYLE = { | |
163 'default' : { | |
164 'border_size': 0, | |
165 'margins': (0,0), | |
166 'base_color' : guichan.Color(28,28,28), | |
167 'foreground_color' : guichan.Color(255,255,255), | |
168 'background_color' : guichan.Color(50,50,50), | |
169 }, | |
170 'Button' : { | |
171 'border_size': 2, | |
172 'margins' : (5,2), | |
173 'min_size' : (15,10), | |
174 }, | |
175 'CheckBox' : { | |
176 'border_size': 0, | |
177 }, | |
178 'RadioButton' : { | |
179 'border_size': 0, | |
180 'background_color' : guichan.Color(0,0,0), | |
181 }, | |
182 'Label' : { | |
183 'border_size': 0, | |
184 }, | |
185 'ClickLabel' : { | |
186 'border_size': 0, | |
187 }, | |
188 'ListBox' : { | |
189 'border_size': 0, | |
190 }, | |
191 'Window' : { | |
192 'border_size': 0, | |
193 'margins': (5,5), | |
194 'opaque' : 1, | |
195 'titlebar_height' : 12, | |
196 'vexpanding' : 1, | |
197 #'background_image' : 'gui/backgrounds/background.png', | |
198 #'font' : 'samanata_large' | |
199 }, | |
200 'TextBox' : { | |
201 }, | |
202 ('Container','HBox','VBox') : { | |
203 'border_size': 0, | |
204 'margins': (0,0), | |
205 'padding':2, | |
206 #'background_image' : 'gui/backgrounds/background.png', | |
207 } | |
208 } |