1 /***************************************************************************
2 guibutton.cpp
3 -------------------
4 created : Fri Aug 13 22:18:21 CEST 1999
5 copyright : (C) 1999-2013 by Eric Espie, Bernhard Wymann
6 email : torcs@free.fr
7 version : $Id: guibutton.cpp,v 1.3.2.6 2013/08/28 13:07:33 berniw Exp $
8 ***************************************************************************/
9
10 /***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19
20 /** @file
21 GUI Buttons Management.
22 @author <a href=mailto:torcs@free.fr>Eric Espie</a>
23 @version $Id: guibutton.cpp,v 1.3.2.6 2013/08/28 13:07:33 berniw Exp $
24 @ingroup gui
25 */
26
27 #include <stdlib.h>
28 #ifdef WIN32
29 #include <windows.h>
30 #endif
31 #include <tgfclient.h>
32 #include "gui.h"
33 #include "guifont.h"
34
35 void
gfuiButtonInit(void)36 gfuiButtonInit(void)
37 {
38 }
39
40 /** Add a graphical button to a screen.
41 @ingroup gui
42 @param scr Screen
43 @param disabled filename of the image when the button is disabled
44 @param enabled filename of the image when the button is enabled
45 @param focused filename of the image when the button is focused
46 @param pushed filename of the image when the button is pushed
47 @param x X position on screen
48 @param y Y position on screen (0 = bottom)
49 @param align Button alignment
50 @param mouse Mouse behavior:
51 <br>GFUI_MOUSE_UP Action performed when the mouse right button is released
52 <br>GFUI_MOUSE_DOWN Action performed when the mouse right button is pushed
53 @param userDataOnPush Parameter to the Push callback
54 @param onPush Push callback function
55 @param userDataOnFocus Parameter to the Focus (and lost) callback
56 @param onFocus Focus callback function
57 @param onFocusLost Focus Lost callback function
58 @return Button Id
59 <br>-1 Error
60 */
61 int
GfuiGrButtonCreate(void * scr,const char * disabled,const char * enabled,const char * focused,const char * pushed,int x,int y,int align,int mouse,void * userDataOnPush,tfuiCallback onPush,void * userDataOnFocus,tfuiCallback onFocus,tfuiCallback onFocusLost)62 GfuiGrButtonCreate(void *scr, const char *disabled, const char *enabled, const char *focused, const char *pushed,
63 int x, int y, int align, int mouse,
64 void *userDataOnPush, tfuiCallback onPush,
65 void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost)
66 {
67 tGfuiGrButton *button;
68 tGfuiObject *object;
69 tGfuiScreen *screen = (tGfuiScreen*)scr;
70 int width, height;
71
72 object = (tGfuiObject*)calloc(1, sizeof(tGfuiObject));
73 object->widget = GFUI_GRBUTTON;
74 object->focusMode = GFUI_FOCUS_MOUSE_MOVE;
75 object->id = screen->curId++;
76 object->visible = 1;
77
78 button = &(object->u.grbutton);
79 button->state = GFUI_BTN_RELEASED;
80 button->userDataOnPush = userDataOnPush;
81 button->onPush = onPush;
82 button->userDataOnFocus = userDataOnFocus;
83 button->onFocus = onFocus;
84 button->onFocusLost = onFocusLost;
85 button->mouseBehaviour = mouse;
86
87 button->disabled = GfImgReadPng(disabled, &width, &height, 1.0);
88 button->enabled = GfImgReadPng(enabled, &width, &height, 1.0);
89 button->focused = GfImgReadPng(focused, &width, &height, 1.0);
90 button->pushed = GfImgReadPng(pushed, &width, &height, 1.0);
91
92 switch (align) {
93 case GFUI_ALIGN_HR_VB:
94 object->xmin = x - width;
95 object->xmax = x;
96 object->ymin = y;
97 object->ymax = y + height;
98 break;
99 case GFUI_ALIGN_HR_VC:
100 object->xmin = x - width;
101 object->xmax = x;
102 object->ymin = y - height / 2;
103 object->ymax = y + height / 2;
104 break;
105 case GFUI_ALIGN_HR_VT:
106 object->xmin = x - width;
107 object->xmax = x;
108 object->ymin = y - height;
109 object->ymax = y;
110 break;
111 case GFUI_ALIGN_HC_VB:
112 object->xmin = x - width / 2;
113 object->xmax = x + width / 2;
114 object->ymin = y;
115 object->ymax = y + height;
116 break;
117 case GFUI_ALIGN_HC_VC:
118 object->xmin = x - width / 2;
119 object->xmax = x + width / 2;
120 object->ymin = y - height / 2;
121 object->ymax = y + height / 2;
122 break;
123 case GFUI_ALIGN_HC_VT:
124 object->xmin = x - width / 2;
125 object->xmax = x + width / 2;
126 object->ymin = y - height;
127 object->ymax = y;
128 break;
129 case GFUI_ALIGN_HL_VB:
130 object->xmin = x;
131 object->xmax = x + width;
132 object->ymin = y;
133 object->ymax = y + height;
134 break;
135 case GFUI_ALIGN_HL_VC:
136 object->xmin = x;
137 object->xmax = x + width;
138 object->ymin = y - height / 2;
139 object->ymax = y + height / 2;
140 break;
141 case GFUI_ALIGN_HL_VT:
142 object->xmin = x;
143 object->xmax = x + width;
144 object->ymin = y - height;
145 object->ymax = y;
146 break;
147 default:
148 break;
149 }
150
151 button->width = width;
152 button->height = height;
153
154 gfuiAddObject(screen, object);
155 return object->id;
156 }
157
158 /** Add a state button to a screen.
159 @ingroup gui
160 @param scr Screen
161 @param text Button label
162 @param font Font id
163 @param x X position on screen
164 @param y Y position on screen (0 = bottom)
165 @param width width of the button (0 = text size)
166 @param align Button alignment:
167 <br>GFUI_ALIGN_HR_VB horizontal right, vertical bottom
168 <br>GFUI_ALIGN_HR_VC horizontal right, vertical center
169 <br>GFUI_ALIGN_HR_VT horizontal right, vertical top
170 <br>GFUI_ALIGN_HC_VB horizontal center, vertical bottom
171 <br>GFUI_ALIGN_HC_VC horizontal center, vertical center
172 <br>GFUI_ALIGN_HC_VT horizontal center, vertical top
173 <br>GFUI_ALIGN_HL_VB horizontal left, vertical bottom
174 <br>GFUI_ALIGN_HL_VC horizontal left, vertical center
175 <br>GFUI_ALIGN_HL_VT horizontal left, vertical top
176 @param mouse Mouse behavior:
177 <br>GFUI_MOUSE_UP Action performed when the mouse right button is released
178 <br>GFUI_MOUSE_DOWN Action performed when the mouse right button is pushed
179 @param userDataOnPush Parameter to the Push callback
180 @param onPush Push callback function
181 @param userDataOnFocus Parameter to the Focus (and lost) callback
182 @param onFocus Focus callback function
183 @param onFocusLost Focus Lost callback function
184 @return Button Id
185 <br>-1 Error
186 */
187 int
GfuiButtonStateCreate(void * scr,const char * text,int font,int x,int y,int width,int align,int mouse,void * userDataOnPush,tfuiCallback onPush,void * userDataOnFocus,tfuiCallback onFocus,tfuiCallback onFocusLost)188 GfuiButtonStateCreate(void *scr, const char *text, int font, int x, int y, int width, int align, int mouse,
189 void *userDataOnPush, tfuiCallback onPush,
190 void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost)
191 {
192 int id;
193 tGfuiButton *button;
194 tGfuiObject *curObject;
195 tGfuiScreen *screen = (tGfuiScreen*)scr;
196
197 id = GfuiButtonCreate(scr, text, font, x, y, width, align, mouse, userDataOnPush, onPush, userDataOnFocus,
198 onFocus, onFocusLost);
199
200 curObject = screen->objects;
201 if (curObject != NULL) {
202 do {
203 curObject = curObject->next;
204 if (curObject->id == id) {
205 if (curObject->widget == GFUI_BUTTON) {
206 button = &(curObject->u.button);
207 button->buttonType = GFUI_BTN_STATE;
208 }
209 return id;
210 }
211 } while (curObject != screen->objects);
212 }
213
214 return id;
215 }
216
217
218 /** Add a button to a screen.
219 @ingroup gui
220 @param scr Screen
221 @param text Button label
222 @param font Font id
223 @param x X position on screen
224 @param y Y position on screen (0 = bottom)
225 @param width width of the button (0 = text size)
226 @param align Button alignment:
227 <br>GFUI_ALIGN_HR_VB horizontal right, vertical bottom
228 <br>GFUI_ALIGN_HR_VC horizontal right, vertical center
229 <br>GFUI_ALIGN_HR_VT horizontal right, vertical top
230 <br>GFUI_ALIGN_HC_VB horizontal center, vertical bottom
231 <br>GFUI_ALIGN_HC_VC horizontal center, vertical center
232 <br>GFUI_ALIGN_HC_VT horizontal center, vertical top
233 <br>GFUI_ALIGN_HL_VB horizontal left, vertical bottom
234 <br>GFUI_ALIGN_HL_VC horizontal left, vertical center
235 <br>GFUI_ALIGN_HL_VT horizontal left, vertical top
236 @param mouse Mouse behavior:
237 <br>GFUI_MOUSE_UP Action performed when the mouse right button is released
238 <br>GFUI_MOUSE_DOWN Action performed when the mouse right button is pushed
239 @param userDataOnPush Parameter to the Push callback
240 @param onPush Push callback function
241 @param userDataOnFocus Parameter to the Focus (and lost) callback
242 @param onFocus Focus callback function
243 @param onFocusLost Focus Lost callback function
244 @return Button Id
245 <br>-1 Error
246 */
247 int
GfuiButtonCreate(void * scr,const char * text,int font,int x,int y,int width,int align,int mouse,void * userDataOnPush,tfuiCallback onPush,void * userDataOnFocus,tfuiCallback onFocus,tfuiCallback onFocusLost)248 GfuiButtonCreate(void *scr, const char *text, int font, int x, int y, int width, int align, int mouse,
249 void *userDataOnPush, tfuiCallback onPush,
250 void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost)
251 {
252 tGfuiButton *button;
253 tGfuiLabel *label;
254 tGfuiObject *object;
255 tGfuiScreen *screen = (tGfuiScreen*)scr;
256
257
258 object = (tGfuiObject*)calloc(1, sizeof(tGfuiObject));
259 object->widget = GFUI_BUTTON;
260 object->focusMode = GFUI_FOCUS_MOUSE_MOVE;
261 object->id = screen->curId++;
262 object->visible = 1;
263
264 button = &(object->u.button);
265 button->state = GFUI_BTN_RELEASED;
266 button->userDataOnPush = userDataOnPush;
267 button->onPush = onPush;
268 button->userDataOnFocus = userDataOnFocus;
269 button->onFocus = onFocus;
270 button->onFocusLost = onFocusLost;
271 button->mouseBehaviour = mouse;
272 button->buttonType = GFUI_BTN_PUSH;
273
274 button->bgColor[0] = &(GfuiColor[GFUI_BGBTNDISABLED][0]);
275 button->bgColor[1] = &(GfuiColor[GFUI_BGBTNENABLED][0]);
276 button->bgColor[2] = &(GfuiColor[GFUI_BGBTNCLICK][0]);
277 button->bgFocusColor[0] = &(GfuiColor[GFUI_BGBTNDISABLED][0]);
278 button->bgFocusColor[1] = &(GfuiColor[GFUI_BGBTNFOCUS][0]);
279 button->bgFocusColor[2] = &(GfuiColor[GFUI_BGBTNCLICK][0]);
280 button->fgColor[0] = &(GfuiColor[GFUI_BTNDISABLED][0]);
281 button->fgColor[1] = &(GfuiColor[GFUI_BTNENABLED][0]);
282 button->fgColor[2] = &(GfuiColor[GFUI_BTNCLICK][0]);
283 button->fgFocusColor[0] = &(GfuiColor[GFUI_BTNDISABLED][0]);
284 button->fgFocusColor[1] = &(GfuiColor[GFUI_BTNFOCUS][0]);
285 button->fgFocusColor[2] = &(GfuiColor[GFUI_BTNCLICK][0]);
286
287 label = &(button->label);
288 label->text = (char*)calloc(1, 100);
289 strncpy(label->text, text, 100);
290 label->text[99] = '\0';
291 label->font = gfuiFont[font];
292 label->maxlen = 99;
293 if (width == 0) {
294 width = gfuiFont[font]->getWidth((const char *)text);
295 }
296
297 label->align = align;
298
299 switch(align&0xF0) {
300 case 0x00 /* LEFT */:
301 label->x = object->xmin = x;
302 label->y = y - 2 * gfuiFont[font]->getDescender();
303 object->ymin = y;
304 object->xmax = x + width;
305 object->ymax = y + gfuiFont[font]->getHeight() - gfuiFont[font]->getDescender();
306 break;
307 case 0x10 /* CENTER */:
308 object->xmin = x - width / 2;
309 label->x = x - gfuiFont[font]->getWidth((const char *)text) / 2;
310 label->y = y - 2 * gfuiFont[font]->getDescender();
311 object->ymin = y;
312 object->xmax = x + width / 2;
313 object->ymax = y + gfuiFont[font]->getHeight() - gfuiFont[font]->getDescender();
314 break;
315 case 0x20 /* RIGHT */:
316 label->x = object->xmin = x - width;
317 label->y = y - 2 * gfuiFont[font]->getDescender();
318 object->ymin = y;
319 object->xmax = x;
320 object->ymax = y + gfuiFont[font]->getHeight() - gfuiFont[font]->getDescender();
321 break;
322 }
323 #define HORIZ_MARGIN 10
324 object->xmin -= HORIZ_MARGIN;
325 object->xmax += HORIZ_MARGIN;
326
327 gfuiAddObject(screen, object);
328 return object->id;
329 }
330
331
GfuiLeanButtonCreate(void * scr,const char * text,int font,int x,int y,int width,int align,int mouse,void * userDataOnPush,tfuiCallback onPush,void * userDataOnFocus,tfuiCallback onFocus,tfuiCallback onFocusLost)332 int GfuiLeanButtonCreate(void *scr, const char *text, int font, int x, int y, int width, int align, int mouse,
333 void *userDataOnPush, tfuiCallback onPush,
334 void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost)
335 {
336 int id = GfuiButtonCreate(scr, text, font, x, y, width, align, mouse,
337 userDataOnPush, onPush, userDataOnFocus, onFocus, onFocusLost);
338 tGfuiObject *o = gfuiGetObject(scr, id);
339 if (o->widget == GFUI_BUTTON) {
340 // Undo margins
341 o->xmax -= HORIZ_MARGIN;
342 o->xmin += HORIZ_MARGIN;
343
344 tGfuiButton *button = &(o->u.button);
345 button->bgColor[1] = &(GfuiColor[GFUI_BGBTNFOCUS][0]);
346 }
347 return id;
348 }
349
350 /** Change the label of a button.
351 @ingroup gui
352 @param scr Screen
353 @param id Button Id
354 @param text New label of the button
355 */
356 void
GfuiButtonSetText(void * scr,int id,const char * text)357 GfuiButtonSetText(void *scr, int id, const char *text)
358 {
359 tGfuiObject *curObject;
360 tGfuiScreen *screen = (tGfuiScreen*)scr;
361 int oldmin, oldmax;
362
363 curObject = screen->objects;
364 if (curObject != NULL) {
365 do {
366 curObject = curObject->next;
367 if (curObject->id == id) {
368 if (curObject->widget == GFUI_BUTTON) {
369 oldmax = curObject->xmax;
370 oldmin = curObject->xmin;
371 gfuiSetLabelText(curObject, &(curObject->u.button.label), text);
372 curObject->xmax = oldmax;
373 curObject->xmin = oldmin;
374 }
375 return;
376 }
377 } while (curObject != screen->objects);
378 }
379 }
380
381 /** Get the Id of the button focused in the current screen.
382 @ingroup gui
383 @return Button Id
384 <br>-1 if no button or no screen or the focus is not on a button
385 */
386 int
GfuiButtonGetFocused(void)387 GfuiButtonGetFocused(void)
388 {
389 tGfuiObject *curObject;
390
391 if (GfuiScreen != NULL) {
392 curObject = GfuiScreen->objects;
393 if (curObject != NULL) {
394 do {
395 curObject = curObject->next;
396 if (curObject->focus) {
397 if (curObject->widget == GFUI_BUTTON) {
398 return curObject->id;
399 }
400 return -1;
401 }
402 } while (curObject != GfuiScreen->objects);
403 }
404 }
405 return -1;
406 }
407
408 void
gfuiDrawButton(tGfuiObject * obj)409 gfuiDrawButton(tGfuiObject *obj)
410 {
411 tGfuiLabel *label;
412 tGfuiButton *button;
413 float *fgColor;
414 float *bgColor;
415
416 button = &(obj->u.button);
417 if (obj->state == GFUI_DISABLE) {
418 button->state = GFUI_BTN_DISABLE;
419 } else if (obj->state == GFUI_ENABLE && button->state == GFUI_BTN_DISABLE) {
420 button->state = GFUI_BTN_RELEASED;
421 }
422
423 if (obj->focus) {
424 fgColor = button->fgFocusColor[button->state];
425 bgColor = button->bgFocusColor[button->state];
426 } else {
427 fgColor = button->fgColor[button->state];
428 bgColor = button->bgColor[button->state];
429 }
430 if (bgColor[3] != 0.0) {
431 glColor4fv(bgColor);
432 glBegin(GL_QUADS);
433 glVertex2i(obj->xmin, obj->ymin);
434 glVertex2i(obj->xmin, obj->ymax);
435 glVertex2i(obj->xmax, obj->ymax);
436 glVertex2i(obj->xmax, obj->ymin);
437 glEnd();
438 glColor4fv(fgColor);
439 glBegin(GL_LINE_STRIP);
440 glVertex2i(obj->xmin, obj->ymin);
441 glVertex2i(obj->xmin, obj->ymax);
442 glVertex2i(obj->xmax, obj->ymax);
443 glVertex2i(obj->xmax, obj->ymin);
444 glVertex2i(obj->xmin, obj->ymin);
445 glEnd();
446 }
447 label = &(button->label);
448 glColor4fv(fgColor);
449 gfuiPrintString(label->x, label->y, label->font, label->text);
450 }
451
452 void
gfuiDrawGrButton(tGfuiObject * obj)453 gfuiDrawGrButton(tGfuiObject *obj)
454 {
455 int sw, sh, vw, vh;
456 tGfuiGrButton *button;
457 unsigned char *img;
458
459 button = &(obj->u.grbutton);
460 if (obj->state == GFUI_DISABLE) {
461 img = button->disabled;
462 } else if (button->state == GFUI_BTN_PUSHED) {
463 img = button->pushed;
464 } else if (obj->focus) {
465 img = button->focused;
466 } else {
467 img = button->enabled;
468 }
469 GfScrGetSize(&sw, &sh, &vw, &vh);
470 glRasterPos2i(obj->xmin, obj->ymin);
471 glPixelZoom((float)vw / (float)GfuiScreen->width, (float)vh / (float)GfuiScreen->height);
472 glDrawPixels(button->width, button->height, GL_RGBA, GL_UNSIGNED_BYTE, img);
473 }
474
475 void
gfuiGrButtonAction(int action)476 gfuiGrButtonAction(int action)
477 {
478 tGfuiObject *object = GfuiScreen->hasFocus;
479 if (object->state == GFUI_DISABLE) {
480 return;
481 }
482
483 tGfuiGrButton *button;
484 button = &(GfuiScreen->hasFocus->u.grbutton);
485
486 switch (button->buttonType) {
487 case GFUI_BTN_PUSH:
488 if (action == 2) { /* enter key */
489 if (button->onPush != NULL) {
490 button->onPush(button->userDataOnPush);
491 }
492 } else if (action == 1) { /* mouse up */
493 if (button->state != GFUI_BTN_RELEASED) {
494 button->state = GFUI_BTN_RELEASED;
495 if (button->mouseBehaviour == GFUI_MOUSE_UP) {
496 if (button->onPush != NULL) {
497 button->onPush(button->userDataOnPush);
498 }
499 }
500 }
501 } else { /* mouse down */
502 if (button->state != GFUI_BTN_PUSHED) {
503 button->state = GFUI_BTN_PUSHED;
504 if (button->mouseBehaviour == GFUI_MOUSE_DOWN) {
505 if (button->onPush != NULL) {
506 button->onPush(button->userDataOnPush);
507 }
508 }
509 }
510 }
511 break;
512
513 case GFUI_BTN_STATE:
514 if (action == 2) { /* enter key */
515 if (button->state == GFUI_BTN_RELEASED) {
516 button->state = GFUI_BTN_PUSHED;
517 if (button->onPush != NULL) {
518 button->onPush(button->userDataOnPush);
519 }
520 } else {
521 button->state = GFUI_BTN_RELEASED;
522 }
523 } else if (action == 1) { /* mouse up */
524 if (button->mouseBehaviour == GFUI_MOUSE_UP) {
525 if (button->state == GFUI_BTN_RELEASED) {
526 button->state = GFUI_BTN_PUSHED;
527 if (button->onPush != NULL) {
528 button->onPush(button->userDataOnPush);
529 }
530 } else {
531 button->state = GFUI_BTN_RELEASED;
532 }
533 }
534 } else { /* mouse down */
535 if (button->mouseBehaviour == GFUI_MOUSE_DOWN) {
536 if (button->state == GFUI_BTN_RELEASED) {
537 button->state = GFUI_BTN_PUSHED;
538 if (button->onPush != NULL) {
539 button->onPush(button->userDataOnPush);
540 }
541 } else {
542 button->state = GFUI_BTN_RELEASED;
543 }
544 }
545 }
546 break;
547 }
548 }
549
550 void
gfuiButtonAction(int action)551 gfuiButtonAction(int action)
552 {
553 tGfuiObject *object = GfuiScreen->hasFocus;
554 if (object->state == GFUI_DISABLE) {
555 return;
556 }
557
558 tGfuiButton *button;
559 button = &(GfuiScreen->hasFocus->u.button);
560
561 switch (button->buttonType) {
562 case GFUI_BTN_PUSH:
563 if (action == 2) { /* enter key */
564 if (button->onPush != NULL) {
565 button->onPush(button->userDataOnPush);
566 }
567 } else if (action == 1) { /* mouse up */
568 button->state = GFUI_BTN_RELEASED;
569 if (button->mouseBehaviour == GFUI_MOUSE_UP) {
570 if (button->onPush != NULL) {
571 button->onPush(button->userDataOnPush);
572 }
573 }
574 } else { /* mouse down */
575 button->state = GFUI_BTN_PUSHED;
576 if (button->mouseBehaviour == GFUI_MOUSE_DOWN) {
577 if (button->onPush != NULL) {
578 button->onPush(button->userDataOnPush);
579 }
580 }
581 }
582 break;
583
584 case GFUI_BTN_STATE:
585 if (action == 2) { /* enter key */
586 if (button->state == GFUI_BTN_RELEASED) {
587 button->state = GFUI_BTN_PUSHED;
588 if (button->onPush != NULL) {
589 button->onPush(button->userDataOnPush);
590 }
591 } else {
592 button->state = GFUI_BTN_RELEASED;
593 }
594 } else if (action == 1) { /* mouse up */
595 if (button->mouseBehaviour == GFUI_MOUSE_UP) {
596 if (button->state == GFUI_BTN_RELEASED) {
597 button->state = GFUI_BTN_PUSHED;
598 if (button->onPush != NULL) {
599 button->onPush(button->userDataOnPush);
600 }
601 } else {
602 button->state = GFUI_BTN_RELEASED;
603 }
604 }
605 } else { /* mouse down */
606 if (button->mouseBehaviour == GFUI_MOUSE_DOWN) {
607 if (button->state == GFUI_BTN_RELEASED) {
608 button->state = GFUI_BTN_PUSHED;
609 if (button->onPush != NULL) {
610 button->onPush(button->userDataOnPush);
611 }
612 } else {
613 button->state = GFUI_BTN_RELEASED;
614 }
615 }
616 }
617 break;
618 }
619 }
620
621 void
gfuiReleaseButton(tGfuiObject * obj)622 gfuiReleaseButton(tGfuiObject *obj)
623 {
624 tGfuiButton *button;
625 tGfuiLabel *label;
626
627 button = &(obj->u.button);
628 label = &(button->label);
629
630 freez(button->userDataOnFocus);
631 free(label->text);
632 free(obj);
633 }
634
635 void
gfuiReleaseGrButton(tGfuiObject * obj)636 gfuiReleaseGrButton(tGfuiObject *obj)
637 {
638 tGfuiGrButton *button;
639
640 button = &(obj->u.grbutton);
641
642 free(button->disabled);
643 free(button->enabled);
644 free(button->focused);
645 free(button->pushed);
646 free(obj);
647 }
648