*** empty log message ***
[supertux.git] / src / button.cpp
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", datadir.c_str(), icon_file);
27       if(!faccessible(filename))
28         snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str());
29     }
30   else
31     {
32       snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str());
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 = BUTTON_NONE;
54   pbutton->show_info = false;
55   pbutton->bkgd = NULL;
56 }
57
58 void button_change_icon(button_type* pbutton,char* icon_file)
59 {
60   char filename[1024];
61
62   if(icon_file != NULL)
63     {
64       snprintf(filename, 1024, "%s/%s", datadir.c_str(), icon_file);
65       if(!faccessible(filename))
66         snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str());
67     }
68   else
69     {
70       snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str());
71     }
72   
73   texture_free(&pbutton->icon);
74   texture_load(&pbutton->icon,filename,USE_ALPHA);
75 }
76
77 button_type* button_create(char* icon_file, char* info, SDLKey shortcut, int x, int y)
78 {
79   button_type* pnew_button = (button_type*) malloc(sizeof(button_type));
80   button_load(pnew_button,icon_file, info, shortcut, x, y);
81   return pnew_button;
82 }
83
84 void button_draw(button_type* pbutton)
85 {
86   fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200);
87   fillrect(pbutton->x+1,pbutton->y+1,pbutton->w-2,pbutton->h-2,175,175,175,200);
88   if(pbutton->bkgd != NULL)
89   {
90   texture_draw(pbutton->bkgd,pbutton->x,pbutton->y);
91   }
92   texture_draw(&pbutton->icon,pbutton->x,pbutton->y);
93   if(pbutton->show_info)
94     {
95       char str[80];
96       int i = -32;
97
98       if(0 > pbutton->x - (int)strlen(pbutton->info) * white_small_text.w)
99         i = pbutton->w + strlen(pbutton->info) * white_small_text.w;
100
101       if(pbutton->info)
102         text_draw(&white_small_text, pbutton->info, i + pbutton->x - strlen(pbutton->info) * white_small_text.w, pbutton->y, 1);
103       sprintf(str,"(%s)", SDL_GetKeyName(pbutton->shortcut));
104       text_draw(&white_small_text, str, i + pbutton->x - strlen(str) * white_small_text.w, pbutton->y + white_small_text.h+2, 1);
105     }
106   if(pbutton->state == BUTTON_PRESSED)
107     fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200);
108   else if(pbutton->state == BUTTON_HOVER)
109     fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,150,150,150,128);
110 }
111
112 void button_free(button_type* pbutton)
113 {
114   free(pbutton->info);
115   texture_free(&pbutton->icon);
116 }
117
118 void button_event(button_type* pbutton, SDL_Event *event)
119 {
120   SDLKey key = event->key.keysym.sym;
121
122   if(event->motion.x > pbutton->x && event->motion.x < pbutton->x + pbutton->w &&
123       event->motion.y > pbutton->y && event->motion.y < pbutton->y + pbutton->h)
124     {
125       if(event->type == SDL_MOUSEBUTTONDOWN)
126         {
127           if(event->button.button == SDL_BUTTON_LEFT)
128             {
129               pbutton->state = BUTTON_PRESSED;
130             }
131           else
132             {
133               pbutton->show_info = true;
134             }
135         }
136       else if(event->type == SDL_MOUSEBUTTONUP)
137         {
138           if(event->button.button == SDL_BUTTON_LEFT && pbutton->state == BUTTON_PRESSED)
139             {
140               pbutton->state = BUTTON_CLICKED;
141             }
142           else if(event->button.button != SDL_BUTTON_LEFT && pbutton->state != BUTTON_PRESSED)
143             {
144               pbutton->show_info = true;
145             }
146         }
147
148       if(pbutton->state != BUTTON_PRESSED && pbutton->state != BUTTON_CLICKED)
149         {
150           pbutton->state = BUTTON_HOVER;
151           mouse_cursor->set_state(MC_LINK);
152         }
153     }
154   else if(event->type != SDL_KEYDOWN && event->type != SDL_KEYUP)
155     {
156       pbutton->state = BUTTON_NONE;
157       if(pbutton->show_info)
158         {
159           pbutton->show_info = false;
160         }
161     }
162
163   if(event->type == SDL_KEYDOWN)
164     {
165       if(key == pbutton->shortcut)
166         pbutton->state = BUTTON_PRESSED;
167     }
168   else if(event->type == SDL_KEYUP)
169     {
170       if(pbutton->state == BUTTON_PRESSED && key == pbutton->shortcut)
171         pbutton->state = BUTTON_CLICKED;
172     }
173   else if(event->type == SDL_MOUSEMOTION)
174     {
175
176       if(pbutton->show_info)
177         {
178           pbutton->show_info = false;
179         }
180     }
181 }
182
183 int button_get_state(button_type* pbutton)
184 {
185   int state;
186   if(pbutton->state == BUTTON_CLICKED)
187     {
188       state = pbutton->state;
189       pbutton->state = BUTTON_NONE;
190       return state;
191     }
192   else
193     {
194       return pbutton->state;
195     }
196 }
197
198 void button_panel_init(button_panel_type* pbutton_panel, int x, int y, int w, int h)
199 {
200   pbutton_panel->num_items = 0;
201   pbutton_panel->item = NULL;
202   pbutton_panel->x = x;
203   pbutton_panel->y = y;
204   pbutton_panel->w = w;
205   pbutton_panel->h = h;
206   pbutton_panel->hidden = false;
207 }
208
209 button_type* button_panel_event(button_panel_type* pbutton_panel, SDL_Event* event)
210 {
211   if(pbutton_panel->hidden == false)
212     {
213       int i;
214       for(i = 0; i < pbutton_panel->num_items; ++i)
215         {
216           button_event(&pbutton_panel->item[i],event);
217           if(pbutton_panel->item[i].state != -1)
218             return &pbutton_panel->item[i];
219         }
220       return NULL;
221     }
222   else
223     {
224       return NULL;
225     }
226 }
227
228 void button_panel_free(button_panel_type* pbutton_panel)
229 {
230   int i;
231   for(i = 0; i < pbutton_panel->num_items; ++i)
232     {
233       button_free(&pbutton_panel->item[i]);
234     }
235   if(pbutton_panel->num_items)
236     free(pbutton_panel->item);
237 }
238
239 void button_panel_draw(button_panel_type* pbutton_panel)
240 {
241   if(pbutton_panel->hidden == false)
242     {
243       int i;
244       fillrect(pbutton_panel->x,pbutton_panel->y,pbutton_panel->w,pbutton_panel->h,100,100,100,200);
245       for(i = 0; i < pbutton_panel->num_items; ++i)
246         {
247           button_draw(&pbutton_panel->item[i]);
248         }
249     }
250 }
251
252 void button_panel_additem(button_panel_type* pbutton_panel, button_type* pbutton, int tag)
253 {
254   int max_cols, row, col;
255
256   ++pbutton_panel->num_items;
257   pbutton_panel->item = (button_type*) realloc(pbutton_panel->item, sizeof(button_type) * pbutton_panel->num_items);
258   memcpy(&pbutton_panel->item[pbutton_panel->num_items-1],pbutton,sizeof(button_type));
259   free(pbutton);
260
261   /* A button_panel takes control of the buttons it contains and arranges them */
262
263   max_cols = pbutton_panel->w / 32;
264
265   row = (pbutton_panel->num_items-1) / max_cols;
266   col = (pbutton_panel->num_items-1) % max_cols;
267
268   pbutton_panel->item[pbutton_panel->num_items-1].x = pbutton_panel->x + col * 32;
269   pbutton_panel->item[pbutton_panel->num_items-1].y = pbutton_panel->y + row * 32;
270   pbutton_panel->item[pbutton_panel->num_items-1].tag = tag;
271
272 }
273