use PhysicsFS for saving levels
[btb/d2x.git] / ui / gadget.c
1 /* $Id: gadget.c,v 1.6 2005-02-26 10:13:51 chris Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 #ifdef RCS
16 static char rcsid[] = "$Id: gadget.c,v 1.6 2005-02-26 10:13:51 chris Exp $";
17 #endif
18
19 #ifdef HAVE_CONFIG_H
20 #include "conf.h"
21 #endif
22
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #include "u_mem.h"
27 #include "fix.h"
28 #include "pstypes.h"
29 #include "gr.h"
30 #include "ui.h"
31
32 #include "key.h"
33
34 UI_GADGET * selected_gadget;
35
36 UI_GADGET * ui_gadget_add( UI_WINDOW * wnd, short kind, short x1, short y1, short x2, short y2 )
37 {
38         UI_GADGET * gadget;
39
40         gadget = (UI_GADGET *) d_malloc(sizeof(UI_GADGET));
41         if (gadget==NULL) exit(1);
42
43         if (wnd->gadget == NULL )
44         {
45                 wnd->gadget = gadget;
46                 gadget->prev = gadget;
47                 gadget->next = gadget;
48         } else {
49                 wnd->gadget->prev->next = gadget;
50                 gadget->next = wnd->gadget;
51                 gadget->prev = wnd->gadget->prev;
52                 wnd->gadget->prev = gadget;
53         }
54
55         gadget->when_tab = NULL;
56         gadget->when_btab = NULL;
57         gadget->when_up = NULL;
58         gadget->when_down = NULL;
59         gadget->when_left = NULL;
60         gadget->when_right = NULL;
61         gadget->kind = kind;
62         gadget->status = 1;
63         gadget->oldstatus = 0;
64         if ( x1==0 && x2==0 && y1==0 && y2== 0 )
65                 gadget->canvas = NULL;
66         else
67                 gadget->canvas = gr_create_sub_canvas( wnd->canvas, x1, y1, x2-x1+1, y2-y1+1 );
68         gadget->x1 = gadget->canvas->cv_bitmap.bm_x;
69         gadget->y1 = gadget->canvas->cv_bitmap.bm_y;
70         gadget->x2 = gadget->canvas->cv_bitmap.bm_x+x2-x1+1;
71         gadget->y2 = gadget->canvas->cv_bitmap.bm_y+y2-y1+1;
72         gadget->parent = NULL;
73         gadget->hotkey = -1;
74         return gadget;
75
76 }
77
78 void ui_gadget_delete_all( UI_WINDOW * wnd )
79 {
80         UI_GADGET * tmp;
81
82         ui_pad_deactivate();
83
84         while( wnd->gadget != NULL )
85         {
86                 tmp = wnd->gadget;
87                 if (tmp->next == tmp )
88                 {
89                         wnd->gadget = NULL;
90                 } else {
91                         tmp->next->prev = tmp->prev;
92                         tmp->prev->next = tmp->next;
93                         wnd->gadget = tmp->next;
94                 }
95                 if (tmp->canvas)
96                         gr_free_sub_canvas( tmp->canvas );
97
98
99                 if (tmp->kind == 1 )    // Button
100                 {
101                         UI_GADGET_BUTTON * but1 = (UI_GADGET_BUTTON *)tmp;
102                         if (but1->text)
103                                 d_free( but1->text );
104                 }
105
106                 if (tmp->kind == 6 )    // Inputbox
107                 {
108                         UI_GADGET_INPUTBOX * but1 = (UI_GADGET_INPUTBOX *)tmp;
109                         d_free( but1->text );
110                 }
111
112                 if (tmp->kind == 5 )    // Checkbox
113                 {
114                         UI_GADGET_CHECKBOX * but1 = (UI_GADGET_CHECKBOX *)tmp;
115                         d_free( but1->text );
116                 }
117                 
118                 if (tmp->kind == 9 )    // Icon
119                 {
120                         UI_GADGET_ICON * but1 = (UI_GADGET_ICON *)tmp;
121                         d_free( but1->text );
122                 }
123
124
125                 d_free( tmp );
126         }
127 }
128
129
130 int is_under_another_window( UI_WINDOW * win, UI_GADGET * gadget )
131 {
132         UI_WINDOW * temp;
133
134         temp = win->next;
135
136         while( temp != NULL )   {
137                 if (    ( gadget->x1 > temp->x)                                         &&
138                                 ( gadget->x1 < (temp->x+temp->width) )  &&
139                                 ( gadget->y1 > temp->y)                                         && 
140                                 ( gadget->y1 < (temp->y+temp->height) )
141                         )       
142                 {
143                                 //gadget->status =1;
144                                 return 1;
145                 }
146                 
147
148                 if (    ( gadget->x2 > temp->x)                                         &&
149                                 ( gadget->x2 < (temp->x+temp->width) )  &&
150                                 ( gadget->y2 > temp->y)                                         && 
151                                 ( gadget->y2 < (temp->y+temp->height) )
152                         )
153                 {
154                                 //gadget->status =1;
155                                 return 1;
156                 }
157                 
158
159                 temp = temp->next;
160         }
161         return 0;
162 }
163
164
165 int ui_mouse_on_gadget( UI_GADGET * gadget )
166 {
167         if ((Mouse.x >= gadget->x1) && (Mouse.x <= gadget->x2-1) &&     (Mouse.y >= gadget->y1) &&      (Mouse.y <= gadget->y2-1) )     {
168                 if (is_under_another_window(CurWindow, gadget))
169                         return 0;
170                 return 1;
171         } else
172                 return 0;
173 }
174
175 void ui_window_do_gadgets( UI_WINDOW * wnd )
176 {
177         int keypress;
178         UI_GADGET * tmp, * tmp1;
179
180         CurWindow = wnd;
181
182         keypress = last_keypress;
183
184         tmp = wnd->gadget;
185
186         if (tmp == NULL ) return;
187
188         if (selected_gadget==NULL)
189                 selected_gadget = tmp;
190
191         tmp1 = wnd->keyboard_focus_gadget;
192
193         do
194         {
195                 if (ui_mouse_on_gadget(tmp) && B1_JUST_PRESSED )
196                 {
197                         selected_gadget = tmp;
198                         if (tmp->parent!=NULL)
199                         {
200                                 while (tmp->parent != NULL )
201                                         tmp = tmp->parent;
202                                 wnd->keyboard_focus_gadget = tmp;
203                                 break;
204                         }
205                         else
206                         {
207                                 wnd->keyboard_focus_gadget = tmp;
208                                 break;
209                         }
210                 }
211                 if ( tmp->hotkey == keypress )
212                 {
213                         wnd->keyboard_focus_gadget = tmp;
214                         break;
215                 }
216                 tmp = tmp->next;
217         } while( tmp != wnd->gadget );
218
219         if (wnd->keyboard_focus_gadget != NULL)
220         {
221                 switch (keypress )
222                 {
223                         case (KEY_TAB):
224                                 if ( wnd->keyboard_focus_gadget->when_tab != NULL )
225                                         wnd->keyboard_focus_gadget = wnd->keyboard_focus_gadget->when_tab;
226                                 break;
227                         case (KEY_TAB+KEY_SHIFTED):
228                                 if ( wnd->keyboard_focus_gadget->when_btab != NULL )
229                                         wnd->keyboard_focus_gadget = wnd->keyboard_focus_gadget->when_btab;
230                                 break;
231                         case (KEY_UP):
232                                 if ( wnd->keyboard_focus_gadget->when_up != NULL )
233                                         wnd->keyboard_focus_gadget = wnd->keyboard_focus_gadget->when_up;
234                                 break;
235                         case (KEY_DOWN):
236                                 if ( wnd->keyboard_focus_gadget->when_down != NULL )
237                                         wnd->keyboard_focus_gadget = wnd->keyboard_focus_gadget->when_down;
238                                 break;
239                         case (KEY_LEFT):
240                                 if ( wnd->keyboard_focus_gadget->when_left != NULL )
241                                         wnd->keyboard_focus_gadget = wnd->keyboard_focus_gadget->when_left;
242                                 break;
243                         case (KEY_RIGHT):
244                                 if ( wnd->keyboard_focus_gadget->when_right != NULL )
245                                         wnd->keyboard_focus_gadget = wnd->keyboard_focus_gadget->when_right;
246                                 break;
247                 }
248         }
249
250         if (wnd->keyboard_focus_gadget != tmp1)
251         {
252                 if (wnd->keyboard_focus_gadget != NULL )
253                         wnd->keyboard_focus_gadget->status = 1;
254                 if (tmp1 != NULL )
255                         tmp1->status = 1;
256         }
257
258         tmp = wnd->gadget;
259         do
260         {
261                 if (!is_under_another_window( CurWindow, tmp )) {
262                         UI_WINDOW *curwindow_save=CurWindow;
263
264                         switch( tmp->kind )
265                         {
266                         case 1:
267                                 ui_button_do( (UI_GADGET_BUTTON *)tmp, keypress );
268                                 break;
269                         case 2:
270                                 ui_listbox_do( (UI_GADGET_LISTBOX *)tmp, keypress );
271                                 break;
272                         case 3:
273                                 ui_scrollbar_do( (UI_GADGET_SCROLLBAR *)tmp, keypress );
274                                 break;
275                         case 4:
276                                 ui_radio_do( (UI_GADGET_RADIO *)tmp, keypress );
277                                 break;
278                         case 5:
279                                 ui_checkbox_do( (UI_GADGET_CHECKBOX *)tmp, keypress );
280                                 break;
281                         case 6:
282                                 ui_inputbox_do( (UI_GADGET_INPUTBOX *)tmp, keypress );
283                                 break;
284                         case 7:
285                                 ui_userbox_do( (UI_GADGET_USERBOX *)tmp, keypress );
286                                 break;
287                         case 8:
288                                 ui_keytrap_do( (UI_GADGET_KEYTRAP *)tmp, keypress );
289                                 break;
290                         case 9:
291                                 ui_icon_do( (UI_GADGET_ICON *)tmp, keypress );
292                                 break;
293                         }
294
295                         CurWindow=curwindow_save;
296                 }
297
298                 tmp = tmp->next;
299         } while( tmp != wnd->gadget );
300 }
301
302
303
304 UI_GADGET * ui_gadget_get_next( UI_GADGET * gadget )
305 {
306         UI_GADGET * tmp;
307
308         tmp = gadget->next;
309
310         while( tmp != gadget && (tmp->parent!=NULL) )
311                 tmp = tmp->next;
312
313         return tmp;
314 }
315
316 UI_GADGET * ui_gadget_get_prev( UI_GADGET * gadget )
317 {
318         UI_GADGET * tmp;
319
320         tmp = gadget->prev;
321
322         while( tmp != gadget && (tmp->parent!=NULL) )
323                 tmp = tmp->prev;
324
325         return tmp;
326 }
327
328 void ui_gadget_calc_keys( UI_WINDOW * wnd)
329 {
330         UI_GADGET * tmp;
331
332         tmp = wnd->gadget;
333
334         if (tmp==NULL) return;
335
336         do
337         {
338                 tmp->when_tab = ui_gadget_get_next(tmp);
339                 tmp->when_btab = ui_gadget_get_prev(tmp);
340
341                 tmp = tmp->next;
342         } while( tmp != wnd->gadget );
343
344 }