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
)))
125 pship
=&(pdialog
->pplayer
->spaceship
);
127 if (victory_enabled(VC_SPACERACE
)
128 && pplayer
== client
.conn
.playing
129 && pship
->state
== SSHIP_STARTED
130 && pship
->success_rate
> 0.0) {
131 gui_dialog_set_response_sensitive(pdialog
->shell
,
132 GTK_RESPONSE_ACCEPT
, TRUE
);
134 gui_dialog_set_response_sensitive(pdialog
->shell
,
135 GTK_RESPONSE_ACCEPT
, FALSE
);
138 spaceship_dialog_update_info(pdialog
);
139 spaceship_dialog_update_image(pdialog
);
142 /****************************************************************
143 popup the dialog 10% inside the main-window
144 *****************************************************************/
145 void popup_spaceship_dialog(struct player
*pplayer
)
147 struct spaceship_dialog
*pdialog
;
149 if(!(pdialog
=get_spaceship_dialog(pplayer
)))
150 pdialog
=create_spaceship_dialog(pplayer
);
152 gui_dialog_raise(pdialog
->shell
);
155 /****************************************************************
157 *****************************************************************/
158 void popdown_spaceship_dialog(struct player
*pplayer
)
160 struct spaceship_dialog
*pdialog
;
162 if((pdialog
=get_spaceship_dialog(pplayer
)))
163 gui_dialog_destroy(pdialog
->shell
);
168 /****************************************************************
169 Spaceship dialog canvas got exposed
170 *****************************************************************/
171 static gboolean
spaceship_image_canvas_expose(GtkWidget
*widget
,
175 struct spaceship_dialog
*pdialog
= (struct spaceship_dialog
*)data
;
176 struct canvas store
= FC_STATIC_CANVAS_INIT
;
180 put_spaceship(&store
, 0, 0, pdialog
->pplayer
);
185 /****************************************************************
186 Spaceship dialog being destroyed
187 *****************************************************************/
188 static void spaceship_destroy_callback(GtkWidget
*w
, gpointer data
)
190 struct spaceship_dialog
*pdialog
= (struct spaceship_dialog
*)data
;
192 dialog_list_remove(dialog_list
, pdialog
);
197 /****************************************************************
198 User has responded to spaceship dialog
199 *****************************************************************/
200 static void spaceship_response(struct gui_dialog
*dlg
, int response
,
204 case GTK_RESPONSE_ACCEPT
:
206 send_packet_spaceship_launch(&client
.conn
);
211 gui_dialog_destroy(dlg
);
216 /****************************************************************
217 Create new spaceship dialog
218 *****************************************************************/
219 struct spaceship_dialog
*create_spaceship_dialog(struct player
*pplayer
)
221 struct spaceship_dialog
*pdialog
;
222 GtkWidget
*hbox
, *frame
;
225 pdialog
=fc_malloc(sizeof(struct spaceship_dialog
));
226 pdialog
->pplayer
=pplayer
;
228 gui_dialog_new(&pdialog
->shell
, GTK_NOTEBOOK(top_notebook
), NULL
, TRUE
);
229 gui_dialog_set_title(pdialog
->shell
, player_name(pplayer
));
231 gui_dialog_add_button(pdialog
->shell
,
232 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
);
233 gui_dialog_add_button(pdialog
->shell
,
234 _("_Launch"), GTK_RESPONSE_ACCEPT
);
236 g_signal_connect(pdialog
->shell
->vbox
, "destroy",
237 G_CALLBACK(spaceship_destroy_callback
), pdialog
);
238 gui_dialog_response_set_callback(pdialog
->shell
, spaceship_response
);
241 gtk_grid_set_column_spacing(GTK_GRID(hbox
), 5);
242 gtk_container_add(GTK_CONTAINER(pdialog
->shell
->vbox
), hbox
);
244 frame
=gtk_frame_new(NULL
);
245 gtk_container_add(GTK_CONTAINER(hbox
), frame
);
247 pdialog
->image_canvas
=gtk_drawing_area_new();
248 gtk_widget_set_can_focus(pdialog
->image_canvas
, TRUE
);
249 get_spaceship_dimensions(&w
, &h
);
250 gtk_widget_set_size_request(pdialog
->image_canvas
, w
, h
);
252 gtk_widget_set_events(pdialog
->image_canvas
, GDK_EXPOSURE_MASK
);
253 gtk_container_add(GTK_CONTAINER(frame
), pdialog
->image_canvas
);
254 gtk_widget_realize(pdialog
->image_canvas
);
256 g_signal_connect(pdialog
->image_canvas
, "draw",
257 G_CALLBACK(spaceship_image_canvas_expose
), pdialog
);
259 pdialog
->info_label
= gtk_label_new(get_spaceship_descr(NULL
));
261 gtk_label_set_justify(GTK_LABEL(pdialog
->info_label
), GTK_JUSTIFY_LEFT
);
262 gtk_widget_set_halign(pdialog
->info_label
, GTK_ALIGN_START
);
263 gtk_widget_set_valign(pdialog
->info_label
, GTK_ALIGN_START
);
265 gtk_container_add(GTK_CONTAINER(hbox
), pdialog
->info_label
);
266 gtk_widget_set_name(pdialog
->info_label
, "spaceship_label");
268 dialog_list_prepend(dialog_list
, pdialog
);
270 gtk_widget_grab_focus(pdialog
->image_canvas
);
272 gui_dialog_show_all(pdialog
->shell
);
274 refresh_spaceship_dialog(pdialog
->pplayer
);
279 /****************************************************************
280 Update spaceship dialog info label text
281 *****************************************************************/
282 void spaceship_dialog_update_info(struct spaceship_dialog
*pdialog
)
284 gtk_label_set_text(GTK_LABEL(pdialog
->info_label
),
285 get_spaceship_descr(&pdialog
->pplayer
->spaceship
));
288 /****************************************************************
289 Should also check connectedness, and show non-connected
291 *****************************************************************/
292 void spaceship_dialog_update_image(struct spaceship_dialog
*pdialog
)
294 gtk_widget_queue_draw(pdialog
->image_canvas
);