4 #include "SDL_gfxPrimitives.h"
8 static int pick_font_point(struct smode_t
*smode
);
9 static SDL_Surface
*set_graphics_mode(struct smode_t
*smode
);
10 static enum boxtype_t
get_box_type(struct smode_t
*smode
,
11 struct widget_t
*widget
);
12 static enum boxtype_t
get_inv_box_type(struct smode_t
*smode
,
13 struct widget_t
*widget
);
14 static enum boxtype_t
get_perm_in_box_type(struct smode_t
*smode
,
15 struct widget_t
*widget
);
17 void default_smode(struct smode_t
*smode
) {
21 smode
->fullscreen
= 0;
22 smode
->focus
= 2; /* !!! might not be true in windowed mode, not that the main menu cares */
23 smode
->restrictfocus
= SDL_GRAB_OFF
;
28 void clear_smode(struct smode_t
*smode
) {
29 clear_sel(&smode
->sel
);
31 smode
->active
.widget
= 0;
32 smode
->active
.id
= (size_t)-1;
34 /*smode->button.button = 0;
35 smode->button.xp = -1;
36 smode->button.yp = -1;*/
38 /*smode->lastclick.button = 0;
39 smode->lastclick.xp = -1;
40 smode->lastclick.yp = -1;*/
43 void clear_sel(struct widget_sel_t
*sel
) {
47 sel
->p
.id
= (size_t)-1;
50 SDL_Surface
*init_sdl(struct smode_t
*smode
) {
53 if(SDL_Init(SDL_INIT_VIDEO
/*| SDL_INIT_AUDIO*/) < 0) {
54 fatal_error("Can't init SDL", __FILE__
, __LINE__
);
59 screen
= set_graphics_mode(smode
);
60 if(!screen
) fatal_error("Can't set graphics mode", __FILE__
, __LINE__
);
62 set_caption("Loading");
64 smode
->restrictfocus
= set_focus(smode
->restrictfocus
);
68 if(TTF_Init() < 0) fatal_error("Can't init SDL_ttf", __FILE__
, __LINE__
);
70 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY
,
71 SDL_DEFAULT_REPEAT_INTERVAL
);
76 SDL_GrabMode
set_focus(SDL_GrabMode mode
) {
77 if(SDL_WM_GrabInput(SDL_GRAB_QUERY
) != mode
) {
78 return SDL_WM_GrabInput(mode
);
89 void free_resize_image(struct resize_image_t
*image
) {
90 SDL_FreeSurface(image
->original
);
91 SDL_FreeSurface(image
->image
);
94 void free_fonts(struct font_t
*font
) {
95 if(font
->mono
== font
->sans
) {
96 TTF_CloseFont(font
->mono
);
99 TTF_CloseFont(font
->mono
);
100 TTF_CloseFont(font
->sans
);
104 void free_theme(struct theme_t
*theme
) {
107 for(x
= 0; x
< BOXTYPES
; x
++) {
108 free_resize_image(&theme
->box
[x
].corners
);
111 free_resize_image(&theme
->check
);
114 void load_icon(void) {
115 SDL_Surface
*icon
= SDL_LoadBMP(ICON_FILE
);
118 SDL_WM_SetIcon(icon
, NULL
);
119 SDL_FreeSurface(icon
);
122 print_warning("Can't open icon \"" ICON_FILE
"\"",
127 void load_fonts(struct font_t
*font
) {
128 font
->mono
= TTF_OpenFont(MONOSPACE_FONT
, font
->point
);
129 font
->sans
= TTF_OpenFont(SANS_SERIF_FONT
, font
->point
);
131 if(!font
->mono
&& !font
->sans
) {
132 fatal_error("Can't open either of these fonts: monospace, sans serif",
137 font
->mono
= font
->sans
;
138 print_warning("Can't open monospace font, "
139 "using sans serif font as its replacement", __FILE__
, __LINE__
);
142 font
->sans
= font
->mono
;
143 print_warning("Can't open sans serif font, "
144 "using monospace font as its replacement", __FILE__
, __LINE__
);
147 TTF_SetFontStyle(font
->mono
, TTF_STYLE_NORMAL
);
148 TTF_SetFontStyle(font
->sans
, TTF_STYLE_NORMAL
);
151 void load_theme(struct theme_t
*theme
, const char *path
) {
153 size_t len
= strlen(path
) + GUI_PATH_LEN
;
154 /* gui/path/boxtype/8.3\0 */
155 char *filename
= malloc(len
+ 1 + 8+1 + 8+1+3 + 1);
156 /* !!! use global declaration? */
157 char *btstr
[] = {"out", "out_hov", "out_act", "in", "in_hov", "in_act"};
158 size_t btlen
[] = {3, 7, 7, 2, 6, 6};
160 strcpy(filename
, GUI_PATH
);
161 strcpy(filename
+ GUI_PATH_LEN
, path
);
162 filename
[len
++] = '/';
164 for(x
= 0; x
< BOXTYPES
; x
++) {
165 strcpy(filename
+ len
, btstr
[x
]);
166 filename
[len
+ btlen
[x
]] = '/';
167 strcpy(filename
+ len
+ btlen
[x
] + 1, "corners.png");
169 load_resize_image(&theme
->box
[x
].corners
, filename
);
172 strcpy(filename
+ len
, "check.png");
174 load_resize_image(&theme
->check
, filename
);
179 static int pick_font_point(struct smode_t
*smode
) {
180 int mindim
= (smode
->width
/ 1.2 < smode
->height
? smode
->width
/ 1.2
183 return (int)(mindim
/ 30.0 + 0.5);
186 SDL_Surface
*load_image(const char *filename
) {
187 SDL_Surface
*image
= IMG_Load(filename
);
189 if(!image
) print_warning("Can't open image", __FILE__
, __LINE__
);
194 void load_resize_image(struct resize_image_t
*image
, const char *filename
) {
195 image
->original
= load_image(filename
);
199 SDL_Surface
*resize_screen(struct smode_t
*smode
, SDL_ResizeEvent
*resize
) {
200 smode
->width
= resize
->w
;
201 smode
->height
= resize
->h
;
203 return set_graphics_mode(smode
);
206 int toggle_fullscreen(SDL_Surface
**screen
, struct smode_t
*smode
) {
207 SDL_Surface
*nscreen
;
209 smode
->fullscreen
= !smode
->fullscreen
;
211 if(SDL_WM_ToggleFullScreen(*screen
)) return 0;
213 nscreen
= set_graphics_mode(smode
);
219 smode
->fullscreen
= !smode
->fullscreen
; /* undo toggling above */
220 print_warning("Can't toggle fullscreen", __FILE__
, __LINE__
);
225 void reload_fonts(struct font_t
*font
, struct smode_t
*smode
) {
226 int np
= pick_font_point(smode
);
228 if(font
->point
!= np
) {
229 if(font
->point
>= 0) free_fonts(font
);
236 void set_caption(const char *s
) {
237 char wt
[BUFSIZ
] = TITLE_PREFIX
;
241 SDL_WM_SetCaption(wt
, NULL
);
244 void resize_theme(struct theme_t
*theme
, struct smode_t
*smode
) {
247 theme
->boxw
= smode
->width
/ 30.0 / 2;
248 theme
->boxh
= smode
->height
/ 30.0 / 2;
250 for(x
= 0; x
< BOXTYPES
; x
++) {
251 if(!theme
->box
[x
].corners
.original
) continue;
253 if(theme
->box
[x
].corners
.image
) {
254 SDL_FreeSurface(theme
->box
[x
].corners
.image
);
257 theme
->box
[x
].corners
.image
=
258 zoomSurface(theme
->box
[x
].corners
.original
,
259 smode
->width
/ 30.0 / theme
->box
[x
].corners
.original
->w
,
260 smode
->height
/ 30.0 / theme
->box
[x
].corners
.original
->h
,
264 if(theme
->check
.original
) {
265 if(theme
->check
.image
) {
266 SDL_FreeSurface(theme
->check
.image
);
269 theme
->check
.image
= zoomSurface(theme
->check
.original
,
270 smode
->width
/ 30.0 / theme
->check
.original
->w
,
271 smode
->height
/ 30.0 / theme
->check
.original
->h
,
276 static SDL_Surface
*set_graphics_mode(struct smode_t
*smode
) {
277 Uint32 flags
= SDL_SWSURFACE
| SDL_RESIZABLE
;
278 if(smode
->fullscreen
) flags
|= SDL_FULLSCREEN
;
280 return SDL_SetVideoMode(smode
->width
, smode
->height
, smode
->depth
, flags
);
283 void lock_screen(SDL_Surface
*screen
) {
284 if(SDL_MUSTLOCK(screen
)) {
285 if(SDL_LockSurface(screen
) < 0) {
286 print_warning("Can't lock screen", __FILE__
, __LINE__
);
291 void unlock_screen(SDL_Surface
*screen
) {
292 if(SDL_MUSTLOCK(screen
)) {
293 SDL_UnlockSurface(screen
);
297 void blit_surface(SDL_Surface
*screen
, SDL_Surface
*image
, int xp
, int yp
) {
303 if(SDL_BlitSurface(image
, NULL
, screen
, &rect
) < 0) {
304 print_warning("Can't blit surface", __FILE__
, __LINE__
);
308 void blit_surface_area(SDL_Surface
*screen
, SDL_Surface
*image
,
309 int tx
, int ty
, int fx
, int fy
, int fw
, int fh
) {
320 if(SDL_BlitSurface(image
, &from
, screen
, &to
) < 0) {
321 print_warning("Can't blit surface", __FILE__
, __LINE__
);
325 void blit_surface_repeat(SDL_Surface
*screen
, SDL_Surface
*image
,
326 int xp
, int yp
, int w
, int h
) {
329 SDL_Rect srect
, drect
;
334 for(x
= 0; x
< w
; x
+= image
->w
) {
335 for(y
= 0; y
< h
; y
+= image
->h
) {
339 if(x
+ image
->w
> w
) srect
.w
= w
- x
;
340 else srect
.w
= image
->w
;
341 if(y
+ image
->h
> h
) srect
.h
= h
- y
;
342 else srect
.h
= image
->h
;
344 if(SDL_BlitSurface(image
, &srect
, screen
, &drect
) < 0) {
345 print_warning("Can't blit surface", __FILE__
, __LINE__
);
351 void blit_surface_repeat_area(SDL_Surface
*screen
, SDL_Surface
*image
,
352 int tx
, int ty
, int tw
, int th
, int fx
, int fy
, int fw
, int fh
) {
355 SDL_Rect srect
, drect
;
360 for(x
= 0; x
< tw
; x
+= fw
) {
361 for(y
= 0; y
< th
; y
+= fh
) {
365 if(x
+ fw
> tw
) srect
.w
= tw
- x
;
367 if(y
+ fh
> th
) srect
.h
= th
- y
;
370 if(SDL_BlitSurface(image
, &srect
, screen
, &drect
) < 0) {
371 print_warning("Can't blit surface", __FILE__
, __LINE__
);
377 void blit_surface_fill_from(SDL_Surface
*screen
, SDL_Surface
*image
,
378 int tx
, int ty
, int tw
, int th
, int fx1
, int fy1
) {
381 SDL_Rect srect
, drect
;
383 /*x = image->w - fx1 < tw ? image->w - fx1 : tw;
384 y = image->h - fy1 < th ? image->h - fy1 : th;
385 blit_surface_area(screen, image,
386 tx, ty, fx1, fy1, x, y);*/
388 for(x
= fx1
- image
->w
; x
< tw
; x
+= image
->w
) {
389 for(y
= fy1
- image
->h
; y
< th
; y
+= image
->h
) {
393 srect
.w
= image
->w
- -x
;
399 if(x
+ image
->w
> tw
) srect
.w
= tw
- x
;
400 else srect
.w
= image
->w
;
406 srect
.h
= image
->h
- -y
;
412 if(y
+ image
->h
> th
) srect
.h
= th
- y
;
413 else srect
.h
= image
->h
;
416 if(SDL_BlitSurface(image
, &srect
, screen
, &drect
) < 0) {
417 print_warning("Can't blit surface", __FILE__
, __LINE__
);
423 /*void fill_area(SDL_Surface *screen, int x, int y, int w, int h, Uint32 col) {
431 SDL_FillRect(screen, &r, col);
434 int in_rect(int xp
, int yp
, int x
, int y
, int w
, int h
) {
435 return xp
>= x
&& xp
< x
+ w
&& yp
>= y
&& yp
< y
+ h
;
438 int in_sdl_rect(int xp
, int yp
, SDL_Rect
*r
) {
439 return xp
>= r
->x
&& xp
< r
->x
+ r
->w
&& yp
>= r
->y
&& yp
< r
->y
+ r
->h
;
442 /*int two_in_rect(int x1, int y1, int x2, int y2, int x, int y, int w, int h) {
443 return in_rect(x1, y1, x, y, w, h) && in_rect(x2, y2, x, y, w, h);
446 static enum boxtype_t
get_box_type(struct smode_t
*smode
,
447 struct widget_t
*widget
) {
450 Uint8 button
= SDL_GetMouseState(&xp
, &yp
);
452 if(widget
== smode
->sel
.p
.widget
) {
453 if(in_sdl_rect(xp
, yp
, &widget
->pos
)) {
454 if(smode
->sel
.clickin
) return BOX_IN_ACTIVE
;
456 return BOX_OUT_HOVER
;
459 if(smode
->sel
.clickin
) return BOX_OUT_ACTIVE
;
465 static enum boxtype_t
get_inv_box_type(struct smode_t
*smode
,
466 struct widget_t
*widget
) {
469 Uint8 button
= SDL_GetMouseState(&xp
, &yp
);
471 if(widget
== smode
->sel
.p
.widget
) {
472 if(in_sdl_rect(xp
, yp
, &widget
->pos
)) {
473 if(smode
->sel
.clickin
) return BOX_OUT_ACTIVE
;
478 if(smode
->sel
.clickin
) return BOX_IN_ACTIVE
;
484 static enum boxtype_t
get_perm_in_box_type(struct smode_t
*smode
,
485 struct widget_t
*widget
) {
488 Uint8 button
= SDL_GetMouseState(&xp
, &yp
);
490 if(widget
== smode
->sel
.p
.widget
) {
491 if(smode
->sel
.clickin
) return BOX_IN_ACTIVE
;
493 if(in_sdl_rect(xp
, yp
, &widget
->pos
)) {
498 if(widget
== smode
->active
.widget
) {
499 return BOX_IN_ACTIVE
;
505 int is_box_in(enum boxtype_t bt
) {
506 return bt
== BOX_IN
|| bt
== BOX_IN_HOVER
|| bt
== BOX_IN_ACTIVE
;
509 int is_box_out(enum boxtype_t bt
) {
510 return bt
== BOX_OUT
|| bt
== BOX_OUT_HOVER
|| bt
== BOX_OUT_ACTIVE
;
513 int is_box_normal(enum boxtype_t bt
) {
514 return bt
== BOX_IN
|| bt
== BOX_OUT
;
517 int is_box_hover(enum boxtype_t bt
) {
518 return bt
== BOX_IN_HOVER
|| bt
== BOX_OUT_HOVER
;
521 int is_box_active(enum boxtype_t bt
) {
522 return bt
== BOX_IN_ACTIVE
|| bt
== BOX_OUT_ACTIVE
;
525 enum boxtype_t
paint_box(SDL_Surface
*screen
, struct smode_t
*smode
,
526 struct theme_t
*theme
, SDL_Surface
*text
, SDL_Rect
*b
,
527 enum boxtype_t bt
, int centre
) {
531 /*if(!b->text) return BOX_ERROR;*/
533 cw
= b
->w
- theme
->boxw
* 2;
534 ch
= b
->h
- theme
->boxh
* 2;
536 if(theme
->box
[bt
].corners
.image
) {
537 if(theme
->box
[bt
].corners
.image
->w
% 2) cw
--;
538 if(theme
->box
[bt
].corners
.image
->h
% 2) ch
--;
541 blit_surface_area(screen
, theme
->box
[bt
].corners
.image
, b
->x
, b
->y
,
542 0, 0, theme
->boxw
, theme
->boxh
);
545 blit_surface_area(screen
, theme
->box
[bt
].corners
.image
,
546 b
->x
, b
->y
+ theme
->boxh
+ ch
, 0, theme
->boxh
,
547 theme
->boxw
, theme
->boxh
);
550 blit_surface_area(screen
, theme
->box
[bt
].corners
.image
,
551 b
->x
+ theme
->boxw
+ cw
, b
->y
,
552 theme
->boxw
, 0, theme
->boxw
, theme
->boxh
);
555 blit_surface_area(screen
, theme
->box
[bt
].corners
.image
,
556 b
->x
+ theme
->boxw
+ cw
, b
->y
+ theme
->boxh
+ ch
,
557 theme
->boxw
, theme
->boxh
, theme
->boxw
, theme
->boxh
);
560 blit_surface_repeat_area(screen
, theme
->box
[bt
].corners
.image
,
561 b
->x
+ theme
->boxw
, b
->y
, cw
, theme
->boxh
,
562 theme
->boxw
, 0, 1, theme
->boxh
);
565 blit_surface_repeat_area(screen
, theme
->box
[bt
].corners
.image
,
566 b
->x
+ theme
->boxw
, b
->y
+ theme
->boxh
+ ch
,
567 cw
, theme
->boxh
, theme
->boxw
, theme
->boxh
,
571 blit_surface_repeat_area(screen
, theme
->box
[bt
].corners
.image
,
572 b
->x
, b
->y
+ theme
->boxh
, theme
->boxw
, ch
,
573 0, theme
->boxh
, theme
->boxw
, 1);
576 blit_surface_repeat_area(screen
, theme
->box
[bt
].corners
.image
,
577 b
->x
+ theme
->boxw
+ cw
, b
->y
+ theme
->boxh
,
578 theme
->boxw
, ch
, theme
->boxw
, theme
->boxh
,
582 blit_surface_repeat_area(screen
, theme
->box
[bt
].corners
.image
,
583 b
->x
+ theme
->boxw
, b
->y
+ theme
->boxh
,
585 theme
->boxw
, theme
->boxh
, 1, 1);
588 if(text
->w
<= b
->w
&& text
->h
<= b
->h
) {
591 x
= b
->x
+ theme
->boxw
+ (cw
- text
->w
) / 2;
592 y
= b
->y
+ theme
->boxh
+ (ch
- text
->h
) / 2;
594 if(is_box_in(bt
)) x
++, y
++;
596 blit_surface(screen
, text
, x
, y
);
599 x
= b
->x
+ theme
->boxh
+ (ch
- text
->h
) / 2;
600 y
= b
->y
+ theme
->boxh
+ (ch
- text
->h
) / 2;
602 a
= text
->w
> cw
? text
->w
- cw
: 0;
604 if(is_box_in(bt
)) x
++, y
++;
606 blit_surface_area(screen
, text
, x
, y
, a
, 0, text
->w
- a
,
608 y
= /*TTF_FontHeight(font->sans)*/ 16;
609 vlineRGBA(screen
, x
+ (text
->w
- a
) + 1,
610 b
->y
+ (b
->h
- y
) / 2, b
->y
+ (b
->h
+ y
) / 2,
615 /* !!! shrink text and then blit it? Or maybe:
616 print_warning("Text too small for button", __FILE__, __LINE__); */
620 /*SDL_SaveBMP(theme->box[bt].corners.image, "temp/corners.bmp");*/
624 /*fill_area(screen, xp + theme->box[bt].corners.image->w / 2,
625 yp + theme->box[bt].corners.image->h / 2,
626 theme->box[bt].corners.image->w + text->w,
627 theme->box[bt].corners.image->h + text->h,
628 gp(theme->box[bt].corners.image,
629 theme->box[bt].corners.image->w / 2,
630 theme->box[bt].corners.image->h / 2));*/
635 void init_button(struct widget_t
*widget
, TTF_Font
*font
, const char *text
,
636 int x
, int y
, int w
, int h
) {
638 static const SDL_Color white
= {255, 255, 255, 0};
640 widget
->type
= WIDGET_BUTTON
;
641 widget
->p
.button
= malloc(sizeof(*widget
->p
.button
));
642 widget
->p
.button
->text
= TTF_RenderText_Blended(font
, text
, white
);
649 void init_checkbox(struct widget_t
*widget
, TTF_Font
*font
, const char *text
,
650 struct theme_t
*theme
, int checked
, int x
, int y
, int w
, int h
, int bw
) {
652 static const SDL_Color white
= {255, 255, 255, 0};
654 widget
->type
= WIDGET_CHECKBOX
;
655 widget
->p
.checkbox
= malloc(sizeof(*widget
->p
.checkbox
));
656 widget
->p
.checkbox
->text
= TTF_RenderText_Blended(font
, text
, white
);
657 widget
->p
.checkbox
->checked
= checked
;
658 widget
->p
.checkbox
->bw
= bw
;
665 void init_textbox(struct widget_t
*widget
, TTF_Font
*font
, const char *data
,
666 size_t len
, struct theme_t
*theme
, int x
, int y
, int w
, int h
) {
668 static const SDL_Color white
= {255, 255, 255, 0};
670 widget
->type
= WIDGET_TEXTBOX
;
671 widget
->p
.textbox
= malloc(sizeof(*widget
->p
.textbox
));
672 widget
->p
.textbox
->data
= duplicate_string(data
, len
);
673 widget
->p
.textbox
->len
= len
;
674 widget
->p
.textbox
->text
= TTF_RenderText_Blended(font
, data
, white
);
675 widget
->p
.textbox
->ra
= 0;
682 size_t in_widget_array(int xp
, int yp
, struct widget_t
*widget
, size_t n
) {
685 for(x
= 0; x
< n
; x
++) {
686 if(in_sdl_rect(xp
, yp
, &widget
[x
].pos
)) {
694 int set_widget_sel(struct widget_sel_t
*sel
, int xp
, int yp
, int click
,
695 size_t offset
, struct widget_t
*widget
, size_t n
) {
701 r
= in_sdl_rect(xp
, yp
, &sel
->p
.widget
->pos
);
703 if(sel
->wasin
!= r
) {
709 if(sel
->clickin
!= click
) {
710 sel
->clickin
= click
;
715 if(v
&& !sel
->clickin
&& !sel
->wasin
) clear_sel(sel
);
718 x
= in_widget_array(xp
, yp
, widget
, n
);
720 if(x
!= (size_t)-1) {
722 sel
->clickin
= click
;
723 sel
->p
.widget
= widget
+ x
;
724 sel
->p
.id
= x
+ offset
;
732 /*if(sel->wasin && x != (size_t)-1 && x + offset == sel->id) return 0;
733 if(!sel->wasin && x == (size_t)-1) return 0;*/
735 /*if(state == STATE_NORMAL_NORMAL || state == STATE_CLICK_NORMAL
736 || state == STATE_ACTIVE_NORMAL)) {
738 if(x != (size_t)-1) return 0;
741 if(x == (size_t)-1) return 0;
745 sel->widget = widget + x;
746 sel->id = x + offset;
751 enum boxtype_t
paint_widget(SDL_Surface
*screen
, struct smode_t
*smode
,
752 struct theme_t
*theme
, struct widget_t
*widget
) {
754 enum boxtype_t bt
= BOX_ERROR
, t
;
757 switch(widget
->type
) {
759 t
= get_box_type(smode
, widget
);
760 bt
= paint_box(screen
, smode
, theme
,
761 widget
->p
.button
->text
, &widget
->pos
, t
, 1);
763 case WIDGET_CHECKBOX
:
765 r
.w
= widget
->p
.checkbox
->bw
;
767 if(!widget
->p
.checkbox
->checked
) {
768 t
= get_box_type(smode
, widget
);
769 bt
= paint_box(screen
, smode
, theme
,
770 t
== BOX_IN_ACTIVE
? theme
->check
.image
: 0, &r
, t
, 1);
773 t
= get_inv_box_type(smode
, widget
);
774 bt
= paint_box(screen
, smode
, theme
,
775 t
!= BOX_OUT_ACTIVE
? theme
->check
.image
: 0, &r
, t
, 1);
778 blit_surface(screen
, widget
->p
.checkbox
->text
, r
.x
+ r
.w
* 1.3,
779 r
.y
+ (r
.h
- widget
->p
.checkbox
->text
->h
) / 2);
782 t
= get_perm_in_box_type(smode
, widget
);
783 bt
= paint_box(screen
, smode
, theme
,
784 widget
->p
.textbox
->text
, &widget
->pos
, t
, 0);
793 void perform_widget_click(struct widget_t
*widget
) {
794 switch(widget
->type
) {
795 case WIDGET_CHECKBOX
:
796 widget
->p
.checkbox
->checked
= !widget
->p
.checkbox
->checked
;
803 int render_restricted_text(SDL_Surface
**text
, const char *data
,
804 TTF_Font
*font
, int w
) {
806 static const SDL_Color white
= {255, 255, 255, 0};
807 const char *p
= data
;
813 TTF_SizeText(font
, p
++, &tw
, NULL
);
814 } while(tw
> w
&& *p
);
818 *text
= TTF_RenderText_Blended(font
, p
- 1, white
);
824 *text
= TTF_RenderText_Blended(font
, p
, white
);
829 int widget_process_character(struct widget_t
*widget
, SDL_keysym
*sym
,
830 struct font_t
*font
, struct theme_t
*theme
) {
832 /*if(sym->mod & KMOD_SHIFT) {
833 if(isalpha(c)) c = toupper(c);
835 if((p = strchr(from, c))) {
841 if(!(sym
->unicode
>> 7)) {
842 if(isprint(sym
->unicode
)) {
843 switch(widget
->type
) {
845 widget
->p
.textbox
->data
= realloc(widget
->p
.textbox
->data
,
846 widget
->p
.textbox
->len
+ 2);
847 widget
->p
.textbox
->data
[widget
->p
.textbox
->len
]
849 widget
->p
.textbox
->data
[++widget
->p
.textbox
->len
] = 0;
850 widget
->p
.textbox
->ra
= render_restricted_text(
851 &widget
->p
.textbox
->text
, widget
->p
.textbox
->data
,
852 font
->sans
, widget
->pos
.w
- theme
->boxw
* 2);
860 else if(sym
->unicode
== '\b') {
861 switch(widget
->type
) {
863 if(widget
->p
.textbox
->len
) {
864 widget
->p
.textbox
->data
= realloc(widget
->p
.textbox
->data
,
865 widget
->p
.textbox
->len
+ 1);
866 widget
->p
.textbox
->data
[--widget
->p
.textbox
->len
] = 0;
867 widget
->p
.textbox
->ra
= render_restricted_text(
868 &widget
->p
.textbox
->text
, widget
->p
.textbox
->data
,
869 font
->sans
, widget
->pos
.w
- theme
->boxw
* 2);
885 int widget_can_be_active(enum widget_type_t wt
) {
886 return wt
== WIDGET_TEXTBOX
;
889 void enable_unicode(enum widget_type_t wt
) {
892 if(wt
== WIDGET_TEXTBOX
) {
896 if(SDL_EnableUNICODE(-1) != v
) SDL_EnableUNICODE(v
);
899 void paint_widget_array(SDL_Surface
*screen
, struct smode_t
*smode
,
900 struct theme_t
*theme
, struct widget_t
*widget
, size_t n
) {
904 for(x
= 0; x
< n
; x
++) {
905 paint_widget(screen
, smode
, theme
, widget
+ x
);
909 void free_widget_array(struct widget_t
*widget
, size_t n
) {
912 for(x
= 0; x
< n
; x
++) {
913 switch(widget
[x
].type
) {
915 SDL_FreeSurface(widget
[x
].p
.button
->text
);
917 case WIDGET_CHECKBOX
:
918 SDL_FreeSurface(widget
[x
].p
.checkbox
->text
);
921 free(widget
[x
].p
.textbox
->data
);
922 SDL_FreeSurface(widget
[x
].p
.textbox
->text
);
927 free(widget
[x
].p
.all
);