webperimental: Mountain vision bonus.
[freeciv.git] / client / gui-sdl2 / spaceshipdlg.c
blob6a92962c2a852e10b0b235fdce6b000e853157b8
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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 /* utility */
19 #include "fcintl.h"
20 #include "log.h"
22 /* common */
23 #include "game.h"
24 #include "packets.h"
25 #include "victory.h"
27 /* client */
28 #include "client_main.h"
29 #include "text.h"
31 /* gui-sdl2 */
32 #include "graphics.h"
33 #include "gui_id.h"
34 #include "gui_main.h"
35 #include "gui_tilespec.h"
36 #include "mapview.h"
37 #include "widget.h"
39 #include "spaceshipdlg.h"
41 #define SPECLIST_TAG dialog
42 #define SPECLIST_TYPE struct SMALL_DLG
43 #include "speclist.h"
45 #define dialog_list_iterate(dialoglist, pdialog) \
46 TYPED_LIST_ITERATE(struct SMALL_DLG, dialoglist, pdialog)
47 #define dialog_list_iterate_end LIST_ITERATE_END
49 static struct dialog_list *dialog_list = NULL;
50 static bool dialog_list_has_been_initialised = FALSE;
52 /**************************************************************************
53 Find spaceship dialog related to specified player.
54 **************************************************************************/
55 static struct SMALL_DLG *get_spaceship_dialog(struct player *pplayer)
57 if (!dialog_list_has_been_initialised) {
58 dialog_list = dialog_list_new();
59 dialog_list_has_been_initialised = TRUE;
62 dialog_list_iterate(dialog_list, pDialog) {
63 if (pDialog->pEndWidgetList->data.player == pplayer) {
64 return pDialog;
66 } dialog_list_iterate_end;
68 return NULL;
71 /**************************************************************************
72 User interacted with spaceship dialog window.
73 **************************************************************************/
74 static int space_dialog_window_callback(struct widget *pWindow)
76 if (Main.event.button.button == SDL_BUTTON_LEFT) {
77 move_window_group(pWindow->private_data.small_dlg->pBeginWidgetList, pWindow);
80 return -1;
83 /**************************************************************************
84 User interacted with spaceship dialog close button.
85 **************************************************************************/
86 static int exit_space_dialog_callback(struct widget *pWidget)
88 if (Main.event.button.button == SDL_BUTTON_LEFT) {
89 popdown_spaceship_dialog(pWidget->data.player);
90 flush_dirty();
93 return -1;
96 /**************************************************************************
97 User interacted with spaceship dialog launch button.
98 **************************************************************************/
99 static int launch_spaceship_callback(struct widget *pWidget)
101 if (Main.event.button.button == SDL_BUTTON_LEFT) {
102 send_packet_spaceship_launch(&client.conn);
105 return -1;
108 /**************************************************************************
109 Refresh (update) the spaceship dialog for the given player.
110 **************************************************************************/
111 void refresh_spaceship_dialog(struct player *pPlayer)
113 struct SMALL_DLG *pSpaceShp;
114 struct widget *pbuf;
116 if (!(pSpaceShp = get_spaceship_dialog(pPlayer))) {
117 return;
120 /* launch button */
121 pbuf = pSpaceShp->pEndWidgetList->prev->prev;
122 if (victory_enabled(VC_SPACERACE)
123 && pPlayer == client.conn.playing
124 && pPlayer->spaceship.state == SSHIP_STARTED
125 && pPlayer->spaceship.success_rate > 0.0) {
126 set_wstate(pbuf, FC_WS_NORMAL);
129 /* update text info */
130 pbuf = pbuf->prev;
131 copy_chars_to_utf8_str(pbuf->string_utf8,
132 get_spaceship_descr(&pPlayer->spaceship));
133 /* ------------------------------------------ */
135 /* redraw */
136 redraw_group(pSpaceShp->pBeginWidgetList, pSpaceShp->pEndWidgetList, 0);
137 widget_mark_dirty(pSpaceShp->pEndWidgetList);
139 flush_dirty();
142 /**************************************************************************
143 Popup (or raise) the spaceship dialog for the given player.
144 **************************************************************************/
145 void popup_spaceship_dialog(struct player *pPlayer)
147 struct SMALL_DLG *pSpaceShp;
149 if (!(pSpaceShp = get_spaceship_dialog(pPlayer))) {
150 struct widget *pBuf, *pWindow;
151 utf8_str *pstr;
152 char cbuf[128];
153 SDL_Rect area;
155 pSpaceShp = fc_calloc(1, sizeof(struct SMALL_DLG));
157 fc_snprintf(cbuf, sizeof(cbuf), _("The %s Spaceship"),
158 nation_adjective_for_player(pPlayer));
159 pstr = create_utf8_from_char(cbuf, adj_font(12));
160 pstr->style |= TTF_STYLE_BOLD;
162 pWindow = create_window_skeleton(NULL, pstr, 0);
164 pWindow->action = space_dialog_window_callback;
165 set_wstate(pWindow, FC_WS_NORMAL);
166 pWindow->data.player = pPlayer;
167 pWindow->private_data.small_dlg = pSpaceShp;
168 add_to_gui_list(ID_WINDOW, pWindow);
169 pSpaceShp->pEndWidgetList = pWindow;
171 area = pWindow->area;
173 /* ---------- */
174 /* create exit button */
175 pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
176 WF_WIDGET_HAS_INFO_LABEL
177 | WF_RESTORE_BACKGROUND);
178 pBuf->info_label = create_utf8_from_char(_("Close Dialog (Esc)"),
179 adj_font(12));
180 pBuf->data.player = pPlayer;
181 pBuf->action = exit_space_dialog_callback;
182 set_wstate(pBuf, FC_WS_NORMAL);
183 pBuf->key = SDLK_ESCAPE;
184 area.w = MAX(area.w, (pBuf->size.w + adj_size(10)));
186 add_to_gui_list(ID_BUTTON, pBuf);
188 pBuf = create_themeicon_button_from_chars(current_theme->OK_Icon, pWindow->dst,
189 _("Launch"), adj_font(12), 0);
191 pBuf->action = launch_spaceship_callback;
192 area.w = MAX(area.w, pBuf->size.w);
193 area.h += pBuf->size.h + adj_size(20);
194 add_to_gui_list(ID_BUTTON, pBuf);
196 pstr = create_utf8_from_char(get_spaceship_descr(NULL), adj_font(12));
197 pstr->bgcol = (SDL_Color) {0, 0, 0, 0};
198 pBuf = create_iconlabel(NULL, pWindow->dst, pstr, WF_RESTORE_BACKGROUND);
199 area.w = MAX(area.w, pBuf->size.w);
200 area.h += pBuf->size.h + adj_size(20);
201 add_to_gui_list(ID_LABEL, pBuf);
203 pSpaceShp->pBeginWidgetList = pBuf;
204 /* -------------------------------------------------------- */
206 area.w = MAX(area.w, adj_size(300) - (pWindow->size.w - pWindow->area.w));
208 resize_window(pWindow, NULL, NULL,
209 (pWindow->size.w - pWindow->area.w) + area.w,
210 (pWindow->size.h - pWindow->area.h) + area.h);
212 area = pWindow->area;
214 widget_set_position(pWindow,
215 (main_window_width() - pWindow->size.w) / 2,
216 (main_window_height() - pWindow->size.h) / 2);
218 /* exit button */
219 pBuf = pWindow->prev;
220 pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
221 pBuf->size.y = pWindow->size.y + adj_size(2);
223 /* launch button */
224 pBuf = pBuf->prev;
225 pBuf->size.x = area.x + (area.w - pBuf->size.w) / 2;
226 pBuf->size.y = area.y + area.h - pBuf->size.h - adj_size(7);
228 /* info label */
229 pBuf = pBuf->prev;
230 pBuf->size.x = area.x + (area.w - pBuf->size.w) / 2;
231 pBuf->size.y = area.y + adj_size(7);
233 dialog_list_prepend(dialog_list, pSpaceShp);
235 refresh_spaceship_dialog(pPlayer);
236 } else {
237 if (select_window_group_dialog(pSpaceShp->pBeginWidgetList,
238 pSpaceShp->pEndWidgetList)) {
239 widget_flush(pSpaceShp->pEndWidgetList);
244 /**************************************************************************
245 Close the spaceship dialog for the given player.
246 **************************************************************************/
247 void popdown_spaceship_dialog(struct player *pPlayer)
249 struct SMALL_DLG *pSpaceShp;
251 if ((pSpaceShp = get_spaceship_dialog(pPlayer))) {
252 popdown_window_group_dialog(pSpaceShp->pBeginWidgetList,
253 pSpaceShp->pEndWidgetList);
254 dialog_list_remove(dialog_list, pSpaceShp);
255 FC_FREE(pSpaceShp);