level-editor is completly impleted for the current level-format now!
[supertux.git] / src / button.c
1 //
2 // C Implementation: button
3 //
4 // Description:
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #include <string.h>
14 #include <stdlib.h>
15 #include "setup.h"
16 #include "screen.h"
17 #include "globals.h"
18 #include "button.h"
19
20 void button_load(button_type* pbutton,char* icon_file, char* info, SDLKey shortcut, int x, int y)
21 {
22   char filename[1024];
23
24   if(icon_file != NULL)
25     {
26       snprintf(filename, 1024, "%s/%s", DATA_PREFIX, icon_file);
27       if(!faccessible(filename))
28         snprintf(filename, 1024, "%s/images/icons/default-icon.png", DATA_PREFIX);
29     }
30   else
31     {
32       snprintf(filename, 1024, "%s/images/icons/default-icon.png", DATA_PREFIX);
33     }
34   texture_load(&pbutton->icon,filename,USE_ALPHA);
35
36   if(info == NULL)
37     {
38       pbutton->info = NULL;
39     }
40   else
41     {
42       pbutton->info = (char*) malloc(sizeof(char)*(strlen(info) + 1));
43       strcpy(pbutton->info,info);
44     }
45
46   pbutton->shortcut = shortcut;
47
48   pbutton->x = x;
49   pbutton->y = y;
50   pbutton->w = pbutton->icon.w;
51   pbutton->h = pbutton->icon.h;
52   pbutton->tag = -1;
53   pbutton->state = -1;
54   pbutton->show_info = NO;
55   pbutton->bkgd = NULL;
56 }
57
58 button_type* button_create(char* icon_file, char* info, SDLKey shortcut, int x, int y)
59 {
60   button_type* pnew_button = (button_type*) malloc(sizeof(button_type));
61   button_load(pnew_button,icon_file, info, shortcut, x, y);
62   return pnew_button;
63 }
64
65 void button_draw(button_type* pbutton)
66 {
67   fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200);
68   fillrect(pbutton->x+1,pbutton->y+1,pbutton->w-2,pbutton->h-2,175,175,175,200);
69   if(pbutton->bkgd != NULL)
70   {
71   texture_draw(pbutton->bkgd,pbutton->x,pbutton->y,NO_UPDATE);
72   }
73   texture_draw(&pbutton->icon,pbutton->x,pbutton->y,NO_UPDATE);
74   if(pbutton->show_info == YES)
75     {
76       char str[80];
77       int i = -32;
78
79       if(0 > pbutton->x - (int)strlen(pbutton->info) * white_small_text.w)
80         i = pbutton->w + strlen(pbutton->info) * white_small_text.w;
81
82       if(pbutton->info)
83         text_draw(&white_small_text, pbutton->info, i + pbutton->x - strlen(pbutton->info) * white_small_text.w, pbutton->y, 1, NO_UPDATE);
84       sprintf(str,"(%s)", SDL_GetKeyName(pbutton->shortcut));
85       text_draw(&white_small_text, str, i + pbutton->x - strlen(str) * white_small_text.w, pbutton->y + white_small_text.h+2, 1, NO_UPDATE);
86     }
87   if(pbutton->state == BN_PRESSED)
88     fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200);
89   else if(pbutton->state == BN_HOVER)
90     fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,150,150,150,128);
91 }
92
93 void button_free(button_type* pbutton)
94 {
95   free(pbutton->info);
96   texture_free(&pbutton->icon);
97 }
98
99 void button_event(button_type* pbutton, SDL_Event *event)
100 {
101   SDLKey key = event->key.keysym.sym;
102
103   if(event->motion.x > pbutton->x && event->motion.x < pbutton->x + pbutton->w &&
104       event->motion.y > pbutton->y && event->motion.y < pbutton->y + pbutton->h)
105     {
106       if(event->type == SDL_MOUSEBUTTONDOWN)
107         {
108           if(event->button.button == SDL_BUTTON_LEFT)
109             {
110               pbutton->state = BN_PRESSED;
111             }
112           else
113             {
114               pbutton->show_info = YES;
115             }
116         }
117       else if(event->type == SDL_MOUSEBUTTONUP)
118         {
119           if(event->button.button == SDL_BUTTON_LEFT && pbutton->state == BN_PRESSED)
120             {
121               pbutton->state = BN_CLICKED;
122             }
123           else if(event->button.button != SDL_BUTTON_LEFT && pbutton->state != BN_PRESSED)
124             {
125               pbutton->show_info = YES;
126             }
127         }
128
129       if(pbutton->state != BN_PRESSED && pbutton->state != BN_CLICKED)
130         {
131           pbutton->state = BN_HOVER;
132         }
133     }
134   else if(event->type != SDL_KEYDOWN && event->type != SDL_KEYUP)
135     {
136       pbutton->state = -1;
137       if(pbutton->show_info)
138         {
139           pbutton->show_info = NO;
140         }
141     }
142
143   if(event->type == SDL_KEYDOWN)
144     {
145       if(key == pbutton->shortcut)
146         pbutton->state = BN_PRESSED;
147     }
148   else if(event->type == SDL_KEYUP)
149     {
150       if(pbutton->state == BN_PRESSED && key == pbutton->shortcut)
151         pbutton->state = BN_CLICKED;
152     }
153   else if(event->type == SDL_MOUSEMOTION)
154     {
155
156       if(pbutton->show_info)
157         {
158           pbutton->show_info = NO;
159         }
160     }
161 }
162
163 int button_get_state(button_type* pbutton)
164 {
165   int state;
166   if(pbutton->state == BN_CLICKED)
167     {
168       state = pbutton->state;
169       pbutton->state = -1;
170       return state;
171     }
172   else
173     {
174       return pbutton->state;
175     }
176 }
177
178 void button_panel_init(button_panel_type* pbutton_panel, int x, int y, int w, int h)
179 {
180   pbutton_panel->num_items = 0;
181   pbutton_panel->item = NULL;
182   pbutton_panel->x = x;
183   pbutton_panel->y = y;
184   pbutton_panel->w = w;
185   pbutton_panel->h = h;
186   pbutton_panel->hidden = NO;
187 }
188
189 button_type* button_panel_event(button_panel_type* pbutton_panel, SDL_Event* event)
190 {
191   if(pbutton_panel->hidden == NO)
192     {
193       int i;
194       for(i = 0; i < pbutton_panel->num_items; ++i)
195         {
196           button_event(&pbutton_panel->item[i],event);
197           if(pbutton_panel->item[i].state != -1)
198             return &pbutton_panel->item[i];
199         }
200       return NULL;
201     }
202   else
203     {
204       return NULL;
205     }
206 }
207
208 void button_panel_free(button_panel_type* pbutton_panel)
209 {
210   int i;
211   for(i = 0; i < pbutton_panel->num_items; ++i)
212     {
213       button_free(&pbutton_panel->item[i]);
214     }
215   if(pbutton_panel->num_items)
216     free(pbutton_panel->item);
217 }
218
219 void button_panel_draw(button_panel_type* pbutton_panel)
220 {
221   if(pbutton_panel->hidden == NO)
222     {
223       int i;
224       fillrect(pbutton_panel->x,pbutton_panel->y,pbutton_panel->w,pbutton_panel->h,100,100,100,200);
225       for(i = 0; i < pbutton_panel->num_items; ++i)
226         {
227           button_draw(&pbutton_panel->item[i]);
228         }
229     }
230 }
231
232 void button_panel_additem(button_panel_type* pbutton_panel, button_type* pbutton, int tag)
233 {
234   int max_cols, row, col;
235
236   ++pbutton_panel->num_items;
237   pbutton_panel->item = (button_type*) realloc(pbutton_panel->item, sizeof(button_type) * pbutton_panel->num_items);
238   memcpy(&pbutton_panel->item[pbutton_panel->num_items-1],pbutton,sizeof(button_type));
239   free(pbutton);
240
241   /* A button_panel takes control of the buttons it contains and arranges them */
242
243   max_cols = pbutton_panel->w / 32;
244
245   row = (pbutton_panel->num_items-1) / max_cols;
246   col = (pbutton_panel->num_items-1) % max_cols;
247
248   printf("R %d C %d\n",row,col);
249
250   pbutton_panel->item[pbutton_panel->num_items-1].x = pbutton_panel->x + col * 32;
251   pbutton_panel->item[pbutton_panel->num_items-1].y = pbutton_panel->y + row * 32;
252   pbutton_panel->item[pbutton_panel->num_items-1].tag = tag;
253
254 }
255