]> icculus.org git repositories - divverent/nexuiz.git/blob - menu/mcontrols.qc
grappling hook
[divverent/nexuiz.git] / menu / mcontrols.qc
1 ///////////////////////////////////////////////
2 // Controls/Item Source File
3 ///////////////////////
4 // This file belongs to dpmod/darkplaces
5 // AK contains all item specific stuff
6 ////////////////////////////////////////////////
7
8 ////////////////
9 // ITEM_WINDOW
10 //
11
12 void(void) ITEM_WINDOW =
13 {
14         self.flag = self.flag | FLAG_NOSELECT | FLAG_DRAWONLY;
15
16         item_init(
17                 defct_reinit,
18                 defct_destroy,
19                 defct_key,
20                 defct_draw,
21                 defct_mouse_enter,
22                 defct_mouse_leave,
23                 defct_action,
24                 defct_refresh);
25
26         ctcall_init();
27 };
28
29 //////////////////
30 // ITEM_REFERENCE
31 ///
32
33 void(void) ITEM_REFERENCE =
34 {
35         self.flag = self.flag | FLAG_NOSELECT | FLAG_DRAWONLY;
36
37         // if there is no link, this is a dynamic reference
38         if(self.link != "")
39         {
40                 self._child = menu_getitem(self.link);
41                 if(self._child == null_entity)
42                 {
43                         print(self.name, " removed, cause link ", self.link, " not found\n");
44                         remove(self);   // no need to call terminate
45                         return;
46                 }
47         }
48
49         item_init(
50                 defct_reinit,
51                 defct_destroy,
52                 defct_key,
53                 defct_draw,
54                 defct_mouse_enter,
55                 defct_mouse_leave,
56                 defct_action,
57                 defct_refresh);
58
59         ctcall_init();
60 };
61
62 ////////////////
63 // ITEM_CUSTOM
64 ////
65
66 void(void) ITEM_CUSTOM =
67 {
68         item_init(defct_reinit, defct_destroy, defct_key, defct_draw, defct_mouse_enter, defct_mouse_leave, defct_action, defct_refresh);
69         ctcall_init();
70 };
71
72 /////////////////
73 // ITEM_PICTURE
74 ///
75
76 // ITEM_PICTURE has a special draw function
77 void(void) ITEM_PICTURE_DRAW =
78 {
79         menu_drawpic(self.pos, self.picture, self.size, self.color, self.alpha, self.drawflag);
80
81         ctcall_draw();
82 };
83
84 void(void) ITEM_PICTURE_DESTROY =
85 {
86         gfx_unloadpic(self.picture);
87
88         ctcall_destroy();
89 };
90
91 void(void) ITEM_PICTURE =
92 {
93         if(self.picture == "")
94                 // a picture has to have a picture
95                 remove(self);           // no need to call terminate
96
97         // load the picture if it isnt loaded already
98         gfx_loadpic(self.picture, MENU_ENFORCELOADING);
99
100         // if flag wasnt set yet, then set it to FLAG_DRAWONLY
101         if(self.flag == 0)
102                 self.flag = FLAG_DRAWONLY;
103
104         if(self.color == '0 0 0')
105                 self.color = ITEM_PICTURE_NORMAL_COLOR;
106         if(self.alpha == 0)
107                 self.alpha = ITEM_PICTURE_NORMAL_ALPHA;
108
109         item_init(
110                 defct_reinit,
111                 ITEM_PICTURE_DESTROY,
112                 defct_key,
113                 ITEM_PICTURE_DRAW,
114                 defct_mouse_enter,
115                 defct_mouse_leave,
116                 defct_action,
117                 defct_refresh);
118
119         ctcall_init();
120 };
121
122 /////////////
123 // ITEM_TEXT
124 ///
125
126 void(void) ITEM_TEXT_REFRESH =
127 {
128         // first do own refresh, *then* call the default refresh !
129         if(self.size == '0 0 0')
130         {
131                 if(self.font_size == '0 0 0')
132                         self.font_size = ITEM_TEXT_FONT_SIZE;
133
134                 self.size_x = self.font_size_x * strlen(self.text);
135                 self.size_y = self.font_size_y;
136         } else if(self.font_size == '0 0 0')
137         {
138                         self.font_size_x = self.size_x / strlen(self.text);
139                         self.font_size_y = self.size_y;
140         }
141
142         def_refresh();
143         ctcall_refresh();
144 };
145
146 void(void) ITEM_TEXT_DRAW =
147 {
148         if(self.text != "")
149         {
150                 // align to the rect pos - (pos + size)
151                 vector alignpos;
152                 // now check the alignement
153                 if(self.alignment & TEXT_ALIGN_CENTER)
154                         alignpos_x = self.pos_x + (self.size_x - strlen(self.text) * self.font_size_x) / 2;
155                 else if(self.alignment & TEXT_ALIGN_RIGHT)
156                         alignpos_x = self.pos_x + self.size_x - strlen(self.text) * self.font_size_x;
157                 else
158                         alignpos_x = self.pos_x;
159                 alignpos_y = self.pos_y;
160
161                 menu_drawstring(alignpos, self.text, self.font_size, self.color, self.alpha, self.drawflag);
162         }
163         ctcall_draw();
164 };
165
166 void(void) ITEM_TEXT =
167 {
168         if(self.flag == 0)
169                 self.flag = FLAG_DRAWONLY;
170
171         if(self.color == '0 0 0')
172                 self.color = ITEM_TEXT_NORMAL_COLOR;
173         if(self.alpha == 0)
174                 self.alpha = ITEM_TEXT_NORMAL_ALPHA;
175
176         ITEM_TEXT_REFRESH();
177         if(self.alignment & TEXT_ALIGN_CENTERPOS)
178         {
179                 self.pos_x = self.pos_x - self.size_x / 2;
180         } else  if(self.alignment & TEXT_ALIGN_LEFTPOS)
181         {
182                 self.pos_x = self.pos_x - self.size_x;
183         }
184
185         item_init(
186                 defct_reinit,
187                 defct_destroy,
188                 defct_key,
189                 ITEM_TEXT_DRAW,
190                 defct_mouse_enter,
191                 defct_mouse_leave,
192                 defct_action,
193                 ITEM_TEXT_REFRESH);
194
195         ctcall_init();
196 };
197
198 /////////////////
199 // ITEM_RECTANLE
200 ///
201
202 void(void) ITEM_RECTANGLE_DRAW =
203 {
204         menu_fillarea(self.pos, self.size, self.color, self.alpha, self.drawflag);
205 };
206
207 void(void) ITEM_RECTANGLE =
208 {
209         if(self.flag == 0)
210                 self.flag = FLAG_DRAWONLY;
211
212         item_init(
213                 defct_reinit,
214                 defct_destroy,
215                 defct_key,
216                 ITEM_RECTANGLE_DRAW,
217                 defct_mouse_enter,
218                 defct_mouse_leave,
219                 defct_action,
220                 defct_refresh);
221
222         ctcall_init();
223 };
224
225 ////////////////
226 // ITEM_BUTTON
227 ///
228
229 void(void) ITEM_BUTTON_DRAW =
230 {
231         if(self._button_state == BUTTON_NORMAL)
232                 menu_drawpic(self.pos, self.picture, self.size, self.color, self.alpha, self.drawflag);
233         else if(self._button_state == BUTTON_SELECTED)
234                 menu_drawpic(self.pos, self.picture_selected, self.size, self.color_selected, self.alpha_selected, self.drawflag_selected);
235         else
236                 menu_drawpic(self.pos, self.picture_pressed, self.size, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
237
238         ctcall_draw();
239 };
240
241 void(void) ITEM_BUTTON_REFRESH =
242 {
243         if( self.hold_pressed + self._press_time < time )
244         {
245                 if( menu_selected != self && self._button_state != BUTTON_NORMAL )
246                         self._button_state = BUTTON_NORMAL;
247                 else if( menu_selected == self && self._button_state != BUTTON_SELECTED)
248                 {
249                         self._button_state = BUTTON_SELECTED;
250                         if(self.sound_selected != "" && menu_automatedselection == false)
251                                 snd_play(self.sound_selected);
252                 }
253         }
254
255         def_refresh();
256         ctcall_refresh();
257 };
258
259 void(float keynr, float ascii) ITEM_BUTTON_KEY =
260 {
261         if(ctcall_key(keynr, ascii))
262                 return;
263
264         if(keynr == K_ENTER || keynr == K_MOUSE1)
265         {
266                 self._action();
267         } else
268                 def_keyevent(keynr, ascii);
269 };
270
271 void(void) ITEM_BUTTON_ACTION =
272 {
273         self._press_time = time;
274         self._button_state = BUTTON_PRESSED;
275         if(self.sound_pressed)
276                 snd_play(self.sound_pressed);
277
278         ctcall_action();
279 };
280 void(void) ITEM_BUTTON_REINIT =
281 {
282         self._button_state = BUTTON_NORMAL;
283
284         ctcall_reinit();
285 };
286
287 void(void) ITEM_BUTTON_DESTROY =
288 {
289         gfx_unloadpic(self.picture);
290         gfx_unloadpic(self.picture_selected);
291         gfx_unloadpic(self.picture_pressed);
292
293         ctcall_destroy();
294 };
295
296 void(void) ITEM_BUTTON =
297 {
298         if(self.picture == "" || self.picture_selected == "" || self.picture_pressed == "")
299                 // a picture has to have pictures
300                 remove(self);   // no need to call terminate
301
302         // load the picture if it isnt loaded already
303         gfx_loadpic(self.picture, MENU_ENFORCELOADING);
304         gfx_loadpic(self.picture_selected, MENU_ENFORCELOADING);
305         gfx_loadpic(self.picture_pressed, MENU_ENFORCELOADING);
306
307         if(self.sound_selected != "")
308                 snd_loadsound(self.sound_selected, SOUND_ENFORCELOADING);
309         else
310                 self.sound_selected = SOUND_SELECT;
311
312         if(self.sound_pressed != "")
313                 snd_loadsound(self.sound_pressed, SOUND_ENFORCELOADING);
314         else
315                 self.sound_pressed = SOUND_ACTION;
316
317         // if flag wasnt set yet, then set it to FLAG_DRAWONLY
318         if(self.flag == 0)
319                 self.flag = FLAG_AUTOSETCLICK;
320
321         if(self.color == '0 0 0')
322                 self.color = ITEM_PICTURE_NORMAL_COLOR;
323         if(self.alpha == 0)
324                 self.alpha = ITEM_PICTURE_NORMAL_ALPHA;
325         if(self.color_selected == '0 0 0')
326                 self.color_selected = ITEM_PICTURE_SELECTED_COLOR;
327         if(self.alpha_selected == 0)
328                 self.alpha_selected = ITEM_PICTURE_SELECTED_ALPHA;
329         if(self.color_pressed == '0 0 0')
330                 self.color_pressed = ITEM_PICTURE_PRESSED_COLOR;
331         if(self.alpha_pressed == 0)
332                 self.alpha_pressed = ITEM_PICTURE_PRESSED_ALPHA;
333
334         if(self.hold_pressed == 0)
335                 self.hold_pressed = ITEM_BUTTON_HOLD_PRESSED;
336
337         item_init(
338                 ITEM_BUTTON_REINIT,
339                 ITEM_BUTTON_DESTROY,
340                 ITEM_BUTTON_KEY,
341                 ITEM_BUTTON_DRAW,
342                 defct_mouse_enter,
343                 defct_mouse_leave,
344                 ITEM_BUTTON_ACTION,
345                 ITEM_BUTTON_REFRESH);
346
347         ctcall_init();
348 };
349
350 ////////////////////
351 // ITEM_TEXTBUTTON
352 ///
353
354 void(void) ITEM_TEXTBUTTON_REFRESH =
355 {
356         // first do own refresh, *then* call the default refresh !
357         if(self.size == '0 0 0')
358         {
359                 if(self.font_size == '0 0 0')
360                         self.font_size = ITEM_TEXT_FONT_SIZE;
361
362                 self.size_x = self.font_size_x * strlen(self.text);
363                 self.size_y = self.font_size_y;
364         } else if(self.font_size == '0 0 0')
365         {
366                         self.font_size_x = self.size_x / strlen(self.text);
367                         self.font_size_y = self.size_y;
368         }
369
370         /*if((self.hold_pressed + self._press_time < time && self._button_state == BUTTON_PRESSED) || (menu_selected != self && self._button_state == BUTTON_SELECTED))
371         {
372                 self._button_state = BUTTON_NORMAL;
373         }
374         if(menu_selected == self && self._button_state == BUTTON_NORMAL)
375         {
376                 self._button_state = BUTTON_SELECTED;
377                 if(self.sound_selected != "" && menu_automatedselection == false)
378                         snd_play(self.sound_selected);
379         }*/
380         /*if( self.hold_pressed + self._press_time < time )
381         {
382                 if( menu_selected != self && self._button_state != BUTTON_NORMAL )
383                         self._button_state = BUTTON_NORMAL;
384                 else if( menu_selected == self && self._button_state != BUTTON_SELECTED)
385                 {
386                         self._button_state = BUTTON_SELECTED;
387                         if(self.sound_selected != "" && menu_automatedselection == false)
388                                 snd_play(self.sound_selected);
389                 }
390         }*/
391         if( self._button_state == BUTTON_PRESSED ) {
392                 if( self.hold_pressed + self._press_time < time )
393                         if( menu_selected == self )
394                                 self._button_state = BUTTON_SELECTED;
395                         else
396                                 self._button_state = BUTTON_NORMAL;
397         } else if( self._button_state == BUTTON_NORMAL && menu_selected == self ) {
398                 self._button_state = BUTTON_SELECTED;
399                 if( self.sound_selected != "" && menu_automatedselection == false )
400                         snd_play( self.sound_selected );
401         } else if( menu_selected != self )
402                 self._button_state = BUTTON_NORMAL;
403
404         def_refresh();
405         ctcall_refresh();
406 };
407
408 void(void) ITEM_TEXTBUTTON_DRAW =
409 {
410         if(self.text == "")
411                 return;
412
413         // align to the rect pos - (pos + size)
414         vector alignpos;
415         // now check the alignement
416         if(self.alignment & TEXT_ALIGN_CENTER)
417                 alignpos_x = self.pos_x + (self.size_x - strlen(self.text) * self.font_size_x) / 2;
418         else if(self.alignment & TEXT_ALIGN_RIGHT)
419                 alignpos_x = self.pos_x + self.size_x - strlen(self.text) * self.font_size_x;
420         else
421                 alignpos_x = self.pos_x;
422                 alignpos_y = self.pos_y;
423
424         if(self.style == TEXTBUTTON_STYLE_OUTLINE && self._button_state != BUTTON_NORMAL)
425         {
426                 vector p,s;
427                 // left
428                 p_x = self.pos_x;
429                 p_y = self.pos_y;
430                 s_x = TEXTBUTTON_OUTLINE_WIDTH;
431                 s_y = self.size_y;
432                 if(self._button_state == BUTTON_PRESSED)
433                 {
434                         menu_fillarea(p, s, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
435                 }
436                 else if(self._button_state == BUTTON_SELECTED)
437                 {
438                         menu_fillarea(p, s, self.color_selected, self.alpha_selected, self.drawflag_selected);
439                 }
440                 // right
441                 p_x = self.pos_x + self.size_x - TEXTBUTTON_OUTLINE_WIDTH;
442                 p_y = self.pos_y;
443                 s_x = TEXTBUTTON_OUTLINE_WIDTH;
444                 s_y = self.size_y;
445                 if(self._button_state == BUTTON_PRESSED)
446                 {
447                         menu_fillarea(p, s, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
448                 }
449                 else if(self._button_state == BUTTON_SELECTED)
450                 {
451                         menu_fillarea(p, s, self.color_selected, self.alpha_selected, self.drawflag_selected);
452                 }
453                 // top
454                 p_x = self.pos_x;
455                 p_y = self.pos_y;
456                 s_y = TEXTBUTTON_OUTLINE_WIDTH;
457                 s_x = self.size_x;
458                 if(self._button_state == BUTTON_PRESSED)
459                 {
460                         menu_fillarea(p, s, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
461                 }
462                 else if(self._button_state == BUTTON_SELECTED)
463                 {
464                         menu_fillarea(p, s, self.color_selected, self.alpha_selected, self.drawflag_selected);
465                 }
466                 // bottom
467                 p_x = self.pos_x;
468                 p_y = self.pos_y + self.size_y - TEXTBUTTON_OUTLINE_WIDTH;
469                 s_y = TEXTBUTTON_OUTLINE_WIDTH;
470                 s_x = self.size_x;
471                 if(self._button_state == BUTTON_PRESSED)
472                 {
473                         menu_fillarea(p, s, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
474                 }
475                 else if(self._button_state == BUTTON_SELECTED)
476                 {
477                         menu_fillarea(p, s, self.color_selected, self.alpha_selected, self.drawflag_selected);
478                 }
479         } else  if(self.style == TEXTBUTTON_STYLE_BOX)
480         {
481                 if(self._button_state == BUTTON_PRESSED)
482                 {
483                         menu_fillarea(alignpos, self.size, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
484                 }
485                 else if(self._button_state == BUTTON_SELECTED)
486                 {
487                         menu_fillarea(alignpos, self.size, self.color_selected, self.alpha_selected, self.drawflag_selected);
488                 }
489         }
490
491         if(self._button_state == BUTTON_NORMAL || self.style == TEXTBUTTON_STYLE_BOX || self.style == TEXTBUTTON_STYLE_OUTLINE)
492                 menu_drawstring(alignpos, self.text, self.font_size, self.color, self.alpha, self.drawflag);
493
494         if(self.style == TEXTBUTTON_STYLE_TEXT)
495         {
496                 if(self._button_state == BUTTON_PRESSED)
497                 {
498                         menu_drawstring(alignpos, self.text, self.font_size, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
499                 }
500                 else if(self._button_state == BUTTON_SELECTED)
501                 {
502                         menu_drawstring(alignpos, self.text, self.font_size, self.color_selected, self.alpha_selected, self.drawflag_selected);
503                 }
504         }
505
506         ctcall_draw();
507 };
508
509 void(void) ITEM_TEXTBUTTON_ACTION =
510 {
511         self._press_time = time;
512         self._button_state = BUTTON_PRESSED;
513         if(self.sound_pressed)
514                 snd_play(self.sound_pressed);
515
516         ctcall_action();
517 };
518
519 void(float keynr, float ascii) ITEM_TEXTBUTTON_KEY =
520 {
521         if(ctcall_key(keynr, ascii))
522                 return;
523
524         if(keynr == K_ENTER || keynr == K_MOUSE1)
525         {
526                 self._action();
527         } else
528                 def_keyevent(keynr, ascii);
529 };
530
531 void(void) ITEM_TEXTBUTTON_REINIT =
532 {
533         self._button_state = BUTTON_NORMAL;
534
535         ctcall_reinit();
536 };
537
538 void(void) ITEM_TEXTBUTTON =
539 {
540         if(self.flag == 0)
541                 self.flag = FLAG_AUTOSETCLICK;
542
543         if(self.color == '0 0 0')
544                 self.color = ITEM_TEXT_NORMAL_COLOR;
545         if(self.alpha == 0)
546                 self.alpha = ITEM_TEXT_NORMAL_ALPHA;
547         if(self.color_selected == '0 0 0')
548                 self.color_selected = ITEM_TEXT_SELECTED_COLOR;
549         if(self.alpha_selected == 0)
550                 self.alpha_selected = ITEM_TEXT_SELECTED_ALPHA;
551         if(self.color_pressed == '0 0 0')
552                 self.color_pressed = ITEM_TEXT_PRESSED_COLOR;
553         if(self.alpha_pressed == 0)
554                 self.alpha_pressed = ITEM_TEXT_PRESSED_ALPHA;
555
556         if(self.hold_pressed == 0)
557                 self.hold_pressed = ITEM_BUTTON_HOLD_PRESSED;
558
559         if(self.sound_selected != "")
560                 snd_loadsound(self.sound_selected, SOUND_ENFORCELOADING);
561         else
562                 self.sound_selected = SOUND_SELECT;
563
564         if(self.sound_pressed != "")
565                 snd_loadsound(self.sound_pressed, SOUND_ENFORCELOADING);
566         else
567                 self.sound_pressed = SOUND_ACTION;
568
569         ITEM_TEXTBUTTON_REFRESH();
570         if(self.alignment & TEXT_ALIGN_CENTERPOS)
571         {
572                 self.pos_x = self.pos_x - self.size_x / 2;
573         } else  if(self.alignment & TEXT_ALIGN_LEFTPOS)
574         {
575                 self.pos_x = self.pos_x - self.size_x;
576         }
577
578         item_init(
579                 ITEM_TEXTBUTTON_REINIT,
580                 defct_destroy,
581                 ITEM_TEXTBUTTON_KEY,
582                 ITEM_TEXTBUTTON_DRAW,
583                 defct_mouse_enter,
584                 defct_mouse_leave,
585                 ITEM_TEXTBUTTON_ACTION,
586                 ITEM_TEXTBUTTON_REFRESH);
587
588         ctcall_init();
589 };
590
591 // ITEM_SLIDER
592
593 void(void) ITEM_SLIDER_DRAW =
594 {
595         vector slider_pos;
596
597         // draw the bar
598         if(self.picture_bar != "")
599         {
600                 menu_drawpic(self.pos, self.picture_bar, self.size, self.color, self.alpha, self.drawflag);
601         }
602         else
603         {
604                 menu_fillarea(self.pos, self.size, self.color, self.alpha, self.drawflag);
605         }
606
607         // draw the slider
608         slider_pos = self.pos;
609         slider_pos_x = slider_pos_x + self.left_margin + ((self.size_x - self.slider_size_x - self.left_margin - self.right_margin) / (self.max_value - self.min_value)) * (self.value - self.min_value);
610         if(self.picture != "")
611         {
612                 menu_drawpic(slider_pos, self.picture, self.slider_size, self.color, self.alpha, self.drawflag);
613         }
614         else
615         {
616                 menu_fillarea(slider_pos, self.slider_size, self.color + ITEM_SLIDER_BAR_COLOR_DELTA, self.alpha, self.drawflag);
617         }
618 };
619
620 void(void) ITEM_SLIDER_UPDATESLIDER =
621 {
622         self.value = bound(self.min_value, self.value, self.max_value);
623         if(self.slidermove)
624                 self.slidermove();
625 };
626
627 void(float keynr, float ascii) ITEM_SLIDER_KEY =
628 {
629         float old;
630         old = self.value;
631
632         if(ctcall_key(keynr, ascii))
633                 return;
634
635         if(keynr == K_LEFTARROW)
636         {
637                 self.value = (rint(self.value / self.step) - 1) * self.step;
638         }
639         else if(keynr == K_RIGHTARROW)
640         {
641                 self.value = (rint(self.value / self.step) + 1)* self.step;
642         }
643         else if(keynr == K_MOUSE1)
644         {
645                 if(inrect(menu_cursor, self.pos, self.size))
646                 {
647                         if(menu_cursor_x - self.pos_x <= self.left_margin)
648                         {
649                                 self.value = (rint(self.value / self.step) - 1)* self.step;
650                         }
651                         else if(menu_cursor_x - self.pos_x >= self.size_x - self.right_margin)
652                         {
653                                 self.value = (rint(self.value / self.step) + 1)* self.step;
654                         }
655                         else
656                         {
657                                 self.value = self.min_value + ((menu_cursor_x - self.slider_size_x / 2) - self.pos_x - self.left_margin) * ((self.max_value - self.min_value) / (self.size_x - self.slider_size_x - self.left_margin - self.right_margin));
658                         }
659                 }
660         }
661         else
662         {
663                 def_keyevent(keynr, ascii);
664                 return;
665         }
666         // play sound
667         if(old < self.value)
668         {
669                 snd_play(self.sound_increase);
670         }
671         else if(self.value < old)
672         {
673                 snd_play(self.sound_decrease);
674         }
675
676         ITEM_SLIDER_UPDATESLIDER();
677         ctcall_action();
678 };
679
680 void(void) ITEM_SLIDER_DESTROY =
681 {
682         if(self.picture != "" && self.picture != ITEM_SLIDER_DEFAULT_SLIDER)
683                 gfx_unloadpic(self.picture);
684         if(self.picture_bar != "" && self.picture_bar != ITEM_SLIDER_DEFAULT_BAR)
685                 gfx_unloadpic(self.picture);
686         if(self.sound_increase != SOUND_INCREASE)
687                 snd_unloadsound(self.sound_decrease);
688         if(self.sound_increase != SOUND_INCREASE)
689                 snd_unloadsound(self.sound_increase);
690
691         ctcall_destroy();
692 };
693
694 void(void) ITEM_SLIDER =
695 {
696         if(self.picture != "")
697                 self.picture = gfx_loadpic(self.picture, MENU_ENFORCELOADING);
698         if(self.picture == "")
699                 self.picture = gfx_loadpic(ITEM_SLIDER_DEFAULT_SLIDER, MENU_ENFORCELOADING);
700         if(self.picture_bar != "")
701                 self.picture_bar = gfx_loadpic(self.picture_bar, MENU_ENFORCELOADING);
702         if(self.picture_bar == "")
703                 self.picture_bar = gfx_loadpic(ITEM_SLIDER_DEFAULT_BAR, MENU_ENFORCELOADING);
704         if(self.sound_decrease == "")
705                 self.sound_decrease = SOUND_DECREASE;
706         else
707                 snd_loadsound(self.sound_decrease, MENU_ENFORCELOADING);
708         if(self.sound_increase == "")
709                 self.sound_increase = SOUND_INCREASE;
710         else
711                 snd_loadsound(self.sound_increase, MENU_ENFORCELOADING);
712
713         if(self.color == '0 0 0')
714                 self.color = ITEM_SLIDER_COLOR;
715         if(self.alpha == 0)
716                 self.alpha = ITEM_SLIDER_ALPHA;
717         if(self.step == 0)
718                 self.step = ITEM_SLIDER_STEP;
719         if(self.slider_size == '0 0 0')
720         {
721                 /*if(self.picture != "")
722                         self.slider_size = gfx_getimagesize(self.picture);
723                 else*/
724                         self.slider_size = ITEM_SLIDER_SIZE;
725         }
726         if(self.left_margin == 0)
727                 self.left_margin = ITEM_SLIDER_LEFT_MARGIN;
728         if(self.right_margin == 0)
729                 self.right_margin = ITEM_SLIDER_RIGHT_MARGIN;
730
731         item_init(
732                 defct_reinit,
733                 defct_destroy,
734                 ITEM_SLIDER_KEY,
735                 ITEM_SLIDER_DRAW,
736                 defct_mouse_enter,
737                 defct_mouse_leave,
738                 defct_action,
739                 defct_refresh);
740
741         ctcall_init();
742 };
743
744 // ITEM_TEXTSWITCH
745
746 void(void) ITEM_TEXTSWITCH_DRAW =
747 {
748         string temp;
749
750         // get the current text
751         temp = self.text;
752         self.text = getaltstring(self.value, self.text);
753         // call ITEM_TEXT
754         ITEM_TEXT_DRAW();
755         self.text = temp;
756 };
757
758 void(void) ITEM_TEXTSWITCH_REFRESH =
759 {
760         string temp;
761
762         temp = self.text;
763         self.text = getaltstring(self.value, self.text);
764
765         ITEM_TEXT_REFRESH();
766
767         self.text = temp;
768 };
769
770 void(float keynr, float ascii)  ITEM_TEXTSWITCH_KEY =
771 {
772         float dir;
773         if(ctcall_key(keynr, ascii))
774                 return;
775
776         if(keynr == K_LEFTARROW || keynr == K_MOUSE2)
777         {
778                 dir = 1;
779                 self.value = self.value - 1;
780                 if(self.value < 0)
781                         self.value = getaltstringcount(self.text) - 1;
782         }
783         else if(keynr == K_RIGHTARROW || keynr == K_MOUSE1 || keynr == K_ENTER)
784         {
785                 dir = -1;
786                 self.value = self.value + 1;
787                 if(self.value > getaltstringcount(self.text) - 1)
788                         self.value = 0;
789         } else
790         {
791                 def_keyevent(keynr, ascii);
792                 return;
793         }
794         // play sound
795         if( dir == -1 )
796                 snd_play(self.sound_increase);
797         else if( dir == 1 )
798                 snd_play(self.sound_decrease);
799
800         if(self.switchchange)
801                 self.switchchange();
802 };
803
804 void(void) ITEM_TEXTSWITCH_DESTROY =
805 {
806         if(self.sound_increase != SOUND_INCREASE)
807                 snd_unloadsound(self.sound_decrease);
808         if(self.sound_increase != SOUND_INCREASE)
809                 snd_unloadsound(self.sound_increase);
810 }
811
812 void(void) ITEM_TEXTSWITCH =
813 {
814         string temp;
815
816         if(self.sound_decrease == "")
817                 self.sound_decrease = SOUND_DECREASE;
818         else
819                 snd_loadsound(self.sound_decrease, MENU_ENFORCELOADING);
820         if(self.sound_increase == "")
821                 self.sound_increase = SOUND_INCREASE;
822         else
823                 snd_loadsound(self.sound_increase, MENU_ENFORCELOADING);
824
825         temp = self.text;
826         self.text = getaltstring(self.value, self.text);
827         ITEM_TEXT();
828         self.text = temp;
829
830         item_init(
831                 defct_reinit,
832                 ITEM_TEXTSWITCH_DESTROY,
833                 ITEM_TEXTSWITCH_KEY,
834                 ITEM_TEXTSWITCH_DRAW,
835                 defct_mouse_enter,
836                 defct_mouse_leave,
837                 defct_action,
838                 ITEM_TEXTSWITCH_REFRESH);
839
840         ctcall_init();
841 };
842
843 // ITEM_EDITBOX
844
845 void(void) ITEM_EDITBOX_REINIT =
846 {
847         self._cursorpos = 0;
848         self._button_state = BUTTON_NORMAL;
849 };
850
851 void(void) ITEM_EDITBOX_DRAW =
852 {
853         vector csize, cpos;
854
855         if(self.text != "")
856                 ITEM_TEXT_DRAW();
857
858         if(self._button_state == BUTTON_NORMAL || mod(time * 1000, 1000 / EDITBOX_CURSOR_FREQ) > 500 / EDITBOX_CURSOR_FREQ)
859                 return;
860
861         csize_x = 1.5;
862         csize_y = self.font_size_y;
863         csize_z = 0;
864         cpos = self.pos;
865         cpos_x = cpos_x + self._cursorpos * self.font_size_x;
866
867         menu_fillarea(cpos, csize, self.color_selected, self.alpha_selected, self.drawflag_selected);
868 };
869
870 void(float ascii) ITEM_EDITBOX_INSERT =
871 {
872         string firsthalf, secondhalf;
873         float len;
874
875         if(self._cursorpos > strlen(self.text))
876                 return;
877
878         if(self.format == "")
879         {
880                 // no format stuff, so lets have fun
881                 firsthalf = substring(self.text, 0, self._cursorpos);
882                 secondhalf = substring(self.text, self._cursorpos, strlen(self.text) - self._cursorpos);
883                 strunzone(self.text);
884                 self.text = strcat(firsthalf, chr(ascii));
885                 self.text = strcat(self.text, secondhalf);
886                 if(self.maxlen >= 0 && strlen(self.text) > self.maxlen)
887                 {
888                         // remove the last char(s)
889                         self.text = substring(self.text, 0, self.maxlen);
890                 }
891                 // move the cursor forward
892                 if(strlen(self.text) >= self._cursorpos)
893                         self._cursorpos = self._cursorpos + 1;
894
895                 self.text = strzone(self.text);
896         }
897         else // here begins the funny part
898         {
899                 // TODO: add wildcard support :-/
900                 // move the cursor to the next space
901                 len = strlen(self.format);
902                 while(substring(self.format, self._cursorpos, 1) != " " && len > self._cursorpos)
903                 {
904                         self._cursorpos = self._cursorpos + 1;
905                 }
906                 if(self._cursorpos >= len)
907                         return;
908
909                 firsthalf = substring(self.text, 0, self._cursorpos);
910                 secondhalf = substring(self.text, self._cursorpos + 1 , strlen(self.text) - self._cursorpos - 1);
911                 strunzone(self.text);
912                 self.text = strcat(firsthalf, chr(ascii), secondhalf);
913                 self.text = strzone(self.text);
914         }
915 };
916
917 void(void) ITEM_EDITBOX_LEFT =
918 {
919         if(self._cursorpos > 0)
920                 self._cursorpos = self._cursorpos - 1;
921 };
922
923 void(void) ITEM_EDITBOX_RIGHT =
924 {
925         if(self._cursorpos < strlen(self.text))
926                 self._cursorpos = self._cursorpos + 1;
927 };
928
929 void(float keynr, float ascii) ITEM_EDITBOX_KEY =
930 {
931         if(ctcall_key(keynr, ascii))
932                 return;
933
934         if(ascii >= 30 && ascii <= 126)
935         {
936                 ITEM_EDITBOX_INSERT(ascii);
937         } else if(keynr == K_BACKSPACE)
938         {
939                 if(self.format == "")
940                 {
941                         string firsthalf, secondhalf;
942
943                         firsthalf = substring(self.text,0, self._cursorpos - 1);
944                         secondhalf = substring(self.text,self._cursorpos, strlen(self.text) - self._cursorpos);
945                         strunzone(self.text);
946                         self.text = strcat(firsthalf, secondhalf);
947                         self.text = strzone(self.text);
948
949                         ITEM_EDITBOX_LEFT();
950                 }
951         } else if(keynr == K_ENTER)
952         {
953                 self._action();
954                 //snd_play(self.sound_action);
955         } else if(keynr == K_LEFTARROW)
956         {
957                 ITEM_EDITBOX_LEFT();
958         }
959         else if(keynr == K_RIGHTARROW)
960         {
961                 ITEM_EDITBOX_RIGHT();
962         }
963         else
964                 def_keyevent(keynr, ascii);
965
966         snd_play(self.sound_pressed);
967 };
968
969 void(void) ITEM_EDITBOX_REFRESH =
970 {
971         if(menu_selected != self && menu_selected != self._parent)
972                 self._button_state = BUTTON_NORMAL;
973         else if(self._button_state == BUTTON_NORMAL)
974         {
975                 self._button_state = BUTTON_SELECTED;
976
977                 if(self.sound_selected != "" && menu_automatedselection == false)
978                         snd_play(self.sound_selected);
979         }
980
981         if(self._cursorpos > strlen(self.text))
982                 self._cursorpos = strlen(self.text);
983
984         // hack: we want the text to scroll if possible
985         // self.clip_pos holds the normal value
986         if( self._cursorpos >= self.size_x / self.font_size_x - 1.5 && self.maxlen > self.size_x / self.font_size_x )
987                 self.pos_x = self.clip_pos_x -(self._cursorpos - floor( self.size_x / self.font_size_x - 1.5)) * self.font_size_x;
988         else
989                 self.pos_x = self.clip_pos_x;
990
991         ITEM_TEXT_REFRESH();
992 };
993
994 void(void) ITEM_EDITBOX =
995 {
996         if(self.sound_selected != "")
997                 snd_loadsound(self.sound_selected, SOUND_ENFORCELOADING);
998         else
999                 self.sound_selected = SOUND_SELECT;
1000
1001         if(self.sound_pressed != "")
1002                 snd_loadsound(self.sound_pressed, SOUND_ENFORCELOADING);
1003         else
1004                 self.sound_pressed = SOUND_ACTION;
1005
1006         // if flag wasnt set yet, then set it to FLAG_DRAWONLY
1007         if(self.flag == 0)
1008                 self.flag = FLAG_AUTOSETCLICK;
1009
1010         //init clip_pos
1011         self.clip_pos = self.pos;
1012
1013         if(self.color == '0 0 0')
1014                 self.color = ITEM_PICTURE_NORMAL_COLOR;
1015         if(self.alpha == 0)
1016                 self.alpha = ITEM_PICTURE_NORMAL_ALPHA;
1017         if(self.color_selected == '0 0 0')
1018                 self.color_selected = ITEM_PICTURE_SELECTED_COLOR;
1019         if(self.alpha_selected == 0)
1020                 self.alpha_selected = ITEM_PICTURE_SELECTED_ALPHA;
1021
1022         self.text = strzone(self.text);
1023
1024         ITEM_TEXT_REFRESH();
1025         if(self.alignment & TEXT_ALIGN_CENTERPOS)
1026         {
1027                 self.pos_x = self.pos_x - self.size_x / 2;
1028         } else  if(self.alignment & TEXT_ALIGN_LEFTPOS)
1029         {
1030                 self.pos_x = self.pos_x - self.size_x;
1031         }
1032
1033         item_init(
1034                 defct_reinit,
1035                 defct_destroy,
1036                 ITEM_EDITBOX_KEY,
1037                 ITEM_EDITBOX_DRAW,
1038                 defct_mouse_enter,
1039                 defct_mouse_leave,
1040                 defct_action,
1041                 ITEM_EDITBOX_REFRESH);
1042
1043         ctcall_init();
1044 };
1045
1046 /*
1047 /////////////////////////////////////////////////////////////////////////
1048 // The "actual" funtions
1049
1050 void(void) ctinit_picture =
1051 {
1052
1053 };
1054
1055 // draws a text (uses the std. way)
1056 void(string text, vector pos, vector size, float alignment, float style, float state) ctdrawtext =
1057 {
1058         vector alignpos;
1059
1060         if(text == "")
1061                 return;
1062
1063         // align to the rect pos - (pos + size)
1064
1065         // now check the alignement
1066         if(alignment & TEXT_ALIGN_CENTER)
1067                 alignpos_x = pos_x + (size_x - strlen(text) * self.font_size_x) / 2;
1068         else if(alignment & TEXT_ALIGN_RIGHT)
1069                 alignpos_x = pos_x + size_x - strlen(text) * self.font_size_x;
1070         else
1071                 alignpos_x = pos_x;
1072                 alignpos_y = pos_y;
1073
1074         if(style == TEXTBUTTON_STYLE_OUTLINE && state != BUTTON_NORMAL)
1075         {
1076                 vector p,s;
1077                 // left
1078                 p_x = pos_x;
1079                 p_y = pos_y;
1080                 s_x = TEXTBUTTON_OUTLINE_WIDTH;
1081                 s_y = size_y;
1082                 if(state == BUTTON_PRESSED)
1083                 {
1084                         menu_fillarea(p, s, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
1085                 }
1086                 else if(state == BUTTON_SELECTED)
1087                 {
1088                         menu_fillarea(p, s, self.color_selected, self.alpha_selected, self.drawflag_selected);
1089                 }
1090                 // right
1091                 p_x = pos_x + size_x - TEXTBUTTON_OUTLINE_WIDTH;
1092                 p_y = pos_y;
1093                 s_x = TEXTBUTTON_OUTLINE_WIDTH;
1094                 s_y = size_y;
1095                 if(state == BUTTON_PRESSED)
1096                 {
1097                         menu_fillarea(p, s, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
1098                 }
1099                 else if(state == BUTTON_SELECTED)
1100                 {
1101                         menu_fillarea(p, s, self.color_selected, self.alpha_selected, self.drawflag_selected);
1102                 }
1103                 // top
1104                 p_x = pos_x;
1105                 p_y = pos_y;
1106                 s_y = TEXTBUTTON_OUTLINE_WIDTH;
1107                 s_x = size_x;
1108                 if(state == BUTTON_PRESSED)
1109                 {
1110                         menu_fillarea(p, s, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
1111                 }
1112                 else if(self._button_state == BUTTON_SELECTED)
1113                 {
1114                         menu_fillarea(p, s, self.color_selected, self.alpha_selected, self.drawflag_selected);
1115                 }
1116                 // bottom
1117                 p_x = pos_x;
1118                 p_y = pos_y + size_y - TEXTBUTTON_OUTLINE_WIDTH;
1119                 s_y = TEXTBUTTON_OUTLINE_WIDTH;
1120                 s_x = size_x;
1121                 if(state == BUTTON_PRESSED)
1122                 {
1123                         menu_fillarea(p, s, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
1124                 }
1125                 else if(state == BUTTON_SELECTED)
1126                 {
1127                         menu_fillarea(p, s, self.color_selected, self.alpha_selected, self.drawflag_selected);
1128                 }
1129         } else  if(style == TEXTBUTTON_STYLE_BOX)
1130         {
1131                 if(state == BUTTON_PRESSED)
1132                 {
1133                         menu_fillarea(alignpos, size, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
1134                 }
1135                 else if(self._button_state == BUTTON_SELECTED)
1136                 {
1137                         menu_fillarea(alignpos, size, self.color_selected, self.alpha_selected, self.drawflag_selected);
1138                 }
1139         }
1140
1141         if(state == BUTTON_NORMAL || style == TEXTBUTTON_STYLE_BOX || style == TEXTBUTTON_STYLE_OUTLINE)
1142                 menu_drawstring(alignpos, text, self.font_size, self.color, self.alpha, self.drawflag);
1143
1144         if(style == TEXTBUTTON_STYLE_TEXT)
1145         {
1146                 if(state == BUTTON_PRESSED)
1147                 {
1148                         menu_drawstring(alignpos, text, self.font_size, self.color_pressed, self.alpha_pressed, self.drawflag_pressed);
1149                 }
1150                 else if(state == BUTTON_SELECTED)
1151                 {
1152                         menu_drawstring(alignpos, text, self.font_size, self.color_selected, self.alpha_selected, self.drawflag_selected);
1153                 }
1154         }
1155 };*/