Freeciv-3.1
Loading...
Searching...
No Matches
gamedlgs.c
Go to the documentation of this file.
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.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include <gtk/gtk.h>
23#include <gdk/gdkkeysyms.h>
24
25/* utility */
26#include "log.h"
27#include "shared.h"
28#include "string_vector.h"
29#include "support.h"
30
31/* common */
32#include "events.h"
33#include "fcintl.h"
34#include "government.h"
35#include "multipliers.h"
36
37/* client */
38#include "client_main.h"
39#include "options.h"
40
41/* client/gui-gtk-4.0 */
42#include "chatline.h"
43#include "cityrep.h"
44#include "dialogs.h"
45#include "gui_main.h"
46#include "gui_stuff.h"
47#include "ratesdlg.h"
48
49#include "gamedlgs.h"
50
51/*************************************************************************/
52static GtkWidget *rates_dialog_shell;
53static GtkWidget *rates_gov_label;
57
58static GtkWidget *multiplier_dialog_shell;
60
62/*************************************************************************/
63
65
66static void rates_changed_callback(GtkWidget *range);
67
68/**********************************************************************/
71static void rates_set_values(int tax, int no_tax_scroll,
72 int lux, int no_lux_scroll,
73 int sci, int no_sci_scroll)
74{
75 char buf[64];
76 int tax_lock, lux_lock, sci_lock;
77 int maxrate;
78
79 tax_lock = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rates_tax_toggle));
80 lux_lock = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rates_lux_toggle));
81 sci_lock = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rates_sci_toggle));
82
83 if (NULL != client.conn.playing) {
84 maxrate = get_player_bonus(client.conn.playing, EFT_MAX_RATES);
85 } else {
86 maxrate = 100;
87 }
88
89 /* This's quite a simple-minded "double check".. */
90 tax = MIN(tax, maxrate);
91 lux = MIN(lux, maxrate);
92 sci = MIN(sci, maxrate);
93
94 if (tax + sci + lux != 100) {
95 if (tax != rates_tax_value) {
96 if (!lux_lock) {
97 lux = MIN(MAX(100 - tax - sci, 0), maxrate);
98 }
99 if (!sci_lock) {
100 sci = MIN(MAX(100 - tax - lux, 0), maxrate);
101 }
102 } else if (lux != rates_lux_value) {
103 if (!tax_lock) {
104 tax = MIN(MAX(100 - lux - sci, 0), maxrate);
105 }
106 if (!sci_lock) {
107 sci = MIN(MAX(100 - lux - tax, 0), maxrate);
108 }
109 } else if (sci != rates_sci_value) {
110 if (!lux_lock) {
111 lux = MIN(MAX(100 - tax - sci, 0), maxrate);
112 }
113 if (!tax_lock) {
114 tax = MIN(MAX(100 - lux - sci, 0), maxrate);
115 }
116 }
117
118 if (tax + sci + lux != 100) {
119 tax = rates_tax_value;
120 lux = rates_lux_value;
121 sci = rates_sci_value;
122
123 rates_tax_value = -1;
124 rates_lux_value = -1;
125 rates_sci_value = -1;
126
127 no_tax_scroll = 0;
128 no_lux_scroll = 0;
129 no_sci_scroll = 0;
130 }
131 }
132
133 if (tax != rates_tax_value) {
134 fc_snprintf(buf, sizeof(buf), "%3d%%", tax);
135
136 if (strcmp(buf, gtk_label_get_text(GTK_LABEL(rates_tax_label))) != 0) {
137 gtk_label_set_text(GTK_LABEL(rates_tax_label), buf);
138 }
139 if (!no_tax_scroll) {
140 g_signal_handler_block(rates_tax_scale, rates_tax_sig);
141 gtk_range_set_value(GTK_RANGE(rates_tax_scale), tax / 10);
142 g_signal_handler_unblock(rates_tax_scale, rates_tax_sig);
143 }
144 rates_tax_value = tax;
145 }
146
147 if (lux != rates_lux_value) {
148 fc_snprintf(buf, sizeof(buf), "%3d%%", lux);
149
150 if (strcmp(buf, gtk_label_get_text(GTK_LABEL(rates_lux_label))) != 0) {
151 gtk_label_set_text(GTK_LABEL(rates_lux_label), buf);
152 }
153 if (!no_lux_scroll) {
154 g_signal_handler_block(rates_lux_scale, rates_lux_sig);
155 gtk_range_set_value(GTK_RANGE(rates_lux_scale), lux / 10);
156 g_signal_handler_unblock(rates_lux_scale, rates_lux_sig);
157 }
158 rates_lux_value = lux;
159 }
160
161 if (sci != rates_sci_value) {
162 fc_snprintf(buf, sizeof(buf), "%3d%%", sci);
163
164 if (strcmp(buf, gtk_label_get_text(GTK_LABEL(rates_sci_label))) != 0) {
165 gtk_label_set_text(GTK_LABEL(rates_sci_label), buf);
166 }
167 if (!no_sci_scroll) {
168 g_signal_handler_block(rates_sci_scale, rates_sci_sig);
169 gtk_range_set_value(GTK_RANGE(rates_sci_scale), sci / 10);
170 g_signal_handler_unblock(rates_sci_scale, rates_sci_sig);
171 }
172 rates_sci_value = sci;
173 }
174}
175
176/**********************************************************************/
179static void rates_changed_callback(GtkWidget *range)
180{
181 int percent = gtk_range_get_value(GTK_RANGE(range));
182
183 if (range == rates_tax_scale) {
184 int tax_value;
185
186 tax_value = 10 * percent;
187 tax_value = MIN(tax_value, 100);
189 } else if (range == rates_lux_scale) {
190 int lux_value;
191
192 lux_value = 10 * percent;
193 lux_value = MIN(lux_value, 100);
195 } else {
196 int sci_value;
197
198 sci_value = 10 * percent;
199 sci_value = MIN(sci_value, 100);
201 }
202}
203
204/**********************************************************************/
207static void rates_command_callback(GtkWidget *w, gint response_id)
208{
209 if (response_id == GTK_RESPONSE_OK) {
212 }
213
214 gtk_window_destroy(GTK_WINDOW(rates_dialog_shell));
215}
216
217/**********************************************************************/
220static int mult_to_scale(const struct multiplier *pmul, int val)
221{
222 return (val - pmul->start) / pmul->step;
223}
224
225/**********************************************************************/
228static int scale_to_mult(const struct multiplier *pmul, int scale)
229{
230 return scale * pmul->step + pmul->start;
231}
232
233/**********************************************************************/
236static void multipliers_command_callback(GtkWidget *w, gint response_id)
237{
238 struct packet_player_multiplier mul;
239
240 if (response_id == GTK_RESPONSE_OK && can_client_issue_orders()) {
243 int value = gtk_range_get_value(GTK_RANGE(multipliers_scale[i]));
244
245 mul.multipliers[i] = scale_to_mult(m, value);
247 mul.count = multiplier_count();
249 }
250
251 gtk_window_destroy(GTK_WINDOW(multiplier_dialog_shell));
252}
253
254/**********************************************************************/
257static void multiplier_dialog_update_values(bool set_positions)
258{
259 multipliers_iterate(pmul) {
261 int val = player_multiplier_value(client_player(), pmul);
262 int target = player_multiplier_target_value(client_player(), pmul);
263
265 fc_assert(scale_to_mult(pmul, mult_to_scale(pmul, val)) == val);
266 fc_assert(scale_to_mult(pmul, mult_to_scale(pmul, target)) == target);
267
268 gtk_scale_clear_marks(GTK_SCALE(multipliers_scale[multiplier]));
269 gtk_scale_add_mark(GTK_SCALE(multipliers_scale[multiplier]),
270 mult_to_scale(pmul, val), GTK_POS_BOTTOM,
271 /* TRANS: current value of policy in force */
272 Q_("?multiplier:Now"));
273
274 if (set_positions) {
275 gtk_range_set_value(GTK_RANGE(multipliers_scale[multiplier]),
276 mult_to_scale(pmul, target));
277 }
279}
280
281/**********************************************************************/
285{
287 return;
288 }
289
290 /* If dialog belongs to a player rather than an observer, we don't
291 * want to lose any local changes made by the player.
292 * This dialog should be the only way the values can change, anyway. */
294}
295
296/**********************************************************************/
299static GtkWidget *create_multiplier_dialog(void)
300{
301 GtkWidget *shell, *content;
302 GtkWidget *label, *scale;
303
305 shell = gtk_dialog_new_with_buttons(_("Change policies"),
306 NULL,
307 0,
308 _("_Cancel"),
309 GTK_RESPONSE_CANCEL,
310 _("_OK"),
311 GTK_RESPONSE_OK,
312 NULL);
313 } else {
314 shell = gtk_dialog_new_with_buttons(_("Policies"),
315 NULL,
316 0,
317 _("_Close"),
318 GTK_RESPONSE_CLOSE,
319 NULL);
320 }
322
323 content = gtk_dialog_get_content_area(GTK_DIALOG(shell));
324
326 label = gtk_label_new(_("Changes will not take effect until next turn."));
327 gtk_box_insert_child_after(GTK_BOX(content), label, NULL);
328 }
329
330 multipliers_iterate(pmul) {
332 int mscale;
333
335 label = gtk_label_new(multiplier_name_translation(pmul));
336 /* Map each multiplier step to a single step on the UI, to enforce
337 * the step size. */
338 scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,
339 mult_to_scale(pmul, pmul->start),
340 mult_to_scale(pmul, pmul->stop), 1);
342 mscale = mult_to_scale(pmul, pmul->stop) / 10;
343 gtk_range_set_increments(GTK_RANGE(multipliers_scale[multiplier]),
344 1, MAX(2, mscale));
345 g_signal_connect(multipliers_scale[multiplier], "destroy",
346 G_CALLBACK(widget_destroyed),
348 gtk_box_insert_child_after(GTK_BOX(content), label, NULL);
349 gtk_box_insert_child_after(GTK_BOX(content), scale, NULL);
350 gtk_widget_set_sensitive(multipliers_scale[multiplier],
354
356
357 g_signal_connect(shell, "destroy",
359
360 g_signal_connect(shell, "response",
361 G_CALLBACK(multipliers_command_callback), NULL);
362
363 gtk_widget_show(content);
364
365 return shell;
366}
367
368/**********************************************************************/
372{
375 }
376
378 return;
379 }
380
381 gtk_window_present(GTK_WINDOW(multiplier_dialog_shell));
382}
383
384/**********************************************************************/
387static GtkWidget *create_rates_dialog(void)
388{
389 GtkWidget *shell, *content;
390 GtkWidget *frame, *hbox;
391 int i;
392
394 return NULL;
395 }
396
397 shell = gtk_dialog_new_with_buttons(_("Select tax, luxury and science rates"),
398 NULL,
399 0,
400 _("_Cancel"),
401 GTK_RESPONSE_CANCEL,
402 _("_OK"),
403 GTK_RESPONSE_OK,
404 NULL);
406 gtk_dialog_set_default_response(GTK_DIALOG(shell), GTK_RESPONSE_OK);
407 content = gtk_dialog_get_content_area(GTK_DIALOG(shell));
408
409 rates_gov_label = gtk_label_new("");
410 gtk_box_insert_child_after(GTK_BOX(content), rates_gov_label, NULL);
411
412 frame = gtk_frame_new( _("Tax") );
413 gtk_box_insert_child_after(GTK_BOX(content), frame, NULL);
414
415 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
416 gtk_frame_set_child(GTK_FRAME(frame), hbox);
417
419 gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 10, 1);
420 gtk_range_set_increments(GTK_RANGE(rates_tax_scale), 1, 1);
421 for (i = 0; i <= 10; i++) {
422 gtk_scale_add_mark(GTK_SCALE(rates_tax_scale), i, GTK_POS_TOP, NULL);
423 }
424 gtk_widget_set_size_request(rates_tax_scale, 300, 40);
425 gtk_scale_set_digits(GTK_SCALE(rates_tax_scale), 0);
426 gtk_scale_set_draw_value(GTK_SCALE(rates_tax_scale), FALSE);
427 gtk_box_append(GTK_BOX(hbox), rates_tax_scale);
428
429 rates_tax_label = gtk_label_new(" 0%");
430 gtk_box_append(GTK_BOX(hbox), rates_tax_label);
431 gtk_widget_set_size_request(rates_tax_label, 40, -1);
432
433 rates_tax_toggle = gtk_toggle_button_new_with_label( _("Lock") );
434 gtk_box_append(GTK_BOX(hbox), rates_tax_toggle);
435
436 frame = gtk_frame_new( _("Luxury") );
437 gtk_box_insert_child_after(GTK_BOX(content), frame, NULL);
438
439 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
440 gtk_frame_set_child(GTK_FRAME(frame), hbox);
441
443 gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 10, 1);
444 gtk_range_set_increments(GTK_RANGE(rates_lux_scale), 1, 1);
445 for (i = 0; i <= 10; i++) {
446 gtk_scale_add_mark(GTK_SCALE(rates_lux_scale), i, GTK_POS_TOP, NULL);
447 }
448 gtk_widget_set_size_request(rates_lux_scale, 300, 40);
449 gtk_scale_set_digits(GTK_SCALE(rates_lux_scale), 0);
450 gtk_scale_set_draw_value(GTK_SCALE(rates_lux_scale), FALSE);
451 gtk_box_append(GTK_BOX(hbox), rates_lux_scale);
452
453 rates_lux_label = gtk_label_new(" 0%");
454 gtk_box_append(GTK_BOX(hbox), rates_lux_label);
455 gtk_widget_set_size_request(rates_lux_label, 40, -1);
456
457 rates_lux_toggle = gtk_toggle_button_new_with_label( _("Lock") );
458 gtk_box_append(GTK_BOX(hbox), rates_lux_toggle);
459
460 frame = gtk_frame_new( _("Science") );
461 gtk_box_insert_child_after(GTK_BOX(content), frame, NULL);
462
463 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
464 gtk_frame_set_child(GTK_FRAME(frame), hbox);
465
467 gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 10, 1);
468 gtk_range_set_increments(GTK_RANGE(rates_sci_scale), 1, 1);
469 for (i = 0; i <= 10; i++) {
470 gtk_scale_add_mark(GTK_SCALE(rates_sci_scale), i, GTK_POS_TOP, NULL);
471 }
472 gtk_widget_set_size_request(rates_sci_scale, 300, 40);
473 gtk_scale_set_digits(GTK_SCALE(rates_sci_scale), 0);
474 gtk_scale_set_draw_value(GTK_SCALE(rates_sci_scale), FALSE);
475 gtk_box_append(GTK_BOX(hbox), rates_sci_scale);
476
477 rates_sci_label = gtk_label_new(" 0%");
478 gtk_box_append(GTK_BOX(hbox), rates_sci_label);
479 gtk_widget_set_size_request(rates_sci_label, 40, -1);
480
481 rates_sci_toggle = gtk_toggle_button_new_with_label( _("Lock") );
482 gtk_box_append(GTK_BOX(hbox), rates_sci_toggle);
483
484 g_signal_connect(shell, "response",
485 G_CALLBACK(rates_command_callback), NULL);
486 g_signal_connect(shell, "destroy",
488
489 gtk_widget_show(shell);
490
491 rates_tax_value = -1;
492 rates_lux_value = -1;
493 rates_sci_value = -1;
494
496 g_signal_connect_after(rates_tax_scale, "value-changed",
497 G_CALLBACK(rates_changed_callback), NULL);
498
500 g_signal_connect_after(rates_lux_scale, "value-changed",
501 G_CALLBACK(rates_changed_callback), NULL);
502
504 g_signal_connect_after(rates_sci_scale, "value-changed",
505 G_CALLBACK(rates_changed_callback), NULL);
506
510
511 return shell;
512}
513
514/**********************************************************************/
518{
520 return;
521 }
522
523 if (!rates_dialog_shell) {
525 }
526 if (!rates_dialog_shell) {
527 return;
528 }
529
530 gchar *buf = g_strdup_printf(_("%s max rate: %d%%"),
532 get_player_bonus(client.conn.playing, EFT_MAX_RATES));
533 gtk_label_set_text(GTK_LABEL(rates_gov_label), buf);
534 g_free(buf);
535 gtk_range_set_fill_level(GTK_RANGE(rates_tax_scale),
537 EFT_MAX_RATES)/10);
538 gtk_range_set_fill_level(GTK_RANGE(rates_lux_scale),
540 EFT_MAX_RATES)/10);
541 gtk_range_set_fill_level(GTK_RANGE(rates_sci_scale),
543 EFT_MAX_RATES)/10);
544
545 gtk_window_present(GTK_WINDOW(rates_dialog_shell));
546}
struct civclient client
bool can_client_issue_orders(void)
#define client_player()
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:771
#define MAX_NUM_MULTIPLIERS
Definition fc_types.h:55
int Multiplier_type_id
Definition fc_types.h:356
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
const char * government_name_for_player(const struct player *pplayer)
Definition government.c:153
static void multipliers_command_callback(GtkWidget *w, gint response_id)
Definition gamedlgs.c:246
static gulong rates_sci_sig
Definition gamedlgs.c:61
static GtkWidget * rates_tax_scale
Definition gamedlgs.c:56
static gulong rates_tax_sig
Definition gamedlgs.c:61
static GtkWidget * rates_tax_toggle
Definition gamedlgs.c:54
static int rates_lux_value
Definition gamedlgs.c:64
static GtkWidget * multiplier_dialog_shell
Definition gamedlgs.c:58
static GtkWidget * rates_gov_label
Definition gamedlgs.c:53
static int rates_sci_value
Definition gamedlgs.c:64
static GtkWidget * rates_sci_label
Definition gamedlgs.c:55
static void rates_changed_callback(GtkWidget *range)
Definition gamedlgs.c:179
static GtkWidget * create_rates_dialog(void)
Definition gamedlgs.c:399
static GtkWidget * rates_sci_scale
Definition gamedlgs.c:56
static GtkWidget * rates_lux_scale
Definition gamedlgs.c:56
static GtkWidget * create_multiplier_dialog(void)
Definition gamedlgs.c:308
static gulong rates_lux_sig
Definition gamedlgs.c:61
void popup_multiplier_dialog(void)
Definition gamedlgs.c:383
static GtkWidget * rates_lux_label
Definition gamedlgs.c:55
static GtkWidget * rates_lux_toggle
Definition gamedlgs.c:54
void popup_rates_dialog(void)
Definition gamedlgs.c:533
static void rates_command_callback(GtkWidget *w, gint response_id)
Definition gamedlgs.c:207
static void rates_set_values(int tax, int no_tax_scroll, int lux, int no_lux_scroll, int sci, int no_sci_scroll)
Definition gamedlgs.c:71
static GtkWidget * rates_tax_label
Definition gamedlgs.c:55
static int rates_tax_value
Definition gamedlgs.c:64
void real_multipliers_dialog_update(void *unused)
Definition gamedlgs.c:293
static int scale_to_mult(const struct multiplier *pmul, int scale)
Definition gamedlgs.c:227
static int mult_to_scale(const struct multiplier *pmul, int val)
Definition gamedlgs.c:219
static GtkWidget * rates_sci_toggle
Definition gamedlgs.c:54
static GtkWidget * multipliers_scale[MAX_NUM_MULTIPLIERS]
Definition gamedlgs.c:59
static void multiplier_dialog_update_values(bool set_positions)
Definition gamedlgs.c:266
static GtkWidget * rates_dialog_shell
Definition gamedlgs.c:52
GtkWidget * toplevel
Definition gui_main.c:124
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:281
static struct gui_dialog * shell
Definition messagedlg.c:39
void widget_destroyed(GtkWidget *wdg, void *data)
Definition gui_stuff.c:1145
#define fc_assert(condition)
Definition log.h:176
Multiplier_type_id multiplier_count(void)
Definition multipliers.c:88
const char * multiplier_name_translation(const struct multiplier *pmul)
Definition multipliers.c:97
bool multiplier_can_be_changed(struct multiplier *pmul, struct player *pplayer)
Multiplier_type_id multiplier_index(const struct multiplier *pmul)
Definition multipliers.c:80
#define multipliers_iterate(_mul_)
Definition multipliers.h:61
#define multipliers_iterate_end
Definition multipliers.h:67
int dsend_packet_player_rates(struct connection *pc, int tax, int luxury, int science)
int send_packet_player_multiplier(struct connection *pc, const struct packet_player_multiplier *packet)
int player_multiplier_target_value(const struct player *pplayer, const struct multiplier *pmul)
Definition player.c:1945
int player_multiplier_value(const struct player *pplayer, const struct multiplier *pmul)
Definition player.c:1922
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
struct connection conn
Definition client_main.h:96
struct player * playing
Definition connection.h:156
int multipliers[MAX_NUM_MULTIPLIERS]
struct player_economic economic
Definition player.h:284
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47