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 }