Qt client - remove right click menu from end turn sidebar
[freeciv.git] / client / gui-gtk-2.0 / gamedlgs.c
blobfc5934e3814880dc455334dc5beb07c04b6e5527
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
22 #include <gtk/gtk.h>
23 #include <gdk/gdkkeysyms.h>
25 /* utility */
26 #include "log.h"
27 #include "shared.h"
28 #include "string_vector.h"
29 #include "support.h"
31 /* common */
32 #include "events.h"
33 #include "fcintl.h"
34 #include "government.h"
35 #include "multipliers.h"
36 #include "packets.h"
37 #include "player.h"
39 /* client */
40 #include "client_main.h"
41 #include "options.h"
43 /* client/gui-gtk-2.0 */
44 #include "chatline.h"
45 #include "cityrep.h"
46 #include "dialogs.h"
47 #include "gui_main.h"
48 #include "gui_stuff.h"
49 #include "ratesdlg.h"
51 #include "gamedlgs.h"
53 /******************************************************************/
54 static GtkWidget *rates_dialog_shell;
55 static GtkWidget *rates_gov_label;
56 static GtkWidget *rates_tax_toggle, *rates_lux_toggle, *rates_sci_toggle;
57 static GtkWidget *rates_tax_label, *rates_lux_label, *rates_sci_label;
58 static GtkObject *rates_tax_adj, *rates_lux_adj, *rates_sci_adj;
60 static GtkWidget *multiplier_dialog_shell;
61 static GtkWidget *multipliers_scale[MAX_NUM_MULTIPLIERS];
63 static gulong rates_tax_sig, rates_lux_sig, rates_sci_sig;
64 /******************************************************************/
66 static int rates_tax_value, rates_lux_value, rates_sci_value;
68 static void rates_changed_callback(GtkAdjustment *adj);
70 /**************************************************************************
71 Set tax values to display
72 **************************************************************************/
73 static void rates_set_values(int tax, int no_tax_scroll,
74 int lux, int no_lux_scroll,
75 int sci, int no_sci_scroll)
77 char buf[64];
78 int tax_lock, lux_lock, sci_lock;
79 int maxrate;
81 tax_lock = GTK_TOGGLE_BUTTON(rates_tax_toggle)->active;
82 lux_lock = GTK_TOGGLE_BUTTON(rates_lux_toggle)->active;
83 sci_lock = GTK_TOGGLE_BUTTON(rates_sci_toggle)->active;
85 if (NULL != client.conn.playing) {
86 maxrate = get_player_bonus(client.conn.playing, EFT_MAX_RATES);
87 } else {
88 maxrate = 100;
90 /* This's quite a simple-minded "double check".. */
91 tax=MIN(tax, maxrate);
92 lux=MIN(lux, maxrate);
93 sci=MIN(sci, maxrate);
95 if(tax+sci+lux!=100)
97 if((tax!=rates_tax_value))
99 if(!lux_lock)
100 lux=MIN(MAX(100-tax-sci, 0), maxrate);
101 if(!sci_lock)
102 sci=MIN(MAX(100-tax-lux, 0), maxrate);
104 else if((lux!=rates_lux_value))
106 if(!tax_lock)
107 tax=MIN(MAX(100-lux-sci, 0), maxrate);
108 if(!sci_lock)
109 sci=MIN(MAX(100-lux-tax, 0), maxrate);
111 else if((sci!=rates_sci_value))
113 if(!lux_lock)
114 lux=MIN(MAX(100-tax-sci, 0), maxrate);
115 if(!tax_lock)
116 tax=MIN(MAX(100-lux-sci, 0), maxrate);
119 if(tax+sci+lux!=100) {
120 tax=rates_tax_value;
121 lux=rates_lux_value;
122 sci=rates_sci_value;
124 rates_tax_value=-1;
125 rates_lux_value=-1;
126 rates_sci_value=-1;
128 no_tax_scroll=0;
129 no_lux_scroll=0;
130 no_sci_scroll=0;
135 if (tax!=rates_tax_value) {
136 fc_snprintf(buf, sizeof(buf), "%3d%%", tax);
137 if (strcmp(buf, GTK_LABEL(rates_tax_label)->label) != 0)
138 gtk_label_set_text(GTK_LABEL(rates_tax_label), buf);
139 if(!no_tax_scroll)
141 g_signal_handler_block(rates_tax_adj, rates_tax_sig);
142 gtk_adjustment_set_value(GTK_ADJUSTMENT(rates_tax_adj), tax/10 );
143 g_signal_handler_unblock(rates_tax_adj, rates_tax_sig);
145 rates_tax_value=tax;
148 if(lux!=rates_lux_value) {
149 fc_snprintf(buf, sizeof(buf), "%3d%%", lux);
150 if (strcmp(buf, GTK_LABEL(rates_lux_label)->label) != 0)
151 gtk_label_set_text(GTK_LABEL(rates_lux_label), buf);
152 if(!no_lux_scroll)
154 g_signal_handler_block(rates_lux_adj, rates_lux_sig);
155 gtk_adjustment_set_value(GTK_ADJUSTMENT(rates_lux_adj), lux/10 );
156 g_signal_handler_unblock(rates_lux_adj, rates_lux_sig);
158 rates_lux_value=lux;
161 if(sci!=rates_sci_value) {
162 fc_snprintf(buf, sizeof(buf), "%3d%%", sci);
163 if (strcmp(buf, GTK_LABEL(rates_sci_label)->label) != 0)
164 gtk_label_set_text(GTK_LABEL(rates_sci_label),buf);
165 if(!no_sci_scroll)
167 g_signal_handler_block(rates_sci_adj, rates_sci_sig);
168 gtk_adjustment_set_value(GTK_ADJUSTMENT(rates_sci_adj), sci/10 );
169 g_signal_handler_unblock(rates_sci_adj, rates_sci_sig);
171 rates_sci_value=sci;
176 /**************************************************************************
177 User changes rates
178 **************************************************************************/
179 static void rates_changed_callback(GtkAdjustment *adj)
181 int percent=adj->value;
183 if(adj==GTK_ADJUSTMENT(rates_tax_adj)) {
184 int tax_value;
186 tax_value=10*percent;
187 tax_value=MIN(tax_value, 100);
188 rates_set_values(tax_value,1, rates_lux_value,0, rates_sci_value,0);
190 else if(adj==GTK_ADJUSTMENT(rates_lux_adj)) {
191 int lux_value;
193 lux_value=10*percent;
194 lux_value=MIN(lux_value, 100);
195 rates_set_values(rates_tax_value,0, lux_value,1, rates_sci_value,0);
197 else {
198 int sci_value;
200 sci_value=10*percent;
201 sci_value=MIN(sci_value, 100);
202 rates_set_values(rates_tax_value,0, rates_lux_value,0, sci_value,1);
207 /**************************************************************************
208 User has responded to rates dialog
209 **************************************************************************/
210 static void rates_command_callback(GtkWidget *w, gint response_id)
212 if (response_id == GTK_RESPONSE_OK) {
213 dsend_packet_player_rates(&client.conn, rates_tax_value, rates_lux_value,
214 rates_sci_value);
216 gtk_widget_destroy(rates_dialog_shell);
219 /**************************************************************************
220 Convert real multiplier display value to scale value
221 **************************************************************************/
222 static int mult_to_scale(const struct multiplier *pmul, int val)
224 return (val - pmul->start) / pmul->step;
227 /**************************************************************************
228 Convert scale units to real multiplier display value
229 **************************************************************************/
230 static int scale_to_mult(const struct multiplier *pmul, int scale)
232 return scale * pmul->step + pmul->start;
235 /**************************************************************************
236 Format value for multiplier scales
237 **************************************************************************/
238 static gchar *multiplier_value_callback(GtkScale *scale, gdouble value,
239 void *udata)
241 const struct multiplier *pmul = udata;
243 return g_strdup_printf("%d", scale_to_mult(pmul, value));
246 /**************************************************************************
247 User has responded to multipliers dialog
248 **************************************************************************/
249 static void multipliers_command_callback(GtkWidget *w, gint response_id)
251 struct packet_player_multiplier mul;
253 if (response_id == GTK_RESPONSE_OK && can_client_issue_orders()) {
254 multipliers_iterate(m) {
255 Multiplier_type_id i = multiplier_index(m);
256 int value = gtk_range_get_value(GTK_RANGE(multipliers_scale[i]));
258 mul.multipliers[i] = scale_to_mult(m, value);
259 } multipliers_iterate_end;
260 mul.count = multiplier_count();
261 send_packet_player_multiplier(&client.conn, &mul);
263 gtk_widget_destroy(multiplier_dialog_shell);
266 /**************************************************************************
267 Update values in multipliers dialog
268 **************************************************************************/
269 static void multiplier_dialog_update_values(bool set_positions)
271 multipliers_iterate(pmul) {
272 Multiplier_type_id multiplier = multiplier_index(pmul);
273 int val = player_multiplier_value(client_player(), pmul);
274 int target = player_multiplier_target_value(client_player(), pmul);
276 fc_assert(multiplier < ARRAY_SIZE(multipliers_scale));
277 fc_assert(scale_to_mult(pmul, mult_to_scale(pmul, val)) == val);
278 fc_assert(scale_to_mult(pmul, mult_to_scale(pmul, target)) == target);
280 /* XXX: if building against ancient Gtk, manage without this bit of UI. */
281 #if GTK_CHECK_VERSION(2,16,0)
282 gtk_scale_clear_marks(GTK_SCALE(multipliers_scale[multiplier]));
283 gtk_scale_add_mark(GTK_SCALE(multipliers_scale[multiplier]),
284 mult_to_scale(pmul, val), GTK_POS_BOTTOM,
285 /* TRANS: current value of policy in force */
286 Q_("?multiplier:Cur"));
287 #endif
289 if (set_positions) {
290 gtk_range_set_value(GTK_RANGE(multipliers_scale[multiplier]),
291 mult_to_scale(pmul, target));
293 } multipliers_iterate_end;
296 /**************************************************************************
297 Callback when server indicates multiplier values have changed
298 **************************************************************************/
299 void real_multipliers_dialog_update(void)
301 if (!multiplier_dialog_shell) {
302 return;
305 /* If dialog belongs to a player rather than an observer, we don't
306 * want to lose any local changes made by the player.
307 * This dialog should be the only way the values can change, anyway. */
308 multiplier_dialog_update_values(!can_client_issue_orders());
311 /****************************************************************
312 Create multipliers dialog
313 ****************************************************************/
314 static GtkWidget *create_multiplier_dialog(void)
316 GtkWidget *shell, *content;
317 GtkWidget *label, *scale;
319 if (can_client_issue_orders()) {
320 shell = gtk_dialog_new_with_buttons(_("Change policies"),
321 NULL,
323 GTK_STOCK_CANCEL,
324 GTK_RESPONSE_CANCEL,
325 GTK_STOCK_OK,
326 GTK_RESPONSE_OK,
327 NULL);
328 } else {
329 shell = gtk_dialog_new_with_buttons(_("Policies"),
330 NULL,
332 GTK_STOCK_CLOSE,
333 GTK_RESPONSE_CLOSE,
334 NULL);
336 setup_dialog(shell, toplevel);
338 gtk_window_set_position(GTK_WINDOW(shell), GTK_WIN_POS_MOUSE);
339 content = gtk_dialog_get_content_area(GTK_DIALOG(shell));
341 if (can_client_issue_orders()) {
342 label = gtk_label_new(_("Changes will not take effect until next turn."));
343 gtk_box_pack_start( GTK_BOX( content ), label, FALSE, FALSE, 0);
346 multipliers_iterate(pmul) {
347 Multiplier_type_id multiplier = multiplier_index(pmul);
349 fc_assert(multiplier < ARRAY_SIZE(multipliers_scale));
350 label = gtk_label_new(multiplier_name_translation(pmul));
351 /* Map each multiplier step to a single step on the UI, to enforce
352 * the step size. */
353 scale = gtk_hscale_new_with_range(mult_to_scale(pmul, pmul->start),
354 mult_to_scale(pmul, pmul->stop), 1);
355 multipliers_scale[multiplier] = scale;
356 gtk_range_set_increments(GTK_RANGE(multipliers_scale[multiplier]),
357 1, MAX(2, mult_to_scale(pmul, pmul->stop) / 10));
358 g_signal_connect(multipliers_scale[multiplier], "format-value",
359 G_CALLBACK(multiplier_value_callback), pmul);
360 g_signal_connect(multipliers_scale[multiplier], "destroy",
361 G_CALLBACK(gtk_widget_destroyed),
362 &multipliers_scale[multiplier]);
363 gtk_box_pack_start( GTK_BOX( content ), label, TRUE, TRUE, 5 );
364 gtk_box_pack_start( GTK_BOX( content ), scale, TRUE, TRUE, 5 );
365 gtk_widget_set_sensitive(multipliers_scale[multiplier],
366 can_client_issue_orders());
367 } multipliers_iterate_end;
369 multiplier_dialog_update_values(TRUE);
371 g_signal_connect(shell, "destroy",
372 G_CALLBACK(gtk_widget_destroyed), &multiplier_dialog_shell);
374 g_signal_connect(shell, "response",
375 G_CALLBACK(multipliers_command_callback), NULL);
377 gtk_widget_show_all(content);
379 return shell;
382 /****************************************************************
383 Popup multipliers dialog
384 *****************************************************************/
385 void popup_multiplier_dialog(void)
387 if (!multiplier_dialog_shell) {
388 multiplier_dialog_shell = create_multiplier_dialog();
391 if (!multiplier_dialog_shell) {
392 return;
395 gtk_window_present(GTK_WINDOW(multiplier_dialog_shell));
398 /****************************************************************
399 Create rates dialog
400 *****************************************************************/
401 static GtkWidget *create_rates_dialog(void)
403 GtkWidget *shell;
404 GtkWidget *frame, *hbox;
406 GtkWidget *scale;
408 if (!can_client_issue_orders()) {
409 return NULL;
412 shell = gtk_dialog_new_with_buttons(_("Select tax, luxury and science rates"),
413 NULL,
415 GTK_STOCK_CANCEL,
416 GTK_RESPONSE_CANCEL,
417 GTK_STOCK_OK,
418 GTK_RESPONSE_OK,
419 NULL);
420 setup_dialog(shell, toplevel);
421 gtk_dialog_set_default_response(GTK_DIALOG(shell), GTK_RESPONSE_OK);
422 gtk_window_set_position(GTK_WINDOW(shell), GTK_WIN_POS_MOUSE);
424 rates_gov_label = gtk_label_new("");
425 gtk_box_pack_start( GTK_BOX( GTK_DIALOG( shell )->vbox ), rates_gov_label, TRUE, TRUE, 5 );
427 frame = gtk_frame_new( _("Tax") );
428 gtk_box_pack_start( GTK_BOX( GTK_DIALOG( shell )->vbox ), frame, TRUE, TRUE, 5 );
430 hbox = gtk_hbox_new( FALSE, 10 );
431 gtk_container_add( GTK_CONTAINER( frame ), hbox );
433 rates_tax_adj = gtk_adjustment_new( 0.0, 0.0, 11.0, 1.0, 1.0, 1.0 );
434 scale = gtk_hscale_new( GTK_ADJUSTMENT( rates_tax_adj ) );
435 gtk_widget_set_size_request(scale, 300, 40);
436 gtk_scale_set_digits( GTK_SCALE( scale ), 0 );
437 gtk_scale_set_draw_value( GTK_SCALE( scale ), FALSE );
438 gtk_box_pack_start( GTK_BOX( hbox ), scale, TRUE, TRUE, 0 );
440 rates_tax_label = gtk_label_new(" 0%");
441 gtk_box_pack_start( GTK_BOX( hbox ), rates_tax_label, TRUE, TRUE, 0 );
442 gtk_widget_set_size_request(rates_tax_label, 40, -1);
444 rates_tax_toggle = gtk_check_button_new_with_label( _("Lock") );
445 gtk_box_pack_start( GTK_BOX( hbox ), rates_tax_toggle, TRUE, TRUE, 0 );
447 frame = gtk_frame_new( _("Luxury") );
448 gtk_box_pack_start( GTK_BOX( GTK_DIALOG( shell )->vbox ), frame, TRUE, TRUE, 5 );
450 hbox = gtk_hbox_new( FALSE, 10 );
451 gtk_container_add( GTK_CONTAINER( frame ), hbox );
453 rates_lux_adj = gtk_adjustment_new( 0.0, 0.0, 11.0, 1.0, 1.0, 1.0 );
454 scale = gtk_hscale_new( GTK_ADJUSTMENT( rates_lux_adj ) );
455 gtk_widget_set_size_request(scale, 300, 40);
456 gtk_scale_set_digits( GTK_SCALE( scale ), 0 );
457 gtk_scale_set_draw_value( GTK_SCALE( scale ), FALSE );
458 gtk_box_pack_start( GTK_BOX( hbox ), scale, TRUE, TRUE, 0 );
460 rates_lux_label = gtk_label_new(" 0%");
461 gtk_box_pack_start( GTK_BOX( hbox ), rates_lux_label, TRUE, TRUE, 0 );
462 gtk_widget_set_size_request(rates_lux_label, 40, -1);
464 rates_lux_toggle = gtk_check_button_new_with_label( _("Lock") );
465 gtk_box_pack_start( GTK_BOX( hbox ), rates_lux_toggle, TRUE, TRUE, 0 );
467 frame = gtk_frame_new( _("Science") );
468 gtk_box_pack_start( GTK_BOX( GTK_DIALOG( shell )->vbox ), frame, TRUE, TRUE, 5 );
470 hbox = gtk_hbox_new( FALSE, 10 );
471 gtk_container_add( GTK_CONTAINER( frame ), hbox );
473 rates_sci_adj = gtk_adjustment_new( 0.0, 0.0, 11.0, 1.0, 1.0, 1.0 );
474 scale = gtk_hscale_new( GTK_ADJUSTMENT( rates_sci_adj ) );
475 gtk_widget_set_size_request(scale, 300, 40);
476 gtk_scale_set_digits( GTK_SCALE( scale ), 0 );
477 gtk_scale_set_draw_value( GTK_SCALE( scale ), FALSE );
478 gtk_box_pack_start( GTK_BOX( hbox ), scale, TRUE, TRUE, 0 );
480 rates_sci_label = gtk_label_new(" 0%");
481 gtk_box_pack_start( GTK_BOX( hbox ), rates_sci_label, TRUE, TRUE, 0 );
482 gtk_widget_set_size_request(rates_sci_label, 40, -1);
484 rates_sci_toggle = gtk_check_button_new_with_label( _("Lock") );
485 gtk_box_pack_start( GTK_BOX( hbox ), rates_sci_toggle, TRUE, TRUE, 0 );
488 g_signal_connect(shell, "response",
489 G_CALLBACK(rates_command_callback), NULL);
490 g_signal_connect(shell, "destroy",
491 G_CALLBACK(gtk_widget_destroyed), &rates_dialog_shell);
493 gtk_widget_show_all( GTK_DIALOG( shell )->vbox );
494 gtk_widget_show_all( GTK_DIALOG( shell )->action_area );
496 rates_tax_value=-1;
497 rates_lux_value=-1;
498 rates_sci_value=-1;
500 rates_tax_sig =
501 g_signal_connect_after(rates_tax_adj, "value_changed",
502 G_CALLBACK(rates_changed_callback), NULL);
504 rates_lux_sig =
505 g_signal_connect_after(rates_lux_adj, "value_changed",
506 G_CALLBACK(rates_changed_callback), NULL);
508 rates_sci_sig =
509 g_signal_connect_after(rates_sci_adj, "value_changed",
510 G_CALLBACK(rates_changed_callback), NULL);
512 rates_set_values(client.conn.playing->economic.tax, 0,
513 client.conn.playing->economic.luxury, 0,
514 client.conn.playing->economic.science, 0);
515 return shell;
519 /****************************************************************
520 Popup rates dialog
521 *****************************************************************/
522 void popup_rates_dialog(void)
524 if (!can_client_issue_orders()) {
525 return;
528 if (!rates_dialog_shell) {
529 rates_dialog_shell = create_rates_dialog();
531 if (!rates_dialog_shell) {
532 return;
535 gchar *buf = g_strdup_printf(_("%s max rate: %d%%"),
536 government_name_for_player(client.conn.playing),
537 get_player_bonus(client.conn.playing, EFT_MAX_RATES));
538 gtk_label_set_text(GTK_LABEL(rates_gov_label), buf);
539 g_free(buf);
541 gtk_window_present(GTK_WINDOW(rates_dialog_shell));