ya2 · news · projects · code · about

removed uml diagrams
[pmachines.git] / ya2 / lib / p3d / gui.py
1 from inspect import getmro
2 from panda3d.core import TextNode, Texture
3 from direct.gui.DirectGuiGlobals import FLAT, ENTER, EXIT, DISABLED, NORMAL, \
4 B1PRESS
5 from direct.showbase.DirectObject import DirectObject
6 from direct.gui.DirectButton import DirectButton
7 from direct.gui.DirectCheckButton import DirectCheckButton
8 from direct.gui.DirectOptionMenu import DirectOptionMenu
9 from direct.gui.OnscreenImage import OnscreenImage
10 from direct.gui.DirectSlider import DirectSlider
11 from direct.gui.DirectEntry import DirectEntry, ENTRY_FOCUS_STATE
12 from direct.gui.DirectLabel import DirectLabel
13 from direct.gui.DirectFrame import DirectFrame
14 from direct.gui.OnscreenText import OnscreenText
15 from direct.gui.DirectScrolledFrame import DirectScrolledFrame
16 from ya2.observer import Subject
17 # from ya2.lib.ivals import Seq, Wait, PosIval, Func
18
19
20 class CommonBase:
21
22 def set_widget(self):
23 from ya2.lib.gui import Frame, Slider, Btn, Label, OptionMenu, \
24 CheckBtn, Entry, Img, Text, ScrolledFrame
25 from ya2.lib.p3d.widget import FrameMixin, SliderMixin, BtnMixin, \
26 OptionMenuMixin, CheckBtnMixin, EntryMixin, ImgMixin, \
27 ScrolledFrameMixin
28 self.__class__ = self.__class__ # for pylint
29 libwdg2wdg = {
30 FrameMixin: [Frame],
31 ScrolledFrameMixin: [ScrolledFrame],
32 SliderMixin: [Slider],
33 BtnMixin: [Btn, Label],
34 OptionMenuMixin: [OptionMenu],
35 CheckBtnMixin: [CheckBtn],
36 EntryMixin: [Entry],
37 ImgMixin: [Img, Text]}
38 for libwdg, wdgcls in libwdg2wdg.items():
39 if any(cls in getmro(self.__class__) for cls in wdgcls):
40 par_cls = libwdg
41 clsname = self.__class__.__name__ + 'Widget'
42 self.__class__ = type(clsname, (self.__class__, par_cls), {})
43 self.init(self)
44 if not hasattr(self, 'bind'): return
45 bind_args = [(ENTER, self.on_wdg_enter), (EXIT, self.on_wdg_exit)]
46 list(map(lambda args: self.bind(*args), bind_args))
47
48 def set_enter_transition(self):
49 start_pos = self.get_pos()
50 pos = self.pos - (3.6, 0)
51 self.set_pos((pos.x, 1, pos.y))
52 Seq(
53 Wait(abs(pos.y - 1) / 4),
54 PosIval(self.get_np(), .5, start_pos)
55 ).start()
56
57 def set_exit_transition(self, destroy):
58 start_pos = self.get_pos()
59 end_pos = (self.pos.x + 3.6, 1, self.pos.y)
60 seq = Seq(
61 Wait(abs(self.pos.y - 1) / 4),
62 PosIval(self.get_np(), .5, end_pos),
63 Func(self.destroy if destroy else self.hide))
64 if not destroy: seq += Func(self.set_pos, start_pos)
65 seq.start()
66
67 def translate(self):
68 if hasattr(self, 'bind_transl'): self.wdg['text'] = self.bind_transl
69
70
71 class P3dImg(CommonBase):
72
73 def __init__(self, filepath, pos=(0, 0), scale=1.0, background=False,
74 foreground=False, parent=None):
75 self.img = OnscreenImage(
76 filepath, pos=(pos[0], 1, pos[1]), scale=scale, parent=parent)
77 if background: self.img.set_bin('background', 10)
78 alpha_formats = [12] # panda3d.core.texture.Frgba
79 if self.img.get_texture().get_format() in alpha_formats:
80 self.img.set_transparency(True)
81 if foreground: self.img.set_bin('gui-popup', 50)
82
83 def reparent_to(self, node): return self.img.reparent_to(node)
84 def show(self): return self.img.show()
85 def hide(self): return self.img.hide()
86 def set_shader(self, shader): return self.img.set_shader(shader)
87 def set_shader_input(self, name, val):
88 return self.img.set_shader_input(name, val)
89 def set_texture(self, texturestage, texture):
90 return self.img.set_texture(texturestage, texture)
91
92 def set_exit_transition(self, destroy):
93 start_pos = self.get_pos()
94 end_pos = (self.pos.x + 3.6, 1, self.pos.y)
95 seq = Seq(
96 Wait(abs(self.pos.y - 1) / 4),
97 PosIval(self.get_np(), .5, end_pos),
98 Func(self.destroy if destroy else self.hide))
99 if not destroy: seq += Func(self.set_pos, (start_pos[0], start_pos[2]))
100 seq.start()
101
102 def set_pos(self, pos): return self.img.set_pos(pos[0], 1, pos[1])
103
104 def get_pos(self, pos=None): return self.img.get_pos(*[pos] if pos else [])
105
106 @property
107 def parent(self): return self.img.get_parent()
108
109 @property
110 def hidden(self): return self.img.is_hidden()
111
112 def set_transparent(self): return self.img.set_transparency(True)
113
114 def destroy(self): self.img = self.img.destroy()
115
116
117 # class P3dBase(CommonBase):
118
119 # def __init__(self, tra_src=None, tra_tra=None):
120 # # self.text_src_tra = None # it breaks the gui
121 # if tra_src and tra_tra: self.bind_tra(tra_src, tra_tra)
122
123 # def set_pos(self, pos): return self.wdg.set_pos(pos)
124 # def show(self): return self.wdg.show()
125 # def hide(self): return self.wdg.hide()
126
127 # def bind_tra(self, text_src, text_transl):
128 # # text_transl is not used, anyway we need it since we have this kind of
129 # # use: self.bind_transl('example str', _('example str'))
130 # # this allows to change translations on the fly keeping the source
131 # # text for remapping it later
132 # # TODO: try reverse mapping? i.e. retrieve the src string from the
133 # # translated one
134 # self.text_src_tra = text_src
135 # self.text_tra_tra = text_transl
136 # tra = lambda self: _(self.text_tra_tra)
137 # self.__class__.bind_transl = property(tra)
138 # self['text'] = self.bind_transl
139
140 # def get_pos(self, pos=None):
141 # return self.wdg.get_pos(*[pos] if pos else [])
142
143 # def __setitem__(self, key, value): self.wdg[key] = value
144
145 # def __getitem__(self, key): return self.wdg[key]
146
147 # def get_np(self): return self.wdg
148
149 # @property
150 # def hidden(self): return self.wdg.is_hidden()
151
152 # def destroy(self): self.wdg.destroy()
153
154
155 # class P3dAbs(P3dBase):
156
157 # def get_value(self): return self.wdg.getValue()
158 # def initialiseoptions(self): return self.wdg.initialiseoptions()
159 # def set_z(self, val): return self.wdg.set_z(val)
160 # def set_shader(self, shader): return self.wdg.set_shader(shader)
161 # def set_shader_input(self, name, val):
162 # return self.wdg.set_shader_input(name, val)
163 # def set_transparency(self, val): return self.wdg.set_transparency(val)
164 # def bind(self, evt, mth): return self.wdg.bind(evt, mth)
165
166 # def attachNewNode(self, gui_itm, sort_order):
167 # # it won't work if we name it attach_node. hopefully this will be
168 # # possible when we'll use decorators in place of mixins
169 # return self.wdg.attachNewNode(gui_itm, sort_order)
170
171 # @property
172 # def is_enabled(self): return self.wdg['state'] != DISABLED
173
174
175 # class P3dBtn(P3dAbs):
176
177 # def __init__(
178 # self, text='', parent=None, pos=(0, 0), scale=(1, 1),
179 # cmd=None, frame_size=(-1, 1, -1, 1), click_snd=None,
180 # text_fg=(1, 1, 1, 1), frame_col=(1, 1, 1, 1), text_font=None,
181 # over_snd=None, extra_args=None, frame_texture=None, img=None,
182 # tra_src=None, tra_tra=None, text_scale=1.0):
183 # str2par = {'bottomcenter': base.a2dBottomCenter}
184 # parent = str2par.get(parent, parent)
185 # extra_args = extra_args or []
186 # self.wdg = DirectButton(
187 # text=text, parent=parent, pos=(pos[0], 1, pos[1]),
188 # scale=(scale[0], 1, scale[1]), command=cmd,
189 # frameSize=frame_size, clickSound=click_snd, text_fg=text_fg,
190 # frameColor=frame_col, text_font=text_font, rolloverSound=over_snd,
191 # extraArgs=extra_args, frameTexture=frame_texture, image=img,
192 # text_scale=text_scale)
193 # P3dAbs.__init__(self, tra_src, tra_tra)
194 # self['relief'] = FLAT
195 # args = [(ENTER, self._on_enter), (EXIT, self._on_exit)]
196 # list(map(lambda args: self.bind(*args), args))
197
198 # def _on_enter(self, pos): pass # pos comes from mouse
199
200 # def _on_exit(self, pos): pass # pos comes from mouse
201
202 # # we add these with the mixins
203 # # def enable(self): self['state'] = NORMAL
204
205 # # def disable(self): self['state'] = DISABLED
206
207
208 # class P3dSlider(P3dAbs):
209
210 # def __init__(
211 # self, parent=None, pos=(0, 0), scale=1, val=0,
212 # frame_col=(1, 1, 1, 1), thumb_frame_col=(1, 1, 1, 1),
213 # cmd=None, range_=(0, 1), tra_src=None, tra_tra=None):
214 # self.wdg = DirectSlider(
215 # parent=parent, pos=(pos[0], 1, pos[1]), scale=scale, value=val,
216 # frameColor=frame_col, thumb_frameColor=thumb_frame_col,
217 # command=cmd, range=range_)
218 # P3dAbs.__init__(self, tra_src, tra_tra)
219
220
221 # class P3dCheckBtn(P3dAbs):
222
223 # def __init__(
224 # self, pos=(0, 0), text='', indicator_val=False,
225 # indicator_frame_col=(1, 1, 1, 1), frame_col=(1, 1, 1, 1),
226 # scale=(1, 1, 1), click_snd=None, over_snd=None,
227 # text_fg=(1, 1, 1, 1), text_font=None, cmd=None, tra_src=None,
228 # tra_tra=None):
229 # self.wdg = DirectCheckButton(
230 # pos=(pos[0], 1, pos[1]), text=text, indicatorValue=indicator_val,
231 # indicator_frameColor=indicator_frame_col,
232 # frameColor=frame_col, scale=scale, clickSound=click_snd,
233 # rolloverSound=over_snd, text_fg=text_fg, text_font=text_font,
234 # command=cmd)
235 # P3dAbs.__init__(self, tra_src, tra_tra)
236
237
238 # class P3dOptionMenu(P3dAbs):
239
240 # def __init__(
241 # self, text='', items=None, pos=(0, 0), scale=(1, 1, 1),
242 # initialitem='', cmd=None, frame_size=(-1, 1, -1, 1),
243 # click_snd=None, over_snd=None, text_may_change=False,
244 # text_fg=(1, 1, 1, 1), item_frame_col=(1, 1, 1, 1),
245 # frame_col=(1, 1, 1, 1), highlight_col=(1, 1, 1, 1),
246 # text_scale=.05, popup_marker_col=(1, 1, 1, 1),
247 # item_relief=None, item_text_font=None, text_font=None,
248 # tra_src=None, tra_tra=None):
249 # items = items or []
250 # self.wdg = DirectOptionMenu(
251 # text=text, items=items, pos=(pos[0], 1, pos[1]), scale=scale,
252 # initialitem=initialitem, command=cmd, frameSize=frame_size,
253 # clickSound=click_snd, rolloverSound=over_snd,
254 # textMayChange=text_may_change, text_fg=text_fg,
255 # item_frameColor=item_frame_col, frameColor=frame_col,
256 # highlightColor=highlight_col, text_scale=text_scale,
257 # popupMarker_frameColor=popup_marker_col,
258 # item_relief=item_relief, item_text_font=item_text_font,
259 # text_font=text_font)
260 # P3dAbs.__init__(self, tra_src, tra_tra)
261
262 # def set(self, idx, f_cmd=1): return self.wdg.set(idx, f_cmd)
263
264 # @property
265 # def curr_val(self): return self.wdg.get()
266
267 # @property
268 # def curr_idx(self): return self.wdg.selectedIndex
269
270
271 # class P3dEntry(P3dAbs, DirectObject, Subject):
272
273 # def __init__(
274 # self, scale=.05, pos=(0, 0), entry_font=None, width=12,
275 # frame_col=(1, 1, 1, 1), initial_text='', obscured=False,
276 # cmd=None, focus_in_cmd=None, focus_in_args=None,
277 # focus_out_cmd=None, focus_out_args=None, parent=None,
278 # tra_src=None, tra_tra=None, text_fg=(1, 1, 1, 1), on_tab=None,
279 # on_click=None):
280 # self.__focused = False
281 # self.__focus_in_cmd = focus_in_cmd
282 # self.__focus_out_cmd = focus_out_cmd
283 # DirectObject.__init__(self)
284 # Subject.__init__(self)
285 # focus_in_args = focus_in_args or []
286 # focus_out_args = focus_out_args or []
287 # self.wdg = DirectEntry(
288 # scale=scale, pos=(pos[0], 1, pos[1]), entryFont=entry_font,
289 # width=width, frameColor=frame_col, initialText=initial_text,
290 # obscured=obscured, command=cmd, focusInCommand=self._focus_in_cmd,
291 # focusInExtraArgs=focus_in_args,
292 # focusOutCommand=self._focus_out_cmd,
293 # focusOutExtraArgs=focus_out_args, parent=parent,
294 # text_fg=text_fg)
295 # P3dAbs.__init__(self, tra_src, tra_tra)
296 # if on_tab:
297 # self.on_tab_cb = on_tab
298 # self.accept('tab-up', self.on_tab)
299 # if on_click: self.wdg.bind(B1PRESS, on_click)
300
301 # def set(self, txt): return self.wdg.set(txt)
302
303 # def _focus_in_cmd(self, *args):
304 # self.__focused = True
305 # if self.__focus_in_cmd: self.__focus_in_cmd(*args)
306 # self.notify('on_entry_enter')
307
308 # def _focus_out_cmd(self, *args):
309 # self.__focused = False
310 # if self.__focus_out_cmd: self.__focus_out_cmd(*args)
311 # self.notify('on_entry_exit')
312
313 # def on_tab(self):
314 # if self.wdg['focus'] == ENTRY_FOCUS_STATE: self.on_tab_cb()
315
316 # @property
317 # def focused(self): return self.__focused
318
319 # @property
320 # def text(self): return self.wdg.get()
321
322 # def enter_text(self, txt):
323 # return self.wdg.enterText(txt)
324
325 # def enable(self): self['state'] = NORMAL
326
327 # def disable(self): self['state'] = DISABLED
328
329 # def destroy(self):
330 # self.ignore('tab-up')
331 # self.on_tab_cb = None
332 # Subject.destroy(self)
333 # P3dAbs.destroy(self)
334
335
336 # class P3dLabel(P3dAbs):
337
338 # def __init__(
339 # self, text='', pos=(0, 0), parent=None, text_wordwrap=12,
340 # text_align=None, text_fg=(1, 1, 1, 1), text_font=None, scale=.05,
341 # frame_col=(1, 1, 1, 1), tra_src=None, tra_tra=None, hpr=(0, 0, 0)):
342 # self.wdg = DirectLabel(
343 # text=text, pos=(pos[0], 1, pos[1]), parent=parent,
344 # text_wordwrap=text_wordwrap, text_align=text_align,
345 # text_fg=text_fg, text_font=text_font, scale=scale,
346 # frameColor=frame_col, hpr=hpr)
347 # P3dAbs.__init__(self, tra_src, tra_tra)
348
349 # def set_bin(self, bin_name, priority): return self.wdg.set_bin(bin_name, priority)
350
351 # def set_x(self, x): return self.wdg.set_x(x)
352
353 # def set_alpha_scale(self, alpha): return self.wdg.set_alpha_scale(alpha)
354
355
356 # class P3dTxt(P3dBase):
357
358 # def __init__(
359 # self, txt='', pos=(0, 0), scale=.05, wordwrap=12, parent=None,
360 # fg=(1, 1, 1, 1), font=None, align=None, tra_src=None,
361 # tra_tra=None):
362 # str2par = {'bottomleft': base.a2dBottomLeft,
363 # 'bottomright': base.a2dBottomRight,
364 # 'leftcenter': base.a2dLeftCenter}
365 # str2al = {'left': TextNode.A_left, 'right': TextNode.A_right,
366 # 'center': TextNode.A_center}
367 # if parent and parent in str2par: parent = str2par[parent]
368 # if align: align = str2al[align]
369 # self.wdg = OnscreenText(
370 # text=txt, pos=pos, scale=scale, wordwrap=wordwrap,
371 # parent=parent, fg=fg, font=font, align=align)
372 # P3dBase.__init__(self, tra_src, tra_tra)
373
374 # def set_r(self, r): return self.wdg.set_r(r)
375
376
377 # class P3dFrame(P3dAbs):
378
379 # def __init__(self, frame_size=(-1, 1, -1, 1), frame_col=(1, 1, 1, 1),
380 # pos=(0, 0), parent=None, texture_coord=False):
381 # P3dAbs.__init__(self)
382 # self.wdg = DirectFrame(frameSize=frame_size, frameColor=frame_col,
383 # pos=(pos[0], 1, pos[1]), parent=parent)
384 # if texture_coord: self.wdg['frameTexture'] = Texture()
385
386
387 # class P3dScrolledFrame(P3dAbs):
388
389 # def __init__(
390 # self, frame_sz=(-1, 1, -1, 1), canvas_sz=(0, 1, 0, 1),
391 # scrollbar_width=.05, frame_col=(1, 1, 1, 1),
392 # pos=(0, 0), parent='topleft'):
393 # P3dAbs.__init__(self)
394 # par2p3d = {'topleft': base.a2dTopLeft}
395 # if parent and parent in par2p3d: parent = par2p3d[parent]
396 # self.wdg = DirectScrolledFrame(
397 # frameSize=frame_sz,
398 # canvasSize=canvas_sz,
399 # scrollBarWidth=scrollbar_width,
400 # frameColor=frame_col,
401 # pos=(pos[0], 1, pos[1]),
402 # parent=parent)
403
404 # @property
405 # def canvas(self): return self.wdg.getCanvas()