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"
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
;
177 pdialog
=(struct spaceship_dialog
*)data
;
178 spaceship_dialog_update_image(pdialog
);
182 /****************************************************************
183 Spaceship dialog being destroyed
184 *****************************************************************/
185 static void spaceship_destroy_callback(GtkWidget
*w
, gpointer data
)
187 struct spaceship_dialog
*pdialog
= (struct spaceship_dialog
*)data
;
189 dialog_list_remove(dialog_list
, pdialog
);
194 /****************************************************************
195 User has responded to spaceship dialog
196 *****************************************************************/
197 static void spaceship_response(struct gui_dialog
*dlg
, int response
,
201 case GTK_RESPONSE_ACCEPT
:
203 send_packet_spaceship_launch(&client
.conn
);
208 gui_dialog_destroy(dlg
);
213 /****************************************************************
214 Create new spaceship dialog
215 *****************************************************************/
216 struct spaceship_dialog
*create_spaceship_dialog(struct player
*pplayer
)
218 struct spaceship_dialog
*pdialog
;
219 GtkWidget
*hbox
, *frame
;
222 pdialog
=fc_malloc(sizeof(struct spaceship_dialog
));
223 pdialog
->pplayer
=pplayer
;
225 gui_dialog_new(&pdialog
->shell
, GTK_NOTEBOOK(top_notebook
), NULL
, TRUE
);
226 gui_dialog_set_title(pdialog
->shell
, player_name(pplayer
));
228 gui_dialog_add_button(pdialog
->shell
,
229 _("_Launch"), GTK_RESPONSE_ACCEPT
);
230 gui_dialog_add_button(pdialog
->shell
,
231 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
);
233 g_signal_connect(pdialog
->shell
->vbox
, "destroy",
234 G_CALLBACK(spaceship_destroy_callback
), pdialog
);
235 gui_dialog_response_set_callback(pdialog
->shell
, spaceship_response
);
237 hbox
=gtk_hbox_new(FALSE
, 5);
238 gtk_box_pack_start(GTK_BOX(pdialog
->shell
->vbox
), hbox
, FALSE
, FALSE
, 0);
240 frame
=gtk_frame_new(NULL
);
241 gtk_box_pack_start(GTK_BOX(hbox
), frame
, FALSE
, FALSE
, 0);
243 pdialog
->image_canvas
=gtk_drawing_area_new();
244 GTK_WIDGET_SET_FLAGS(pdialog
->image_canvas
, GTK_CAN_FOCUS
);
245 get_spaceship_dimensions(&w
, &h
);
246 gtk_widget_set_size_request(pdialog
->image_canvas
, w
, h
);
248 gtk_widget_set_events(pdialog
->image_canvas
, GDK_EXPOSURE_MASK
);
249 gtk_container_add(GTK_CONTAINER(frame
), pdialog
->image_canvas
);
250 gtk_widget_realize(pdialog
->image_canvas
);
252 g_signal_connect(pdialog
->image_canvas
, "expose_event",
253 G_CALLBACK(spaceship_image_canvas_expose
), pdialog
);
255 pdialog
->info_label
= gtk_label_new(get_spaceship_descr(NULL
));
257 gtk_label_set_justify(GTK_LABEL(pdialog
->info_label
), GTK_JUSTIFY_LEFT
);
258 gtk_misc_set_alignment(GTK_MISC(pdialog
->info_label
), 0.0, 0.0);
260 gtk_box_pack_start(GTK_BOX(hbox
), pdialog
->info_label
, FALSE
, FALSE
, 0);
261 gtk_widget_set_name(pdialog
->info_label
, "spaceship_label");
263 dialog_list_prepend(dialog_list
, pdialog
);
265 gtk_widget_grab_focus(pdialog
->image_canvas
);
267 gui_dialog_show_all(pdialog
->shell
);
269 refresh_spaceship_dialog(pdialog
->pplayer
);
274 /****************************************************************
275 Update spaceship dialog info label text
276 *****************************************************************/
277 void spaceship_dialog_update_info(struct spaceship_dialog
*pdialog
)
279 gtk_label_set_text(GTK_LABEL(pdialog
->info_label
),
280 get_spaceship_descr(&pdialog
->pplayer
->spaceship
));
283 /****************************************************************
284 Should also check connectedness, and show non-connected
286 *****************************************************************/
287 void spaceship_dialog_update_image(struct spaceship_dialog
*pdialog
)
289 struct canvas store
= {.type
= CANVAS_PIXMAP
,
290 .v
= {.pixmap
= pdialog
->image_canvas
->window
}};
292 put_spaceship(&store
, 0, 0, pdialog
->pplayer
);