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>
35 #include "spaceship.h"
39 #include "client_main.h"
46 /* client/gui-gtk-3.0 */
50 #include "gui_stuff.h"
57 #include "spaceshipdlg.h"
59 struct spaceship_dialog
{
60 struct player
*pplayer
;
61 struct gui_dialog
*shell
;
63 GtkWidget
*info_label
;
64 GtkWidget
*image_canvas
;
67 #define SPECLIST_TAG dialog
68 #define SPECLIST_TYPE struct spaceship_dialog
71 #define dialog_list_iterate(dialoglist, pdialog) \
72 TYPED_LIST_ITERATE(struct spaceship_dialog, dialoglist, pdialog)
73 #define dialog_list_iterate_end LIST_ITERATE_END
75 static struct dialog_list
*dialog_list
;
77 static struct spaceship_dialog
*get_spaceship_dialog(struct player
*pplayer
);
78 static struct spaceship_dialog
*create_spaceship_dialog(struct player
81 static void spaceship_dialog_update_image(struct spaceship_dialog
*pdialog
);
82 static void spaceship_dialog_update_info(struct spaceship_dialog
*pdialog
);
84 /****************************************************************
85 Initialize spaceship dialogs
86 *****************************************************************/
87 void spaceship_dialog_init()
89 dialog_list
= dialog_list_new();
92 /****************************************************************
93 Free resources allocated for spaceship dialogs
94 *****************************************************************/
95 void spaceship_dialog_done()
97 dialog_list_destroy(dialog_list
);
100 /****************************************************************
101 Get spaceship dialog about certain player
102 *****************************************************************/
103 struct spaceship_dialog
*get_spaceship_dialog(struct player
*pplayer
)
105 dialog_list_iterate(dialog_list
, pdialog
) {
106 if (pdialog
->pplayer
== pplayer
) {
109 } dialog_list_iterate_end
;
114 /****************************************************************
115 Refresh spaceship dialog of certain player
116 *****************************************************************/
117 void refresh_spaceship_dialog(struct player
*pplayer
)
119 struct spaceship_dialog
*pdialog
;
120 struct player_spaceship
*pship
;
122 if (!(pdialog
= get_spaceship_dialog(pplayer
))) {
126 pship
= &(pdialog
->pplayer
->spaceship
);
128 if (victory_enabled(VC_SPACERACE
)
129 && pplayer
== client
.conn
.playing
130 && pship
->state
== SSHIP_STARTED
131 && pship
->success_rate
> 0.0) {
132 gui_dialog_set_response_sensitive(pdialog
->shell
,
133 GTK_RESPONSE_ACCEPT
, TRUE
);
135 gui_dialog_set_response_sensitive(pdialog
->shell
,
136 GTK_RESPONSE_ACCEPT
, FALSE
);
139 spaceship_dialog_update_info(pdialog
);
140 spaceship_dialog_update_image(pdialog
);
143 /****************************************************************
144 Popup the dialog 10% inside the main-window
145 *****************************************************************/
146 void popup_spaceship_dialog(struct player
*pplayer
)
148 struct spaceship_dialog
*pdialog
;
150 if (!(pdialog
= get_spaceship_dialog(pplayer
))) {
151 pdialog
= create_spaceship_dialog(pplayer
);
154 gui_dialog_raise(pdialog
->shell
);
157 /****************************************************************
159 *****************************************************************/
160 void popdown_spaceship_dialog(struct player
*pplayer
)
162 struct spaceship_dialog
*pdialog
;
164 if ((pdialog
= get_spaceship_dialog(pplayer
))) {
165 gui_dialog_destroy(pdialog
->shell
);
169 /****************************************************************
170 Spaceship dialog canvas got exposed
171 *****************************************************************/
172 static gboolean
spaceship_image_canvas_expose(GtkWidget
*widget
,
176 struct spaceship_dialog
*pdialog
= (struct spaceship_dialog
*)data
;
177 struct canvas store
= FC_STATIC_CANVAS_INIT
;
181 put_spaceship(&store
, 0, 0, pdialog
->pplayer
);
186 /****************************************************************
187 Spaceship dialog being destroyed
188 *****************************************************************/
189 static void spaceship_destroy_callback(GtkWidget
*w
, gpointer data
)
191 struct spaceship_dialog
*pdialog
= (struct spaceship_dialog
*)data
;
193 dialog_list_remove(dialog_list
, pdialog
);
198 /****************************************************************
199 User has responded to spaceship dialog
200 *****************************************************************/
201 static void spaceship_response(struct gui_dialog
*dlg
, int response
,
205 case GTK_RESPONSE_ACCEPT
:
206 send_packet_spaceship_launch(&client
.conn
);
210 gui_dialog_destroy(dlg
);
215 /****************************************************************
216 Create new spaceship dialog
217 *****************************************************************/
218 struct spaceship_dialog
*create_spaceship_dialog(struct player
*pplayer
)
220 struct spaceship_dialog
*pdialog
;
221 GtkWidget
*hbox
, *frame
;
224 pdialog
= fc_malloc(sizeof(struct spaceship_dialog
));
225 pdialog
->pplayer
= pplayer
;
227 gui_dialog_new(&pdialog
->shell
, GTK_NOTEBOOK(top_notebook
), NULL
, TRUE
);
228 gui_dialog_set_title(pdialog
->shell
, player_name(pplayer
));
230 gui_dialog_add_button(pdialog
->shell
,
231 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
);
232 gui_dialog_add_button(pdialog
->shell
,
233 _("_Launch"), GTK_RESPONSE_ACCEPT
);
235 g_signal_connect(pdialog
->shell
->vbox
, "destroy",
236 G_CALLBACK(spaceship_destroy_callback
), pdialog
);
237 gui_dialog_response_set_callback(pdialog
->shell
, spaceship_response
);
239 hbox
= gtk_grid_new();
240 gtk_grid_set_column_spacing(GTK_GRID(hbox
), 5);
241 gtk_container_add(GTK_CONTAINER(pdialog
->shell
->vbox
), hbox
);
243 frame
= gtk_frame_new(NULL
);
244 gtk_container_add(GTK_CONTAINER(hbox
), frame
);
246 pdialog
->image_canvas
= gtk_drawing_area_new();
247 gtk_widget_set_can_focus(pdialog
->image_canvas
, TRUE
);
248 get_spaceship_dimensions(&w
, &h
);
249 gtk_widget_set_size_request(pdialog
->image_canvas
, w
, h
);
251 gtk_widget_set_events(pdialog
->image_canvas
, GDK_EXPOSURE_MASK
);
252 gtk_container_add(GTK_CONTAINER(frame
), pdialog
->image_canvas
);
253 gtk_widget_realize(pdialog
->image_canvas
);
255 g_signal_connect(pdialog
->image_canvas
, "draw",
256 G_CALLBACK(spaceship_image_canvas_expose
), pdialog
);
258 pdialog
->info_label
= gtk_label_new(get_spaceship_descr(NULL
));
260 gtk_label_set_justify(GTK_LABEL(pdialog
->info_label
), GTK_JUSTIFY_LEFT
);
261 gtk_widget_set_halign(pdialog
->info_label
, GTK_ALIGN_START
);
262 gtk_widget_set_valign(pdialog
->info_label
, GTK_ALIGN_START
);
264 gtk_container_add(GTK_CONTAINER(hbox
), pdialog
->info_label
);
265 gtk_widget_set_name(pdialog
->info_label
, "spaceship_label");
267 dialog_list_prepend(dialog_list
, pdialog
);
269 gtk_widget_grab_focus(pdialog
->image_canvas
);
271 gui_dialog_show_all(pdialog
->shell
);
273 refresh_spaceship_dialog(pdialog
->pplayer
);
278 /****************************************************************
279 Update spaceship dialog info label text
280 *****************************************************************/
281 void spaceship_dialog_update_info(struct spaceship_dialog
*pdialog
)
283 gtk_label_set_text(GTK_LABEL(pdialog
->info_label
),
284 get_spaceship_descr(&pdialog
->pplayer
->spaceship
));
287 /****************************************************************
288 Should also check connectedness, and show non-connected
290 *****************************************************************/
291 void spaceship_dialog_update_image(struct spaceship_dialog
*pdialog
)
293 gtk_widget_queue_draw(pdialog
->image_canvas
);