1 /*
2 GUILIB: An example GUI framework library for use with SDL
3 */
4
5 #include <string.h>
6
7 #include "SDL.h"
8 #include "GUI_button.h"
9 #include "GUI_loadimage.h"
10
11
12 /* the check marks bitmap */
13 #include "the_checker.h"
14 SDL_Surface *checkmarks=NULL;
15
16
17
18 /* The default callback quits the GUI */
Default_ActiveProc(void * unused)19 static GUI_status Default_ActiveProc(void *unused)
20 {
21 return(GUI_QUIT);
22 }
23
24
GUI_Button(void * data,int x,int y,SDL_Surface * image,SDL_Surface * image2,GUI_ActiveProc activeproc)25 GUI_Button:: GUI_Button(void *data, int x, int y, SDL_Surface *image,
26 SDL_Surface *image2,GUI_ActiveProc activeproc)
27 : GUI_Widget(data, x, y, image->w, image->h)
28 {
29 if ( activeproc == NULL ) {
30 ActiveProc = Default_ActiveProc;
31 } else {
32 ActiveProc = activeproc;
33 }
34 button = image;
35 button2 = image2;
36 freebutton = 0;
37 for (int i=0;i<3; ++i ) {
38 pressed[i]=0;
39 }
40 enabled=1;
41 buttonFont=NULL;
42 freefont=0;
43 flatbutton=0;
44 is_checkable=0;
45 checked=0;
46 }
47
GUI_Button(void * data,int x,int y,int w,int h,GUI_ActiveProc activeproc)48 GUI_Button:: GUI_Button(void *data, int x, int y, int w, int h,
49 GUI_ActiveProc activeproc)
50 : GUI_Widget(data, x, y, w, h)
51 {
52 if ( activeproc == NULL ) {
53 ActiveProc = Default_ActiveProc;
54 } else {
55 ActiveProc = activeproc;
56 }
57 button = NULL;
58 button2 = NULL;
59 freebutton = 0;
60 for (int i=0;i<3; ++i ) {
61 pressed[i]=0;
62 }
63 enabled=1;
64 buttonFont=NULL;
65 freefont=0;
66 flatbutton=0;
67 is_checkable=0;
68 checked=0;
69 }
70
GUI_Button(void * data,int x,int y,int w,int h,char * text,GUI_Font * font,int alignment,int is_checkbutton,GUI_ActiveProc activeproc,int flat)71 GUI_Button::GUI_Button(void *data, int x, int y, int w, int h, char *text,
72 GUI_Font *font, int alignment, int is_checkbutton,
73 GUI_ActiveProc activeproc, int flat)
74 : GUI_Widget(data,x,y,w,h)
75 {
76 if ( activeproc == NULL )
77 ActiveProc = Default_ActiveProc;
78 else
79 ActiveProc = activeproc;
80
81 if (font!=NULL)
82 {
83 buttonFont=font;
84 freefont=0;
85 }
86 else
87 {
88 buttonFont=new GUI_Font();
89 freefont=1;
90 }
91 flatbutton=flat;
92 freebutton=1;
93 button=NULL;
94 button2=NULL;
95
96 is_checkable=is_checkbutton;
97 checked=0;
98 if (is_checkable &&(checkmarks==NULL))
99 {
100 checkmarks=GUI_LoadImage(checker_w,checker_h,checker_pal,checker_data);
101 SDL_SetColorKey(checkmarks,SDL_SRCCOLORKEY,0);
102 }
103 ChangeTextButton(-1,-1,-1,-1,text,alignment);
104
105 for (int i=0;i<3; ++i ) {
106 pressed[i]=0;
107 }
108 enabled=1;
109 }
110
~GUI_Button()111 GUI_Button::~GUI_Button()
112 {
113 if (freebutton)
114 {
115 if (button)
116 SDL_FreeSurface(button);
117 if (button2)
118 SDL_FreeSurface(button2);
119 }
120 if (freefont)
121 delete buttonFont;
122 }
123
124 /* Resize/reposition/change text */
ChangeTextButton(int x,int y,int w,int h,char * text,int alignment)125 void GUI_Button::ChangeTextButton(int x, int y, int w, int h, char* text, int alignment)
126 {
127 if (x>=0)
128 area.x=x;
129 if (y>=0)
130 area.y=y;
131 if (w>=0)
132 area.w=w;
133 if (h>=0)
134 area.h=h;
135
136 if (freebutton)
137 {
138 if (button)
139 SDL_FreeSurface(button);
140 if (button2)
141 SDL_FreeSurface(button2);
142 if (flatbutton)
143 {
144 button=CreateTextButtonImage(BUTTON2D_UP,text,alignment);
145 button2=CreateTextButtonImage(BUTTON2D_DOWN,text,alignment);
146 }
147 else
148 {
149 button=CreateTextButtonImage(BUTTON3D_UP,text,alignment);
150 button2=CreateTextButtonImage(BUTTON3D_DOWN,text,alignment);
151 }
152 }
153 }
154
155 /* Show the widget */
Display(void)156 void GUI_Button:: Display(void)
157 {
158 if (button)
159 {
160 if ((button2!=NULL) && (pressed[0])==1)
161 SDL_BlitSurface(button2,NULL,screen,&area);
162 else
163 SDL_BlitSurface(button,NULL,screen,&area);
164 }
165 if (is_checkable)
166 {
167 /*
168 **** OLD VERSION WITH TEXT CHECKMARK ****
169 if (checked)
170 {
171 buttonFont->SetTransparency(1);
172 buttonFont->SetColoring(255,0,0);
173 buttonFont->TextOut(screen,area.x+4,area.y+4,textmark);
174 }
175 */
176 SDL_Rect src,dest=area;
177 src.x=8-(checked*8); src.y=0;
178 src.w=8; src.h=10;
179 dest.x+=4; dest.y+=4;
180 dest.w=8; dest.h=10;
181 SDL_BlitSurface(checkmarks,&src,screen,&dest);
182 }
183 if (!enabled)
184 {
185 Uint8 *pointer;
186 int pixel=SDL_MapRGB(screen->format,0,0,0);;
187 Uint8 bytepp=screen->format->BytesPerPixel;
188
189 if (!SDL_LockSurface(screen))
190 {
191 for (int y=0;y<area.h;y+=2)
192 {
193 pointer=(Uint8*)screen->pixels+screen->pitch*(area.y+y)+(area.x*bytepp);
194 for (int x=0;x<area.w>>1;x++)
195 {
196 switch (bytepp)
197 {
198 case 1:
199 *((Uint8 *)(pointer)) = (Uint8)pixel;
200 pointer+=2;
201 break;
202 case 2:
203 *((Uint16 *)(pointer)) = (Uint16)pixel;
204 pointer+=4;
205 break;
206 case 3: /* Format/endian independent */
207 Uint8 r, g, b;
208
209 r = (pixel>>screen->format->Rshift)&0xFF;
210 g = (pixel>>screen->format->Gshift)&0xFF;
211 b = (pixel>>screen->format->Bshift)&0xFF;
212 *((pointer)+screen->format->Rshift/8) = r;
213 *((pointer)+screen->format->Gshift/8) = g;
214 *((pointer)+screen->format->Bshift/8) = b;
215 pointer+=6;
216 break;
217 case 4:
218 *((Uint32 *)(pointer)) = (Uint32)pixel;
219 pointer+=8;
220 break;
221 }
222 }
223 }
224 SDL_UnlockSurface(screen);
225 }
226 }
227 }
228
229 /* Mouse hits activate us */
MouseDown(int x,int y,int button)230 GUI_status GUI_Button:: MouseDown(int x, int y, int button)
231 {
232 if (enabled &&(button==1))
233 {
234 pressed[0]=1;
235 Redraw();
236 }
237 return GUI_PASS;
238 }
239
MouseUp(int x,int y,int button)240 GUI_status GUI_Button::MouseUp(int x,int y,int button)
241 {
242 if ((button==1) && (pressed[0]))
243 {
244 pressed[0]=0;
245 if ((x>=0) && (y>=0))
246 if (ActiveProc(widget_data)==GUI_QUIT)
247 return GUI_QUIT;
248 Redraw();
249 }
250 return GUI_PASS;
251 }
252
MouseMotion(int x,int y,Uint8 state)253 GUI_status GUI_Button::MouseMotion(int x,int y,Uint8 state)
254 {
255 if ((pressed[0]==1) && ((x<0) || (y<0)))
256 {
257 pressed[0]=2;
258 Redraw();
259 }
260 if ((pressed[0]==2) && (x>=0) && (y>=0))
261 {
262 pressed[0]=1;
263 Redraw();
264 }
265 return GUI_PASS;
266 }
267
Disable()268 void GUI_Button::Disable()
269 {
270 enabled=0;
271 Redraw();
272 }
273
Enable(int flag)274 void GUI_Button::Enable(int flag)
275 {
276 enabled=flag;
277 Redraw();
278 }
279
CreateTextButtonImage(int style,char * text,int alignment)280 SDL_Surface* GUI_Button::CreateTextButtonImage(int style, char *text, int alignment)
281 {
282 SDL_Rect fillrect;
283 int th,tw,tx,ty;
284 SDL_Surface *img=SDL_AllocSurface(SDL_SWSURFACE,area.w,area.h,
285 16,31 << 11,63 << 5,31,0);
286 Uint32 color1=SDL_MapRGB(img->format,BL_R,BL_G,BL_B);
287 Uint32 color2=SDL_MapRGB(img->format,BS_R,BS_G,BS_B);
288 Uint32 color3=SDL_MapRGB(img->format,BF_R,BF_G,BF_B);
289 Uint32 color4=SDL_MapRGB(img->format,BI2_R,BI2_G,BI2_B);
290
291 if (img==NULL) return NULL;
292
293 buttonFont->SetColoring(0,0,0);
294 buttonFont->SetTransparency(1);
295 buttonFont->TextExtent(text,&tw,&th);
296 if (tw>(area.w-(4+is_checkable*16)))
297 {
298 text[(area.w-(4+is_checkable*16))/buttonFont->CharWidth()]=0;
299 buttonFont->TextExtent(text,&tw,&th);
300 }
301 if (th>(area.h-4))
302 {
303 text[0]=0;
304 }
305 switch (alignment)
306 {
307 case BUTTON_TEXTALIGN_LEFT:
308 tx=4+(is_checkable*16);
309 break;
310 case BUTTON_TEXTALIGN_CENTER:
311 tx=(area.w-tw) >> 1;
312 break;
313 case BUTTON_TEXTALIGN_RIGHT:
314 tx=area.w-5-tw;
315 break;
316 }
317 ty=(area.h-th) >> 1;
318
319 switch (style)
320 {
321 case BUTTON3D_UP:
322 fillrect.x=0; fillrect.y=0;
323 fillrect.w=area.w; fillrect.h=2;
324 SDL_FillRect(img,&fillrect,color1);
325 fillrect.y=area.h-2;
326 SDL_FillRect(img,&fillrect,color2);
327 fillrect.x=0; fillrect.y=0;
328 fillrect.w=2; fillrect.h=area.h;
329 SDL_FillRect(img,&fillrect,color1);
330 fillrect.x=area.w-2;
331 SDL_FillRect(img,&fillrect,color2);
332 fillrect.h=1; fillrect.w=1;
333 SDL_FillRect(img,&fillrect,color1);
334 fillrect.x=1;
335 fillrect.y=area.h-1;
336 SDL_FillRect(img,&fillrect,color2);
337 fillrect.x=2; fillrect.y=2;
338 fillrect.w=area.w-4; fillrect.h=area.h-4;
339 SDL_FillRect(img,&fillrect,color3);
340 buttonFont->TextOut(img,tx,ty,text);
341 break;
342 case BUTTON3D_DOWN:
343 fillrect.x=0; fillrect.y=0;
344 fillrect.w=area.w; fillrect.h=area.h;
345 SDL_FillRect(img,&fillrect,color3);
346 buttonFont->TextOut(img,tx+1,ty+1,text);
347 break;
348 case BUTTON2D_UP:
349 fillrect.x=0; fillrect.y=0;
350 fillrect.w=area.w; fillrect.h=area.h;
351 SDL_FillRect(img,&fillrect,color3);
352 buttonFont->TextOut(img,tx,ty,text);
353 break;
354 case BUTTON2D_DOWN:
355 fillrect.x=0; fillrect.y=0;
356 fillrect.w=area.w; fillrect.h=area.h;
357 SDL_FillRect(img,&fillrect,color4);
358 buttonFont->SetTransparency(0);
359 buttonFont->SetColoring(BI1_R,BI1_G,BI1_B,BI2_R,BI2_G,BI2_B);
360 buttonFont->TextOut(img,tx,ty,text);
361 break;
362 }
363 return img;
364 }
365