1 /*
2 * gtkatlantic - the gtk+ monopd client, enjoy network monopoly games
3 *
4 *
5 * Copyright © 2002-2015 Sylvain Rochet
6 *
7 * gtkatlantic is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <gtk/gtk.h>
28 #include <cairo.h>
29
30 #include "global.h"
31 #include "interface.h"
32 #include "callback.h"
33 #include "game.h"
34 #include "client.h"
35 #include "display.h"
36
37 #include "engine.h"
38
interface_create_mainwindow()39 void interface_create_mainwindow() {
40
41 // GtkWidget *HandleBar;
42 //global->Menu
43 GtkWidget *Button;
44 GtkWidget *Menu;
45 GtkWidget *MenuItem;
46
47 GdkPixbuf *pixbuf;
48
49 global->MainWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
50 gtk_window_set_title(GTK_WINDOW(global->MainWin), "GtkAtlantic");
51 gtk_widget_set_size_request(global->MainWin, 700, 487);
52
53 /* icons */
54 GList *iconlist = NULL;
55 pixbuf = gdk_pixbuf_new_from_file (PACKAGE_ICON_DIR "/128x128/apps/gtkatlantic.png", NULL);
56 if (pixbuf) iconlist = g_list_append(iconlist, pixbuf);
57 pixbuf = gdk_pixbuf_new_from_file (PACKAGE_ICON_DIR "/64x64/apps/gtkatlantic.png", NULL);
58 if (pixbuf) iconlist = g_list_append(iconlist, pixbuf);
59 pixbuf = gdk_pixbuf_new_from_file (PACKAGE_ICON_DIR "/48x48/apps/gtkatlantic.png", NULL);
60 if (pixbuf) iconlist = g_list_append(iconlist, pixbuf);
61 pixbuf = gdk_pixbuf_new_from_file (PACKAGE_ICON_DIR "/32x32/apps/gtkatlantic.png", NULL);
62 if (pixbuf) iconlist = g_list_append(iconlist, pixbuf);
63 pixbuf = gdk_pixbuf_new_from_file (PACKAGE_ICON_DIR "/16x16/apps/gtkatlantic.png", NULL);
64 if (pixbuf) iconlist = g_list_append(iconlist, pixbuf);
65 gtk_window_set_default_icon_list(iconlist);
66
67 g_signal_connect(G_OBJECT(global->MainWin), "delete-event", G_CALLBACK(gtk_main_quit), NULL);
68
69 global->MainBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
70 gtk_container_add(GTK_CONTAINER(global->MainWin), global->MainBox);
71
72 global->Menu = gtk_menu_bar_new();
73 gtk_box_pack_start(GTK_BOX(global->MainBox), global->Menu, FALSE, FALSE, 0);
74
75 /* GAME MENU */
76 Button = gtk_menu_item_new_with_label("Game");
77 gtk_menu_shell_append(GTK_MENU_SHELL(global->Menu), Button);
78
79 Menu = gtk_menu_new();
80 gtk_menu_item_set_submenu(GTK_MENU_ITEM(Button), Menu);
81
82 MenuItem = gtk_menu_item_new_with_label("Connect to server...");
83 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
84 g_object_set_data(G_OBJECT(global->Menu), "connect_to_server", MenuItem);
85 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_menu_connect_to_server), NULL);
86
87 MenuItem = gtk_menu_item_new_with_label("Connect to metaserver");
88 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
89 g_object_set_data(G_OBJECT(global->Menu), "connect_to_metaserver", MenuItem);
90 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(Callback_ConnectMetaServer), NULL);
91
92 MenuItem = gtk_menu_item_new_with_label("Public server list...");
93 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
94 g_object_set_data(G_OBJECT(global->Menu), "public_server_list", MenuItem);
95 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_menu_public_server_list), NULL);
96
97 MenuItem = gtk_menu_item_new();
98 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
99
100 MenuItem = gtk_menu_item_new_with_label("Change nickname...");
101 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
102 g_object_set_data(G_OBJECT(global->Menu), "change_nickname", MenuItem);
103 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_menu_change_nickname), NULL);
104
105 MenuItem = gtk_menu_item_new_with_label("Show estates tree...");
106 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
107 g_object_set_data(G_OBJECT(global->Menu), "show_estate_tree", MenuItem);
108 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_estates_tree), NULL);
109
110 MenuItem = gtk_menu_item_new_with_label("Add player");
111 g_object_set_data(G_OBJECT(global->Menu), "upgrade_spectator", MenuItem);
112 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
113 GtkWidget *SubMenu = gtk_menu_new();
114 gtk_menu_item_set_submenu(GTK_MENU_ITEM(MenuItem), SubMenu);
115
116 MenuItem = gtk_menu_item_new();
117 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
118
119 MenuItem = gtk_menu_item_new_with_label("Reconnect (after client crash)");
120 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
121 g_object_set_data(G_OBJECT(global->Menu), "reconnect", MenuItem);
122 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_menu_reconnect), NULL);
123
124 MenuItem = gtk_menu_item_new_with_label("Leave game (disconnect)");
125 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
126 g_object_set_data(G_OBJECT(global->Menu), "leave_game", MenuItem);
127 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_menu_LeaveGame), NULL);
128
129 MenuItem = gtk_menu_item_new();
130 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
131
132 MenuItem = gtk_menu_item_new_with_label("Exit");
133 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
134 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(gtk_main_quit), NULL);
135
136 /* CONFIG MENU */
137 Button = gtk_menu_item_new_with_label("Settings");
138 gtk_menu_shell_append(GTK_MENU_SHELL(global->Menu), Button);
139
140 Menu = gtk_menu_new();
141 gtk_menu_item_set_submenu(GTK_MENU_ITEM(Button), Menu);
142
143 MenuItem = gtk_menu_item_new_with_label("Preferences...");
144 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
145 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(Callback_ShowConfiguration), NULL);
146
147 // MenuItem = gtk_menu_item_new_with_label("Themes (unavailable yet)");
148 // gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
149 // g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(Callback_menu_Themes), NULL);
150
151 /* HELP MENU */
152 Button = gtk_menu_item_new_with_label("Help");
153 gtk_menu_shell_append(GTK_MENU_SHELL(global->Menu), Button);
154
155 Menu = gtk_menu_new();
156 gtk_menu_item_set_submenu(GTK_MENU_ITEM(Button), Menu);
157
158 MenuItem = gtk_menu_item_new_with_label("Index...");
159 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
160 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(interface_create_helpwin), NULL);
161
162 MenuItem = gtk_menu_item_new_with_label("About...");
163 gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
164 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(interface_create_aboutwin), NULL);
165
166
167 global->InfoLabel = gtk_label_new(NULL);
168 gtk_widget_set_margin_top(global->InfoLabel, 0);
169 gtk_widget_set_margin_bottom(global->InfoLabel, 3);
170 #if GTK_CHECK_VERSION(3,12,0)
171 gtk_widget_set_margin_start(global->InfoLabel, 3);
172 gtk_widget_set_margin_end(global->InfoLabel, 3);
173 #else /* GTK_CHECK_VERSION(3,12,0) */
174 gtk_widget_set_margin_left(global->InfoLabel, 3);
175 gtk_widget_set_margin_right(global->InfoLabel, 3);
176 #endif /* GTK_CHECK_VERSION(3,12,0) */
177 gtk_widget_set_halign(global->InfoLabel, GTK_ALIGN_START);
178 gtk_widget_set_valign(global->InfoLabel, GTK_ALIGN_CENTER);
179 gtk_box_pack_end(GTK_BOX(global->MainBox), global->InfoLabel, FALSE, FALSE, 0);
180
181 gtk_widget_show_all(global->MainWin);
182
183 /* Light theme */
184 global->bg_green = "#c8ffc8";
185 global->bg_red = "#ffc8c8";
186
187 GtkStyleContext *stylecontext = gtk_widget_get_style_context(global->MainWin);
188 if (!stylecontext) {
189 return;
190 }
191
192 GdkRGBA rgba;
193 gtk_style_context_get_color(stylecontext, GTK_STATE_FLAG_NORMAL, &rgba);
194 if (rgba.red * 0.2126 + rgba.green * 0.7152 + rgba.blue * 0.0722 > 0.5) {
195 /* Dark theme */
196 global->bg_green = "#007000";
197 global->bg_red = "#700000";
198 }
199 }
200
201
interface_create_getgamespage(bool autoconnect)202 void interface_create_getgamespage(bool autoconnect) {
203
204 //global->MainBox
205 //global->MainVerticalBox
206 GtkWidget *GameFrame;
207 GtkWidget *GameListVBox;
208 GtkWidget *GameScrollwin;
209 GtkWidget *GameList;
210 GtkWidget *ConnectButton;
211
212 GtkTreeSelection *select;
213 GtkCellRenderer *renderer;
214 GtkTreeViewColumn *column;
215
216 global->phase = PHASE_GETGAMES;
217
218 interface_unparent_chat();
219
220 if (global->MainVerticalBox) gtk_widget_destroy(global->MainVerticalBox);
221 global->MainVerticalBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
222 gtk_container_set_border_width(GTK_CONTAINER(global->MainVerticalBox), 3);
223 gtk_box_pack_start(GTK_BOX(global->MainBox), global->MainVerticalBox, TRUE, TRUE, 0);
224 g_signal_connect(G_OBJECT(global->MainVerticalBox), "destroy", G_CALLBACK(CallBack_get_games_page_destroyed), NULL);
225
226 /* list of open game & gametype */
227 GameFrame = gtk_frame_new("Create or join a monopd game");
228 gtk_box_pack_start(GTK_BOX(global->MainVerticalBox), GameFrame, TRUE, TRUE, 0);
229
230 GameListVBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
231 gtk_container_add(GTK_CONTAINER(GameFrame), GameListVBox);
232
233 /* Game list container */
234 GameScrollwin = gtk_scrolled_window_new(NULL, NULL);
235 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(GameScrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
236 gtk_container_set_border_width(GTK_CONTAINER(GameScrollwin), 2);
237 gtk_box_pack_start(GTK_BOX(GameListVBox), GameScrollwin, TRUE, TRUE, 0);
238
239 /* Game list */
240 GameList = gtk_tree_view_new();
241 gtk_container_add(GTK_CONTAINER(GameScrollwin), GameList);
242 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(GameList));
243 gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
244 g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(Callback_GetGame_Select), NULL);
245
246 renderer = gtk_cell_renderer_text_new();
247 column = gtk_tree_view_column_new_with_attributes("Host", renderer, "text", GAMELIST_COLUMN_HOST, "cell-background", GAMELIST_COLUMN_BGCOLOR, NULL);
248 gtk_tree_view_append_column(GTK_TREE_VIEW(GameList), column);
249 column = gtk_tree_view_column_new_with_attributes("Version", renderer, "text", GAMELIST_COLUMN_VERSION, "cell-background", GAMELIST_COLUMN_BGCOLOR, NULL);
250 gtk_tree_view_append_column(GTK_TREE_VIEW(GameList), column);
251 column = gtk_tree_view_column_new_with_attributes("Game", renderer, "text", GAMELIST_COLUMN_GAME, "cell-background", GAMELIST_COLUMN_BGCOLOR, NULL);
252 gtk_tree_view_append_column(GTK_TREE_VIEW(GameList), column);
253 column = gtk_tree_view_column_new_with_attributes("Status", renderer, "text", GAMELIST_COLUMN_STATUS, "cell-background", GAMELIST_COLUMN_BGCOLOR, NULL);
254 gtk_tree_view_append_column(GTK_TREE_VIEW(GameList), column);
255 column = gtk_tree_view_column_new_with_attributes("Players", renderer, "text", GAMELIST_COLUMN_PLAYERS, "cell-background", GAMELIST_COLUMN_BGCOLOR, NULL);
256 gtk_tree_view_append_column(GTK_TREE_VIEW(GameList), column);
257
258 global->game_store = gtk_list_store_new(GAMELIST_COLUMN_NUM, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT);
259 gtk_tree_view_set_model(GTK_TREE_VIEW(GameList), GTK_TREE_MODEL(global->game_store));
260 g_object_unref(global->game_store);
261
262 /* Server list */
263 global->server_store = gtk_list_store_new(SERVERLIST_COLUMN_NUM, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
264
265 /* big connect button */
266 ConnectButton = gtk_button_new_with_label("Select a game");
267 gtk_widget_set_size_request(ConnectButton, 150, -1);
268 gtk_container_set_border_width(GTK_CONTAINER(ConnectButton), 3);
269 gtk_widget_set_sensitive(ConnectButton, FALSE);
270 gtk_box_pack_start(GTK_BOX(GameListVBox), ConnectButton, FALSE, FALSE, 0);
271 g_signal_connect(G_OBJECT(ConnectButton), "clicked", G_CALLBACK(Callback_ConnectButton), NULL);
272 g_object_set_data(G_OBJECT(global->MainVerticalBox), "connect_button", ConnectButton);
273
274 GtkWidget *MenuItem;
275 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "connect_to_server");
276 gtk_widget_set_sensitive(MenuItem, TRUE);
277 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "connect_to_metaserver");
278 gtk_widget_set_sensitive(MenuItem, TRUE);
279 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "public_server_list");
280 gtk_widget_set_sensitive(MenuItem, FALSE);
281 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "change_nickname");
282 gtk_widget_set_sensitive(MenuItem, FALSE);
283 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "show_estate_tree");
284 gtk_widget_set_sensitive(MenuItem, FALSE);
285 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "upgrade_spectator");
286 gtk_widget_set_sensitive(MenuItem, FALSE);
287 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "reconnect");
288 gtk_widget_set_sensitive(MenuItem, game_cookie_available());
289 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "leave_game");
290 gtk_widget_set_sensitive(MenuItem, FALSE);
291
292 gtk_widget_show_all(global->MainVerticalBox);
293
294 /* autoconnect to server */
295 if (autoconnect) {
296 if (config->metaserver_autoconnect) {
297 create_connection_metaserver();
298 }
299
300 if (config->getgames_autoconnect) {
301 create_connection_get_games(config->getgames_host, config->getgames_port);
302 }
303 }
304 }
305
306
interface_create_gameconfigpage()307 void interface_create_gameconfigpage() {
308
309 //global->MainBox
310 //global->MainVerticalBox
311 GtkWidget *HorizontalBox;
312 GtkWidget *VerticalBoxLeft;
313 GtkWidget *ChatFrame;
314 //currentgame->ChatBox
315 GtkWidget *VerticalBoxRight;
316 GtkWidget *PlayerScrollwin;
317 GtkWidget *PlayerListFrame;
318 GtkWidget *ConfigurationFrame;
319 //currentgame->GameConfigBox
320 GtkWidget *HorizontalBoxButton;
321 GtkWidget *StartButton;
322 GtkWidget *LeaveButton;
323
324
325 GtkTreeSelection *select;
326 GtkCellRenderer *renderer;
327 GtkTreeViewColumn *column;
328 GtkListStore *store;
329
330 global->phase = PHASE_GAMECREATE;
331
332 interface_unparent_chat();
333
334 gtk_widget_destroy(global->MainVerticalBox);
335 global->MainVerticalBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
336 gtk_container_set_border_width(GTK_CONTAINER(global->MainVerticalBox), 3);
337 gtk_box_pack_start(GTK_BOX(global->MainBox), global->MainVerticalBox, TRUE, TRUE, 0);
338
339 /* main horizontal box */
340 HorizontalBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
341 gtk_box_pack_start(GTK_BOX(global->MainVerticalBox), HorizontalBox, TRUE, TRUE, 0);
342
343 VerticalBoxLeft = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
344 gtk_box_pack_start(GTK_BOX(HorizontalBox), VerticalBoxLeft, TRUE, TRUE, 0);
345
346 /* player list frame */
347 PlayerListFrame = gtk_frame_new("Players");
348 gtk_widget_set_size_request(PlayerListFrame, -1, 180);
349 gtk_box_pack_start(GTK_BOX(VerticalBoxLeft), PlayerListFrame, FALSE, FALSE, 0);
350
351 PlayerScrollwin = gtk_scrolled_window_new(NULL, NULL);
352 gtk_container_set_border_width(GTK_CONTAINER(PlayerScrollwin), 2);
353 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(PlayerScrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
354 gtk_container_add(GTK_CONTAINER(PlayerListFrame), PlayerScrollwin);
355
356 /* player list */
357 currentgame->PlayerList = gtk_tree_view_new();
358 gtk_container_add(GTK_CONTAINER(PlayerScrollwin), currentgame->PlayerList);
359 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(currentgame->PlayerList));
360 gtk_tree_selection_set_mode(select, GTK_SELECTION_NONE);
361
362 renderer = gtk_cell_renderer_text_new();
363 column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", PLAYERLIST_COLUMN_NAME, NULL);
364 gtk_tree_view_append_column(GTK_TREE_VIEW(currentgame->PlayerList), column);
365 column = gtk_tree_view_column_new_with_attributes("Host", renderer, "text", PLAYERLIST_COLUMN_HOST, NULL);
366 gtk_tree_view_append_column(GTK_TREE_VIEW(currentgame->PlayerList), column);
367
368 store = gtk_list_store_new(PLAYERLIST_COLUMN_NUM, G_TYPE_STRING, G_TYPE_STRING);
369 gtk_tree_view_set_model(GTK_TREE_VIEW(currentgame->PlayerList), GTK_TREE_MODEL(store));
370 g_object_unref(store);
371
372 /* chat frame */
373 ChatFrame = gtk_frame_new("Chat");
374 gtk_box_pack_start(GTK_BOX(VerticalBoxLeft), ChatFrame, TRUE, TRUE, 0);
375 interface_create_chat(ChatFrame);
376
377
378 /* vertical box right */
379 VerticalBoxRight = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
380 gtk_box_pack_start(GTK_BOX(HorizontalBox), VerticalBoxRight, FALSE, FALSE, 0);
381
382 /* game configuration frame */
383 ConfigurationFrame = gtk_frame_new("Game configuration");
384 gtk_box_pack_start(GTK_BOX(VerticalBoxRight), ConfigurationFrame, FALSE, FALSE, 0);
385
386 /* config box might already been created by <configupdate/> early events */
387 if (!currentgame->GameConfigBox) {
388 currentgame->GameConfigBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
389 }
390 gtk_container_set_border_width(GTK_CONTAINER(currentgame->GameConfigBox), 5);
391 gtk_container_add(GTK_CONTAINER(ConfigurationFrame), currentgame->GameConfigBox);
392
393 /* horizontal box button */
394 HorizontalBoxButton = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
395 gtk_box_pack_end(GTK_BOX(VerticalBoxRight), HorizontalBoxButton, FALSE, FALSE, 0);
396
397 /* leave button */
398 LeaveButton = gtk_button_new_with_label("Leave game");
399 gtk_box_pack_start(GTK_BOX(HorizontalBoxButton), LeaveButton, TRUE, TRUE, 0);
400 g_signal_connect(G_OBJECT(LeaveButton), "clicked", G_CALLBACK(CallBack_menu_LeaveGame), NULL);
401
402 /* start button */
403 StartButton = gtk_button_new_with_label("Start game");
404 gtk_widget_set_sensitive(StartButton, (global->my_playerid == currentgame->master));
405 gtk_box_pack_start(GTK_BOX(HorizontalBoxButton), StartButton, TRUE, TRUE, 0);
406 g_signal_connect(G_OBJECT(StartButton), "clicked", G_CALLBACK(Callback_StartButton), NULL);
407 g_object_set_data(G_OBJECT(global->MainVerticalBox), "start_button", StartButton);
408
409 GtkWidget *MenuItem;
410 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "connect_to_server");
411 gtk_widget_set_sensitive(MenuItem, FALSE);
412 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "connect_to_metaserver");
413 gtk_widget_set_sensitive(MenuItem, FALSE);
414 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "public_server_list");
415 gtk_widget_set_sensitive(MenuItem, FALSE);
416 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "change_nickname");
417 gtk_widget_set_sensitive(MenuItem, TRUE);
418 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "show_estate_tree");
419 gtk_widget_set_sensitive(MenuItem, FALSE);
420 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "upgrade_spectator");
421 gtk_widget_set_sensitive(MenuItem, FALSE);
422 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "reconnect");
423 gtk_widget_set_sensitive(MenuItem, FALSE);
424 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "leave_game");
425 gtk_widget_set_sensitive(MenuItem, TRUE);
426
427 gtk_widget_show_all(global->MainVerticalBox);
428 }
429
430
interface_create_gameinitpage()431 void interface_create_gameinitpage() {
432
433 //global->MainBox
434 //global->MainVerticalBox
435 GtkWidget *Label;
436
437 global->phase = PHASE_GAMEINIT;
438
439 interface_unparent_chat();
440
441 gtk_widget_destroy(global->MainVerticalBox);
442 global->MainVerticalBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
443 gtk_box_pack_start(GTK_BOX(global->MainBox), global->MainVerticalBox, TRUE, TRUE, 0);
444
445 /* text */
446 Label = gtk_label_new("Please wait while loading...");
447 gtk_widget_set_halign(Label, GTK_ALIGN_CENTER);
448 gtk_widget_set_valign(Label, GTK_ALIGN_CENTER);
449 gtk_box_pack_start(GTK_BOX(global->MainVerticalBox), Label, TRUE, TRUE, 0);
450
451 gtk_widget_show_all(global->MainVerticalBox);
452
453 /* We are going to receive <display/> events before game is in running state */
454 currentgame->BoardCenter = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
455 display_init();
456
457 while(gtk_events_pending()) gtk_main_iteration();
458 }
459
460
interface_create_gameboardpage()461 void interface_create_gameboardpage() {
462
463 //global->MainBox
464 //global->MainVerticalBox
465 GtkWidget *MainHorizontalBox;
466 GtkWidget *VerticalBoxPlayerlistChat;
467 //currentgame->PlayerList
468 GtkWidget *PlayerSeparator;
469 GtkWidget *ChatFrame;
470 //call interface_create_chat
471 GtkWidget *FixedBoard;
472 GtkWidget *EventBox;
473 //currentgame->BoardCenter;
474 //currentgame->estate[].gdkrgb
475 GtkWidget *EstatePopupMenu;
476
477 eng_frame *board_frame;
478 eng_obj *pic;
479 gint32 i, j, star, houses;
480 gchar *text, *tmp1, *tmp2;
481 player *p;
482
483 GtkWidget *MenuItem;
484
485 global->phase = PHASE_GAMEPLAY;
486
487 interface_unparent_chat();
488
489 gtk_widget_destroy(global->MainVerticalBox);
490 global->MainVerticalBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
491 gtk_container_set_border_width(GTK_CONTAINER(global->MainVerticalBox), 3);
492 gtk_box_pack_start(GTK_BOX(global->MainBox), global->MainVerticalBox, TRUE, TRUE, 0);
493
494 /* horizontal box for board / player status */
495 MainHorizontalBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
496 gtk_box_pack_start(GTK_BOX(global->MainVerticalBox), MainHorizontalBox, TRUE, TRUE, 0);
497
498 /* vertical box for player and chat */
499 VerticalBoxPlayerlistChat = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
500 if(config->game_playerlist_position == GAME_PLAYERLIST_POS_RIGHT)
501 gtk_box_pack_end(GTK_BOX(MainHorizontalBox), VerticalBoxPlayerlistChat, TRUE, FALSE, 0);
502 else /* left (default) */
503 gtk_box_pack_start(GTK_BOX(MainHorizontalBox), VerticalBoxPlayerlistChat, TRUE, TRUE, 0);
504 gtk_widget_set_hexpand(VerticalBoxPlayerlistChat, TRUE);
505 gtk_widget_set_vexpand(VerticalBoxPlayerlistChat, TRUE);
506
507 /* players */
508 currentgame->PlayerList = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
509 gtk_box_pack_start(GTK_BOX(VerticalBoxPlayerlistChat), currentgame->PlayerList, FALSE, FALSE, 0);
510
511 /* first player separator */
512 PlayerSeparator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
513 gtk_box_pack_start(GTK_BOX(currentgame->PlayerList), PlayerSeparator, FALSE, FALSE, 0);
514
515 /* chat */
516 ChatFrame = gtk_frame_new("Chat");
517 gtk_box_pack_start(GTK_BOX(VerticalBoxPlayerlistChat), ChatFrame, TRUE, TRUE, 0);
518 interface_create_chat(ChatFrame);
519
520 /* board */
521 board_frame = currentgame->board_frame = eng_frame_create();
522 eng_frame_set_width(board_frame, data->board_width);
523 eng_frame_set_height(board_frame, data->board_height);
524
525 /* add players */
526 game_sort_playerlist_by_turnorder();
527 for (p = player_h; p; p = p->next) {
528 if (p->spectator) continue;
529 if (p->game != currentgame->gameid) continue;
530 interface_gameboard_add_player(p);
531 }
532 game_update_tokens();
533
534 FixedBoard = gtk_fixed_new();
535 gtk_box_pack_start(GTK_BOX(MainHorizontalBox), FixedBoard, FALSE, FALSE, 0);
536
537 /* board center */
538 if (!currentgame->BoardCenter) {
539 currentgame->BoardCenter = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
540 display_init();
541 }
542 gtk_container_set_border_width(GTK_CONTAINER(currentgame->BoardCenter), 0);
543 gtk_widget_set_size_request( GTK_WIDGET(currentgame->BoardCenter), data->board_center_width, data->board_center_height);
544 gtk_fixed_put(GTK_FIXED(FixedBoard), currentgame->BoardCenter, data->board_center_x, data->board_center_y);
545
546 /* board estates */
547 for(i = 0 ; i < data->number_estates ; i++) {
548
549 j = data->estate[i].buffer_board;
550
551 EventBox = gtk_event_box_new();
552 gtk_fixed_put(GTK_FIXED(FixedBoard), EventBox, data->estate[i].x, data->estate[i].y);
553
554 currentgame->estate[i].gdkrgb = gtk_drawing_area_new();
555 gtk_widget_set_size_request( GTK_WIDGET(currentgame->estate[i].gdkrgb), data->pngfile_board_width[j], data->pngfile_board_height[j] );
556
557 gtk_widget_set_events(GTK_WIDGET(currentgame->estate[i].gdkrgb), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
558
559 g_object_set_data(G_OBJECT(EventBox), "estateid", GINT_TO_POINTER(i));
560 g_object_set_data(G_OBJECT(currentgame->estate[i].gdkrgb), "estateid", GINT_TO_POINTER(i));
561
562 g_signal_connect_after(G_OBJECT(EventBox), "enter_notify_event", G_CALLBACK(Callback_EnterAnEstate), NULL);
563 g_signal_connect(G_OBJECT(EventBox), "leave_notify_event", G_CALLBACK(Callback_LeaveAnEstate), NULL);
564 g_signal_connect(G_OBJECT(EventBox), "button_press_event", G_CALLBACK(Callback_ClicOnEstate), NULL);
565 g_signal_connect(G_OBJECT(currentgame->estate[i].gdkrgb), "draw", G_CALLBACK(on_board_draw), NULL);
566
567 gtk_container_add(GTK_CONTAINER(EventBox), currentgame->estate[i].gdkrgb);
568
569 /* building estate popup menu */
570 EstatePopupMenu = gtk_menu_new();
571 g_object_set_data(G_OBJECT(EstatePopupMenu), "estateid", GINT_TO_POINTER(i));
572 g_object_set_data(G_OBJECT(EventBox), "menu", EstatePopupMenu);
573
574 MenuItem = gtk_menu_item_new_with_label("Build house");
575 gtk_menu_shell_append(GTK_MENU_SHELL(EstatePopupMenu), MenuItem);
576 g_object_set_data(G_OBJECT(MenuItem), "action", GINT_TO_POINTER(ESTATE_ACTION_BUILDHOUSE));
577 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_PopupMenuEstate), NULL);
578 gtk_widget_show(MenuItem);
579
580 MenuItem = gtk_menu_item_new_with_label("Sell house");
581 gtk_menu_shell_append(GTK_MENU_SHELL(EstatePopupMenu), MenuItem);
582 g_object_set_data(G_OBJECT(MenuItem), "action", GINT_TO_POINTER(ESTATE_ACTION_SELLHOUSE));
583 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_PopupMenuEstate), NULL);
584 gtk_widget_show(MenuItem);
585
586 MenuItem = gtk_menu_item_new_with_label("(Un)mortage");
587 gtk_menu_shell_append(GTK_MENU_SHELL(EstatePopupMenu), MenuItem);
588 g_object_set_data(G_OBJECT(MenuItem), "action", GINT_TO_POINTER(ESTATE_ACTION_MORTGAGE));
589 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_PopupMenuEstate), NULL);
590 gtk_widget_show(MenuItem);
591
592 MenuItem = gtk_menu_item_new_with_label("Sell property");
593 gtk_menu_shell_append(GTK_MENU_SHELL(EstatePopupMenu), MenuItem);
594 g_object_set_data(G_OBJECT(MenuItem), "action", GINT_TO_POINTER(ESTATE_ACTION_SELL));
595 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_PopupMenuEstate), NULL);
596 gtk_widget_show(MenuItem);
597
598 /* set ToolTips */
599 text = g_strdup_printf("%s", currentgame->estate[i].name);
600
601 if(currentgame->estate[i].group >= 0) {
602 tmp1 = text;
603 tmp2 = g_strdup_printf(" (%s)", currentgame->group[ currentgame->estate[i].group ].name);
604 text = g_strconcat(tmp1, tmp2, NULL);
605 g_free(tmp1);
606 g_free(tmp2);
607 }
608
609 if(currentgame->estate[i].price > 0) {
610 tmp1 = text;
611 tmp2 = g_strdup_printf("\nPrice: %d", currentgame->estate[i].price);
612 text = g_strconcat(tmp1, tmp2, NULL);
613 g_free(tmp1);
614 g_free(tmp2);
615 }
616
617 if(currentgame->estate[i].rent[5] > 0) {
618 tmp1 = text;
619 tmp2 = g_strdup_printf(
620 "\nNo house: %d, One: %d, Two: %d, Three: %d, Four: %d, Hotel: %d"
621 "\nHouse price: %d",
622 currentgame->estate[i].rent[0], currentgame->estate[i].rent[1], currentgame->estate[i].rent[2], currentgame->estate[i].rent[3], currentgame->estate[i].rent[4], currentgame->estate[i].rent[5],
623 currentgame->estate[i].houseprice );
624 text = g_strconcat(tmp1, tmp2, NULL);
625 g_free(tmp1);
626 g_free(tmp2);
627 }
628
629 if(currentgame->estate[i].mortgageprice > 0) {
630 tmp1 = text;
631 tmp2 = g_strdup_printf("\nMortgage value: %d", currentgame->estate[i].mortgageprice);
632 text = g_strconcat(tmp1, tmp2, NULL);
633 g_free(tmp1);
634 g_free(tmp2);
635 }
636
637 gtk_widget_set_tooltip_text(EventBox, text);
638 g_free(text);
639
640 /* pic for estates / stars / houses */
641
642 /* estate */
643 pic = currentgame->estate[i].pic = eng_pic_create(board_frame);
644 eng_pic_set_x(pic, data->estate[i].x);
645 eng_pic_set_y(pic, data->estate[i].y);
646 eng_pic_set_z(pic, 0);
647 eng_pic_set_width(pic, data->pngfile_board_width[j]);
648 eng_pic_set_height(pic, data->pngfile_board_height[j]);
649 eng_pic_set_pixbuf(pic, data->pngfile_board_buf[j]);
650
651 /* star */
652 pic = currentgame->estate[i].star_pic = eng_pic_create(board_frame);
653 eng_pic_set_x(pic, data->estate[i].xstar);
654 eng_pic_set_y(pic, data->estate[i].ystar);
655 eng_pic_set_z(pic, 1);
656
657 /* if estate owned && not mortgaged */
658 if(currentgame->estate[i].owner > 0 && !currentgame->estate[i].mortgaged) {
659
660 star = player_from_id(currentgame->estate[i].owner)->tokenid;
661
662 pic = currentgame->estate[i].star_pic;
663 eng_pic_set_width(pic, data->pngfile_star_width[star]);
664 eng_pic_set_height(pic, data->pngfile_star_height[star]);
665 eng_pic_set_pixbuf(pic, data->pngfile_star_buf[star]);
666 eng_pic_show(pic);
667 }
668
669 /* if estate owned && mortgaged */
670 else if(currentgame->estate[i].owner > 0 && currentgame->estate[i].mortgaged) {
671
672 star = player_from_id(currentgame->estate[i].owner )->tokenid;
673
674 pic = currentgame->estate[i].star_pic;
675 eng_pic_set_width(pic, data->pngfile_star_m_width[star]);
676 eng_pic_set_height(pic, data->pngfile_star_m_height[star]);
677 eng_pic_set_pixbuf(pic, data->pngfile_star_m_buf[star]);
678 eng_pic_show(pic);
679 }
680
681 /* if estate unowned */
682 else /* if( currentgame->estate[i].owner <= 0 ) */ {
683
684 pic = currentgame->estate[i].star_pic;
685 eng_pic_unshow(pic);
686 }
687
688 /* house image */
689 pic = currentgame->estate[i].house_pic = eng_pic_create(board_frame);
690 eng_pic_set_x(pic, data->estate[i].xhouse);
691 eng_pic_set_y(pic, data->estate[i].yhouse);
692 eng_pic_set_z(pic, 1);
693
694 houses = currentgame->estate[i].houses;
695
696 if(houses <= 0) {
697
698 pic = currentgame->estate[i].house_pic;
699 eng_pic_unshow(pic);
700 }
701 else if(houses > 0 && data->estate[i].type_house == TYPE_HOUSE_HORIZONTAL) {
702
703 pic = currentgame->estate[i].house_pic;
704 eng_pic_set_width(pic, data->pngfile_horiz_house_width[ houses ]);
705 eng_pic_set_height(pic, data->pngfile_horiz_house_height[ houses ]);
706 eng_pic_set_pixbuf(pic, data->pngfile_horiz_house_buf[ houses ]);
707 eng_pic_show(pic);
708 }
709 else if(houses > 0 && data->estate[i].type_house == TYPE_HOUSE_VERTICAL) {
710
711 pic = currentgame->estate[i].house_pic;
712 eng_pic_set_width(pic, data->pngfile_vert_house_width[ houses ]);
713 eng_pic_set_height(pic, data->pngfile_vert_house_height[ houses ]);
714 eng_pic_set_pixbuf(pic, data->pngfile_vert_house_buf[ houses ]);
715 eng_pic_show(pic);
716 }
717 }
718
719 /* board first draw */
720 eng_create_frame(board_frame);
721
722 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "connect_to_server");
723 gtk_widget_set_sensitive(MenuItem, FALSE);
724 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "connect_to_metaserver");
725 gtk_widget_set_sensitive(MenuItem, FALSE);
726 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "public_server_list");
727 gtk_widget_set_sensitive(MenuItem, FALSE);
728 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "change_nickname");
729 gtk_widget_set_sensitive(MenuItem, TRUE);
730 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "show_estate_tree");
731 gtk_widget_set_sensitive(MenuItem, TRUE);
732 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "reconnect");
733 gtk_widget_set_sensitive(MenuItem, FALSE);
734 MenuItem = g_object_get_data(G_OBJECT(global->Menu), "leave_game");
735 gtk_widget_set_sensitive(MenuItem, TRUE);
736
737 gtk_widget_show_all(global->MainVerticalBox);
738 }
739
740
interface_gameboard_add_player(player * p)741 void interface_gameboard_add_player(player *p) {
742 GtkWidget *PlayerHorizontalBox;
743 GtkWidget *PlayerGrid;
744 GtkWidget *PlayerPopupMenu;
745 GtkWidget *PlayerSeparator;
746 GtkWidget *EventBox;
747 GtkWidget *MenuItem;
748 gint32 i;
749 eng_obj *pic;
750
751 if (global->phase < PHASE_GAMEPLAY) return;
752 if (p->spectator) return;
753 if (p->game != currentgame->gameid) return;
754 if (p->playerlist_LabelNamePlayer) return; /* already created */
755
756 /* select a token which is not already chosen */
757 for (i = 0; i <= data->token_max; i++) {
758 player *q;
759 for (q = player_h; q; q = q->next) {
760 if (q->spectator) continue;
761 if (q->game != currentgame->gameid) continue;
762 if (q->tokenid == i) break;
763 }
764 if (!q) {
765 p->tokenid = i;
766 break;
767 }
768 }
769 if (p->tokenid < 0) {
770 return;
771 }
772
773 p->playerlist_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
774 gtk_box_pack_start(GTK_BOX(currentgame->PlayerList), p->playerlist_box, FALSE, FALSE, 0);
775
776 /* event box */
777 EventBox = gtk_event_box_new();
778 gtk_widget_set_halign(EventBox, GTK_ALIGN_START);
779 gtk_widget_set_valign(EventBox, GTK_ALIGN_CENTER);
780 g_signal_connect(G_OBJECT(EventBox), "button_press_event", G_CALLBACK(Callback_ClicOnPlayer), NULL);
781 gtk_box_pack_start(GTK_BOX(p->playerlist_box), EventBox, FALSE, FALSE, 0);
782
783 /* box which contain all widgets for a player */
784 PlayerHorizontalBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
785 gtk_container_add(GTK_CONTAINER(EventBox), PlayerHorizontalBox);
786
787 /* building popup player menu */
788 PlayerPopupMenu = gtk_menu_new();
789 g_object_set_data(G_OBJECT(PlayerPopupMenu), "player", p);
790 g_object_set_data(G_OBJECT(EventBox), "menu", PlayerPopupMenu);
791
792 MenuItem = gtk_menu_item_new_with_label("Initiate a trade");
793 gtk_menu_shell_append(GTK_MENU_SHELL(PlayerPopupMenu), MenuItem);
794 g_object_set_data(G_OBJECT(MenuItem), "action", GINT_TO_POINTER(PLAYER_ACTION_TRADE));
795 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_PopupMenuPlayer), NULL);
796 gtk_widget_show(MenuItem);
797
798 MenuItem = gtk_menu_item_new();
799 gtk_menu_shell_append(GTK_MENU_SHELL(PlayerPopupMenu), MenuItem);
800 gtk_widget_show(MenuItem);
801
802 MenuItem = gtk_menu_item_new_with_label("Request version");
803 gtk_menu_shell_append(GTK_MENU_SHELL(PlayerPopupMenu), MenuItem);
804 g_object_set_data(G_OBJECT(MenuItem), "action", GINT_TO_POINTER(PLAYER_ACTION_VERSION));
805 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_PopupMenuPlayer), NULL);
806 gtk_widget_show(MenuItem);
807
808 MenuItem = gtk_menu_item_new_with_label("Request date");
809 gtk_menu_shell_append(GTK_MENU_SHELL(PlayerPopupMenu), MenuItem);
810 g_object_set_data(G_OBJECT(MenuItem), "action", GINT_TO_POINTER(PLAYER_ACTION_DATE));
811 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_PopupMenuPlayer), NULL);
812 gtk_widget_show(MenuItem);
813
814 MenuItem = gtk_menu_item_new_with_label("Request ping");
815 gtk_menu_shell_append(GTK_MENU_SHELL(PlayerPopupMenu), MenuItem);
816 g_object_set_data(G_OBJECT(MenuItem), "action", GINT_TO_POINTER(PLAYER_ACTION_PING));
817 g_signal_connect(G_OBJECT(MenuItem), "activate", G_CALLBACK(CallBack_PopupMenuPlayer), NULL);
818 gtk_widget_show(MenuItem);
819
820 /* token player in playerlist */
821 p->playerlist_token_gdkrgb = gtk_drawing_area_new();
822 gtk_widget_set_size_request(p->playerlist_token_gdkrgb, data->playerlist_token_width, data->playerlist_token_height );
823 gtk_widget_set_halign(p->playerlist_token_gdkrgb, GTK_ALIGN_CENTER);
824 gtk_widget_set_valign(p->playerlist_token_gdkrgb, GTK_ALIGN_CENTER);
825 gtk_box_pack_start(GTK_BOX(PlayerHorizontalBox), p->playerlist_token_gdkrgb, TRUE, TRUE, 0);
826 g_signal_connect(G_OBJECT(p->playerlist_token_gdkrgb), "draw", G_CALLBACK(on_playertoken_draw), NULL);
827 g_object_set_data(G_OBJECT(p->playerlist_token_gdkrgb), "player", p);
828
829 /* name, money, cards owned by player */
830 PlayerGrid = gtk_grid_new();
831 gtk_grid_set_row_spacing(GTK_GRID(PlayerGrid), 0);
832 gtk_grid_set_column_spacing(GTK_GRID(PlayerGrid), 0);
833 gtk_box_pack_start(GTK_BOX(PlayerHorizontalBox), PlayerGrid, FALSE, FALSE, 0);
834
835 /* cards */
836 p->playerlist_cards_gdkrgb = gtk_drawing_area_new();
837 gtk_widget_set_size_request( GTK_WIDGET(p->playerlist_cards_gdkrgb), data->playerlist_cards_width, data->playerlist_cards_height );
838 gtk_grid_attach(GTK_GRID(PlayerGrid), p->playerlist_cards_gdkrgb, 0, 1, 2, 1);
839 g_signal_connect(G_OBJECT(p->playerlist_cards_gdkrgb), "draw", G_CALLBACK(on_playercards_draw), NULL);
840 g_object_set_data(G_OBJECT(p->playerlist_cards_gdkrgb), "player", p);
841
842 /* name */
843 p->playerlist_LabelNamePlayer = gtk_label_new(NULL);
844 gtk_widget_set_halign(p->playerlist_LabelNamePlayer, GTK_ALIGN_START);
845 gtk_widget_set_valign(p->playerlist_LabelNamePlayer, GTK_ALIGN_CENTER);
846 gtk_grid_attach(GTK_GRID(PlayerGrid), p->playerlist_LabelNamePlayer, 0, 0, 1, 1);
847
848 if(p->hasturn) {
849 gchar *tmp = g_markup_printf_escaped("<span foreground=\"#ff0000\">%s</span>", p->name);
850 gtk_label_set_markup(GTK_LABEL(p->playerlist_LabelNamePlayer), tmp);
851 g_free(tmp);
852 } else {
853 gchar *tmp = g_markup_printf_escaped("<span foreground=\"#000000\">%s</span>", p->name);
854 gtk_label_set_markup(GTK_LABEL(p->playerlist_LabelNamePlayer), tmp);
855 g_free(tmp);
856 }
857
858 /* money */
859 p->playerlist_LabelMoneyPlayer = gtk_label_new(NULL);
860 gtk_widget_set_halign(p->playerlist_LabelMoneyPlayer, GTK_ALIGN_END);
861 gtk_widget_set_valign(p->playerlist_LabelMoneyPlayer, GTK_ALIGN_CENTER);
862 gtk_grid_attach(GTK_GRID(PlayerGrid), p->playerlist_LabelMoneyPlayer, 1, 0, 1, 1);
863
864 if(p->hasturn) {
865 gchar *tmp = g_markup_printf_escaped("<span foreground=\"#ff0000\">%d</span>", p->money);
866 gtk_label_set_markup(GTK_LABEL(p->playerlist_LabelMoneyPlayer), tmp);
867 g_free(tmp);
868 } else {
869 gchar *tmp = g_markup_printf_escaped("<span foreground=\"#000000\">%d</span>", p->money);
870 gtk_label_set_markup(GTK_LABEL(p->playerlist_LabelMoneyPlayer), tmp);
871 g_free(tmp);
872 }
873
874 /* playerlist token frame */
875 eng_frame *token_frame = p->playerlist_token_frame = eng_frame_create();
876 eng_frame_set_width(token_frame, data->playerlist_token_width);
877 eng_frame_set_height(token_frame, data->playerlist_token_height);
878
879 /* playerlist token pic */
880 pic = p->playerlist_token_pic = eng_pic_create(token_frame);
881 eng_pic_set_x(pic, (data->playerlist_token_width - data->pngfile_token_width[p->tokenid]) / 2);
882 eng_pic_set_y(pic, (data->playerlist_token_height - data->pngfile_token_height[p->tokenid]) / 2);
883 eng_pic_set_z(pic, 0);
884 eng_pic_set_width(pic, data->pngfile_token_width[p->tokenid]);
885 eng_pic_set_height(pic, data->pngfile_token_height[p->tokenid]);
886 eng_pic_set_pixbuf(pic, data->pngfile_token_buf[p->tokenid]);
887
888 /* draw token */
889 eng_create_frame(token_frame);
890
891 /* engine frame cards */
892 eng_frame *card_frame = p->playerlist_cards_frame = eng_frame_create();
893 eng_frame_set_width(card_frame, data->playerlist_cards_width);
894 eng_frame_set_height(card_frame, data->playerlist_cards_height);
895
896 /* cards */
897 for(i = 0; i < data->number_playerlist_card; i++) {
898 gint32 t;
899
900 pic = p->playerlist_cards_pic[i] = eng_pic_create(card_frame);
901 eng_pic_set_x(pic, data->playerlist_card[i].x);
902 eng_pic_set_y(pic, data->playerlist_card[i].y);
903 eng_pic_set_z(pic, data->playerlist_card[i].z);
904 t = data->playerlist_card[i].buffer_card;
905 eng_pic_set_width(pic, data->pngfile_card_width[t]);
906 eng_pic_set_height(pic, data->pngfile_card_height[t]);
907
908 if(currentgame->estate[ data->playerlist_card[i].estateid ].owner == (gint32)p->playerid) {
909
910 if(currentgame->estate[ data->playerlist_card[i].estateid ].mortgaged) {
911
912 eng_pic_set_alpha(pic, data->playerlist_cards_alphamortgage);
913 eng_pic_set_bgcolor(pic, data->playerlist_cards_cardbgcolormortgage);
914 }
915 else {
916
917 eng_pic_set_alpha(pic, data->playerlist_cards_alphaowned);
918 eng_pic_set_bgcolor(pic, data->playerlist_cards_cardbgcolor);
919 }
920 }
921 else {
922
923 eng_pic_set_alpha(pic, data->playerlist_cards_alphaunowned);
924 eng_pic_set_bgcolor(pic, data->playerlist_cards_cardbgcolor);
925 }
926
927 eng_pic_set_pixbuf(pic, data->pngfile_card_buf[t]);
928 }
929 /* draw cards */
930 eng_create_frame(card_frame);
931
932 /* token on board */
933 pic = p->token_pic = eng_pic_create(currentgame->board_frame);
934 eng_pic_set_z(pic, 1);
935 eng_pic_set_width(pic, data->pngfile_token_width[p->tokenid]);
936 eng_pic_set_height(pic, data->pngfile_token_height[p->tokenid]);
937 eng_pic_set_pixbuf(pic, data->pngfile_token_buf[p->tokenid]);
938 if (p->bankrupt) {
939 eng_pic_unshow(pic);
940 }
941
942 /* set token location to target location */
943 p->location = p->location_to;
944
945 /* separator */
946 PlayerSeparator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
947 gtk_box_pack_start(GTK_BOX(p->playerlist_box), PlayerSeparator, FALSE, FALSE, 0);
948
949 gtk_widget_show_all(p->playerlist_box);
950 }
951
interface_gameboard_remove_player(player * p)952 void interface_gameboard_remove_player(player *p) {
953 gint32 i;
954
955 if (global->phase < PHASE_GAMEPLAY) return;
956 if (p->spectator) return;
957
958 eng_pic_destroy(p->token_pic);
959 p->token_pic = NULL;
960 p->tokenid = -1;
961
962 if (p->playerlist_box) {
963 gtk_widget_destroy(p->playerlist_box);
964 p->playerlist_box = NULL;
965 p->playerlist_LabelNamePlayer = NULL;
966 p->playerlist_LabelMoneyPlayer = NULL;
967 p->playerlist_cards_gdkrgb = NULL;
968 p->playerlist_token_gdkrgb = NULL;
969 }
970
971 eng_frame_destroy(p->playerlist_token_frame);
972 p->playerlist_token_frame = NULL;
973 p->playerlist_token_pic = NULL;
974
975 eng_frame_destroy(p->playerlist_cards_frame);
976 p->playerlist_cards_frame = NULL;
977 for (i = 0; i < MAX_PLAYERLIST_CARDS; i++) {
978 p->playerlist_cards_pic[i] = NULL;
979 }
980 }
981
982
interface_chat_scroll_to_the_end(gpointer data)983 gboolean interface_chat_scroll_to_the_end(gpointer data) {
984 GtkWidget *widget = GTK_WIDGET(data);
985 GtkTextBuffer *textbuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
986 GtkTextMark *textmark = gtk_text_buffer_get_mark(textbuff, "endmark");
987 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(widget), textmark, 0.0, FALSE, 0.0, 0.0);
988 return FALSE;
989 }
990
991
interface_create_chat(GtkWidget * container)992 void interface_create_chat(GtkWidget *container) {
993
994 //currentgame->ChatBox
995 GtkWidget *ChatScrolledWindow;
996 //currentgame->Chat
997 GtkWidget *SendEntry;
998
999 GtkTextBuffer *textbuff;
1000 GtkTextIter textiter;
1001
1002 if(! currentgame) return;
1003
1004 /* already created */
1005 if(currentgame->ChatBox) {
1006 gtk_container_add(GTK_CONTAINER(container), currentgame->ChatBox);
1007 g_object_unref(G_OBJECT(currentgame->ChatBox));
1008 /* This is a bit ugly but I could not find a better way */
1009 g_timeout_add(100, interface_chat_scroll_to_the_end, currentgame->Chat);
1010 return;
1011 }
1012
1013 currentgame->ChatBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1014 gtk_widget_set_size_request(currentgame->ChatBox, -1, 160);
1015 gtk_container_add(GTK_CONTAINER(container), currentgame->ChatBox);
1016
1017 /* Create a scrolled window and put the textview in it */
1018 ChatScrolledWindow = gtk_scrolled_window_new(NULL, NULL);
1019 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ChatScrolledWindow),
1020 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1021 gtk_box_pack_start(GTK_BOX(currentgame->ChatBox), ChatScrolledWindow, TRUE, TRUE, 0);
1022
1023 currentgame->Chat = gtk_text_view_new();
1024 gtk_text_view_set_editable(GTK_TEXT_VIEW(currentgame->Chat), FALSE);
1025 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(currentgame->Chat), GTK_WRAP_CHAR);
1026 textbuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(currentgame->Chat));
1027 gtk_text_buffer_get_end_iter(textbuff, &textiter);
1028 gtk_text_buffer_create_mark(textbuff, "endmark", &textiter, FALSE);
1029 gtk_container_add(GTK_CONTAINER(ChatScrolledWindow), currentgame->Chat);
1030
1031 /* send entry */
1032 SendEntry = gtk_entry_new();
1033 gtk_box_pack_start(GTK_BOX(currentgame->ChatBox), SendEntry, FALSE, FALSE, 0);
1034 g_signal_connect(G_OBJECT(SendEntry), "activate", G_CALLBACK(Callback_SendButton), (gpointer)SendEntry);
1035 }
1036
1037
interface_unparent_chat()1038 void interface_unparent_chat() {
1039
1040 if(! currentgame) return;
1041 if(! currentgame->ChatBox) return;
1042
1043 GtkWidget *parent = gtk_widget_get_parent(currentgame->ChatBox);
1044 if (parent == NULL) {
1045 return;
1046 }
1047
1048 g_object_ref(G_OBJECT(currentgame->ChatBox));
1049 gtk_container_remove(GTK_CONTAINER(parent), currentgame->ChatBox);
1050 }
1051
1052
interface_create_auctionbox(gint32 auctionid,gint32 estateid)1053 void interface_create_auctionbox(gint32 auctionid, gint32 estateid) {
1054
1055 GtkWidget *vbox;
1056 GtkWidget *PlayerScrollwin;
1057 GtkWidget *PlayerList;
1058 GtkWidget *hbox_entry;
1059 GtkWidget *entry;
1060 GtkWidget *hbox_buttons;
1061 GtkWidget *button;
1062
1063 GtkWidget *label;
1064 GtkTreeIter iter;
1065 GtkTreeSelection *select;
1066 GtkCellRenderer *renderer;
1067 GtkTreeViewColumn *column;
1068 GtkListStore *store;
1069
1070 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1071 gtk_container_set_border_width(GTK_CONTAINER(vbox), 15);
1072 g_object_set_data(G_OBJECT(currentgame->BoardCenter), "auctionbox", vbox);
1073 gtk_box_pack_start(GTK_BOX(currentgame->BoardCenter), vbox, TRUE, TRUE, 0);
1074
1075 label = gtk_label_new(NULL);
1076 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1077 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1078 gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
1079 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
1080 gtk_widget_set_margin_bottom(label, 15);
1081 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
1082 gchar *tmp = g_markup_printf_escaped("<span size=\"xx-large\"><b>%s</b></span>", currentgame->estate[estateid].name);
1083 gtk_label_set_markup(GTK_LABEL(label), tmp);
1084 g_free(tmp);
1085
1086 /* player list */
1087 PlayerScrollwin = gtk_scrolled_window_new(NULL, NULL);
1088 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(PlayerScrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1089 gtk_box_pack_start(GTK_BOX(vbox), PlayerScrollwin, TRUE, TRUE, 0);
1090
1091 PlayerList = gtk_tree_view_new();
1092 gtk_container_add(GTK_CONTAINER(PlayerScrollwin), PlayerList);
1093 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(PlayerList));
1094 gtk_tree_selection_set_mode(select, GTK_SELECTION_NONE);
1095
1096 renderer = gtk_cell_renderer_text_new();
1097 column = gtk_tree_view_column_new_with_attributes("Player", renderer, "text", AUCTIONPLAYERLIST_COLUMN_NAME, "weight", AUCTIONPLAYERLIST_WEIGHT, "weight-set", AUCTIONPLAYERLIST_WEIGHTSET, NULL);
1098 gtk_tree_view_append_column(GTK_TREE_VIEW(PlayerList), column);
1099 column = gtk_tree_view_column_new_with_attributes("Bid", renderer, "text", AUCTIONPLAYERLIST_COLUMN_BID, "weight", AUCTIONPLAYERLIST_WEIGHT, "weight-set", AUCTIONPLAYERLIST_WEIGHTSET, NULL);
1100 gtk_tree_view_append_column(GTK_TREE_VIEW(PlayerList), column);
1101
1102 store = gtk_list_store_new(AUCTIONPLAYERLIST_COLUMN_NUM, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
1103 g_object_set_data(G_OBJECT(currentgame->BoardCenter), "auction_store", store);
1104 gtk_tree_view_set_model(GTK_TREE_VIEW(PlayerList), GTK_TREE_MODEL(store));
1105 g_object_unref(store);
1106
1107 player *p;
1108 for (p = player_h; p; p = p->next) {
1109 if (p->spectator) continue;
1110 if (p->game != currentgame->gameid) continue;
1111
1112 gtk_list_store_append(store, &iter);
1113 gtk_list_store_set(store, &iter,
1114 AUCTIONPLAYERLIST_COLUMN_NAME, p->name,
1115 AUCTIONPLAYERLIST_COLUMN_BID, 0,
1116 AUCTIONPLAYERLIST_COLUMN_PLAYERID, p->playerid,
1117 AUCTIONPLAYERLIST_WEIGHT, PANGO_WEIGHT_NORMAL,
1118 AUCTIONPLAYERLIST_WEIGHTSET, TRUE,
1119 -1);
1120 }
1121
1122 /* Status label */
1123 label = gtk_label_new(NULL);
1124 gtk_widget_set_halign(label, GTK_ALIGN_START);
1125 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
1126 gtk_widget_set_margin_top(label, 2);
1127 gtk_widget_set_margin_bottom(label, 2);
1128 g_object_set_data(G_OBJECT(currentgame->BoardCenter), "auction_statuslabel", label);
1129 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
1130
1131 /* commands */
1132 hbox_entry = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1133
1134 /* send entry */
1135 entry = gtk_entry_new();
1136 gtk_box_pack_start(GTK_BOX(hbox_entry), entry, FALSE, FALSE, 0);
1137 gtk_entry_set_width_chars(GTK_ENTRY(entry), 4);
1138 g_object_set_data(G_OBJECT(entry), "auctionid", GINT_TO_POINTER(auctionid));
1139 g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(Callback_AuctionButton_Absolute), (gpointer)entry);
1140
1141 button = gtk_button_new_with_label("Bid");
1142 gtk_box_pack_start(GTK_BOX(hbox_entry), button, FALSE, FALSE, 0);
1143 g_object_set_data(G_OBJECT(button), "auctionid", GINT_TO_POINTER(auctionid));
1144 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(Callback_AuctionButton_Absolute), (gpointer)entry);
1145
1146 /* quick button */
1147 hbox_buttons = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1148
1149 button = gtk_button_new_with_label("+1");
1150 g_object_set_data(G_OBJECT(button), "value_add", GINT_TO_POINTER(1));
1151 g_object_set_data(G_OBJECT(button), "auctionid", GINT_TO_POINTER(auctionid));
1152 gtk_box_pack_start(GTK_BOX(hbox_buttons), button, FALSE, FALSE, 0);
1153 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(Callback_AuctionButton_Relative), NULL);
1154
1155 button = gtk_button_new_with_label("+10");
1156 g_object_set_data(G_OBJECT(button), "value_add", GINT_TO_POINTER(10));
1157 g_object_set_data(G_OBJECT(button), "auctionid", GINT_TO_POINTER(auctionid));
1158 gtk_box_pack_start(GTK_BOX(hbox_buttons), button, FALSE, FALSE, 0);
1159 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(Callback_AuctionButton_Relative), NULL);
1160
1161 button = gtk_button_new_with_label("+50");
1162 g_object_set_data(G_OBJECT(button), "value_add", GINT_TO_POINTER(50));
1163 g_object_set_data(G_OBJECT(button), "auctionid", GINT_TO_POINTER(auctionid));
1164 gtk_box_pack_start(GTK_BOX(hbox_buttons), button, FALSE, FALSE, 0);
1165 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(Callback_AuctionButton_Relative), NULL);
1166
1167 button = gtk_button_new_with_label("+100");
1168 g_object_set_data(G_OBJECT(button), "value_add", GINT_TO_POINTER(100));
1169 g_object_set_data(G_OBJECT(button), "auctionid", GINT_TO_POINTER(auctionid));
1170 gtk_box_pack_start(GTK_BOX(hbox_buttons), button, FALSE, FALSE, 0);
1171 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(Callback_AuctionButton_Relative), NULL);
1172
1173
1174 gtk_box_pack_start(GTK_BOX(vbox), hbox_buttons, FALSE, FALSE, 0);
1175 gtk_box_pack_start(GTK_BOX(vbox), hbox_entry, FALSE, FALSE, 0);
1176
1177 gtk_widget_show_all(vbox);
1178 }
1179
1180
1181 /* create about window */
interface_create_aboutwin()1182 void interface_create_aboutwin()
1183 {
1184 const char *const authors[] = {
1185 "Sylvain Rochet <gradator@gradator.net>",
1186 "Xavier Amado <xavier@blackbloodstudios.com>",
1187 NULL
1188 };
1189
1190 gtk_show_about_dialog(GTK_WINDOW(global->MainWin),
1191 "authors", authors,
1192 "comments", "irc.freenode.net #gtkatlantic",
1193 "license-type", GTK_LICENSE_GPL_2_0,
1194 "logo-icon-name", "gtkatlantic",
1195 "program-name", "GtkAtlantic",
1196 "version", VERSION,
1197 "website", "http://gtkatlantic.gradator.net",
1198 NULL);
1199 }
1200
1201
1202 /* create config panel */
interface_create_config_panel()1203 void interface_create_config_panel() {
1204
1205 //global->ConfigWin;
1206 GtkWidget *vbox;
1207 GtkWidget *hbox;
1208 GtkWidget *Frame;
1209 GtkWidget *hboxFrame;
1210 GtkWidget *vboxFrame;
1211 GtkWidget *Label;
1212 GtkWidget *CButton;
1213 GtkWidget *Entry;
1214 GtkWidget *Combo;
1215 GtkAdjustment *Adjust;
1216 GtkWidget *Scale;
1217 GtkWidget *Button;
1218
1219 gchar *text;
1220
1221 if(global->ConfigWin) return;
1222
1223 global->ConfigWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1224 gtk_window_set_title(GTK_WINDOW(global->ConfigWin), "GtkAtlantic: Configuration");
1225 g_signal_connect(G_OBJECT(global->ConfigWin), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
1226 g_signal_connect(G_OBJECT(global->ConfigWin), "destroy", G_CALLBACK(CallBack_configwindow_destroyed), NULL);
1227
1228 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
1229 gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER);
1230 gtk_container_add(GTK_CONTAINER(global->ConfigWin), vbox);
1231
1232
1233 /* PLAYER CONFIG (such has nickname) */
1234 Frame = gtk_frame_new("Player");
1235 gtk_container_set_border_width(GTK_CONTAINER(Frame), BORDER);
1236 gtk_box_pack_start(GTK_BOX(vbox), Frame, FALSE, FALSE, 0);
1237
1238 vboxFrame = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1239 gtk_container_set_border_width(GTK_CONTAINER(vboxFrame), BORDER);
1240 gtk_container_add(GTK_CONTAINER(Frame), vboxFrame);
1241
1242 hboxFrame = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BORDER);
1243 gtk_box_pack_start(GTK_BOX(vboxFrame), hboxFrame, FALSE, FALSE, 0);
1244
1245 Label = gtk_label_new("Nickname");
1246 gtk_box_pack_start(GTK_BOX(hboxFrame), Label, FALSE, FALSE, 0);
1247
1248 Entry = gtk_entry_new();
1249 gtk_box_pack_start(GTK_BOX(hboxFrame), Entry, FALSE, FALSE, 0);
1250 g_object_set_data(G_OBJECT(global->ConfigWin), "config_player_nickname", Entry);
1251 gtk_entry_set_text(GTK_ENTRY(Entry), config->nickname);
1252
1253
1254 /* METASERVER */
1255 Frame = gtk_frame_new("Meta server");
1256 gtk_container_set_border_width(GTK_CONTAINER(Frame), BORDER);
1257 gtk_box_pack_start(GTK_BOX(vbox), Frame, TRUE, TRUE, 0);
1258
1259 vboxFrame = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1260 gtk_container_set_border_width(GTK_CONTAINER(vboxFrame), BORDER);
1261 gtk_container_add(GTK_CONTAINER(Frame), vboxFrame);
1262
1263 CButton = gtk_check_button_new_with_label("Check new releases of GtkAtlantic");
1264 g_object_set_data(G_OBJECT(global->ConfigWin), "config_metaserver_sendclientversion", CButton);
1265 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(CButton), config->metaserver_sendclientversion);
1266 gtk_box_pack_start(GTK_BOX(vboxFrame), CButton, FALSE, FALSE, 0);
1267
1268 CButton = gtk_check_button_new_with_label("Autoconnect");
1269 g_object_set_data(G_OBJECT(global->ConfigWin), "config_metaserver_autoconnect", CButton);
1270 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(CButton), config->metaserver_autoconnect);
1271 gtk_box_pack_start(GTK_BOX(vboxFrame), CButton, FALSE, FALSE, 0);
1272
1273
1274 /* DEFAULT CUSTOM SERVER */
1275 Frame = gtk_frame_new("Default server");
1276 gtk_container_set_border_width(GTK_CONTAINER(Frame), BORDER);
1277 gtk_box_pack_start(GTK_BOX(vbox), Frame, TRUE, TRUE, 0);
1278
1279 vboxFrame = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1280 gtk_container_set_border_width(GTK_CONTAINER(vboxFrame), BORDER);
1281 gtk_container_add(GTK_CONTAINER(Frame), vboxFrame);
1282
1283 hboxFrame = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BORDER);
1284 gtk_box_pack_start(GTK_BOX(vboxFrame), hboxFrame, FALSE, FALSE, 0);
1285
1286 Label = gtk_label_new("Host");
1287 gtk_box_pack_start(GTK_BOX(hboxFrame), Label, FALSE, FALSE, 0);
1288
1289 Entry = gtk_entry_new();
1290 g_object_set_data(G_OBJECT(global->ConfigWin), "config_customserver_host", Entry);
1291 gtk_entry_set_text(GTK_ENTRY(Entry), config->getgames_host);
1292 gtk_box_pack_start(GTK_BOX(hboxFrame), Entry, FALSE, FALSE, 0);
1293
1294 hboxFrame = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BORDER);
1295 gtk_box_pack_start(GTK_BOX(vboxFrame), hboxFrame, FALSE, FALSE, 0);
1296
1297 Label = gtk_label_new("Port");
1298 gtk_box_pack_start(GTK_BOX(hboxFrame), Label, FALSE, FALSE, 0);
1299
1300 Entry = gtk_entry_new();
1301 g_object_set_data(G_OBJECT(global->ConfigWin), "config_customserver_port", Entry);
1302 text = g_strdup_printf("%d", config->getgames_port);
1303 gtk_entry_set_text(GTK_ENTRY(Entry), text);
1304 g_free(text);
1305 gtk_widget_set_size_request(Entry, 45, -1);
1306 gtk_box_pack_start(GTK_BOX(hboxFrame), Entry, FALSE, FALSE, 0);
1307
1308 CButton = gtk_check_button_new_with_label("Autoconnect");
1309 g_object_set_data(G_OBJECT(global->ConfigWin), "config_customserver_autoconnect", CButton);
1310 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(CButton), config->getgames_autoconnect);
1311 gtk_box_pack_start(GTK_BOX(vboxFrame), CButton, FALSE, FALSE, 0);
1312
1313
1314 /* INTERFACE GAME CONFIG */
1315 Frame = gtk_frame_new("Game interface");
1316 gtk_container_set_border_width(GTK_CONTAINER(Frame), BORDER);
1317 gtk_box_pack_start(GTK_BOX(vbox), Frame, FALSE, FALSE, 0);
1318
1319 vboxFrame = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1320 gtk_container_set_border_width(GTK_CONTAINER(vboxFrame), BORDER);
1321 gtk_container_add(GTK_CONTAINER(Frame), vboxFrame);
1322
1323 hboxFrame = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BORDER);
1324 gtk_box_pack_start(GTK_BOX(vboxFrame), hboxFrame, FALSE, FALSE, 0);
1325
1326 Label = gtk_label_new("Display player list at ");
1327 gtk_box_pack_start(GTK_BOX(hboxFrame), Label, FALSE, FALSE, 0);
1328
1329 Combo = gtk_combo_box_text_new();
1330 g_object_set_data(G_OBJECT(global->ConfigWin), "config_gameinterface_playerlistposition", Combo);
1331 gtk_widget_set_size_request(Combo, 60, -1);
1332 gtk_box_pack_start(GTK_BOX(hboxFrame), Combo, FALSE, FALSE, 0);
1333
1334 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(Combo), "left");
1335 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(Combo), "right");
1336
1337 if(config->game_playerlist_position == GAME_PLAYERLIST_POS_LEFT)
1338 gtk_combo_box_set_active(GTK_COMBO_BOX(Combo), 0);
1339 else
1340 gtk_combo_box_set_active(GTK_COMBO_BOX(Combo), 1);
1341
1342
1343 hboxFrame = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BORDER);
1344 gtk_box_pack_start(GTK_BOX(vboxFrame), hboxFrame, FALSE, FALSE, 0);
1345
1346 Label = gtk_label_new("Token speed (in ms per estate) : ");
1347 gtk_box_pack_start(GTK_BOX(hboxFrame), Label, FALSE, FALSE, 0);
1348
1349 Adjust = gtk_adjustment_new (config->game_token_animation_speed, 25, 500, 25, 25, 0);
1350 g_object_set_data(G_OBJECT(global->ConfigWin), "config_gameinterface_tokenanimatespeed", Adjust);
1351 Scale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT(Adjust));
1352 gtk_widget_set_size_request(Scale, 200, -1);
1353 gtk_scale_set_value_pos (GTK_SCALE (Scale), GTK_POS_TOP);
1354 gtk_scale_set_digits (GTK_SCALE (Scale), 0);
1355 gtk_box_pack_start (GTK_BOX (hboxFrame), Scale, FALSE, FALSE, 0);
1356
1357 CButton = gtk_check_button_new_with_label("Show in transparency the tokens of players who are not moving now");
1358 g_object_set_data(G_OBJECT(global->ConfigWin), "config_gameinterface_tokentransparency", CButton);
1359 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(CButton), config->game_token_transparency);
1360 gtk_box_pack_start(GTK_BOX(vboxFrame), CButton, FALSE, FALSE, 0);
1361
1362 /* CANCEL/OK BUTTON */
1363 /* horizontal box buttons */
1364 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1365 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1366
1367 Button = gtk_button_new_with_label("CANCEL");
1368 gtk_widget_set_size_request(Button, 130, 45);
1369 gtk_container_set_border_width(GTK_CONTAINER(Button), 10);
1370 gtk_box_pack_start(GTK_BOX(hbox), Button, TRUE, FALSE, 0);
1371 g_signal_connect_object(G_OBJECT(Button), "clicked", G_CALLBACK(gtk_widget_destroy), global->ConfigWin, G_CONNECT_SWAPPED);
1372
1373 Button = gtk_button_new_with_label("OK");
1374 gtk_widget_set_size_request(Button, 130, 45);
1375 gtk_container_set_border_width(GTK_CONTAINER(Button), 10);
1376 gtk_box_pack_start(GTK_BOX(hbox), Button, TRUE, FALSE, 0);
1377 g_signal_connect(G_OBJECT(Button), "clicked", G_CALLBACK(CallBack_ok_button_configwindow), NULL);
1378
1379 gtk_widget_show_all(global->ConfigWin);
1380 }
1381
1382
1383 /* create the little window connect to server */
interface_create_connectoserver(void)1384 void interface_create_connectoserver(void) {
1385
1386 GtkWidget *win;
1387 GtkWidget *grid;
1388 GtkWidget *Entry;
1389 GtkWidget *Label;
1390
1391 gchar *text;
1392
1393 win = gtk_dialog_new_with_buttons("GtkAtlantic: Connect to server",
1394 GTK_WINDOW(global->MainWin), GTK_DIALOG_MODAL,
1395 "Close", GTK_RESPONSE_CLOSE, "Connect", GTK_RESPONSE_OK, NULL);
1396
1397 grid = gtk_grid_new();
1398 gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
1399 gtk_grid_set_row_spacing(GTK_GRID(grid), 2);
1400 gtk_container_set_border_width(GTK_CONTAINER(grid), 10);
1401 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(win))), grid);
1402
1403 Label = gtk_label_new("Hostname:");
1404 gtk_widget_set_halign(Label, GTK_ALIGN_START);
1405 gtk_widget_set_valign(Label, GTK_ALIGN_CENTER);
1406 gtk_grid_attach(GTK_GRID(grid), Label, 0, 0, 1, 1);
1407
1408 Entry = gtk_entry_new();
1409 gtk_widget_set_size_request(Entry, 150, -1);
1410 g_object_set_data(G_OBJECT(win), "host", Entry);
1411 gtk_entry_set_text(GTK_ENTRY(Entry), config->getgames_host);
1412 gtk_grid_attach(GTK_GRID(grid), Entry, 1, 0, 1, 1);
1413
1414 Label = gtk_label_new("Port:");
1415 gtk_widget_set_halign(Label, GTK_ALIGN_END);
1416 gtk_widget_set_valign(Label, GTK_ALIGN_CENTER);
1417 gtk_grid_attach(GTK_GRID(grid), Label, 0, 1, 1, 1);
1418
1419 Entry = gtk_entry_new();
1420 gtk_widget_set_size_request(Entry, 150, -1);
1421 g_object_set_data(G_OBJECT(win), "port", Entry);
1422 text = g_strdup_printf("%d", config->getgames_port);
1423 gtk_entry_set_text(GTK_ENTRY(Entry), text);
1424 g_free(text);
1425 gtk_grid_attach(GTK_GRID(grid), Entry, 1, 1, 1, 1);
1426
1427 g_signal_connect(G_OBJECT(win), "response", G_CALLBACK(CallBack_response_connect_to_server_window), win);
1428
1429 gtk_widget_show_all(win);
1430 }
1431
1432
1433 /* create the public server list window */
interface_create_publicserverlist(void)1434 void interface_create_publicserverlist(void) {
1435
1436 GtkWidget *win;
1437 GtkWidget *frame;
1438 GtkWidget *scrollwin;
1439 GtkWidget *ServerList;
1440
1441 GtkCellRenderer *renderer;
1442 GtkTreeSelection *select;
1443 GtkTreeViewColumn *column;
1444
1445 win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1446 gtk_widget_set_size_request(win, 700, 300);
1447 gtk_window_set_title(GTK_WINDOW(win), "GtkAtlantic: Public server list");
1448 g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
1449
1450 frame = gtk_frame_new("Public server list");
1451 gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
1452 gtk_container_add(GTK_CONTAINER(win), frame);
1453
1454 scrollwin = gtk_scrolled_window_new(NULL, NULL);
1455 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1456 gtk_container_set_border_width(GTK_CONTAINER(scrollwin), 5);
1457 gtk_container_add(GTK_CONTAINER(frame), scrollwin);
1458
1459 ServerList = gtk_tree_view_new();
1460 gtk_container_add(GTK_CONTAINER(scrollwin), ServerList);
1461 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(ServerList));
1462 gtk_tree_selection_set_mode(select, GTK_SELECTION_NONE);
1463
1464 renderer = gtk_cell_renderer_text_new();
1465 column = gtk_tree_view_column_new_with_attributes("Host", renderer, "text", SERVERLIST_COLUMN_HOST, NULL);
1466 gtk_tree_view_append_column(GTK_TREE_VIEW(ServerList), column);
1467 column = gtk_tree_view_column_new_with_attributes("Port", renderer, "text", SERVERLIST_COLUMN_PORT, NULL);
1468 gtk_tree_view_append_column(GTK_TREE_VIEW(ServerList), column);
1469 column = gtk_tree_view_column_new_with_attributes("Version", renderer, "text", SERVERLIST_COLUMN_VERSION, NULL);
1470 gtk_tree_view_append_column(GTK_TREE_VIEW(ServerList), column);
1471 column = gtk_tree_view_column_new_with_attributes("Users", renderer, "text", SERVERLIST_COLUMN_USERS, NULL);
1472 gtk_tree_view_append_column(GTK_TREE_VIEW(ServerList), column);
1473
1474 gtk_tree_view_set_model(GTK_TREE_VIEW(ServerList), GTK_TREE_MODEL(global->server_store));
1475
1476 gtk_widget_show_all(win);
1477 }
1478
1479
1480 /* create the little window change nickname */
interface_create_nicknamewin()1481 void interface_create_nicknamewin() {
1482
1483 GtkWidget *NicknameWin;
1484 GtkWidget *HBox;
1485 GtkWidget *Entry;
1486 GtkWidget *Label;
1487
1488 NicknameWin = gtk_dialog_new_with_buttons("GtkAtlantic: Nickname",
1489 GTK_WINDOW(global->MainWin), GTK_DIALOG_MODAL,
1490 "_OK", GTK_RESPONSE_OK, NULL);
1491
1492 HBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1493 gtk_container_set_border_width(GTK_CONTAINER(HBox), 10);
1494 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(NicknameWin))), HBox);
1495
1496 Label = gtk_label_new("Nickname:");
1497 gtk_box_pack_start(GTK_BOX(HBox), Label, FALSE, FALSE, 5);
1498
1499 Entry = gtk_entry_new();
1500 gtk_widget_set_size_request(Entry, 150, -1);
1501 g_object_set_data(G_OBJECT(NicknameWin), "nickname", Entry);
1502 gtk_entry_set_text(GTK_ENTRY(Entry), player_from_id(global->my_playerid)->name);
1503 gtk_box_pack_start(GTK_BOX(HBox), Entry, TRUE, TRUE, 0);
1504
1505 g_signal_connect(G_OBJECT(NicknameWin), "response", G_CALLBACK(CallBack_response_changenick_window), NicknameWin);
1506
1507 gtk_widget_show_all(NicknameWin);
1508 }
1509
1510
1511 /* create estates tree */
interface_create_estates_tree()1512 void interface_create_estates_tree() {
1513
1514 GtkWidget *EstateWin;
1515 GtkWidget *HBox;
1516 GtkWidget *ScrollWin;
1517 GtkWidget *EstateTree;
1518 GtkWidget *VBox;
1519 GtkWidget *Label;
1520
1521 GtkTreeViewColumn *estateTreeCol;
1522 GtkCellRenderer *estateTreeRenderer;
1523 GtkTreeStore *stateTreestore;
1524 GtkTreeIter stateTreeIterGroup[MAX_GROUPS], stateTreeIterOther, stateTreeIterChild;
1525 GtkTreeSelection *select;
1526 guint32 i;
1527
1528 if(currentgame->WinEstateTree) return;
1529
1530 currentgame->WinEstateTree = EstateWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1531 gtk_widget_set_size_request(EstateWin, 450, 400);
1532 gtk_window_set_title(GTK_WINDOW(EstateWin), "GtkAtlantic: Estates Tree");
1533 g_signal_connect(G_OBJECT(EstateWin), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
1534 g_signal_connect(G_OBJECT(EstateWin), "destroy", G_CALLBACK(CallBack_EstateTree_Destroyed), NULL);
1535
1536 HBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1537 g_object_set_data(G_OBJECT(currentgame->WinEstateTree), "parent_box", HBox);
1538 // gtk_container_set_border_width(GTK_CONTAINER(HBox), 10);
1539 gtk_container_add(GTK_CONTAINER(EstateWin), HBox);
1540
1541 /* ScrollWin win */
1542 ScrollWin = gtk_scrolled_window_new(NULL, NULL);
1543 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ScrollWin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1544 gtk_widget_set_size_request(ScrollWin, 250, -1);
1545 gtk_box_pack_start(GTK_BOX(HBox), ScrollWin, FALSE, TRUE, 0);
1546
1547 /* estate tree */
1548 EstateTree = gtk_tree_view_new();
1549 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(EstateTree));
1550 gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
1551 g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(CallBack_EstateTree_SelectRow), NULL);
1552
1553 gtk_container_add(GTK_CONTAINER(ScrollWin), EstateTree);
1554
1555 estateTreeCol = gtk_tree_view_column_new();
1556 gtk_tree_view_column_set_title(estateTreeCol, "Estates");
1557 gtk_tree_view_append_column(GTK_TREE_VIEW(EstateTree), estateTreeCol);
1558
1559 estateTreeRenderer = gtk_cell_renderer_text_new();
1560 gtk_tree_view_column_pack_start(estateTreeCol, estateTreeRenderer, TRUE);
1561 gtk_tree_view_column_add_attribute(estateTreeCol, estateTreeRenderer, "text", 0);
1562
1563
1564 stateTreestore = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_INT);
1565
1566 /* create groups node */
1567 for(i = 0 ; i < MAX_GROUPS ; i++) {
1568 if(! currentgame->group[i].name) continue;
1569
1570 gtk_tree_store_append(stateTreestore, &stateTreeIterGroup[i], NULL);
1571 gtk_tree_store_set(stateTreestore, &stateTreeIterGroup[i], 0, currentgame->group[i].name, 1, -1, -1);
1572 }
1573 gtk_tree_store_append(stateTreestore, &stateTreeIterOther, NULL);
1574 gtk_tree_store_set(stateTreestore, &stateTreeIterOther, 0, "Other", 1, -1, -1);
1575
1576 /* create estates node */
1577 for(i = 0 ; i < data->number_estates ; i++) {
1578 if(currentgame->estate[i].group >= 0) {
1579 gtk_tree_store_append(stateTreestore, &stateTreeIterChild, &stateTreeIterGroup[currentgame->estate[i].group]);
1580 } else {
1581 gtk_tree_store_append(stateTreestore, &stateTreeIterChild, &stateTreeIterOther);
1582 }
1583 gtk_tree_store_set(stateTreestore, &stateTreeIterChild, 0, currentgame->estate[i].name, 1, i, -1);
1584 }
1585
1586 gtk_tree_view_set_model(GTK_TREE_VIEW(EstateTree), GTK_TREE_MODEL(stateTreestore));
1587 g_object_unref(stateTreestore); /* the TreeView creates its own reference */
1588
1589 /* Expand groups */
1590 for(i = 0 ; i < MAX_GROUPS ; i++) {
1591 GtkTreePath *path;
1592
1593 if(! currentgame->group[i].name) continue;
1594
1595 path = gtk_tree_model_get_path(GTK_TREE_MODEL(stateTreestore), &stateTreeIterGroup[i]);
1596 if(path) {
1597 gtk_tree_view_expand_row(GTK_TREE_VIEW(EstateTree), path, FALSE);
1598 gtk_tree_path_free(path);
1599 }
1600 }
1601
1602 /* info box */
1603 VBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1604 g_object_set_data(G_OBJECT(currentgame->WinEstateTree), "info_box", VBox);
1605 gtk_container_set_border_width(GTK_CONTAINER(VBox), 10);
1606 gtk_box_pack_start(GTK_BOX(HBox), VBox, TRUE, TRUE, 0);
1607
1608 /* default text */
1609 Label = gtk_label_new("Select an estate...");
1610 gtk_widget_set_halign(Label, GTK_ALIGN_START);
1611 gtk_widget_set_valign(Label, GTK_ALIGN_START);
1612 gtk_box_pack_start(GTK_BOX(VBox), Label, FALSE, TRUE, 0);
1613
1614
1615 gtk_widget_show_all(EstateWin);
1616 }
1617
1618
1619 /* create help window */
interface_create_helpwin()1620 void interface_create_helpwin() {
1621
1622 GtkWidget *HelpWin;
1623 GtkWidget *Scrolled;
1624 GtkWidget *label;
1625
1626 if(global->HelpWin) return;
1627
1628 global->HelpWin = HelpWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1629 gtk_widget_set_size_request(HelpWin, 700, 500);
1630 gtk_window_set_title(GTK_WINDOW(HelpWin), "GtkAtlantic: Help");
1631 g_signal_connect(G_OBJECT(HelpWin), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
1632 g_signal_connect(G_OBJECT(HelpWin), "destroy", G_CALLBACK(CallBack_HelpWin_Destroyed), NULL);
1633
1634 Scrolled = gtk_scrolled_window_new(NULL, NULL);
1635 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1636 gtk_container_add(GTK_CONTAINER(global->HelpWin), Scrolled);
1637
1638 label = gtk_label_new(NULL);
1639 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1640 gtk_container_add(GTK_CONTAINER(Scrolled), label);
1641
1642 gchar *tmp = g_markup_printf_escaped(
1643 "<span size=\"xx-large\"><b>GtkAtlantic Help</b></span>\n"
1644 "\n"
1645 "<span size=\"x-large\"><b>Contents</b></span>\n"
1646 "\n"
1647 "1) About Atlantic\n"
1648 " i. What is the Atlantic game?\n"
1649 " ii. What is GtkAtlantic?\n"
1650 "2) How to play\n"
1651 "3) Fun chat macros\n"
1652 " i. Remote Macros\n"
1653 " ii. Local Macros\n"
1654 "\n"
1655 "\n"
1656 "<span size=\"x-large\"><b>1) About Atlantic</b></span>\n"
1657 "\n"
1658 "<span size=\"large\"><b>i. What is the Atlantic game?</b></span>\n"
1659 "\n"
1660 "The goal in playing Atlantic is to <i>Get rich quick and win!</i> The richest player is the winner :)\n"
1661 "\n"
1662 "In order to win, you need to buy properties quickly and profitably. To succeed, you need at least one set of the same group of "
1663 "properties, so that you can build Houses and ultimately Hotels upon them.\n"
1664 "\n"
1665 "Play begins from <i>Start</i> square. Players move their tokens around the board by clicking the <i>Roll Dice</i> button. When a player lands "
1666 "on an unowned estate, he may <i>Buy</i> it from the bank or put it up for <i>Auction</i>. When a player lands on a estate owned by custom "
1667 "player, he must pay rent to the owner.\n"
1668 "\n"
1669 "Building houses or hotels dramatically increase payable rents - so much so that it may force other players to declare 'Bankruptcy'. "
1670 "To raise money, you can mortgage any owned estate to the bank.\n"
1671 "\n"
1672 "The <i>Chance</i> and <i>Community</i> squares give you a card whose instructions must be followed. Sometimes you are sent to Jail! :(\n"
1673 "\n"
1674 "Atlantic is a game that combines subtlety and a sense of business - a good mood helps if you are losing! :)\n"
1675 "\n"
1676 "<span size=\"large\"><b>ii. What is GtkAtlantic?</b></span>\n"
1677 "\n"
1678 "GtkAtlantic is a network client to play the Atlantic game on monopd servers. The Atlantic game looks like a Monopoly® game.\n"
1679 "\n"
1680 "\n"
1681 "<span size=\"x-large\"><b>2) How to Play</b></span>\n"
1682 "\n"
1683 "Well, it is quite easy to play with GtkAtlantic. If you know how to play Monopoly® you can probably play without problem.\n"
1684 "\n"
1685 "<b>Roll dice:</b> Clic the <i>Roll</i> button.\n"
1686 "\n"
1687 "<b>Buy a house:</b> Clic on the estate on which you want to build a house then choose <i>Build house</i>.\n"
1688 "<b>Sell a house:</b> Clic on the estate on which you want to sell a house then choose <i>Sell house</i>.\n"
1689 "<b>Mortgage an estate:</b> Clic on the estate you want to mortgage then choose <i>(Un)mortgage</i>.\n"
1690 "\n"
1691 "<b>Start a trade with a player:</b> Clic on the player you want to trade with, then select <i>Initiate a trade</i>.\n"
1692 "\n"
1693 "\n"
1694 "<span size=\"x-large\"><b>3) Fun chat commands</b></span>\n"
1695 "\n"
1696 "<span size=\"large\"><b>i. Remote commands</b></span>\n"
1697 "\n"
1698 "Note that all players will know what you are doing, and all players will receive what you have requested. "
1699 "Please do not flood chat - use with care because some players don't like receiving this information. "
1700 "Only a GtkAtlantic client will answer these requests.\n"
1701 "\n"
1702 "<b>!version [player]</b>\n"
1703 "Returns player client version. If no player is specified, returns client version of all players.\n"
1704 "\n"
1705 "<b>!date [player]</b>\n"
1706 "Returns player local time. If no player is specified, returns date of all players.\n"
1707 "\n"
1708 "<b>!ping [player]</b>\n"
1709 "Returns pong if player is still connected. If no player is specified, returns pong of all players\n"
1710 "\n"
1711 "<span size=\"large\"><b>ii. Local commands</b></span>\n"
1712 "\n"
1713 "Local commands to use whenever you want and as often as you need.\n"
1714 "\n"
1715 "<b>/me msg</b>\n"
1716 "Sends an action message\n"
1717 "\n"
1718 "<b>/date</b>\n"
1719 "Returns local time\n"
1720 "\n"
1721 "<b>/nick [new nick]</b>\n"
1722 "Changes nick\n"
1723 "\n"
1724 "<b>/assets [player]</b>\n"
1725 "Returns player assets. If no player is specified, returns assets of all players.\n"
1726 "\n"
1727 "<b>/elapsed</b>\n"
1728 "Returns elapsed time since game start.\n"
1729 "\n"
1730 );
1731 gtk_label_set_markup(GTK_LABEL(label), tmp);
1732 g_free(tmp);
1733
1734 gtk_widget_show_all(HelpWin);
1735 }
1736
1737
infolabel_timeout(gpointer data)1738 static gboolean infolabel_timeout(gpointer data) {
1739 (void)data;
1740
1741 gtk_label_set_text(GTK_LABEL(global->InfoLabel), NULL);
1742 global->timeout_InfoLabel = 0;
1743 return FALSE;
1744 }
1745
interface_set_infolabel(gchar * text,gchar * color,gboolean eternal)1746 void interface_set_infolabel(gchar *text, gchar *color, gboolean eternal) {
1747 gchar *tmp = g_markup_printf_escaped("<span foreground=\"#%s\">%s</span>", color, text);
1748 gtk_label_set_markup(GTK_LABEL(global->InfoLabel), tmp);
1749 g_free(tmp);
1750 if (global->timeout_InfoLabel) {
1751 g_source_remove(global->timeout_InfoLabel);
1752 global->timeout_InfoLabel = 0;
1753 }
1754 if (!eternal) {
1755 global->timeout_InfoLabel = g_timeout_add_seconds(5, infolabel_timeout, NULL);
1756 }
1757 }
1758
1759
1760 /* generic window with a label into */
interface_create_messagewin(gchar * msg)1761 void interface_create_messagewin(gchar *msg) {
1762 (void)msg;
1763 #if 0
1764 GtkWidget *MessageWin;
1765 GtkWidget *VBox;
1766 GtkWidget *Label;
1767 GtkWidget *Button;
1768
1769
1770 MessageWin = gtk_window_new(GTK_WINDOW_DIALOG);
1771 gtk_window_set_title(GTK_WINDOW(MessageWin), "GtkAtlantic: Message");
1772 gtk_window_set_position(GTK_WINDOW(MessageWin), GTK_WIN_POS_CENTER);
1773 gtk_window_set_transient_for(GTK_WINDOW(MessageWin), GTK_WINDOW(global->MainWin));
1774 gtk_window_set_modal(GTK_WINDOW(MessageWin), TRUE);
1775 gtk_widget_set_size_request(MessageWin, -1, -1);
1776 g_signal_connect(G_OBJECT(MessageWin), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
1777
1778 VBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1779 gtk_container_set_border_width(GTK_CONTAINER(VBox), 10);
1780 gtk_container_add(GTK_CONTAINER(MessageWin), VBox);
1781
1782 /* text */
1783 Label = gtk_label_new(msg);
1784 gtk_label_set_line_wrap(GTK_LABEL(Label), TRUE);
1785 gtk_box_pack_start(GTK_BOX(VBox), Label, TRUE, TRUE, 0);
1786
1787 /* ok button */
1788 Button = gtk_button_new_with_label("OK");
1789 gtk_widget_set_halign(Button, GTK_ALIGN_CENTER);
1790 gtk_widget_set_valign(Button, GTK_ALIGN_CENTER);
1791 gtk_widget_set_size_request(Button, 70, -1);
1792 gtk_box_pack_start(GTK_BOX(VBox), Button, FALSE, FALSE, 0);
1793
1794 g_signal_connect_object(G_OBJECT(Button), "clicked", G_CALLBACK(gtk_widget_destroy), MessageWin, G_CONNECT_SWAPPED);
1795
1796 gtk_widget_show_all(MessageWin);
1797 #endif
1798 }
1799
1800
1801
1802 /* when receive event: redraw an estate */
on_board_draw(GtkWidget * widget,cairo_t * cr,gpointer d)1803 void on_board_draw(GtkWidget *widget, cairo_t *cr, gpointer d) {
1804 (void)d;
1805 gint32 id;
1806 eng_frame *frame;
1807 gint32 width, height, stride;
1808 eng_coord coord;
1809 cairo_surface_t *surface;
1810 guint8 *buf;
1811 gint32 bufferid;
1812
1813 id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "estateid"));
1814 frame = currentgame->board_frame;
1815 bufferid = data->estate[id].buffer_board;
1816
1817 width = data->pngfile_board_width[bufferid];
1818 height = data->pngfile_board_height[bufferid];
1819 stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
1820 coord.x = data->estate[id].x;
1821 coord.y = data->estate[id].y;
1822 coord.width = width;
1823 coord.height = height;
1824 coord.stride = stride;
1825
1826 buf = eng_get_zone(frame, &coord);
1827 surface = cairo_image_surface_create_for_data((unsigned char*)buf, CAIRO_FORMAT_ARGB32, width, height, stride);
1828 cairo_set_source_surface(cr, surface, 0, 0);
1829 cairo_paint(cr);
1830 cairo_surface_destroy(surface);
1831 g_free(buf);
1832 }
1833
1834 /* when receive event: redraw player token */
on_playertoken_draw(GtkWidget * widget,cairo_t * cr,gpointer d)1835 void on_playertoken_draw(GtkWidget *widget, cairo_t *cr, gpointer d) {
1836 (void)d;
1837 eng_frame *frame;
1838 gint32 width, height, stride;
1839 eng_coord coord;
1840 cairo_surface_t *surface;
1841 guint8 *buf;
1842
1843 player *p = g_object_get_data(G_OBJECT(widget), "player");
1844 frame = p->playerlist_token_frame;
1845
1846 width = data->playerlist_token_width;
1847 height = data->playerlist_token_height;
1848 stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
1849 coord.x = 0;
1850 coord.y = 0;
1851 coord.width = width;
1852 coord.height = height;
1853 coord.stride = stride;
1854
1855 buf = eng_get_zone(frame, &coord);
1856 surface = cairo_image_surface_create_for_data((unsigned char*)buf, CAIRO_FORMAT_ARGB32, width, height, stride);
1857 cairo_set_source_surface(cr, surface, 0, 0);
1858 cairo_paint(cr);
1859 cairo_surface_destroy(surface);
1860 g_free(buf);
1861 }
1862
1863 /* when receive event: redraw player cards */
on_playercards_draw(GtkWidget * widget,cairo_t * cr,gpointer d)1864 void on_playercards_draw(GtkWidget *widget, cairo_t *cr, gpointer d) {
1865 (void)d;
1866 eng_frame *frame;
1867 gint32 width, height, stride;
1868 eng_coord coord;
1869 cairo_surface_t *surface;
1870 guint8 *buf;
1871
1872 player *p = g_object_get_data(G_OBJECT(widget), "player");
1873 frame = p->playerlist_cards_frame;
1874
1875 width = data->playerlist_cards_width;
1876 height = data->playerlist_cards_height;
1877 stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
1878 coord.x = 0;
1879 coord.y = 0;
1880 coord.width = width;
1881 coord.height = height;
1882 coord.stride = stride;
1883
1884 buf = eng_get_zone(frame, &coord);
1885 surface = cairo_image_surface_create_for_data((unsigned char*)buf, CAIRO_FORMAT_ARGB32, width, height, stride);
1886 cairo_set_source_surface(cr, surface, 0, 0);
1887 cairo_paint(cr);
1888 cairo_surface_destroy(surface);
1889 g_free(buf);
1890 }
1891
1892
1893 /* update display */
update_display()1894 void update_display() {
1895 guint32 i;
1896 eng_frame *frame;
1897
1898 if (global->phase != PHASE_GAMEPLAY) {
1899 return;
1900 }
1901
1902 /* draw the board */
1903 frame = currentgame->board_frame;
1904 eng_create_frame(frame);
1905
1906 for(i = 0 ; i < data->number_estates ; i++) {
1907 eng_coord coord;
1908 gint32 width, height;
1909 gint32 bufferid;
1910
1911 if(! currentgame->estate[i].gdkrgb) continue;
1912 if(! frame) continue;
1913
1914 bufferid = data->estate[i].buffer_board;
1915
1916 width = data->pngfile_board_width[bufferid];
1917 height = data->pngfile_board_height[bufferid];
1918 coord.x1 = data->estate[i].x;
1919 coord.y1 = data->estate[i].y;
1920 coord.x2 = coord.x1 + width -1;
1921 coord.y2 = coord.y1 + height -1;
1922
1923 /* force draw event */
1924 if (eng_zone_is_modified(frame, &coord) ) {
1925 gtk_widget_queue_draw_area(currentgame->estate[i].gdkrgb, 0, 0, width, height);
1926 }
1927 }
1928
1929
1930 /* draw playerlist */
1931 player *p;
1932 for (p = player_h; p; p = p->next) {
1933 eng_frame *frame;
1934 gint32 width, height;
1935 eng_coord coord;
1936
1937 if (p->spectator) continue;
1938 if (p->game != currentgame->gameid) continue;
1939 if (!p->playerlist_cards_gdkrgb) continue;
1940
1941 /* playerlist cards */
1942 frame = p->playerlist_cards_frame;
1943 eng_create_frame(frame);
1944
1945 width = data->playerlist_cards_width;
1946 height = data->playerlist_cards_height;
1947 coord.x1 = 0;
1948 coord.y1 = 0;
1949 coord.x2 = width -1;
1950 coord.y2 = height -1;
1951
1952 /* force draw event */
1953 if ( eng_zone_is_modified(frame, &coord) ) {
1954 gtk_widget_queue_draw_area(p->playerlist_cards_gdkrgb, 0, 0, width, height);
1955 }
1956
1957 /* playerlist token */
1958 frame = p->playerlist_token_frame;
1959 eng_create_frame(frame);
1960
1961 width = data->playerlist_token_width;
1962 height = data->playerlist_token_height;
1963 coord.x1 = 0;
1964 coord.y1 = 0;
1965 coord.x2 = width -1;
1966 coord.y2 = height -1;
1967
1968 /* force draw event */
1969 if ( eng_zone_is_modified(frame, &coord) ) {
1970 gtk_widget_queue_draw_area(p->playerlist_token_gdkrgb, 0, 0, width, height);
1971 }
1972 }
1973 }
1974