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>
28 #include "themespec.h"
33 static int (*baseclass_redraw
)(struct widget
*pwidget
);
35 /**************************************************************************
37 **************************************************************************/
38 static inline int redraw_themelabel2(struct widget
*pLabel
)
41 SDL_Rect src
= {0,0, pLabel
->size
.w
, pLabel
->size
.h
};
42 SDL_Rect dst
= {pLabel
->size
.x
, pLabel
->size
.y
, 0, 0};
48 if(get_wstate(pLabel
) == FC_WS_SELLECTED
) {
49 src
.y
= pLabel
->size
.h
;
52 return alphablit(pLabel
->theme
, &src
, pLabel
->dst
->surface
, &dst
);
55 /**************************************************************************
57 **************************************************************************/
58 static int redraw_label(struct widget
*pLabel
)
61 SDL_Rect area
= pLabel
->size
;
62 SDL_Color bar_color
= *get_theme_color(COLOR_THEME_LABEL_BAR
);
63 SDL_Color backup_color
= {0, 0, 0, 0};
65 ret
= (*baseclass_redraw
)(pLabel
);
70 if(get_wtype(pLabel
) == WT_T2_LABEL
) {
71 return redraw_themelabel2(pLabel
);
74 /* redraw sellect bar */
75 if (get_wstate(pLabel
) == FC_WS_SELLECTED
) {
76 if(get_wflags(pLabel
) & WF_SELLECT_WITHOUT_BAR
) {
77 if (pLabel
->string16
) {
78 backup_color
= pLabel
->string16
->fgcol
;
79 pLabel
->string16
->fgcol
= bar_color
;
80 if(pLabel
->string16
->style
& TTF_STYLE_BOLD
) {
81 pLabel
->string16
->style
|= TTF_STYLE_UNDERLINE
;
83 pLabel
->string16
->style
|= TTF_STYLE_BOLD
;
87 SDL_FillRectAlpha(pLabel
->dst
->surface
, &area
, &bar_color
);
91 /* redraw icon label */
92 ret
= redraw_iconlabel(pLabel
);
94 if ((get_wstate(pLabel
) == FC_WS_SELLECTED
) && (pLabel
->string16
)) {
95 if(get_wflags(pLabel
) & WF_SELLECT_WITHOUT_BAR
) {
96 if (pLabel
->string16
->style
& TTF_STYLE_UNDERLINE
) {
97 pLabel
->string16
->style
&= ~TTF_STYLE_UNDERLINE
;
99 pLabel
->string16
->style
&= ~TTF_STYLE_BOLD
;
101 pLabel
->string16
->fgcol
= backup_color
;
103 if(pLabel
->string16
->render
== 3) {
104 pLabel
->string16
->bgcol
= backup_color
;
112 /**************************************************************************
114 **************************************************************************/
115 void remake_label_size(struct widget
*pLabel
)
117 SDL_Surface
*pIcon
= pLabel
->theme
;
118 SDL_String16
*pText
= pLabel
->string16
;
119 Uint32 flags
= get_wflags(pLabel
);
120 SDL_Rect buf
= { 0, 0, 0, 0 };
121 Uint16 w
= 0, h
= 0, space
;
123 if (flags
& WF_DRAW_TEXT_LABEL_WITH_SPACE
) {
124 space
= adj_size(10);
130 bool without_box
= ((get_wflags(pLabel
) & WF_SELLECT_WITHOUT_BAR
) == WF_SELLECT_WITHOUT_BAR
);
135 bold
= ((pText
->style
& TTF_STYLE_BOLD
) == TTF_STYLE_BOLD
);
136 pText
->style
|= TTF_STYLE_BOLD
;
139 buf
= str16size(pText
);
141 if (without_box
&& !bold
)
143 pText
->style
&= ~TTF_STYLE_BOLD
;
146 w
= MAX(w
, buf
.w
+ space
);
152 if ((flags
& WF_ICON_UNDER_TEXT
) || (flags
& WF_ICON_ABOVE_TEXT
)) {
153 w
= MAX(w
, pIcon
->w
+ space
);
154 h
= MAX(h
, buf
.h
+ pIcon
->h
+ adj_size(3));
156 if (flags
& WF_ICON_CENTER
) {
157 w
= MAX(w
, pIcon
->w
+ space
);
158 h
= MAX(h
, pIcon
->h
);
160 w
= MAX(w
, buf
.w
+ pIcon
->w
+ adj_size(5) + space
);
161 h
= MAX(h
, pIcon
->h
);
166 w
= MAX(w
, pIcon
->w
+ space
);
167 h
= MAX(h
, pIcon
->h
);
176 /**************************************************************************
177 ThemeLabel is String16 with Background ( pIcon ).
178 **************************************************************************/
179 struct widget
* create_themelabel(SDL_Surface
*pIcon
, struct gui_layer
*pDest
,
180 SDL_String16
*pText
, Uint16 w
, Uint16 h
, Uint32 flags
)
182 struct widget
*pLabel
= NULL
;
184 if (!pIcon
&& !pText
) {
188 pLabel
= widget_new();
189 pLabel
->theme
= pIcon
;
190 pLabel
->string16
= pText
;
192 (WF_ICON_CENTER
| WF_FREE_STRING
| WF_FREE_GFX
|
193 WF_RESTORE_BACKGROUND
| flags
));
194 set_wstate(pLabel
, FC_WS_DISABLED
);
195 set_wtype(pLabel
, WT_T_LABEL
);
196 pLabel
->mod
= KMOD_NONE
;
199 baseclass_redraw
= pLabel
->redraw
;
200 pLabel
->redraw
= redraw_label
;
202 remake_label_size(pLabel
);
204 pLabel
->size
.w
= MAX(pLabel
->size
.w
, w
);
205 pLabel
->size
.h
= MAX(pLabel
->size
.h
, h
);
210 /**************************************************************************
211 this Label is String16 with Icon.
212 **************************************************************************/
213 struct widget
* create_iconlabel(SDL_Surface
*pIcon
, struct gui_layer
*pDest
,
214 SDL_String16
*pText
, Uint32 flags
)
216 struct widget
*pILabel
= NULL
;
218 pILabel
= widget_new();
220 pILabel
->theme
= pIcon
;
221 pILabel
->string16
= pText
;
222 set_wflag(pILabel
, WF_FREE_STRING
| WF_FREE_GFX
| flags
);
223 set_wstate(pILabel
, FC_WS_DISABLED
);
224 set_wtype(pILabel
, WT_I_LABEL
);
225 pILabel
->mod
= KMOD_NONE
;
226 pILabel
->dst
= pDest
;
228 baseclass_redraw
= pILabel
->redraw
;
229 pILabel
->redraw
= redraw_label
;
231 remake_label_size(pILabel
);
236 /**************************************************************************
237 ThemeLabel is String16 with Background ( pIcon ).
238 **************************************************************************/
239 struct widget
* create_themelabel2(SDL_Surface
*pIcon
, struct gui_layer
*pDest
,
240 SDL_String16
*pText
, Uint16 w
, Uint16 h
, Uint32 flags
)
242 struct widget
*pLabel
= NULL
;
243 SDL_Surface
*pBuf
= NULL
, *pTheme
= NULL
;
245 SDL_Color store
= {0, 0, 0, 0};
246 SDL_Color bg_color
= *get_theme_color(COLOR_THEME_THEMELABEL2_BG
);
249 if (!pIcon
&& !pText
) {
253 pLabel
= widget_new();
254 pLabel
->theme
= pIcon
;
255 pLabel
->string16
= pText
;
256 set_wflag(pLabel
, (WF_FREE_THEME
| WF_FREE_STRING
| WF_FREE_GFX
| flags
));
257 set_wstate(pLabel
, FC_WS_DISABLED
);
258 set_wtype(pLabel
, WT_T2_LABEL
);
259 pLabel
->mod
= KMOD_NONE
;
260 baseclass_redraw
= pLabel
->redraw
;
261 pLabel
->redraw
= redraw_label
;
263 remake_label_size(pLabel
);
265 pLabel
->size
.w
= MAX(pLabel
->size
.w
, w
);
266 pLabel
->size
.h
= MAX(pLabel
->size
.h
, h
);
268 pBuf
= create_surf_alpha(pLabel
->size
.w
, pLabel
->size
.h
* 2, SDL_SWSURFACE
);
270 if(flags
& WF_RESTORE_BACKGROUND
) {
271 pTheme
= SDL_DisplayFormatAlpha(pBuf
);
277 colorkey
= SDL_MapRGBA(pTheme
->format
, pText
->bgcol
.r
,
278 pText
->bgcol
.g
, pText
->bgcol
.b
, pText
->bgcol
.unused
);
279 SDL_FillRect(pTheme
, NULL
, colorkey
);
284 pLabel
->dst
= gui_layer_new(0, 0, pTheme
);
287 redraw_iconlabel(pLabel
);
291 area
.y
= pLabel
->size
.h
;
293 if(flags
& WF_RESTORE_BACKGROUND
) {
294 SDL_FillRect(pTheme
, &area
, map_rgba(pTheme
->format
, bg_color
));
295 store
= pText
->bgcol
;
296 SDL_GetRGBA(getpixel(pTheme
, area
.x
, area
.y
), pTheme
->format
,
297 &pText
->bgcol
.r
, &pText
->bgcol
.g
,
298 &pText
->bgcol
.b
, &pText
->bgcol
.unused
);
300 SDL_FillRectAlpha(pTheme
, &area
, &bg_color
);
303 pLabel
->size
.y
= pLabel
->size
.h
;
304 redraw_iconlabel(pLabel
);
306 if(flags
& WF_RESTORE_BACKGROUND
) {
307 pText
->bgcol
= store
;
312 if(flags
& WF_FREE_THEME
) {
313 FREESURFACE(pLabel
->theme
);
315 pLabel
->theme
= pTheme
;
316 FC_FREE(pLabel
->dst
);
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
);
327 SDL_Surface
*pDest
, *pTheme
, *pBuf
= create_surf_alpha(pIconLabel
->size
.w
,
328 pIconLabel
->size
.h
* 2, SDL_SWSURFACE
);
330 if(flags
& WF_RESTORE_BACKGROUND
) {
331 pTheme
= SDL_DisplayFormatAlpha(pBuf
);
337 colorkey
= SDL_MapRGBA(pTheme
->format
, pIconLabel
->string16
->bgcol
.r
,
338 pIconLabel
->string16
->bgcol
.g
,
339 pIconLabel
->string16
->bgcol
.b
,
340 pIconLabel
->string16
->bgcol
.unused
);
341 SDL_FillRect(pTheme
, NULL
, colorkey
);
343 start
= pIconLabel
->size
;
344 pIconLabel
->size
.x
= 0;
345 pIconLabel
->size
.y
= 0;
347 pDest
= pIconLabel
->dst
->surface
;
348 pIconLabel
->dst
->surface
= pTheme
;
351 redraw_iconlabel(pIconLabel
);
355 area
.y
= pIconLabel
->size
.h
;
357 if(flags
& WF_RESTORE_BACKGROUND
) {
358 SDL_FillRect(pTheme
, &area
, map_rgba(pTheme
->format
, bg_color
));
359 store
= pIconLabel
->string16
->bgcol
;
360 SDL_GetRGBA(getpixel(pTheme
, area
.x
, area
.y
), pTheme
->format
,
361 &pIconLabel
->string16
->bgcol
.r
, &pIconLabel
->string16
->bgcol
.g
,
362 &pIconLabel
->string16
->bgcol
.b
,
363 &pIconLabel
->string16
->bgcol
.unused
);
365 SDL_FillRectAlpha(pTheme
, &area
, &bg_color
);
368 pIconLabel
->size
.y
= pIconLabel
->size
.h
;
369 redraw_iconlabel(pIconLabel
);
371 if(flags
& WF_RESTORE_BACKGROUND
) {
372 pIconLabel
->string16
->bgcol
= store
;
375 pIconLabel
->size
= start
;
376 if(flags
& WF_FREE_THEME
) {
377 FREESURFACE(pIconLabel
->theme
);
379 pIconLabel
->theme
= pTheme
;
380 if(flags
& WF_FREE_STRING
) {
381 FREESTRING16(pIconLabel
->string16
);
383 pIconLabel
->dst
->surface
= pDest
;
384 set_wtype(pIconLabel
, WT_T2_LABEL
);
386 pIconLabel
->redraw
= redraw_label
;
392 /**************************************************************************
394 **************************************************************************/
395 static int redraw_themelabel(struct widget
*pLabel
)
399 SDL_Surface
*pText
= NULL
;
405 if ((pText
= create_text_surf_from_str16(pLabel
->string16
)) == NULL
) {
409 if (pLabel
->string16
->style
& SF_CENTER
) {
410 x
= (pLabel
->size
.w
- pText
->w
) / 2;
412 if (pLabel
->string16
->style
& SF_CENTER_RIGHT
) {
413 x
= pLabel
->size
.w
- pText
->w
- adj_size(5);
419 y
= (pLabel
->size
.h
- pText
->h
) / 2;
423 ret
= blit_entire_src(pLabel
->theme
, pLabel
->dst
->surface
, pLabel
->size
.x
, pLabel
->size
.y
);
429 ret
= blit_entire_src(pText
, pLabel
->dst
->surface
, pLabel
->size
.x
+ x
, pLabel
->size
.y
+ y
);
437 /**************************************************************************
439 **************************************************************************/
440 int redraw_iconlabel(struct widget
*pLabel
)
442 int space
, ret
= 0; /* FIXME: possibly uninitialized */
444 Sint16 y
= 0; /* FIXME: possibly uninitialized */
453 SDL_SetClipRect(pLabel
->dst
->surface
, &pLabel
->size
);
455 flags
= get_wflags(pLabel
);
457 if (flags
& WF_DRAW_TEXT_LABEL_WITH_SPACE
) {
463 pText
= create_text_surf_from_str16(pLabel
->string16
);
465 if (pLabel
->theme
) { /* Icon */
467 if (flags
& WF_ICON_CENTER_RIGHT
) {
468 xI
= pLabel
->size
.w
- pLabel
->theme
->w
- space
;
470 if (flags
& WF_ICON_CENTER
) {
471 xI
= (pLabel
->size
.w
- pLabel
->theme
->w
) / 2;
477 if (flags
& WF_ICON_ABOVE_TEXT
) {
479 y
= pLabel
->theme
->h
+ adj_size(3)
480 + (pLabel
->size
.h
- (pLabel
->theme
->h
+ adj_size(3)) - pText
->h
) / 2;
482 if (flags
& WF_ICON_UNDER_TEXT
) {
483 y
= (pLabel
->size
.h
- (pLabel
->theme
->h
+ adj_size(3)) - pText
->h
) / 2;
484 yI
= y
+ pText
->h
+ adj_size(3);
486 yI
= (pLabel
->size
.h
- pLabel
->theme
->h
) / 2;
487 y
= (pLabel
->size
.h
- pText
->h
) / 2;
493 yI
= (pLabel
->size
.h
- pLabel
->theme
->h
) / 2;
494 xI
= (pLabel
->size
.w
- pLabel
->theme
->w
) / 2;
500 dst
.x
= pLabel
->size
.x
+ xI
;
501 dst
.y
= pLabel
->size
.y
+ yI
;
503 ret
= alphablit(pLabel
->theme
, NULL
, pLabel
->dst
->surface
, &dst
);
511 if (pLabel
->theme
) { /* Icon */
512 if (!(flags
& WF_ICON_ABOVE_TEXT
) && !(flags
& WF_ICON_UNDER_TEXT
)) {
513 if (flags
& WF_ICON_CENTER_RIGHT
) {
514 if (pLabel
->string16
->style
& SF_CENTER
) {
515 x
= (pLabel
->size
.w
- (pLabel
->theme
->w
+ 5 + space
) -
518 if (pLabel
->string16
->style
& SF_CENTER_RIGHT
) {
519 x
= pLabel
->size
.w
- (pLabel
->theme
->w
+ 5 + space
) - pText
->w
;
524 } /* WF_ICON_CENTER_RIGHT */
526 if (flags
& WF_ICON_CENTER
) {
527 /* text is blit on icon */
529 } else { /* WF_ICON_CENTER_LEFT */
530 if (pLabel
->string16
->style
& SF_CENTER
) {
531 x
= space
+ pLabel
->theme
->w
+ adj_size(5) + ((pLabel
->size
.w
-
533 pLabel
->theme
->w
+ adj_size(5)) -
536 if (pLabel
->string16
->style
& SF_CENTER_RIGHT
) {
537 x
= pLabel
->size
.w
- pText
->w
- space
;
539 x
= space
+ pLabel
->theme
->w
+ adj_size(5);
542 } /* WF_ICON_CENTER_LEFT */
544 } /* !WF_ICON_ABOVE_TEXT && !WF_ICON_UNDER_TEXT */
548 } /* pLabel->theme == Icon */
550 y
= (pLabel
->size
.h
- pText
->h
) / 2;
552 if (pLabel
->string16
->style
& SF_CENTER
) {
553 x
= (pLabel
->size
.w
- pText
->w
) / 2;
555 if (pLabel
->string16
->style
& SF_CENTER_RIGHT
) {
556 x
= pLabel
->size
.w
- pText
->w
- space
;
563 dst
.x
= pLabel
->size
.x
+ x
;
564 dst
.y
= pLabel
->size
.y
+ y
;
566 ret
= alphablit(pText
, NULL
, pLabel
->dst
->surface
, &dst
);
571 SDL_SetClipRect(pLabel
->dst
->surface
, NULL
);
575 /**************************************************************************
577 **************************************************************************/
578 int draw_label(struct widget
*pLabel
, Sint16 start_x
, Sint16 start_y
)
580 pLabel
->size
.x
= start_x
;
581 pLabel
->size
.y
= start_y
;
582 return redraw_label(pLabel
);