Remove hard limitation that AI wonder cities never build settlers
[freeciv.git] / client / gui-sdl2 / widget_checkbox.c
blobe0968ab4bfac46b4b5134037dc946a66e6aceb6c
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)
6 any later version.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* SDL2 */
19 #ifdef SDL2_PLAIN_INCLUDE
20 #include <SDL.h>
21 #else /* SDL2_PLAIN_INCLUDE */
22 #include <SDL2/SDL.h>
23 #endif /* SDL2_PLAIN_INCLUDE */
25 /* utility */
26 #include "log.h"
28 /* gui-sdl2 */
29 #include "colors.h"
30 #include "graphics.h"
31 #include "gui_tilespec.h"
32 #include "themespec.h"
34 #include "widget.h"
35 #include "widget_p.h"
37 static int (*checkbox_baseclass_redraw)(struct widget *pwidget);
38 static int (*textcheckbox_baseclass_redraw)(struct widget *pwidget);
40 /**************************************************************************
41 Blit checkbox gfx to surface its on.
42 **************************************************************************/
43 static int redraw_checkbox(struct widget *pIcon)
45 int ret;
46 SDL_Rect src, area = pIcon->size;
48 ret = (*checkbox_baseclass_redraw)(pIcon);
49 if (ret != 0) {
50 return ret;
53 if (!pIcon->theme) {
54 return -3;
57 src.x = (pIcon->theme->w / 4) * (Uint8) (get_wstate(pIcon));
58 src.y = 0;
59 src.w = (pIcon->theme->w / 4);
60 src.h = pIcon->theme->h;
62 if (pIcon->size.w != src.w) {
63 area.x += (pIcon->size.w - src.w) / 2;
66 if (pIcon->size.h != src.h) {
67 area.y += (pIcon->size.h - src.h) / 2;
70 return alphablit(pIcon->theme, &src, pIcon->dst->surface, &area, 255);
73 /**************************************************************************
74 Blit checkbox-with-text gfx to surface its on.
75 **************************************************************************/
76 static int redraw_textcheckbox(struct widget *pCBox)
78 int ret;
79 SDL_Surface *pTheme_Surface, *pIcon;
81 ret = (*textcheckbox_baseclass_redraw)(pCBox);
82 if (ret != 0) {
83 return ret;
86 if (pCBox->string_utf8 == NULL) {
87 return widget_redraw(pCBox);
90 pTheme_Surface = pCBox->theme;
91 pIcon = create_icon_from_theme(pTheme_Surface, get_wstate(pCBox));
93 if (!pIcon) {
94 return -3;
97 pCBox->theme = pIcon;
99 /* redraw icon label */
100 ret = redraw_iconlabel(pCBox);
102 FREESURFACE(pIcon);
103 pCBox->theme = pTheme_Surface;
105 return ret;
108 /**************************************************************************
109 Create a new checkbox widget.
110 **************************************************************************/
111 struct widget *create_checkbox(struct gui_layer *pDest, bool state,
112 Uint32 flags)
114 struct widget *pCBox = widget_new();
115 struct CHECKBOX *pTmp = fc_calloc(1, sizeof(struct CHECKBOX));
117 if (state) {
118 pCBox->theme = current_theme->CBOX_Sell_Icon;
119 } else {
120 pCBox->theme = current_theme->CBOX_Unsell_Icon;
123 set_wflag(pCBox, (WF_FREE_STRING | WF_FREE_GFX | WF_FREE_PRIVATE_DATA | flags));
124 set_wstate(pCBox, FC_WS_DISABLED);
125 set_wtype(pCBox, WT_CHECKBOX);
126 pCBox->mod = KMOD_NONE;
127 pCBox->dst = pDest;
128 pTmp->state = state;
129 pTmp->pTRUE_Theme = current_theme->CBOX_Sell_Icon;
130 pTmp->pFALSE_Theme = current_theme->CBOX_Unsell_Icon;
131 pCBox->private_data.cbox = pTmp;
133 checkbox_baseclass_redraw = pCBox->redraw;
134 pCBox->redraw = redraw_checkbox;
136 pCBox->size.w = pCBox->theme->w / 4;
137 pCBox->size.h = pCBox->theme->h;
139 return pCBox;
142 /**************************************************************************
143 Create a new checkbox-with-text widget.
144 **************************************************************************/
145 struct widget *create_textcheckbox(struct gui_layer *pDest, bool state,
146 utf8_str *pstr, Uint32 flags)
148 struct widget *pCBox;
149 struct CHECKBOX *pTmp;
150 SDL_Surface *pSurf, *pIcon;
151 struct widget *pTmpWidget;
153 if (pstr == NULL) {
154 return create_checkbox(pDest, state, flags);
157 pTmp = fc_calloc(1, sizeof(struct CHECKBOX));
159 if (state) {
160 pSurf = current_theme->CBOX_Sell_Icon;
161 } else {
162 pSurf = current_theme->CBOX_Unsell_Icon;
165 pIcon = create_icon_from_theme(pSurf, 0);
166 pCBox = create_iconlabel(pIcon, pDest, pstr, (flags | WF_FREE_PRIVATE_DATA));
168 pstr->style &= ~SF_CENTER;
170 pCBox->theme = pSurf;
171 FREESURFACE(pIcon);
173 set_wtype(pCBox, WT_TCHECKBOX);
174 pTmp->state = state;
175 pTmp->pTRUE_Theme = current_theme->CBOX_Sell_Icon;
176 pTmp->pFALSE_Theme = current_theme->CBOX_Unsell_Icon;
177 pCBox->private_data.cbox = pTmp;
179 pTmpWidget = widget_new();
180 /* we can't use pCBox->redraw here, because it is of type iconlabel */
181 textcheckbox_baseclass_redraw = pTmpWidget->redraw;
182 FREEWIDGET(pTmpWidget);
183 pCBox->redraw = redraw_textcheckbox;
185 return pCBox;
188 /**************************************************************************
189 Set theme surfaces for a checkbox.
190 **************************************************************************/
191 int set_new_checkbox_theme(struct widget *pCBox,
192 SDL_Surface *pTrue, SDL_Surface *pFalse)
194 struct CHECKBOX *pTmp;
196 if (!pCBox || (get_wtype(pCBox) != WT_CHECKBOX)) {
197 return -1;
200 if (!pCBox->private_data.cbox) {
201 pCBox->private_data.cbox = fc_calloc(1, sizeof(struct CHECKBOX));
202 set_wflag(pCBox, WF_FREE_PRIVATE_DATA);
203 pCBox->private_data.cbox->state = FALSE;
206 pTmp = pCBox->private_data.cbox;
207 pTmp->pTRUE_Theme = pTrue;
208 pTmp->pFALSE_Theme = pFalse;
209 if (pTmp->state) {
210 pCBox->theme = pTrue;
211 } else {
212 pCBox->theme = pFalse;
215 return 0;
218 /**************************************************************************
219 Change the state of the checkbox.
220 **************************************************************************/
221 void toggle_checkbox(struct widget *pCBox)
223 if (pCBox->private_data.cbox->state) {
224 pCBox->theme = pCBox->private_data.cbox->pFALSE_Theme;
225 pCBox->private_data.cbox->state = FALSE;
226 } else {
227 pCBox->theme = pCBox->private_data.cbox->pTRUE_Theme;
228 pCBox->private_data.cbox->state = TRUE;
232 /**************************************************************************
233 Check state of the checkbox.
234 **************************************************************************/
235 bool get_checkbox_state(struct widget *pCBox)
237 return pCBox->private_data.cbox->state;