1 # from inspect import getmro
2 # from ya2.lib.gui import Btn, Slider, CheckBtn, OptionMenu, Entry
3 # from ya2.engine.vec import Vec2
4 # from ya2.engine.gui.gui import left, right, up, down
5 # from ya2.gameobject import GameObject, GuiColleague, EventColleague
6 # from ya2.engine.gui.imgbtn import ImgBtn
9 # class PageGui(GuiColleague):
11 # def __init__(self, mediator, menu_props, players=[0]):
12 # GuiColleague.__init__(self, mediator)
13 # self.enable_tsk = None
14 # self._back_btn = None
15 # self.menu_props = menu_props
16 # self.players = players
21 # for player in players:
23 # self.__next_wdg((-.1, -1), player, Vec2(-3.6, 1))]
24 # if self.curr_wdgs[-1]:
25 # self.curr_wdgs[-1].on_wdg_enter(None, player)
27 # def build(self, back_btn=True, exit_behav=False):
28 # if back_btn: self.__build_back_btn(exit_behav)
31 # self.transition_enter()
32 # self.eng.cursor_top()
34 # def add_widgets(self, widgets): self.widgets += widgets
36 # def on_arrow(self, direction, player):
37 # if not self.curr_wdgs[player]: return
38 # if self.curr_wdgs[player].__class__.__name__ == 'P3dEntryWidget' and \
39 # self.curr_wdgs[player].focused: return
40 # processed_cmd = self.curr_wdgs[player].on_arrow(direction)
41 # # e.g. up/down in a combobox or left/right in a slider
42 # if processed_cmd: return
43 # next_wdg = self.__next_wdg(direction, player)
44 # if not next_wdg: return
45 # self.focus(next_wdg, player)
47 # def on_enter(self, player):
48 # if not self.curr_wdgs[player]: return
49 # arg = player if len(self.players) > 1 else None
50 # if self.curr_wdgs[player].on_enter(arg): self.enable([player])
51 # # wdg.on_enter returns True when it is an option widget
55 # is_btn = lambda wdg: Btn in getmro(wdg.__class__)
56 # return [wdg for wdg in self.widgets if is_btn(wdg)]
58 # def focus(self, wdg, player):
59 # self.curr_wdgs[player].on_wdg_exit(None, player)
60 # self.curr_wdgs[player] = wdg
61 # self.curr_wdgs[player].on_wdg_enter(None, player)
63 # def __direction_dot_dwg(self, wdg, direction, player, start=None):
64 # if start: start_pos = start
65 # else: start_pos = self.curr_wdgs[player].pos
66 # return (wdg.pos - start_pos).normalized.dot(direction)
68 # def __next_weight(self, wdg, direction, player, start=None):
69 # if start: start_pos = start
70 # else: start_pos = self.curr_wdgs[player].global_pos
71 # dot = self.__direction_dot_dwg(wdg, direction, player, start)
72 # if direction in [(-1, 0), (1, 0)]:
73 # proj_dist = abs(wdg.global_pos.x - start_pos.x)
74 # else: proj_dist = abs(wdg.global_pos.y - start_pos.y)
75 # weights = [.5, .5] if direction in [left, right] else [.1, .9]
76 # return weights[0] * (dot * dot) + weights[1] * (1 - proj_dist)
78 # def __next_wdg(self, direction, player, start=None):
79 # # interactive classes
80 # iclss = [Btn, CheckBtn, Slider, OptionMenu, ImgBtn, Entry]
81 # inter = lambda wdg: any(pcl in iclss for pcl in getmro(wdg.__class__))
82 # allwdgs = [wdg for wdg in self.widgets if inter(wdg)]
83 # wdgs = list(filter(lambda wdg: wdg.is_enabled, allwdgs))
84 # if player < len(self.curr_wdgs) and self.curr_wdgs[player] \
85 # and self.curr_wdgs[player] in wdgs:
86 # # the last check for this case: multiple players appear on the
87 # # same button, one player clicks it, another moves from it
88 # wdgs.remove(self.curr_wdgs[player])
89 # mth = self.__direction_dot_dwg
90 # in_direction = lambda wdg: mth(wdg, direction, player, start) > .1
91 # dirwdgs = list(filter(in_direction, wdgs))
92 # if not dirwdgs: return None
93 # nextweight = lambda wdg: \
94 # self.__next_weight(wdg, direction, player, start)
95 # return max(dirwdgs, key=nextweight)
97 # def _set_widgets(self):
98 # list(map(lambda wdg: wdg.set_widget(), self.widgets))
100 # def _set_entries(self):
101 # for wdg in self.widgets:
102 # if wdg.__class__.__name__ == 'P3dEntryWidget':
103 # wdg.attach(self.on_entry_enter)
104 # wdg.attach(self.on_entry_exit)
106 # def on_entry_enter(self):
107 # if self.menu_props: # i.e. not destroyed
108 # self.disable_navigation(self.players)
110 # def on_entry_exit(self):
111 # if self.menu_props: # i.e. not destroyed
112 # self.enable_navigation(self.players)
114 # def transition_enter(self):
116 # list(map(lambda wdg: wdg.set_enter_transition(), self.widgets))
117 # self.enable(self.players)
119 # def translate(self): list(map(lambda wdg: wdg.translate(), self.widgets))
121 # def enable_navigation(self, players):
122 # if self.enable_tsk: self.eng.rm_do_later(self.enable_tsk)
123 # self.enable_tsk = self.eng.do_later(
124 # .01, self.enable_navigation_aux, [players])
126 # def update_navigation(self):
127 # self.disable_navigation(self.players)
128 # self.enable_navigation(self.players)
130 # def enable_navigation_aux(self, players):
132 # for player in players:
133 # nav = self.menu_props.nav.navinfo_lst[player]
135 # (self.eng.lib.remap_str(nav.left), self.on_arrow,
137 # (self.eng.lib.remap_str(nav.right), self.on_arrow,
139 # (self.eng.lib.remap_str(nav.up), self.on_arrow, [up, player]),
140 # (self.eng.lib.remap_str(nav.down), self.on_arrow,
142 # (self.eng.lib.remap_str(nav.fire), self.on_enter, [player])]
143 # def append_up(evt): return evt + ('' if evt.endswith('-up') else '-up')
144 # evts = [(append_up(evt[0]), evt[1], evt[2]) for evt in evts]
146 # list(map(lambda args: self.mediator.event.accept(*args), evts))
147 # self.eng.joystick_mgr.bind_keyboard(navs)
148 # if self.eng.cfg.dev_cfg.menu_joypad and self._back_btn:
149 # self.mediator.event.accept('joypad0-face_b-up', self.__back_wrapper)
151 # def __back_wrapper(self):
152 # if not self.eng.joystick_mgr.is_recording: self._back_btn['command']()
154 # def disable_navigation(self, players):
155 # if self.enable_tsk:
156 # self.enable_tsk = self.eng.rm_do_later(self.enable_tsk)
157 # for player in players:
158 # nav = self.menu_props.nav.navinfo_lst[player]
159 # # evts = [nav.left, nav.right, nav.up, nav.down, nav.fire]
161 # self.eng.lib.remap_str(nav.left),
162 # self.eng.lib.remap_str(nav.right),
163 # self.eng.lib.remap_str(nav.up),
164 # self.eng.lib.remap_str(nav.down),
165 # self.eng.lib.remap_str(nav.fire)]
166 # def append_up(evt): return evt + ('' if evt.endswith('-up') else '-up')
167 # evts = [append_up(evt) for evt in evts]
168 # self.eng.joystick_mgr.unbind_keyboard()
169 # list(map(self.mediator.event.ignore, evts))
170 # self.mediator.event.ignore('joypad0-face_b-up')
172 # def enable(self, players):
173 # self.enable_navigation(players)
174 # list(map(lambda wdg: wdg.enable(), self.widgets))
176 # def disable(self, players):
177 # if self.enable_tsk:
178 # self.enable_tsk = self.eng.rm_do_later(self.enable_tsk)
179 # self.disable_navigation(players)
180 # list(map(lambda wdg: wdg.disable(), self.widgets))
182 # def transition_exit(self, destroy=True):
183 # list(map(lambda wdg: wdg.set_exit_transition(destroy), self.widgets))
184 # self.disable(self.players)
186 # def __build_back_btn(self, exit_behav):
187 # tra_src = 'Quit' if exit_behav else 'Back'
188 # tra_tra = _('Quit') if exit_behav else _('Back')
189 # callback = self._on_quit if exit_behav else self._on_back
190 # btn = Btn(text='', pos=(0, -.85), cmd=callback,
191 # tra_src=tra_src, tra_tra=tra_tra, **self.menu_props.btn_args)
192 # self.widgets += [btn]
193 # self._back_btn = btn
195 # def _on_back(self, player=0):
196 # self.notify('on_back', self.__class__.__name__)
198 # def _on_quit(self): self.notify('on_quit', self.__class__.__name__)
201 # visible_widgets = [wdg for wdg in self.widgets if wdg.was_visible]
202 # list(map(lambda wdg: wdg.show(), visible_widgets))
203 # self.transition_enter()
206 # for wdg in self.widgets: wdg.was_visible = not wdg.hidden
207 # self.transition_exit(False)
208 # self.notify('on_hide')
211 # self.transition_exit()
212 # self.menu_props = None
215 # class PageEvent(EventColleague):
217 # def on_back(self): pass
219 # def on_quit(self): pass
224 # def show(self): return self.gui.show()
225 # def hide(self): return self.gui.hide()
226 # def enable(self, players): return self.gui.enable(players)
227 # def disable(self, players): return self.gui.disable(players)
229 # def enable_navigation(self, players):
230 # return self.gui.enable_navigation(players)
232 # def disable_navigation(self, players):
233 # return self.gui.disable_navigation(players)
235 # def attach_obs(self, obs_meth, sort=10, rename='', args=None):
236 # return self.gui.attach(obs_meth, sort, rename, args or [])
238 # def detach_obs(self, obs_meth, lambda_call=None):
239 # return self.gui.detach(obs_meth, lambda_call)
242 # class Page(GameObject, PageFacade):
245 # event_cls = PageEvent
247 # def __init__(self, menu_props, players=[0]):
248 # PageFacade.__init__(self)
249 # self.menu_props = menu_props
250 # self.players = players
251 # GameObject.__init__(self)
252 # self._build_event()
254 # list(map(self.gui.attach, [self.on_hide, self.on_back, self.on_quit]))
256 # def _build_event(self):
257 # self.event = self.event_cls(self)
259 # def _build_gui(self):
260 # self.gui = self.gui_cls(self, self.menu_props, self.players)
262 # def on_hide(self): self.event.ignoreAll()
264 # def on_back(self, cls_name, args=None): self.event.on_back() # unused arg
266 # def on_quit(self, cls_name): self.event.on_quit() # unused arg
269 # self.event.destroy()
271 # bases = [basecls for basecls in Page.__bases__
272 # if basecls != PageFacade]
273 # for cls in bases: cls.destroy(self)