1 /* Pioneers - Implementation of the excellent Settlers of Catan board game.
2 * Go buy a copy.
3 *
4 * Copyright (C) 1999 Dave Cole
5 * Copyright (C) 2003 Bas Wijnen <shevek@fmf.nl>
6 * Copyright (C) 2005 Roland Clobus <rclobus@bigfoot.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include "config.h"
24 #include "frontend.h"
25 #include "gui.h"
26
27 static GtkWidget *settings_dlg = NULL;
28
29 enum { TYPE_NUM,
30 TYPE_BOOL,
31 TYPE_STRING
32 };
33
add_setting_desc(GtkWidget * grid,guint row,guint col,const gchar * desc)34 static void add_setting_desc(GtkWidget * grid, guint row, guint col,
35 const gchar * desc)
36 {
37 GtkWidget *label;
38
39 label = gtk_label_new(desc);
40 gtk_widget_show(label);
41 gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1);
42 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
43 }
44
add_setting_desc_with_image(GtkWidget * grid,guint row,guint col,const gchar * desc,const gchar * iconname)45 static void add_setting_desc_with_image(GtkWidget * grid, guint row,
46 guint col, const gchar * desc,
47 const gchar * iconname)
48 {
49 GtkWidget *icon;
50
51 icon = gtk_image_new_from_icon_name(iconname, GTK_ICON_SIZE_MENU);
52 gtk_widget_show(icon);
53 gtk_grid_attach(GTK_GRID(grid), icon, col, row, 1, 1);
54
55 add_setting_desc(grid, row, col + 1, desc);
56 }
57
add_setting_val(GtkWidget * grid,guint row,guint col,gint type,gint int_val,const gchar * char_val,gboolean right_aligned)58 static void add_setting_val(GtkWidget * grid, guint row, guint col,
59 gint type, gint int_val,
60 const gchar * char_val, gboolean right_aligned)
61 {
62 GtkWidget *label;
63 gchar *label_var;
64
65 switch (type) {
66 case TYPE_NUM:
67 label_var = g_strdup_printf("%i", int_val);
68 break;
69
70 case TYPE_BOOL:
71 if (int_val != 0) {
72 label_var = g_strdup(_("Yes"));
73 } else {
74 label_var = g_strdup(_("No"));
75 }
76 break;
77 case TYPE_STRING:
78 if (char_val == NULL) {
79 char_val = " ";
80 }
81 label_var = g_strdup_printf("%s", char_val);
82 break;
83
84 default:
85 label_var = g_strdup(_("Unknown"));
86 break;
87 }
88
89 label = gtk_label_new(label_var);
90 g_free(label_var);
91 gtk_widget_show(label);
92 gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1);
93 gtk_label_set_xalign(GTK_LABEL(label),
94 (right_aligned ? 1.0 : 0.0));
95 }
96
settings_create_content(void)97 static GtkWidget *settings_create_content(void)
98 {
99 const GameParams *game_params;
100 GtkWidget *dlg_vbox;
101 GtkWidget *alignment;
102 GtkWidget *vbox;
103 GtkWidget *hbox;
104 GtkWidget *grid;
105 GtkWidget *label;
106 gchar *sevens_desc;
107 gchar *island_bonus;
108 guint row;
109
110 /* Create some space inside the dialog */
111 dlg_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
112 gtk_container_set_border_width(GTK_CONTAINER(dlg_vbox), 6);
113 gtk_widget_show(dlg_vbox);
114
115 game_params = get_game_params();
116 if (game_params == NULL) {
117 label = gtk_label_new(_("No game in progress..."));
118 gtk_box_pack_start(GTK_BOX(dlg_vbox), label, TRUE, TRUE,
119 6);
120 gtk_widget_show(label);
121
122 return dlg_vbox;
123 }
124
125 label = gtk_label_new(NULL);
126 gtk_label_set_markup(GTK_LABEL(label),
127 /* Label */
128 _("<b>General settings</b>"));
129 gtk_widget_show(label);
130 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
131 gtk_box_pack_start(GTK_BOX(dlg_vbox), label, FALSE, TRUE, 0);
132
133 alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
134 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
135 gtk_widget_show(alignment);
136 gtk_box_pack_start(GTK_BOX(dlg_vbox), alignment, FALSE, FALSE, 0);
137
138 grid = gtk_grid_new();
139 gtk_widget_show(grid);
140 gtk_container_add(GTK_CONTAINER(alignment), grid);
141 gtk_grid_set_row_spacing(GTK_GRID(grid), 3);
142 gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
143
144 row = 0;
145 add_setting_desc(grid, row, 0, _("Number of players:"));
146 add_setting_val(grid, row, 1, TYPE_NUM, game_params->num_players,
147 NULL, FALSE);
148 row++;
149 add_setting_desc(grid, row, 0, _("Victory point target:"));
150 add_setting_val(grid, row, 1, TYPE_NUM,
151 game_params->victory_points, NULL, FALSE);
152 row++;
153 add_setting_desc(grid, row, 0, _("Random terrain:"));
154 add_setting_val(grid, row, 1, TYPE_BOOL,
155 game_params->random_terrain, NULL, FALSE);
156 row++;
157 add_setting_desc(grid, row, 0, _("Allow trade between players:"));
158 add_setting_val(grid, row, 1, TYPE_BOOL,
159 game_params->domestic_trade, NULL, FALSE);
160 row++;
161 add_setting_desc(grid, row, 0,
162 _("Allow trade only before building or buying:"));
163 add_setting_val(grid, row, 1, TYPE_BOOL, game_params->strict_trade,
164 NULL, FALSE);
165 row++;
166 add_setting_desc(grid, row, 0,
167 _("Check victory only at end of turn:"));
168 add_setting_val(grid, row, 1, TYPE_BOOL,
169 game_params->check_victory_at_end_of_turn, NULL,
170 FALSE);
171 row++;
172 add_setting_desc(grid, row, 0, _("Amount of each resource:"));
173 add_setting_val(grid, row, 1, TYPE_NUM,
174 game_params->resource_count, NULL, FALSE);
175
176 if (game_params->sevens_rule == 0) {
177 sevens_desc = g_strdup(_("Normal"));
178 } else if (game_params->sevens_rule == 1) {
179 sevens_desc = g_strdup(_("Reroll on 1st 2 turns"));
180 } else if (game_params->sevens_rule == 2) {
181 sevens_desc = g_strdup(_("Reroll all 7s"));
182 } else {
183 sevens_desc = g_strdup(_("Unknown"));
184 }
185 row++;
186 add_setting_desc(grid, row, 0, _("Sevens rule:"));
187 add_setting_val(grid, row, 1, TYPE_STRING, 0, sevens_desc, FALSE);
188 g_free(sevens_desc);
189
190 row++;
191 add_setting_desc(grid, row, 0,
192 _("Use dice deck instead of dice:"));
193 add_setting_val(grid, row, 1, TYPE_BOOL,
194 game_params->use_dice_deck, NULL, FALSE);
195
196 row++;
197 add_setting_desc(grid, row, 0, _("Number of dice decks:"));
198 add_setting_val(grid, row, 1, TYPE_NUM,
199 game_params->num_dice_decks, NULL, FALSE);
200
201 row++;
202 add_setting_desc(grid, row, 0,
203 _(""
204 "Number of dice cards removed after shuffling:"));
205 add_setting_val(grid, row, 1, TYPE_NUM,
206 game_params->num_removed_dice_cards, NULL, FALSE);
207
208 row++;
209 add_setting_desc(grid, row, 0,
210 _("Use the pirate to block ships:"));
211 add_setting_val(grid, row, 1, TYPE_BOOL, game_params->use_pirate,
212 NULL, FALSE);
213
214 if (game_params->island_discovery_bonus) {
215 guint idx;
216 island_bonus =
217 g_strdup_printf("%d",
218 g_array_index
219 (game_params->island_discovery_bonus,
220 gint, 0));
221 for (idx = 1;
222 idx < game_params->island_discovery_bonus->len;
223 idx++) {
224 gchar *old = island_bonus;
225 gchar *number = g_strdup_printf("%d",
226 g_array_index
227 (game_params->
228 island_discovery_bonus,
229 gint, idx));
230 island_bonus =
231 g_strconcat(island_bonus, ", ", number, NULL);
232 g_free(old);
233 g_free(number);
234 }
235 } else {
236 island_bonus = g_strdup(_("No"));
237 }
238 row++;
239 add_setting_desc(grid, row, 0, _("Island discovery bonuses:"));
240 add_setting_val(grid, row, 1, TYPE_STRING, 0, island_bonus, FALSE);
241 g_free(island_bonus);
242
243 /* Double space, otherwise the columns are too close */
244 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 24);
245 gtk_widget_show(hbox);
246 gtk_box_pack_start(GTK_BOX(dlg_vbox), hbox, TRUE, FALSE, 0);
247
248 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
249 gtk_widget_show(vbox);
250 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
251
252 label = gtk_label_new(NULL);
253 gtk_label_set_markup(GTK_LABEL(label),
254 /* Label */
255 _("<b>Building quotas</b>"));
256 gtk_widget_show(label);
257 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
258 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
259
260 alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
261 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
262 gtk_widget_show(alignment);
263 gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, TRUE, 0);
264
265 grid = gtk_grid_new();
266 gtk_widget_show(grid);
267 gtk_container_add(GTK_CONTAINER(alignment), grid);
268 gtk_grid_set_row_spacing(GTK_GRID(grid), 3);
269 gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
270 row = 0;
271
272 add_setting_desc_with_image(grid, row, 0, _("Roads:"), ICON_ROAD);
273 add_setting_val(grid, row, 2, TYPE_NUM,
274 game_params->num_build_type[BUILD_ROAD], NULL,
275 TRUE);
276 row++;
277 add_setting_desc_with_image(grid, row, 0, _("Settlements:"),
278 ICON_SETTLEMENT);
279 add_setting_val(grid, row, 2, TYPE_NUM,
280 game_params->num_build_type[BUILD_SETTLEMENT],
281 NULL, TRUE);
282 row++;
283 add_setting_desc_with_image(grid, row, 0, _("Cities:"), ICON_CITY);
284 add_setting_val(grid, row, 2, TYPE_NUM,
285 game_params->num_build_type[BUILD_CITY], NULL,
286 TRUE);
287 row++;
288 add_setting_desc_with_image(grid, row, 0, _("City walls:"),
289 ICON_CITY_WALL);
290 add_setting_val(grid, row, 2, TYPE_NUM,
291 game_params->num_build_type[BUILD_CITY_WALL], NULL,
292 TRUE);
293 row++;
294 add_setting_desc_with_image(grid, row, 0, _("Ships:"), ICON_SHIP);
295 add_setting_val(grid, row, 2, TYPE_NUM,
296 game_params->num_build_type[BUILD_SHIP], NULL,
297 TRUE);
298 row++;
299 add_setting_desc_with_image(grid, row, 0, _("Bridges:"),
300 ICON_BRIDGE);
301 add_setting_val(grid, row, 2, TYPE_NUM,
302 game_params->num_build_type[BUILD_BRIDGE], NULL,
303 TRUE);
304
305 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
306 gtk_widget_show(vbox);
307 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, TRUE, 0);
308
309 label = gtk_label_new(NULL);
310 gtk_label_set_markup(GTK_LABEL(label),
311 /* Label */
312 _("<b>Development card deck</b>"));
313 gtk_widget_show(label);
314 gtk_label_set_xalign(GTK_LABEL(label), 0.0);
315 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
316
317 alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
318 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
319 gtk_widget_show(alignment);
320 gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, TRUE, 0);
321
322 grid = gtk_grid_new();
323 gtk_widget_show(grid);
324 gtk_container_add(GTK_CONTAINER(alignment), grid);
325 gtk_grid_set_row_spacing(GTK_GRID(grid), 3);
326 gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
327
328 add_setting_desc(grid, 0, 0, _("Road building cards:"));
329 add_setting_val(grid, 0, 1, TYPE_NUM,
330 game_params->num_develop_type[DEVEL_ROAD_BUILDING],
331 NULL, TRUE);
332 add_setting_desc(grid, 1, 0, _("Monopoly cards:"));
333 add_setting_val(grid, 1, 1, TYPE_NUM,
334 game_params->num_develop_type[DEVEL_MONOPOLY],
335 NULL, TRUE);
336 add_setting_desc(grid, 2, 0, _("Year of plenty cards:"));
337 add_setting_val(grid, 2, 1, TYPE_NUM,
338 game_params->num_develop_type
339 [DEVEL_YEAR_OF_PLENTY], NULL, TRUE);
340 add_setting_desc(grid, 3, 0, _("Chapel cards:"));
341 add_setting_val(grid, 3, 1, TYPE_NUM,
342 game_params->num_develop_type[DEVEL_CHAPEL], NULL,
343 TRUE);
344 add_setting_desc(grid, 4, 0, _("Pioneer university cards:"));
345 add_setting_val(grid, 4, 1, TYPE_NUM,
346 game_params->num_develop_type[DEVEL_UNIVERSITY],
347 NULL, TRUE);
348 add_setting_desc(grid, 5, 0, _("Governor's house cards:"));
349 add_setting_val(grid, 5, 1, TYPE_NUM,
350 game_params->num_develop_type
351 [DEVEL_GOVERNORS_HOUSE], NULL, TRUE);
352 add_setting_desc(grid, 6, 0, _("Library cards:"));
353 add_setting_val(grid, 6, 1, TYPE_NUM,
354 game_params->num_develop_type[DEVEL_LIBRARY], NULL,
355 TRUE);
356 add_setting_desc(grid, 7, 0, _("Market cards:"));
357 add_setting_val(grid, 7, 1, TYPE_NUM,
358 game_params->num_develop_type[DEVEL_MARKET], NULL,
359 TRUE);
360 add_setting_desc(grid, 8, 0, _("Soldier cards:"));
361 add_setting_val(grid, 8, 1, TYPE_NUM,
362 game_params->num_develop_type[DEVEL_SOLDIER], NULL,
363 TRUE);
364
365 return dlg_vbox;
366 }
367
settings_rules_changed(void)368 static void settings_rules_changed(void)
369 {
370 if (settings_dlg) {
371 GtkWidget *vbox;
372 GtkWidget *dlg_vbox;
373 GList *list;
374
375 dlg_vbox =
376 gtk_dialog_get_content_area(GTK_DIALOG(settings_dlg));
377 list = gtk_container_get_children(GTK_CONTAINER(dlg_vbox));
378
379 if (g_list_length(list) > 0)
380 gtk_widget_destroy(GTK_WIDGET(list->data));
381 g_list_free(list);
382
383 vbox = settings_create_content();
384 gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, FALSE,
385 0);
386 }
387 }
388
settings_create_dlg(GtkWindow * parent_window)389 GtkWidget *settings_create_dlg(GtkWindow * parent_window)
390 {
391 GtkWidget *dlg_vbox;
392 GtkWidget *vbox;
393
394 if (settings_dlg != NULL)
395 return settings_dlg;
396
397 settings_dlg = gtk_dialog_new_with_buttons(
398 /* Dialog caption */
399 _(""
400 "Current Game Settings"),
401 parent_window,
402 GTK_DIALOG_DESTROY_WITH_PARENT,
403 /* Button text */
404 _("_Close"),
405 GTK_RESPONSE_CLOSE,
406 NULL);
407 g_signal_connect(G_OBJECT(settings_dlg), "destroy",
408 G_CALLBACK(gtk_widget_destroyed), &settings_dlg);
409
410 dlg_vbox = gtk_dialog_get_content_area(GTK_DIALOG(settings_dlg));
411 gtk_widget_show(dlg_vbox);
412
413 vbox = settings_create_content();
414 gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, FALSE, 0);
415
416 g_signal_connect(G_OBJECT(settings_dlg), "response",
417 G_CALLBACK(gtk_widget_destroy), NULL);
418
419 gtk_widget_show(settings_dlg);
420
421 return settings_dlg;
422 }
423
settings_init(void)424 void settings_init(void)
425 {
426 gui_rules_register_callback(G_CALLBACK(settings_rules_changed));
427 }
428