ya2 · news · projects · code · about

first commit
[pmachines.git] / lib / lib / p3d / widget.py
1 from panda3d.core import LVecBase4f
2 from direct.gui.DirectGuiGlobals import NORMAL, DISABLED
3 from lib.engine.vec import Vec2
4
5
6 class WidgetMixin:
7
8 highlight_color_offset = [
9 LVecBase4f(.4, .4, 0, .4),
10 LVecBase4f(0, 0, .4, .4),
11 LVecBase4f(0, .4, 0, .4),
12 LVecBase4f(.4, 0, 0, .4)]
13
14 def __init__(self):
15 self.start_txt_color = self.start_frame_color = None
16 self.was_visible = True
17 self.curr_offset = LVecBase4f(0, 0, 0, 0)
18
19 def get_np(self): return self.img
20
21 def enable(self): pass
22
23 def disable(self): pass
24
25 @property
26 def pos(self):
27 try: pos = self.get_pos(self.wdg.get_parent())
28 except AttributeError: pos = self.get_pos(self.img.get_parent())
29 return Vec2(pos[0], pos[2])
30
31 @property
32 def global_pos(self):
33 pos = self.get_pos(render2d)
34 return Vec2(pos[0], pos[2])
35
36
37 class ImgMixin(WidgetMixin):
38
39 def init(self, wdg): pass
40
41
42 class FrameMixin(WidgetMixin):
43
44 def init(self, wdg):
45 self.curr_offset = LVecBase4f(0, 0, 0, 0)
46 self.start_frame_color = wdg.get_np()['frameColor']
47
48 def enable(self):
49 self['state'] = NORMAL
50 if hasattr(self, 'set_alpha_scale'): self.set_alpha_scale(1)
51 self.get_np()['frameColor'] = self.start_frame_color
52
53 def disable(self):
54 self['state'] = DISABLED
55 if hasattr(self, 'set_alpha_scale'): self.set_alpha_scale(.25)
56 col = self.start_frame_color
57 self.get_np()['frameColor'] = (col[0], col[1], col[2], col[3] * .4)
58
59 def on_wdg_enter(self, pos=None, player=0): pass
60
61 def on_wdg_exit(self, pos=None, player=0): pass
62
63
64 class ScrolledFrameMixin(WidgetMixin):
65
66 def init(self, wdg): pass
67
68 def enable(self): self['state'] = NORMAL
69
70 def disable(self): self['state'] = DISABLED
71
72 def on_wdg_enter(self, pos=None, player=0): pass
73
74 def on_wdg_exit(self, pos=None, player=0): pass
75
76
77 class BtnMixin(FrameMixin):
78
79 def init(self, wdg):
80 FrameMixin.init(self, wdg)
81 wdg = wdg.get_np()
82 self.start_txt_color = wdg.component('text0').textNode.get_text_color()
83 self.start_txt_scale = wdg.component('text0').textNode.get_text_scale()
84
85 def on_arrow(self, direction): pass
86
87 def on_wdg_enter(self, pos=None, player=0): # pos: mouse's position
88 self.curr_offset += WidgetMixin.highlight_color_offset[player]
89 col = LVecBase4f(self.start_frame_color)
90 self.get_np()['frameColor'] = col + self.curr_offset
91 self.get_np()['text_fg'] = self.start_txt_color + self.curr_offset
92 self.get_np()['text_scale'] = self.start_txt_scale * 1.04
93 self.get_np().set_shader_input('col_offset', self.curr_offset)
94 self.get_np().component('text0').textNode.set_shadow(.064, .064)
95 self.get_np().component('text0').textNode.set_shadow_color(.2, .2, 0, .8)
96
97 def on_wdg_exit(self, pos=None, player=0): # pos: mouse's position
98 self.curr_offset -= WidgetMixin.highlight_color_offset[player]
99 col = LVecBase4f(self.start_frame_color)
100 self.get_np()['frameColor'] = col + self.curr_offset
101 self.get_np()['text_fg'] = self.start_txt_color
102 self.get_np()['text_scale'] = self.start_txt_scale
103 self.get_np()['frameColor'] = self.start_frame_color
104 self.get_np().set_shader_input('col_offset', self.curr_offset)
105 self.get_np().component('text0').textNode.set_shadow(0, 0)
106 self.get_np().component('text0').textNode.set_shadow_color(1, 1, 1, 1)
107
108 def on_enter(self, player):
109 if self['command'] and self['state'] == NORMAL:
110 lst_arg = [player] if player is not None else []
111 self['command'](*self['extraArgs'] + lst_arg)
112
113 def enable(self):
114 FrameMixin.enable(self)
115 t0n = self.get_np().component('text0').textNode
116 t0n.set_text_color(self.start_txt_color)
117 t0n.set_text_scale(self.start_txt_scale)
118
119 def disable(self):
120 FrameMixin.disable(self)
121 col = self.start_txt_color
122 self.get_np()['text_fg'] = (col[0], col[1], col[2], col[3] * .4)
123 t0n = self.get_np().component('text0').textNode
124 t0n.set_text_scale(self.start_txt_scale)
125
126
127 class EntryMixin(FrameMixin):
128
129 def on_arrow(self, direction): pass
130
131 def on_wdg_enter(self, pos=None, player=0): # pos: mouse's position
132 FrameMixin.on_wdg_enter(self, pos, player)
133 self.curr_offset += WidgetMixin.highlight_color_offset[player]
134 col = LVecBase4f(self.start_frame_color)
135 self.get_np()['frameColor'] = col + self.curr_offset
136 # self.get_np()['focus'] = 1 # it focuses it if mouse over
137 # self.get_np().setFocus()
138
139 def on_wdg_exit(self, pos=None, player=0): # pos: mouse's position
140 FrameMixin.on_wdg_exit(self, pos, player)
141 self.curr_offset -= WidgetMixin.highlight_color_offset[player]
142 col = LVecBase4f(self.start_frame_color)
143 self.get_np()['frameColor'] = col + self.curr_offset
144 # self.get_np()['focus'] = 0
145 # self.get_np().setFocus()
146
147 def on_enter(self, player=0):
148 self['focus'] = 1
149 if self['command'] and self['state'] == NORMAL:
150 self['command'](*self['extraArgs'])
151
152
153 class CheckBtnMixin(BtnMixin):
154
155 def on_enter(self, player=0):
156 self['indicatorValue'] = not self['indicatorValue']
157 BtnMixin.on_enter(self, player)
158
159
160 class SliderMixin(FrameMixin):
161
162 def on_arrow(self, direction):
163 if direction in [(-1, 0), (1, 0)]:
164 n_p = self.get_np()
165 delta = (n_p['range'][1] - n_p['range'][0]) / 10.0
166 n_p['value'] += -delta if direction == (-1, 0) else delta
167 return direction in [(-1, 0), (1, 0)]
168
169 def on_enter(self, player=0): pass
170
171
172 class OptionMenuMixin(BtnMixin):
173
174 def on_arrow(self, direction):
175 is_hor = direction in [(-1, 0), (1, 0)]
176 nodepath = self.get_np()
177 if is_hor or nodepath.popupMenu.is_hidden(): return False
178 old_idx = nodepath.highlightedIndex
179 dir2offset = {(0, -1): 1, (0, 1): -1}
180 idx = nodepath.highlightedIndex + dir2offset[direction]
181 idx = min(len(nodepath['items']) - 1, max(0, idx))
182 if old_idx == idx: return True
183 fcol = nodepath.component('item%s' % idx)['frameColor']
184 old_cmp = nodepath.component('item%s' % old_idx)
185 nodepath._unhighlightItem(old_cmp, fcol)
186 nodepath._highlightItem(nodepath.component('item%s' % idx), idx)
187 return True
188
189 def on_enter(self, player=0):
190 nodepath = self.get_np()
191 if nodepath.popupMenu.is_hidden():
192 nodepath.showPopupMenu()
193 nodepath._highlightItem(nodepath.component('item0'), 0)
194 else:
195 nodepath.selectHighlightedIndex()
196 idx = nodepath.selectedIndex
197 if nodepath['command']: nodepath['command'](nodepath['items'][idx])
198 nodepath.hidePopupMenu()
199 idx += -1 if idx else 1
200 try:
201 fcol = nodepath.component('item%s' % idx)['frameColor']
202 curr_name = 'item%s' % nodepath.selectedIndex
203 nodepath._unhighlightItem(nodepath.component(curr_name), fcol)
204 except KeyError: # when there is only one element
205 pass
206 return not nodepath.popupMenu.is_hidden()