]> icculus.org git repositories - divverent/nexuiz.git/blob - menu/mfuncs.qc
Initial revision
[divverent/nexuiz.git] / menu / mfuncs.qc
1 ///////////////////////////////////////////////
2 // Functions Source File
3 ///////////////////////
4 // This file belongs to dpmod/darkplaces
5 // AK contains all menu controlling stuff (sub-menus)
6 ///////////////////////////////////////////////
7
8 // raise function
9 /* template
10
11 void(entity ent)        raise_x =
12 {
13         entity old;
14         if(!ent._x)
15                 return;
16
17         old = self;
18         self = ent;
19         self._x();
20         self = old;
21 };
22 */
23
24 void(entity ent)        raise_reinit =
25 {
26         entity old;
27         if(!ent._reinit)
28                 return;
29
30         old = self;
31         self = ent;
32         self._reinit();
33         self = old;
34 };
35
36 void(entity ent)        raise_destroy =
37 {
38         entity old;
39         if(!ent._destroy)
40                 return;
41
42         old = self;
43         self = ent;
44         self._destroy();
45         self = old;
46 };
47
48 void(entity ent, float keynr, float ascii)      raise_key =
49 {
50         entity old;
51         if(!ent._key)
52                 return;
53
54         old = self;
55         self = ent;
56         self._key(keynr, ascii);
57         self = old;
58 };
59
60 void(entity ent)        raise_draw =
61 {
62         entity old;
63         if(!ent._draw)
64                 return;
65
66         old = self;
67         self = ent;
68         self._draw();
69         self = old;
70 };
71
72 void(entity ent)        raise_mouse_enter =
73 {
74         entity old;
75         if(!ent._mouse_enter)
76                 return;
77
78         old = self;
79         self = ent;
80         self._mouse_enter();
81         self = old;
82 };
83
84 void(entity ent)        raise_mouse_leave =
85 {
86         entity old;
87         if(!ent._mouse_leave)
88                 return;
89
90         old = self;
91         self = ent;
92         self._mouse_leave();
93         self = old;
94 };
95
96 void(entity ent)        raise_action =
97 {
98         entity old;
99         if(!ent._action)
100                 return;
101
102         old = self;
103         self = ent;
104         self._action();
105         self = old;
106 };
107
108 void(entity ent)        raise_refresh =
109 {
110         entity old;
111         if(!ent._refresh)
112                 return;
113
114         old = self;
115         self = ent;
116         self._refresh();
117         self = old;
118 };
119
120 // safe call control function functions
121 // default control functions
122 /* template
123
124 void(void) ctcall_x     =
125 {
126         if(self.x)
127                 self.x();
128 };
129
130 */
131 void(void)      ctcall_init =
132 {
133         if(self.init)
134                 self.init();
135 };
136
137 void(void)  ctcall_reinit =
138 {
139         if(self.reinit)
140                 self.reinit();
141 };
142
143 void(void) ctcall_destroy =
144 {
145         if(self.destroy)
146                 self.destroy();
147 };
148
149 float(float keynr, float ascii)  ctcall_key =
150 {
151         if(self.key)
152                 return self.key(keynr, ascii);
153 };
154
155 void(void)      ctcall_draw =
156 {
157         if(self.draw)
158                 self.draw();
159 };
160
161 void(void)      ctcall_mouse_enter =
162 {
163         if(self.mouse_enter)
164                 self.mouse_enter();
165 };
166
167 void(void)      ctcall_mouse_leave =
168 {
169         if(self.mouse_leave)
170                 self.mouse_leave();
171 };
172
173 void(void)      ctcall_action =
174 {
175         if(self.action)
176                 self.action();
177 };
178
179 void(void) ctcall_refresh =
180 {
181         if(self.refresh)
182                 self.refresh();
183 }
184
185 // default control functions
186 /* template (expect defct_key)
187
188 void(void) defct_x =
189 {
190         ctcall_x();
191 };
192
193 */
194 // defct_init not needed cause its the same like the type function
195
196 void(void) defct_reinit =
197 {
198         ctcall_reinit();
199 };
200
201 void(void) defct_destroy =
202 {
203         ctcall_destroy();
204 };
205
206 void(float keynr, float ascii)  defct_key =
207 {
208         if(!ctcall_key(keynr, ascii))
209                 def_keyevent(keynr, ascii);
210 };
211
212 void(void)      defct_draw =
213 {
214         ctcall_draw();
215 };
216
217 void(void)      defct_mouse_enter =
218 {
219         ctcall_mouse_enter();
220 };
221
222 void(void)      defct_mouse_leave =
223 {
224         ctcall_mouse_leave();
225 };
226
227 void(void)      defct_action =
228 {
229         ctcall_action();
230 };
231
232 void(void)      defct_refresh =
233 {
234         // do first the own fresh stuff and *then* call refresh
235         def_refresh();
236         ctcall_refresh();
237 }
238
239 // default refresh function
240 void(void)      def_refresh =
241 {
242         // refresh stuff
243         if(self.flag & FLAG_AUTOSETCLICK)
244         {
245                 self.click_pos = self.pos;
246                 self.click_size = self.size;
247         }
248         if(self.flag & FLAG_AUTOSETCLIP)
249         {
250                 self.clip_pos = self.pos;
251                 self.clip_size = self.size;
252         }
253 };
254
255 // default key function
256 void(float keynr, float ascii)  def_keyevent =
257 {
258         if(keynr == K_ESCAPE)
259         {
260                 // move up to the parent
261                 menu_selectup();
262         } else if(keynr == K_LEFTARROW || keynr == K_UPARROW)
263         {
264                 // move to the previous element
265                 menu_loopprev();
266
267                 if(menu_selected == self)
268                 {
269                         if(self._prev)
270                         {
271                                 menu_selected = self._prev;
272                                 menu_selectdown();
273                                 if(menu_selected != self._prev)
274                                 {
275                                         return;
276                                 }
277                         }
278                         menu_selected = self;
279                 }
280         } else if(keynr == K_RIGHTARROW || keynr == K_DOWNARROW)
281         {
282                 // move to the  next element
283                 menu_loopnext();
284
285                 if(menu_selected == self)
286                 {
287                         if(self._next)
288                         {
289                                 menu_selected = self._next;
290                                 menu_selectdown();
291                                 if(menu_selected != self._next)
292                                 {
293                                         return;
294                                 }
295                         }
296                         menu_selected = self;
297                 }
298         } else if(keynr == K_ENTER || keynr == K_MOUSE1)
299         {
300                 if(self._action)
301                         self._action();
302                 // move to the child menu
303                 menu_selectdown();
304         }
305 };
306
307 // a rect is described by the top-left point and its size
308 float(vector point, vector r_pos, vector r_size) inrect =
309 {
310         if(point_x < r_pos_x)
311                 return false;
312         if(point_y < r_pos_y)
313                 return false;
314         if(point_x > (r_pos_x + r_size_x))
315                 return false;
316         if(point_y > (r_pos_y + r_size_y))
317                 return false;
318         return true;
319 };
320
321 vector(vector r_pos, vector r_size, vector c_pos, vector c_size) cliprectpos =
322 {
323         vector v;
324
325         // clip r_pos only
326         v_x = max(c_pos_x, r_pos_x);
327         v_y = max(c_pos_y, r_pos_y);
328
329         return v;
330 };
331
332 vector(vector r_pos, vector r_size, vector c_pos, vector c_size) cliprectsize =
333 {
334         vector v;
335         // safe version
336         //r_size_x = bound(c_pos_x, r_pos_x + r_size_x, c_pos_x + c_size_x) - bound(c_pos_x, r_pos_x, c_pos_x + c_size_x);
337         //r_size_y = bound(c_pos_y, r_pos_y + r_size_y, c_pos_y + c_size_y) - bound(c_pos_y, r_pos_y, c_pos_y + c_size_y);
338         v_x = min(c_pos_x + c_size_x, r_pos_x + r_size_x) - max(c_pos_x, r_pos_x);
339         v_y = min(c_pos_y + c_size_y, r_pos_y + r_size_y) - max(c_pos_y, r_pos_y);
340
341         if(v_x <= 0 || v_y <= 0)
342                 v = '0 0 0';
343
344         return v;
345 }
346
347 void(void(void) reinitevent, void(void) destroyevent, void(float key, float ascii) keyevent, void(void) drawevent, void(void) mouse_enterevent, void(void) mouse_leaveevent, void(void) actionevent, void(void) refreshevent)
348         item_init =
349 {
350         self._reinit  = reinitevent;
351         self._destroy = destroyevent;
352
353         self._key       = keyevent;
354         self._draw      = drawevent;
355         self._mouse_enter = mouse_enterevent;
356         self._mouse_leave = mouse_leaveevent;
357         self._action = actionevent;
358         self._refresh = refreshevent;
359 };
360
361 float(float tfactor) getflicker =
362 {
363         // TODO: use tfactor to vary the result
364         return (sin(tfactor * time) + 1)/2;
365 };
366
367 float(string s) getaltstringcount =
368 {
369         float len;
370         float count;
371         float pos;
372
373         len = strlen(s);
374         count = 0;
375         for(pos = 0; pos < len; pos = pos + 1)
376         {
377                 if(substring(s,pos,1) == "'")
378                         count = count + 1;
379         }
380
381         if(mod(count,2) == 1)
382                 return 0; // bad string
383
384         return (count / 2);
385 };
386
387 string(float n, string s) getaltstring =
388 {
389         float start, length;
390         float tmp;
391
392         n = rint(n);
393
394         if(n >= getaltstringcount(s) || n < 0)
395                 return "";
396
397         // go to the beginning of the altstring
398         tmp = 0;
399         for(start = 0;tmp <= n * 2 ; start = start + 1)
400         {
401                 if(substring(s, start, 1) == "'")
402                         tmp = tmp + 1;
403         }
404
405         for(length = 0; substring(s, start + length, 1) != "'"; length = length + 1)
406         {
407         }
408
409         return substring(s, start, length);
410 };
411
412 void(string key) bind_unbindkey =
413 {
414         cmd(strcat("unbind ",key,"\n"));
415 };
416
417 void(string key, string command) bind_bindkey =
418 {
419         cmd(strcat("bind ",key," ",command,"\n"));
420 };
421
422 string(float keynum) bind_getstringforkey =
423 {
424         return keynumtostring(keynum);
425 };
426
427 string(string command) bind_getkeylist =
428 {
429         return findkeysforcommand(command);
430 };
431
432 void(float num, string command) bind_limitbinds =
433 {
434         float maxnum;
435         float counter;
436         string keystr;
437
438         keystr = strzone(bind_getkeylist(command));
439
440         maxnum = getaltstringcount(keystr);
441         if(num > maxnum)
442                 num = maxnum;
443
444         //dprint("num = ", ftos(num),"\n");
445         //dprint("maxnum = ", ftos(maxnum), "\n");
446
447         counter = 0;
448         while(counter < maxnum)
449         {
450                 float keynum;
451
452                 keynum = stof(getaltstring(counter, keystr));
453
454                 //dprint(ftos(keynum),"\n");
455
456                 if(keynum == -1)
457                         break;
458
459                 if(counter >= num)
460                         bind_unbindkey(bind_getstringforkey(keynum));
461
462                 counter = counter + 1;
463         }
464
465         strunzone(keystr);
466 };