ya2 · news · projects · code · about

first commit
[pmachines.git] / lib / engine / gui / menu.py
1 from direct.gui.DirectGuiGlobals import FLAT
2 from lib.gameobject import GuiColleague, LogicColleague, GameObject
3 from lib.lib.gui import Img
4 from lib.engine.audio import AudioSound
5
6
7 class NavInfoPerPlayer:
8
9 def __init__(self, left, right, up, down, fire):
10 self.left = left
11 self.right = right
12 self.up = up
13 self.down = down
14 self.fire = fire
15
16
17 class NavInfo:
18
19 def __init__(self, navinfo_lst):
20 self.navinfo_lst = navinfo_lst
21
22
23 class MenuProps(GameObject):
24
25 def __init__(
26 self, font_path, text_active_col, text_normal_col, text_err_col,
27 text_scale, btn_size, btn_col, background_img_path, over_sfx_path,
28 click_sfx_path, social_imgs_dirpath, nav):
29 GameObject.__init__(self)
30 self.__font_path = font_path
31 self.text_active_col = text_active_col
32 self.text_normal_col = text_normal_col
33 self.text_err_col = text_err_col
34 self.text_scale = text_scale
35 self.btn_size = btn_size
36 self.btn_col = btn_col
37 self.background_img_path = background_img_path
38 self.__over_sfx_path = over_sfx_path
39 self.__click_sfx_path = click_sfx_path
40 self.social_imgs_dirpath = social_imgs_dirpath
41 self.nav = nav
42
43 @property
44 def font(self): return self.eng.font_mgr.load_font(self.__font_path)
45
46 @property
47 def over_sfx(self): return AudioSound(self.__over_sfx_path).snd
48
49 @property
50 def click_sfx(self): return AudioSound(self.__click_sfx_path).snd
51
52 @property
53 def btn_args(self): # it may be used without a menu e.g. results
54 return {
55 'scale': (self.text_scale, self.text_scale),
56 'text_font': self.font,
57 'text_fg': self.text_active_col,
58 'frame_col': self.btn_col,
59 'frame_size': self.btn_size,
60 'over_snd': self.over_sfx,
61 'click_snd': self.click_sfx}
62
63 @property
64 def imgbtn_args(self):
65 return {
66 'over_snd': self.over_sfx,
67 'click_snd': self.click_sfx}
68
69 @property
70 def label_args(self):
71 return {
72 'scale': self.text_scale,
73 'text_fg': self.text_normal_col,
74 'text_font': self.font,
75 'frame_col': (1, 1, 1, 0)}
76
77 @property
78 def option_args(self):
79 tfg = self.text_active_col
80 return {
81 'scale': self.text_scale,
82 'text_font': self.font,
83 'text_fg': tfg,
84 'frame_col': self.btn_col,
85 'frame_size': self.btn_size,
86 'over_snd': self.over_sfx,
87 'click_snd': self.click_sfx,
88 'text_scale': .85,
89 'item_text_font': self.font,
90 'item_frame_col': tfg,
91 'item_relief': FLAT,
92 'popup_marker_col': self.btn_col,
93 'text_may_change': 1,
94 'highlight_col': (tfg[0] * 1.2, tfg[1] * 1.2, tfg[2] * 1.2, .2)}
95
96 @property
97 def checkbtn_args(self):
98 return {
99 'scale': self.text_scale,
100 'text_font': self.font,
101 'text_fg': self.text_active_col,
102 'frame_col': self.btn_col,
103 'over_snd': self.over_sfx,
104 'click_snd': self.click_sfx}
105
106 @property
107 def text_args(self):
108 return {
109 'scale': self.text_scale,
110 'fg': self.text_normal_col,
111 'font': self.font}
112
113
114 class MenuGui(GuiColleague):
115
116 def __init__(self, mediator, menu_props):
117 GuiColleague.__init__(self, mediator)
118 self.menu_props = menu_props
119 self.background = None
120 if not self.menu_props.background_img_path: return
121 self.background = Img(self.menu_props.background_img_path,
122 scale=(1.77778, 1, 1.0),
123 background=True)
124
125 def destroy(self):
126 if self.background: self.background.destroy()
127 self.menu_props = self.background = None
128 GuiColleague.destroy(self)
129
130
131 class MenuLogic(LogicColleague):
132
133 def __init__(self, mediator):
134 LogicColleague.__init__(self, mediator)
135 self.pages = []
136
137 def push_page(self, page):
138 if self.pages:
139 self.pages[-1].hide()
140 if len(self.pages) > 1: # first page doesn't go back
141 self.pages[-1].detach_obs(self.on_back)
142 self.pages[-1].detach_obs(self.on_quit)
143 self.pages += [page]
144 list(map(
145 page.attach_obs, [self.on_back, self.on_quit, self.on_push_page]))
146
147 def enable(self): self.pages[-1].enable()
148
149 def enable_navigation(self): self.pages[-1].enable_navigation()
150
151 def disable(self): self.pages[-1].disable()
152
153 def disable_navigation(self): self.pages[-1].disable_navigation()
154
155 def on_push_page(self, page_code, args=None): pass
156
157 def __back_quit_tmpl(self, idx, fun):
158 page = self.pages.pop()
159 list(map(page.detach_obs, [self.on_back, self.on_quit]))
160 page.destroy()
161 fun()
162 self.pages[idx].show()
163 list(map(self.pages[idx].attach_obs, [self.on_back, self.on_quit]))
164
165 def on_back(self):
166 self.__back_quit_tmpl(-1, lambda: None)
167
168 def on_quit(self):
169 def __on_quit():
170 while len(self.pages) > 1:
171 page = self.pages.pop()
172 page.destroy()
173 self.__back_quit_tmpl(0, __on_quit)
174
175 def destroy(self):
176 list(map(lambda page: page.destroy(), self.pages))
177 self.pages = None
178 LogicColleague.destroy(self)
179
180
181 class MenuFacade:
182
183 def push_page(self, page): return self.logic.push_page(page)
184 def attach_obs(self, obs_meth, sort=10, rename='', args=None):
185 return self.gui.attach(obs_meth, sort, rename, args or [])
186 def detach_obs(self, obs_meth, lambda_call=None):
187 return self.gui.detach(obs_meth, lambda_call)
188 def enable(self): return self.gui.enable()
189 def enable_navigation(self): return self.gui.enable_navigation()
190
191
192 class Menu(GameObject, MenuFacade):
193 gui_cls = MenuGui
194 logic_cls = MenuLogic
195
196 def __init__(self, menu_props):
197 GameObject.__init__(self)
198 self.logic = self.logic_cls(self)
199 self.__menu_props = menu_props
200 self._build_gui()
201
202 def _build_gui(self):
203 self.gui = self.gui_cls(self, self.__menu_props)
204
205 def destroy(self):
206 self.logic.destroy()
207 self.gui.destroy()
208 GameObject.destroy(self)