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