ya2 · news · projects · code · about

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