f0a8e1c8b58d17658fc39ea98fc7fc7e11512f21
[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->state = -1;
53   pbutton->show_info = NO;
54 }
55
56 button_type* button_create(char* icon_file, char* info, SDLKey shortcut, int x, int y)
57 {
58   button_type* pnew_button = (button_type*) malloc(sizeof(button_type));
59   button_load(pnew_button,icon_file, info, shortcut, x, y);
60   return pnew_button;
61 }
62
63 void button_draw(button_type* pbutton)
64 {
65   fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200);
66   fillrect(pbutton->x+1,pbutton->y+1,pbutton->w-2,pbutton->h-2,175,175,175,200);
67   texture_draw(&pbutton->icon,pbutton->x,pbutton->y,NO_UPDATE);
68   if(pbutton->show_info == YES)
69     {
70       char str[80];
71       if(pbutton->info)
72         text_draw(&white_small_text, pbutton->info, pbutton->x - strlen(pbutton->info) * white_small_text.w, pbutton->y, 1, NO_UPDATE);
73       sprintf(str,"(%s)", SDL_GetKeyName(pbutton->shortcut));
74       text_draw(&white_small_text, str, pbutton->x - strlen(str) * white_small_text.w, pbutton->y + white_small_text.h+2, 1, NO_UPDATE);
75     }
76   if(pbutton->state == BN_PRESSED)
77     fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200);
78 }
79
80 void button_free(button_type* pbutton)
81 {
82   free(pbutton->info);
83   texture_free(&pbutton->icon);
84 }
85
86 void button_event(button_type* pbutton, SDL_Event *event)
87 {
88 SDLKey key = event->key.keysym.sym;
89
90   if(event->motion.x > pbutton->x && event->motion.x < pbutton->x + pbutton->w &&
91       event->motion.y > pbutton->y && event->motion.y < pbutton->y + pbutton->h)
92     {
93       if(event->type == SDL_MOUSEBUTTONDOWN)
94         {
95           if(event->button.button == SDL_BUTTON_LEFT)
96             {
97               pbutton->state = BN_PRESSED;
98             }
99           else
100             {
101               pbutton->show_info = YES;
102             }
103         }
104       if(event->type == SDL_MOUSEBUTTONUP)
105         {
106           if(event->button.button == SDL_BUTTON_LEFT && pbutton->state == BN_PRESSED)
107             {
108               pbutton->state = BN_CLICKED;
109             }
110           else if(event->button.button != SDL_BUTTON_LEFT && pbutton->state != BN_PRESSED)
111             {
112               pbutton->show_info = YES;
113             }
114         }
115     }
116   else if(event->type == SDL_MOUSEBUTTONDOWN || event->type == SDL_MOUSEBUTTONUP)
117     {
118       pbutton->state = -1;
119       if(pbutton->show_info)
120         {
121           pbutton->show_info = NO;
122         }
123     }
124     
125   if(event->type == SDL_KEYDOWN)
126     {
127       if(key == pbutton->shortcut)
128         pbutton->state = BN_PRESSED;
129     }
130   else if(event->type == SDL_KEYUP)
131     {
132       if(pbutton->state == BN_PRESSED && key == pbutton->shortcut)
133         pbutton->state = BN_CLICKED;
134     }
135   else if(event->type == SDL_MOUSEMOTION)
136     {
137
138       if(pbutton->show_info)
139         {
140           pbutton->show_info = NO;
141         }
142     }
143 }
144
145 int button_get_state(button_type* pbutton)
146 {
147   int state;
148   if(pbutton->state == BN_CLICKED)
149     {
150       state = pbutton->state;
151       pbutton->state = -1;
152       return state;
153     }
154   else
155     return pbutton->state;
156 }
157
158 void button_panel_init(button_panel_type* pbutton_panel, int x, int y, int w, int h)
159 {
160   pbutton_panel->num_items = 0;
161   pbutton_panel->item = NULL;
162   pbutton_panel->x = x;
163   pbutton_panel->y = y;
164   pbutton_panel->w = w;
165   pbutton_panel->h = h;
166 }
167
168 void button_panel_free(button_panel_type* pbutton_panel)
169 {
170   int i;
171   for(i = 0; i < pbutton_panel->num_items; ++i)
172     {
173       button_free(&pbutton_panel->item[i]);
174     }
175   if(pbutton_panel->num_items)
176     free(pbutton_panel->item);
177 }
178
179 void button_panel_draw(button_panel_type* pbutton_panel)
180 {
181   int i;
182   for(i = 0; i < pbutton_panel->num_items; ++i)
183     {
184       button_draw(&pbutton_panel->item[i]);
185     }
186 }
187
188 void button_panel_additem(button_panel_type* pbutton_panel, button_type* pbutton)
189 {
190   int max_cols, row, col;
191
192   ++pbutton_panel->num_items;
193   pbutton_panel->item = (button_type*) realloc(pbutton_panel->item, sizeof(button_type) * pbutton_panel->num_items);
194   memcpy(&pbutton_panel->item[pbutton_panel->num_items-1],pbutton,sizeof(button_type));
195   free(pbutton);
196
197   /* A button_panel takes control of the buttons it contains and arranges them */
198
199   max_cols = pbutton_panel->w / 32;
200
201   row = pbutton_panel->num_items / max_cols;
202   col = pbutton_panel->num_items % max_cols;
203
204   pbutton_panel->item[pbutton_panel->num_items-1].x = pbutton_panel->x + col * 32;
205   pbutton_panel->item[pbutton_panel->num_items-1].y = pbutton_panel->y + row * 32;
206
207 }
208