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)
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 "client_main.h"
35 #include "gui_tilespec.h"
39 #include "spaceshipdlg.h"
41 #define SPECLIST_TAG dialog
42 #define SPECLIST_TYPE struct SMALL_DLG
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
) {
66 } dialog_list_iterate_end
;
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
);
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
);
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
);
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
;
116 if (!(pSpaceShp
= get_spaceship_dialog(pPlayer
))) {
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 */
131 copy_chars_to_utf8_str(pbuf
->string_utf8
,
132 get_spaceship_descr(&pPlayer
->spaceship
));
133 /* ------------------------------------------ */
136 redraw_group(pSpaceShp
->pBeginWidgetList
, pSpaceShp
->pEndWidgetList
, 0);
137 widget_mark_dirty(pSpaceShp
->pEndWidgetList
);
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
;
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
;
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)"),
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);
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);
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);
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
);
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
);