1 /***********************************************************************
2 Freeciv - Copyright (C) 2006 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
15 #include <fc_config.h>
19 #ifdef SDL2_PLAIN_INCLUDE
21 #else /* SDL2_PLAIN_INCLUDE */
23 #endif /* SDL2_PLAIN_INCLUDE */
32 #include "themespec.h"
37 static int (*baseclass_redraw
)(struct widget
*pwidget
);
39 /**************************************************************************
40 Blit themelabel2 gfx to surface its on.
41 **************************************************************************/
42 static inline int redraw_themelabel2(struct widget
*pLabel
)
44 SDL_Rect src
= {0,0, pLabel
->size
.w
, pLabel
->size
.h
};
45 SDL_Rect dst
= {pLabel
->size
.x
, pLabel
->size
.y
, 0, 0};
51 if (get_wstate(pLabel
) == FC_WS_SELECTED
) {
52 src
.y
= pLabel
->size
.h
;
55 return alphablit(pLabel
->theme
, &src
, pLabel
->dst
->surface
, &dst
, 255);
58 /**************************************************************************
59 Blit label gfx to surface its on.
60 **************************************************************************/
61 static int redraw_label(struct widget
*pLabel
)
64 SDL_Rect area
= pLabel
->size
;
65 SDL_Color bar_color
= *get_theme_color(COLOR_THEME_LABEL_BAR
);
66 SDL_Color backup_color
= {0, 0, 0, 0};
68 ret
= (*baseclass_redraw
)(pLabel
);
73 if (get_wtype(pLabel
) == WT_T2_LABEL
) {
74 return redraw_themelabel2(pLabel
);
77 /* redraw selected bar */
78 if (get_wstate(pLabel
) == FC_WS_SELECTED
) {
79 if (get_wflags(pLabel
) & WF_SELECT_WITHOUT_BAR
) {
80 if (pLabel
->string_utf8
!= NULL
) {
81 backup_color
= pLabel
->string_utf8
->fgcol
;
82 pLabel
->string_utf8
->fgcol
= bar_color
;
83 if (pLabel
->string_utf8
->style
& TTF_STYLE_BOLD
) {
84 pLabel
->string_utf8
->style
|= TTF_STYLE_UNDERLINE
;
86 pLabel
->string_utf8
->style
|= TTF_STYLE_BOLD
;
90 fill_rect_alpha(pLabel
->dst
->surface
, &area
, &bar_color
);
94 /* redraw icon label */
95 ret
= redraw_iconlabel(pLabel
);
97 if ((get_wstate(pLabel
) == FC_WS_SELECTED
) && (pLabel
->string_utf8
!= NULL
)) {
98 if (get_wflags(pLabel
) & WF_SELECT_WITHOUT_BAR
) {
99 if (pLabel
->string_utf8
->style
& TTF_STYLE_UNDERLINE
) {
100 pLabel
->string_utf8
->style
&= ~TTF_STYLE_UNDERLINE
;
102 pLabel
->string_utf8
->style
&= ~TTF_STYLE_BOLD
;
104 pLabel
->string_utf8
->fgcol
= backup_color
;
106 if (pLabel
->string_utf8
->render
== 3) {
107 pLabel
->string_utf8
->bgcol
= backup_color
;
115 /**************************************************************************
116 Calculate new size for a label.
117 **************************************************************************/
118 void remake_label_size(struct widget
*pLabel
)
120 SDL_Surface
*pIcon
= pLabel
->theme
;
121 utf8_str
*text
= pLabel
->string_utf8
;
122 Uint32 flags
= get_wflags(pLabel
);
123 SDL_Rect buf
= { 0, 0, 0, 0 };
124 Uint16 w
= 0, h
= 0, space
;
126 if (flags
& WF_DRAW_TEXT_LABEL_WITH_SPACE
) {
127 space
= adj_size(10);
133 bool without_box
= ((get_wflags(pLabel
) & WF_SELECT_WITHOUT_BAR
) == WF_SELECT_WITHOUT_BAR
);
137 bold
= ((text
->style
& TTF_STYLE_BOLD
) == TTF_STYLE_BOLD
);
138 text
->style
|= TTF_STYLE_BOLD
;
141 utf8_str_size(text
, &buf
);
143 if (without_box
&& !bold
) {
144 text
->style
&= ~TTF_STYLE_BOLD
;
147 w
= MAX(w
, buf
.w
+ space
);
153 if ((flags
& WF_ICON_UNDER_TEXT
) || (flags
& WF_ICON_ABOVE_TEXT
)) {
154 w
= MAX(w
, pIcon
->w
+ space
);
155 h
= MAX(h
, buf
.h
+ pIcon
->h
+ adj_size(3));
157 if (flags
& WF_ICON_CENTER
) {
158 w
= MAX(w
, pIcon
->w
+ space
);
159 h
= MAX(h
, pIcon
->h
);
161 w
= MAX(w
, buf
.w
+ pIcon
->w
+ adj_size(5) + space
);
162 h
= MAX(h
, pIcon
->h
);
167 w
= MAX(w
, pIcon
->w
+ space
);
168 h
= MAX(h
, pIcon
->h
);
177 /**************************************************************************
178 ThemeLabel is utf8_str with Background ( pIcon ).
179 **************************************************************************/
180 struct widget
*create_themelabel(SDL_Surface
*pIcon
, struct gui_layer
*pDest
,
181 utf8_str
*pstr
, Uint16 w
, Uint16 h
,
184 struct widget
*pLabel
= NULL
;
186 if (pIcon
== NULL
&& pstr
== NULL
) {
190 pLabel
= widget_new();
191 pLabel
->theme
= pIcon
;
192 pLabel
->string_utf8
= pstr
;
194 (WF_ICON_CENTER
| WF_FREE_STRING
| WF_FREE_GFX
|
195 WF_RESTORE_BACKGROUND
| flags
));
196 set_wstate(pLabel
, FC_WS_DISABLED
);
197 set_wtype(pLabel
, WT_T_LABEL
);
198 pLabel
->mod
= KMOD_NONE
;
201 baseclass_redraw
= pLabel
->redraw
;
202 pLabel
->redraw
= redraw_label
;
204 remake_label_size(pLabel
);
206 pLabel
->size
.w
= MAX(pLabel
->size
.w
, w
);
207 pLabel
->size
.h
= MAX(pLabel
->size
.h
, h
);
212 /**************************************************************************
213 This Label is UTF8 string with Icon.
214 **************************************************************************/
215 struct widget
*create_iconlabel(SDL_Surface
*pIcon
, struct gui_layer
*pDest
,
216 utf8_str
*pstr
, Uint32 flags
)
218 struct widget
*pILabel
= NULL
;
220 pILabel
= widget_new();
222 pILabel
->theme
= pIcon
;
223 pILabel
->string_utf8
= pstr
;
224 set_wflag(pILabel
, WF_FREE_STRING
| WF_FREE_GFX
| flags
);
225 set_wstate(pILabel
, FC_WS_DISABLED
);
226 set_wtype(pILabel
, WT_I_LABEL
);
227 pILabel
->mod
= KMOD_NONE
;
228 pILabel
->dst
= pDest
;
230 baseclass_redraw
= pILabel
->redraw
;
231 pILabel
->redraw
= redraw_label
;
233 remake_label_size(pILabel
);
238 /**************************************************************************
239 ThemeLabel is UTF8 string with Background ( pIcon ).
240 **************************************************************************/
241 struct widget
*create_themelabel2(SDL_Surface
*pIcon
, struct gui_layer
*pDest
,
242 utf8_str
*pstr
, Uint16 w
, Uint16 h
,
245 struct widget
*pLabel
= NULL
;
246 SDL_Surface
*ptheme
= NULL
;
248 SDL_Color store
= {0, 0, 0, 0};
249 SDL_Color bg_color
= *get_theme_color(COLOR_THEME_THEMELABEL2_BG
);
252 if (pIcon
== NULL
&& pstr
== NULL
) {
256 pLabel
= widget_new();
257 pLabel
->theme
= pIcon
;
258 pLabel
->string_utf8
= pstr
;
259 set_wflag(pLabel
, (WF_FREE_THEME
| WF_FREE_STRING
| WF_FREE_GFX
| flags
));
260 set_wstate(pLabel
, FC_WS_DISABLED
);
261 set_wtype(pLabel
, WT_T2_LABEL
);
262 pLabel
->mod
= KMOD_NONE
;
263 baseclass_redraw
= pLabel
->redraw
;
264 pLabel
->redraw
= redraw_label
;
266 remake_label_size(pLabel
);
268 pLabel
->size
.w
= MAX(pLabel
->size
.w
, w
);
269 pLabel
->size
.h
= MAX(pLabel
->size
.h
, h
);
271 ptheme
= create_surf(pLabel
->size
.w
, pLabel
->size
.h
* 2, SDL_SWSURFACE
);
273 colorkey
= SDL_MapRGBA(ptheme
->format
, pstr
->bgcol
.r
,
274 pstr
->bgcol
.g
, pstr
->bgcol
.b
, pstr
->bgcol
.a
);
275 SDL_FillRect(ptheme
, NULL
, colorkey
);
280 pLabel
->dst
= gui_layer_new(0, 0, ptheme
);
283 redraw_iconlabel(pLabel
);
287 area
.y
= pLabel
->size
.h
;
289 if (flags
& WF_RESTORE_BACKGROUND
) {
290 SDL_FillRect(ptheme
, &area
, map_rgba(ptheme
->format
, bg_color
));
292 SDL_GetRGBA(getpixel(ptheme
, area
.x
, area
.y
), ptheme
->format
,
293 &pstr
->bgcol
.r
, &pstr
->bgcol
.g
,
294 &pstr
->bgcol
.b
, &pstr
->bgcol
.a
);
296 fill_rect_alpha(ptheme
, &area
, &bg_color
);
299 pLabel
->size
.y
= pLabel
->size
.h
;
300 redraw_iconlabel(pLabel
);
302 if (flags
& WF_RESTORE_BACKGROUND
) {
308 if (flags
& WF_FREE_THEME
) {
309 FREESURFACE(pLabel
->theme
);
311 pLabel
->theme
= ptheme
;
312 FC_FREE(pLabel
->dst
);
318 /**************************************************************************
319 Make themeiconlabel2 widget out of iconlabel widget.
320 **************************************************************************/
321 struct widget
*convert_iconlabel_to_themeiconlabel2(struct widget
*pIconLabel
)
323 SDL_Rect start
, area
;
324 SDL_Color store
= {0, 0, 0, 0};
325 SDL_Color bg_color
= *get_theme_color(COLOR_THEME_THEMELABEL2_BG
);
326 Uint32 colorkey
, flags
= get_wflags(pIconLabel
);
328 SDL_Surface
*ptheme
= create_surf(pIconLabel
->size
.w
,
329 pIconLabel
->size
.h
* 2, SDL_SWSURFACE
);
331 colorkey
= SDL_MapRGBA(ptheme
->format
,
332 pIconLabel
->string_utf8
->bgcol
.r
,
333 pIconLabel
->string_utf8
->bgcol
.g
,
334 pIconLabel
->string_utf8
->bgcol
.b
,
335 pIconLabel
->string_utf8
->bgcol
.a
);
336 SDL_FillRect(ptheme
, NULL
, colorkey
);
338 start
= pIconLabel
->size
;
339 pIconLabel
->size
.x
= 0;
340 pIconLabel
->size
.y
= 0;
342 pDest
= pIconLabel
->dst
->surface
;
343 pIconLabel
->dst
->surface
= ptheme
;
346 redraw_iconlabel(pIconLabel
);
350 area
.y
= pIconLabel
->size
.h
;
352 if (flags
& WF_RESTORE_BACKGROUND
) {
353 SDL_FillRect(ptheme
, &area
, map_rgba(ptheme
->format
, bg_color
));
354 store
= pIconLabel
->string_utf8
->bgcol
;
355 SDL_GetRGBA(getpixel(ptheme
, area
.x
, area
.y
), ptheme
->format
,
356 &pIconLabel
->string_utf8
->bgcol
.r
,
357 &pIconLabel
->string_utf8
->bgcol
.g
,
358 &pIconLabel
->string_utf8
->bgcol
.b
,
359 &pIconLabel
->string_utf8
->bgcol
.a
);
361 fill_rect_alpha(ptheme
, &area
, &bg_color
);
364 pIconLabel
->size
.y
= pIconLabel
->size
.h
;
365 redraw_iconlabel(pIconLabel
);
367 if (flags
& WF_RESTORE_BACKGROUND
) {
368 pIconLabel
->string_utf8
->bgcol
= store
;
371 pIconLabel
->size
= start
;
372 if (flags
& WF_FREE_THEME
) {
373 FREESURFACE(pIconLabel
->theme
);
375 pIconLabel
->theme
= ptheme
;
376 if (flags
& WF_FREE_STRING
) {
377 FREEUTF8STR(pIconLabel
->string_utf8
);
379 pIconLabel
->dst
->surface
= pDest
;
380 set_wtype(pIconLabel
, WT_T2_LABEL
);
382 pIconLabel
->redraw
= redraw_label
;
388 /**************************************************************************
389 Blit themelabel gfx to surface its on.
390 **************************************************************************/
391 static int redraw_themelabel(struct widget
*pLabel
)
395 SDL_Surface
*pText
= NULL
;
401 if ((pText
= create_text_surf_from_utf8(pLabel
->string_utf8
)) == NULL
) {
405 if (pLabel
->string_utf8
->style
& SF_CENTER
) {
406 x
= (pLabel
->size
.w
- pText
->w
) / 2;
408 if (pLabel
->string_utf8
->style
& SF_CENTER_RIGHT
) {
409 x
= pLabel
->size
.w
- pText
->w
- adj_size(5);
415 y
= (pLabel
->size
.h
- pText
->h
) / 2;
419 ret
= blit_entire_src(pLabel
->theme
, pLabel
->dst
->surface
, pLabel
->size
.x
, pLabel
->size
.y
);
425 ret
= blit_entire_src(pText
, pLabel
->dst
->surface
, pLabel
->size
.x
+ x
, pLabel
->size
.y
+ y
);
433 /**************************************************************************
434 Blit iconlabel gfx to surface its on.
435 **************************************************************************/
436 int redraw_iconlabel(struct widget
*pLabel
)
438 int space
, ret
= 0; /* FIXME: possibly uninitialized */
440 Sint16 y
= 0; /* FIXME: possibly uninitialized */
449 SDL_SetClipRect(pLabel
->dst
->surface
, &pLabel
->size
);
451 flags
= get_wflags(pLabel
);
453 if (flags
& WF_DRAW_TEXT_LABEL_WITH_SPACE
) {
459 pText
= create_text_surf_from_utf8(pLabel
->string_utf8
);
461 if (pLabel
->theme
) { /* Icon */
463 if (flags
& WF_ICON_CENTER_RIGHT
) {
464 xI
= pLabel
->size
.w
- pLabel
->theme
->w
- space
;
466 if (flags
& WF_ICON_CENTER
) {
467 xI
= (pLabel
->size
.w
- pLabel
->theme
->w
) / 2;
473 if (flags
& WF_ICON_ABOVE_TEXT
) {
475 y
= pLabel
->theme
->h
+ adj_size(3)
476 + (pLabel
->size
.h
- (pLabel
->theme
->h
+ adj_size(3)) - pText
->h
) / 2;
478 if (flags
& WF_ICON_UNDER_TEXT
) {
479 y
= (pLabel
->size
.h
- (pLabel
->theme
->h
+ adj_size(3)) - pText
->h
) / 2;
480 yI
= y
+ pText
->h
+ adj_size(3);
482 yI
= (pLabel
->size
.h
- pLabel
->theme
->h
) / 2;
483 y
= (pLabel
->size
.h
- pText
->h
) / 2;
489 yI
= (pLabel
->size
.h
- pLabel
->theme
->h
) / 2;
490 xI
= (pLabel
->size
.w
- pLabel
->theme
->w
) / 2;
496 dst
.x
= pLabel
->size
.x
+ xI
;
497 dst
.y
= pLabel
->size
.y
+ yI
;
499 ret
= alphablit(pLabel
->theme
, NULL
, pLabel
->dst
->surface
, &dst
, 255);
507 if (pLabel
->theme
) { /* Icon */
508 if (!(flags
& WF_ICON_ABOVE_TEXT
) && !(flags
& WF_ICON_UNDER_TEXT
)) {
509 if (flags
& WF_ICON_CENTER_RIGHT
) {
510 if (pLabel
->string_utf8
->style
& SF_CENTER
) {
511 x
= (pLabel
->size
.w
- (pLabel
->theme
->w
+ 5 + space
) -
514 if (pLabel
->string_utf8
->style
& SF_CENTER_RIGHT
) {
515 x
= pLabel
->size
.w
- (pLabel
->theme
->w
+ 5 + space
) - pText
->w
;
520 /* WF_ICON_CENTER_RIGHT */
522 if (flags
& WF_ICON_CENTER
) {
523 /* text is blit on icon */
525 } else { /* WF_ICON_CENTER_LEFT */
526 if (pLabel
->string_utf8
->style
& SF_CENTER
) {
527 x
= space
+ pLabel
->theme
->w
+ adj_size(5) + ((pLabel
->size
.w
-
529 pLabel
->theme
->w
+ adj_size(5)) -
532 if (pLabel
->string_utf8
->style
& SF_CENTER_RIGHT
) {
533 x
= pLabel
->size
.w
- pText
->w
- space
;
535 x
= space
+ pLabel
->theme
->w
+ adj_size(5);
538 } /* WF_ICON_CENTER_LEFT */
540 /* !WF_ICON_ABOVE_TEXT && !WF_ICON_UNDER_TEXT */
544 /* pLabel->theme == Icon */
546 y
= (pLabel
->size
.h
- pText
->h
) / 2;
548 if (pLabel
->string_utf8
->style
& SF_CENTER
) {
549 x
= (pLabel
->size
.w
- pText
->w
) / 2;
551 if (pLabel
->string_utf8
->style
& SF_CENTER_RIGHT
) {
552 x
= pLabel
->size
.w
- pText
->w
- space
;
559 dst
.x
= pLabel
->size
.x
+ x
;
560 dst
.y
= pLabel
->size
.y
+ y
;
562 ret
= alphablit(pText
, NULL
, pLabel
->dst
->surface
, &dst
, 255);
566 SDL_SetClipRect(pLabel
->dst
->surface
, NULL
);
571 /**************************************************************************
572 Draw the label widget.
573 **************************************************************************/
574 int draw_label(struct widget
*pLabel
, Sint16 start_x
, Sint16 start_y
)
576 pLabel
->size
.x
= start_x
;
577 pLabel
->size
.y
= start_y
;
579 return redraw_label(pLabel
);