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.
7
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 ***********************************************************************/
13
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17
18 /* utility */
19 #include "fcintl.h"
20 #include "log.h"
21
22 /* common */
23 #include "game.h"
24 #include "packets.h"
25 #include "victory.h"
26
27 /* client */
28 #include "client_main.h"
29 #include "text.h"
30
31 /* gui-sdl */
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"
38
39 #include "spaceshipdlg.h"
40
41 #define SPECLIST_TAG dialog
42 #define SPECLIST_TYPE struct SMALL_DLG
43 #include "speclist.h"
44
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
48
49 static struct dialog_list *dialog_list = NULL;
50 static bool dialog_list_has_been_initialised = FALSE;
51
52 /****************************************************************
53 ...
54 *****************************************************************/
get_spaceship_dialog(struct player * pplayer)55 static struct SMALL_DLG *get_spaceship_dialog(struct player *pplayer)
56 {
57 if (!dialog_list_has_been_initialised) {
58 dialog_list = dialog_list_new();
59 dialog_list_has_been_initialised = TRUE;
60 }
61
62 dialog_list_iterate(dialog_list, pDialog) {
63 if (pDialog->pEndWidgetList->data.player == pplayer) {
64 return pDialog;
65 }
66 } dialog_list_iterate_end;
67
68 return NULL;
69 }
70
space_dialog_window_callback(struct widget * pWindow)71 static int space_dialog_window_callback(struct widget *pWindow)
72 {
73 if (Main.event.button.button == SDL_BUTTON_LEFT) {
74 move_window_group(pWindow->private_data.small_dlg->pBeginWidgetList, pWindow);
75 }
76 return -1;
77 }
78
exit_space_dialog_callback(struct widget * pWidget)79 static int exit_space_dialog_callback(struct widget *pWidget)
80 {
81 if (Main.event.button.button == SDL_BUTTON_LEFT) {
82 popdown_spaceship_dialog(pWidget->data.player);
83 flush_dirty();
84 }
85 return -1;
86 }
87
launch_spaceship_callback(struct widget * pWidget)88 static int launch_spaceship_callback(struct widget *pWidget)
89 {
90 if (Main.event.button.button == SDL_BUTTON_LEFT) {
91 send_packet_spaceship_launch(&client.conn);
92 }
93 return -1;
94 }
95
96 /**************************************************************************
97 Refresh (update) the spaceship dialog for the given player.
98 **************************************************************************/
refresh_spaceship_dialog(struct player * pPlayer)99 void refresh_spaceship_dialog(struct player *pPlayer)
100 {
101 struct SMALL_DLG *pSpaceShp;
102 struct widget *pBuf;
103
104 if (!(pSpaceShp = get_spaceship_dialog(pPlayer))) {
105 return;
106 }
107
108 /* launch button */
109 pBuf = pSpaceShp->pEndWidgetList->prev->prev;
110 if (victory_enabled(VC_SPACERACE)
111 && pPlayer == client.conn.playing
112 && pPlayer->spaceship.state == SSHIP_STARTED
113 && pPlayer->spaceship.success_rate > 0.0) {
114 set_wstate(pBuf, FC_WS_NORMAL);
115 }
116
117 /* update text info */
118 pBuf = pBuf->prev;
119 copy_chars_to_string16(pBuf->string16,
120 get_spaceship_descr(&pPlayer->spaceship));
121 /* ------------------------------------------ */
122
123 /* redraw */
124 redraw_group(pSpaceShp->pBeginWidgetList, pSpaceShp->pEndWidgetList, 0);
125 widget_mark_dirty(pSpaceShp->pEndWidgetList);
126
127 flush_dirty();
128 }
129
130 /**************************************************************************
131 Popup (or raise) the spaceship dialog for the given player.
132 **************************************************************************/
popup_spaceship_dialog(struct player * pPlayer)133 void popup_spaceship_dialog(struct player *pPlayer)
134 {
135 struct SMALL_DLG *pSpaceShp;
136
137 if(!(pSpaceShp = get_spaceship_dialog(pPlayer))) {
138 struct widget *pBuf, *pWindow;
139 SDL_String16 *pStr;
140 char cBuf[128];
141 SDL_Rect area;
142
143 pSpaceShp = fc_calloc(1, sizeof(struct SMALL_DLG));
144
145 fc_snprintf(cBuf, sizeof(cBuf), _("The %s Spaceship"),
146 nation_adjective_for_player(pPlayer));
147 pStr = create_str16_from_char(cBuf, adj_font(12));
148 pStr->style |= TTF_STYLE_BOLD;
149
150 pWindow = create_window_skeleton(NULL, pStr, 0);
151
152 pWindow->action = space_dialog_window_callback;
153 set_wstate(pWindow, FC_WS_NORMAL);
154 pWindow->data.player = pPlayer;
155 pWindow->private_data.small_dlg = pSpaceShp;
156 add_to_gui_list(ID_WINDOW, pWindow);
157 pSpaceShp->pEndWidgetList = pWindow;
158
159 area = pWindow->area;
160
161 /* ---------- */
162 /* create exit button */
163 pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
164 WF_WIDGET_HAS_INFO_LABEL
165 | WF_RESTORE_BACKGROUND);
166 pBuf->info_label = create_str16_from_char(_("Close Dialog (Esc)"),
167 adj_font(12));
168 pBuf->data.player = pPlayer;
169 pBuf->action = exit_space_dialog_callback;
170 set_wstate(pBuf, FC_WS_NORMAL);
171 pBuf->key = SDLK_ESCAPE;
172 area.w = MAX(area.w, (pBuf->size.w + adj_size(10)));
173
174 add_to_gui_list(ID_BUTTON, pBuf);
175
176 pBuf = create_themeicon_button_from_chars(current_theme->OK_Icon, pWindow->dst,
177 _("Launch"), adj_font(12), 0);
178
179 pBuf->action = launch_spaceship_callback;
180 area.w = MAX(area.w, pBuf->size.w);
181 area.h += pBuf->size.h + adj_size(20);
182 add_to_gui_list(ID_BUTTON, pBuf);
183
184 pStr = create_str16_from_char(get_spaceship_descr(NULL), adj_font(12));
185 pStr->bgcol = (SDL_Color) {0, 0, 0, 0};
186 pBuf = create_iconlabel(NULL, pWindow->dst, pStr, WF_RESTORE_BACKGROUND);
187 area.w = MAX(area.w, pBuf->size.w);
188 area.h += pBuf->size.h + adj_size(20);
189 add_to_gui_list(ID_LABEL, pBuf);
190
191 pSpaceShp->pBeginWidgetList = pBuf;
192 /* -------------------------------------------------------- */
193
194 area.w = MAX(area.w, adj_size(300) - (pWindow->size.w - pWindow->area.w));
195
196 resize_window(pWindow, NULL, NULL,
197 (pWindow->size.w - pWindow->area.w) + area.w,
198 (pWindow->size.h - pWindow->area.h) + area.h);
199
200 area = pWindow->area;
201
202 widget_set_position(pWindow,
203 (Main.screen->w - pWindow->size.w) / 2,
204 (Main.screen->h - pWindow->size.h) / 2);
205
206 /* exit button */
207 pBuf = pWindow->prev;
208 pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
209 pBuf->size.y = pWindow->size.y + adj_size(2);
210
211 /* launch button */
212 pBuf = pBuf->prev;
213 pBuf->size.x = area.x + (area.w - pBuf->size.w) / 2;
214 pBuf->size.y = area.y + area.h - pBuf->size.h - adj_size(7);
215
216 /* info label */
217 pBuf = pBuf->prev;
218 pBuf->size.x = area.x + (area.w - pBuf->size.w) / 2;
219 pBuf->size.y = area.y + adj_size(7);
220
221 dialog_list_prepend(dialog_list, pSpaceShp);
222
223 refresh_spaceship_dialog(pPlayer);
224 } else {
225 if (sellect_window_group_dialog(pSpaceShp->pBeginWidgetList,
226 pSpaceShp->pEndWidgetList)) {
227 widget_flush(pSpaceShp->pEndWidgetList);
228 }
229 }
230
231 }
232
233 /**************************************************************************
234 Close the spaceship dialog for the given player.
235 **************************************************************************/
popdown_spaceship_dialog(struct player * pPlayer)236 void popdown_spaceship_dialog(struct player *pPlayer)
237 {
238 struct SMALL_DLG *pSpaceShp;
239
240 if((pSpaceShp = get_spaceship_dialog(pPlayer))) {
241 popdown_window_group_dialog(pSpaceShp->pBeginWidgetList,
242 pSpaceShp->pEndWidgetList);
243 dialog_list_remove(dialog_list, pSpaceShp);
244 FC_FREE(pSpaceShp);
245 }
246
247 }
248