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,2006 Bas Wijnen <shevek@fmf.nl>
6 * Copyright (C) 2010 Roland Clobus <rclobus@rclobus.nl>
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 <stdlib.h>
25 #include "frontend.h"
26 #include "player-icon.h"
27 #include "config-gnome.h"
28 #include "client.h"
29 #include "common_gtk.h"
30
31 typedef struct {
32 GtkWidget *dlg;
33 GtkWidget *name_entry;
34 GtkWidget *check_btn;
35 GtkWidget *image;
36 GtkWidget *style_hbox;
37 GtkWidget *color_btn1;
38 GtkWidget *color_btn2;
39 GtkWidget *variant_btn;
40 gchar *original_name;
41 gchar *original_style;
42 gchar *current_style;
43 gulong name_change_cb_id;
44 } DialogData;
45
46 static DialogData name_dialog;
47
48 static void update_icon(DialogData * data);
49
name_change_name_cb(NotifyingString * name)50 static void name_change_name_cb(NotifyingString * name)
51 {
52 gchar *nm = notifying_string_get(name);
53 gtk_entry_set_text(GTK_ENTRY(name_dialog.name_entry), nm);
54 g_free(nm);
55 }
56
change_name_cb(G_GNUC_UNUSED GtkDialog * dlg,int response_id,gpointer user_data)57 static void change_name_cb(G_GNUC_UNUSED GtkDialog * dlg, int response_id,
58 gpointer user_data)
59 {
60 DialogData *dialog = user_data;
61 g_signal_handler_disconnect(requested_name,
62 dialog->name_change_cb_id);
63 if (response_id == GTK_RESPONSE_OK) {
64 const gchar *new_name =
65 gtk_entry_get_text(GTK_ENTRY(dialog->name_entry));
66 const gchar *new_style = dialog->current_style;
67 if (0 != strcmp(new_name, dialog->original_name)) {
68 notifying_string_set(requested_name, new_name);
69 }
70 if (0 != strcmp(new_style, dialog->original_style)) {
71 notifying_string_set(requested_style, new_style);
72 }
73 }
74 g_free(dialog->original_name);
75 g_free(dialog->original_style);
76 g_free(dialog->current_style);
77 gtk_widget_destroy(GTK_WIDGET(dialog->dlg));
78 }
79
realize_player_icon_cb(G_GNUC_UNUSED GtkWidget * widget,gpointer user_data)80 static void realize_player_icon_cb(G_GNUC_UNUSED GtkWidget * widget,
81 gpointer user_data)
82 {
83 DialogData *dialog = user_data;
84
85 update_icon(dialog);
86 }
87
change_style_cb(G_GNUC_UNUSED GtkWidget * widget,gpointer user_data)88 static void change_style_cb(G_GNUC_UNUSED GtkWidget * widget,
89 gpointer user_data)
90 {
91 DialogData *dialog = user_data;
92
93 g_free(dialog->current_style);
94 if (gtk_toggle_button_get_active
95 (GTK_TOGGLE_BUTTON(dialog->check_btn))) {
96 GdkRGBA c1;
97 GdkRGBA c2;
98 guint variant;
99 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER
100 (dialog->color_btn1), &c1);
101 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER
102 (dialog->color_btn2), &c2);
103 variant =
104 gtk_range_get_value(GTK_RANGE(dialog->variant_btn)) -
105 1;
106 dialog->current_style =
107 playericon_create_human_style(&c1, variant, &c2);
108 } else {
109 dialog->current_style = g_strdup(default_player_style);
110 }
111 update_icon(dialog);
112 }
113
activate_style_cb(GtkWidget * widget,gpointer user_data)114 static void activate_style_cb(GtkWidget * widget, gpointer user_data)
115 {
116 DialogData *dialog = user_data;
117 gtk_widget_set_sensitive(dialog->style_hbox,
118 gtk_toggle_button_get_active
119 (GTK_TOGGLE_BUTTON(dialog->check_btn)));
120 change_style_cb(widget, user_data);
121 }
122
name_create_dlg(void)123 void name_create_dlg(void)
124 {
125 GtkWidget *dlg_vbox;
126 GtkWidget *hbox;
127 GtkWidget *lbl;
128 GdkRGBA face_color, variant_color;
129 guint variant;
130 gboolean parse_ok;
131 gint width;
132 gint height;
133
134 if (name_dialog.dlg != NULL) {
135 gtk_window_present(GTK_WINDOW(name_dialog.dlg));
136 return;
137 };
138
139 name_dialog.dlg = gtk_dialog_new_with_buttons(
140 /* Dialog caption */
141 _(""
142 "Change Player Name"),
143 GTK_WINDOW
144 (app_window),
145 GTK_DIALOG_DESTROY_WITH_PARENT,
146 /* Button text */
147 _("_Cancel"),
148 GTK_RESPONSE_CANCEL,
149 /* Button text */
150 _("_OK"),
151 GTK_RESPONSE_OK,
152 NULL);
153 gtk_dialog_set_default_response(GTK_DIALOG(name_dialog.dlg),
154 GTK_RESPONSE_OK);
155 g_signal_connect(G_OBJECT(name_dialog.dlg), "destroy",
156 G_CALLBACK(gtk_widget_destroyed),
157 &name_dialog.dlg);
158 gtk_widget_realize(name_dialog.dlg);
159 gdk_window_set_functions(gtk_widget_get_window(name_dialog.dlg),
160 GDK_FUNC_MOVE | GDK_FUNC_CLOSE);
161
162 dlg_vbox =
163 gtk_dialog_get_content_area(GTK_DIALOG(name_dialog.dlg));
164 gtk_widget_show(dlg_vbox);
165
166 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
167 gtk_widget_show(hbox);
168 gtk_box_pack_start(GTK_BOX(dlg_vbox), hbox, FALSE, TRUE, 0);
169 gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
170
171 /* Label */
172 lbl = gtk_label_new(_("Player name:"));
173 gtk_widget_show(lbl);
174 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, TRUE, 0);
175 gtk_label_set_xalign(GTK_LABEL(lbl), 1.0);
176
177 name_dialog.name_entry = gtk_entry_new();
178 gtk_entry_set_max_length(GTK_ENTRY(name_dialog.name_entry),
179 MAX_NAME_LENGTH);
180 gtk_widget_show(name_dialog.name_entry);
181 gtk_box_pack_start(GTK_BOX(hbox), name_dialog.name_entry, TRUE,
182 TRUE, 0);
183 gtk_entry_set_width_chars(GTK_ENTRY(name_dialog.name_entry),
184 MAX_NAME_LENGTH);
185 name_dialog.original_name = notifying_string_get(requested_name);
186 gtk_entry_set_text(GTK_ENTRY(name_dialog.name_entry),
187 name_dialog.original_name);
188
189 gtk_entry_set_activates_default(GTK_ENTRY(name_dialog.name_entry),
190 TRUE);
191 name_dialog.name_change_cb_id =
192 g_signal_connect(requested_name, "changed",
193 G_CALLBACK(name_change_name_cb), NULL);
194
195 name_dialog.original_style = notifying_string_get(requested_style);
196 name_dialog.current_style = notifying_string_get(requested_style);
197 parse_ok =
198 playericon_parse_human_style(name_dialog.current_style,
199 &face_color, &variant,
200 &variant_color);
201
202 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
203 gtk_widget_show(hbox);
204 gtk_box_pack_start(GTK_BOX(dlg_vbox), hbox, FALSE, TRUE, 0);
205 gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
206
207 name_dialog.style_hbox =
208 gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
209 gtk_widget_set_sensitive(name_dialog.style_hbox, FALSE);
210
211 name_dialog.check_btn = gtk_check_button_new();
212 gtk_widget_show(name_dialog.check_btn);
213 gtk_box_pack_start(GTK_BOX(hbox), name_dialog.check_btn, FALSE,
214 TRUE, 0);
215 g_signal_connect(name_dialog.check_btn, "toggled",
216 G_CALLBACK(activate_style_cb), &name_dialog);
217
218 name_dialog.image = gtk_image_new();
219 gtk_icon_size_lookup(GTK_ICON_SIZE_DIALOG, &width, &height);
220 gtk_widget_set_size_request(name_dialog.image, width, height);
221 gtk_widget_show(name_dialog.image);
222 gtk_box_pack_start(GTK_BOX(hbox), name_dialog.image, FALSE, TRUE,
223 0);
224 g_signal_connect(G_OBJECT(name_dialog.image), "realize",
225 G_CALLBACK(realize_player_icon_cb), &name_dialog);
226
227 gtk_widget_show(name_dialog.style_hbox);
228 gtk_box_pack_start(GTK_BOX(hbox), name_dialog.style_hbox, TRUE,
229 TRUE, 0);
230 gtk_container_set_border_width(GTK_CONTAINER
231 (name_dialog.style_hbox), 5);
232
233 /* Label: set player icon preferences */
234 lbl = gtk_label_new(_("Face:"));
235 gtk_widget_show(lbl);
236 gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox), lbl, FALSE,
237 TRUE, 0);
238 gtk_label_set_xalign(GTK_LABEL(lbl), 1.0);
239
240 name_dialog.color_btn1 =
241 gtk_color_button_new_with_rgba(&face_color);
242 gtk_widget_show(name_dialog.color_btn1);
243 gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox),
244 name_dialog.color_btn1, FALSE, TRUE, 0);
245 g_signal_connect(name_dialog.color_btn1, "color-set",
246 G_CALLBACK(change_style_cb), &name_dialog);
247
248 /* Label: set player icon preferences */
249 lbl = gtk_label_new(_("Variant:"));
250 gtk_widget_show(lbl);
251 gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox), lbl, FALSE,
252 TRUE, 0);
253 gtk_label_set_xalign(GTK_LABEL(lbl), 1.0);
254
255 name_dialog.color_btn2 =
256 gtk_color_button_new_with_rgba(&variant_color);
257 gtk_widget_show(name_dialog.color_btn2);
258 gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox),
259 name_dialog.color_btn2, FALSE, TRUE, 0);
260 g_signal_connect(name_dialog.color_btn2, "color-set",
261 G_CALLBACK(change_style_cb), &name_dialog);
262
263 name_dialog.variant_btn =
264 gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 1.0,
265 playericon_human_style_count(), 1.0);
266 gtk_widget_set_size_request(name_dialog.variant_btn, width, -1);
267 gtk_scale_set_digits(GTK_SCALE(name_dialog.variant_btn), 0);
268 gtk_scale_set_value_pos(GTK_SCALE(name_dialog.variant_btn),
269 GTK_POS_LEFT);
270 gtk_range_set_value(GTK_RANGE(name_dialog.variant_btn),
271 variant + 1);
272 gtk_widget_show(name_dialog.variant_btn);
273 gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox),
274 name_dialog.variant_btn, TRUE, TRUE, 0);
275 g_signal_connect(name_dialog.variant_btn, "value-changed",
276 G_CALLBACK(change_style_cb), &name_dialog);
277 /* destroy dialog when OK or Cancel button gets clicked */
278 g_signal_connect(name_dialog.dlg, "response",
279 G_CALLBACK(change_name_cb), &name_dialog);
280
281 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
282 (name_dialog.check_btn), parse_ok);
283
284 gtk_widget_show(name_dialog.dlg);
285 gtk_widget_grab_focus(name_dialog.name_entry);
286 }
287
update_icon(DialogData * data)288 void update_icon(DialogData * data)
289 {
290 GdkPixbuf *pixbuf;
291 cairo_surface_t *surface;
292 GtkAllocation allocation;
293
294 if (!gtk_widget_get_realized(data->image)) {
295 return;
296 }
297 gtk_widget_get_allocation(data->image, &allocation);
298 surface = playericon_create_icon(data->current_style,
299 player_or_spectator_color
300 (my_player_num()), FALSE, TRUE,
301 allocation.width,
302 allocation.height);
303 pixbuf =
304 gdk_pixbuf_get_from_surface(surface, 0, 0, allocation.width,
305 allocation.height);
306 cairo_surface_destroy(surface);
307
308 gtk_image_set_from_pixbuf(GTK_IMAGE(data->image), pixbuf);
309 g_object_unref(pixbuf);
310 }
311