Freeciv-3.1
Loading...
Searching...
No Matches
plrdlg.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include <gtk/gtk.h>
23#include <gdk/gdkkeysyms.h>
24
25/* utility */
26#include "astring.h"
27#include "fcintl.h"
28#include "support.h"
29
30/* common */
31#include "diptreaty.h"
32#include "packets.h"
33#include "nation.h"
34#include "player.h"
35
36/* client */
37#include "client_main.h"
38#include "climisc.h"
39#include "connectdlg_common.h"
40#include "tilespec.h"
41#include "colors.h"
42#include "graphics.h"
43#include "options.h"
44#include "text.h"
45
46/* client/gui-gtk-4.0 */
47#include "chatline.h"
48#include "dialogs.h"
49#include "gui_main.h"
50#include "gui_stuff.h"
51#include "inteldlg.h"
52#include "spaceshipdlg.h"
53#include "colors.h"
54#include "graphics.h"
55
56#include "plrdlg.h"
57
59static GtkWidget *players_list;
60static GtkTreeSelection *players_selection;
61static GSimpleAction *players_int_command;
62static GSimpleAction *players_meet_command;
63static GSimpleAction *players_war_command;
64static GSimpleAction *players_vision_command;
65static GSimpleAction *players_sship_command;
66
67static GtkListStore *players_dialog_store;
68#define PLR_DLG_COL_STYLE (0 + num_player_dlg_columns)
69#define PLR_DLG_COL_WEIGHT (1 + num_player_dlg_columns)
70#define PLR_DLG_COL_ID (2 + num_player_dlg_columns)
71#define PLR_DLG_COL_TOOLTIP (3 + num_player_dlg_columns)
72
73#define PLR_DLG_COL_TOTAL (PLR_DLG_COL_TOOLTIP + 1)
74
75static void create_players_dialog(void);
76static void players_meet_callback(GSimpleAction *action, GVariant *parameter,
77 gpointer data);
78static void players_war_callback(GSimpleAction *action, GVariant *parameter,
79 gpointer data);
80static void players_vision_callback(GSimpleAction *action, GVariant *parameter,
81 gpointer data);
82static void players_intel_callback(GSimpleAction *action, GVariant *parameter,
83 gpointer data);
84static void players_intel_wonder_callback(GSimpleAction *action,
85 GVariant *parameter, gpointer data);
86static void players_sship_callback(GSimpleAction *action, GVariant *parameter,
87 gpointer data);
88static void players_ai_toggle_callback(GSimpleAction *action, GVariant *parameter,
89 gpointer data);
90static void players_ai_skill_callback(GSimpleAction *action, GVariant *parameter,
91 gpointer data);
92
93static void update_views(void);
94
95static GMenu *display_menu;
96
97/**********************************************************************/
100void popup_players_dialog(bool raise)
101{
104 }
106 if (raise) {
108 }
109}
110
111/**********************************************************************/
120
121/**********************************************************************/
126GdkPixbuf *create_player_icon(const struct player *plr)
127{
128 int width = 20;
129 int height = 20;
130 GdkPixbuf *tmp;
131 cairo_surface_t *surface;
132 struct color *color;
133 cairo_t *cr;
134
135 if (!player_has_color(plr)) {
136 return NULL;
137 }
138
139 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
140
141 cr = cairo_create(surface);
142
143 color = get_color(tileset, COLOR_PLAYER_COLOR_BACKGROUND);
144 gdk_cairo_set_source_rgba(cr, &color->color);
145 cairo_rectangle(cr, 0, 0, width, height);
146 cairo_fill(cr);
147
149 gdk_cairo_set_source_rgba(cr, &color->color);
150 cairo_rectangle(cr, 1, 1, width - 2, height - 2);
151 cairo_fill(cr);
152
153 cairo_destroy(cr);
154 tmp = surface_get_pixbuf(surface, width, height);
155 cairo_surface_destroy(surface);
156
157 return tmp;
158}
159
160/**********************************************************************/
163static void update_players_menu(void)
164{
165 GtkTreeModel *model;
166 GtkTreeIter it;
167
168 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
169 struct player *plr;
170 gint plrno;
171
172 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
173 plr = player_by_number(plrno);
174
175 if (plr->spaceship.state != SSHIP_NONE) {
176 g_simple_action_set_enabled(players_sship_command, TRUE);
177 } else {
178 g_simple_action_set_enabled(players_sship_command, FALSE);
179 }
180
181 if (NULL != client.conn.playing) {
182 /* We keep button sensitive in case of DIPL_SENATE_BLOCKING, so that player
183 * can request server side to check requirements of those effects with omniscience */
184 g_simple_action_set_enabled(players_war_command,
187 player_by_number(plrno))
188 != DIPL_ERROR);
189 } else {
190 g_simple_action_set_enabled(players_war_command, FALSE);
191 }
192
193 g_simple_action_set_enabled(players_vision_command,
197
198 g_simple_action_set_enabled(players_meet_command, can_meet_with_player(plr));
199 g_simple_action_set_enabled(players_int_command, can_intel_with_player(plr));
200 return;
201 }
202
203 g_simple_action_set_enabled(players_meet_command, FALSE);
204 g_simple_action_set_enabled(players_int_command, FALSE);
205}
206
207/**********************************************************************/
210static void selection_callback(GtkTreeSelection *selection, gpointer data)
211{
213}
214
215/**********************************************************************/
218static gboolean left_button_press_callback(GtkGestureClick *gesture, int n_press,
219 double x, double y)
220{
221 GtkTreeView *view
222 = GTK_TREE_VIEW(gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture)));
223
224 if (n_press == 2) {
225 GtkTreePath *path;
226
227 gtk_tree_view_get_cursor(view, &path, NULL);
228 if (path) {
229 GtkTreeModel *model = gtk_tree_view_get_model(view);
230 GtkTreeIter it;
231 gint id;
232 struct player *plr;
233
234 gtk_tree_model_get_iter(model, &it, path);
235 gtk_tree_path_free(path);
236
237 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &id, -1);
238 plr = player_by_number(id);
239
240 if (can_intel_with_player(plr)) {
242 }
243 }
244 }
245
246 return FALSE;
247}
248
249/**********************************************************************/
252static gboolean right_button_press_callback(GtkGestureClick *gesture, int n_press,
253 double x, double y)
254{
255 GtkTreeView *view
256 = GTK_TREE_VIEW(gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture)));
257
258 if (n_press == 2) {
259 GtkTreePath *path;
260
261 gtk_tree_view_get_cursor(view, &path, NULL);
262 if (path) {
263 GtkTreeModel *model = gtk_tree_view_get_model(view);
264 GtkTreeIter it;
265 gint id;
266 struct player *plr;
267
268 gtk_tree_model_get_iter(model, &it, path);
269 gtk_tree_path_free(path);
270
271 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &id, -1);
272 plr = player_by_number(id);
273
274 if (can_meet_with_player(plr)) {
276 }
277 }
278 }
279
280 return FALSE;
281}
282
283/**********************************************************************/
286static gint plrdlg_sort_func(GtkTreeModel *model,
287 GtkTreeIter *a, GtkTreeIter *b, gpointer data)
288{
289 GValue value = { 0, };
290 struct player *player1;
291 struct player *player2;
292 gint n;
293
294 n = GPOINTER_TO_INT(data);
295
296 gtk_tree_model_get_value(model, a, PLR_DLG_COL_ID, &value);
297 player1 = player_by_number(g_value_get_int(&value));
298 g_value_unset(&value);
299
300 gtk_tree_model_get_value(model, b, PLR_DLG_COL_ID, &value);
301 player2 = player_by_number(g_value_get_int(&value));
302 g_value_unset(&value);
303
304 return player_dlg_columns[n].sort_func(player1, player2);
305}
306
307/**********************************************************************/
310static GtkListStore *players_dialog_store_new(void)
311{
312 GtkListStore *store;
313 GType model_types[num_player_dlg_columns + PLR_DLG_COL_TOTAL];
314 int i;
315
316 for (i = 0; i < num_player_dlg_columns; i++) {
317 switch (player_dlg_columns[i].type) {
318 case COL_FLAG:
319 model_types[i] = GDK_TYPE_PIXBUF;
320 break;
321 case COL_COLOR:
322 model_types[i] = GDK_TYPE_PIXBUF;
323 break;
324 case COL_BOOLEAN:
325 model_types[i] = G_TYPE_BOOLEAN;
326 break;
327 case COL_TEXT:
328 case COL_RIGHT_TEXT:
329 model_types[i] = G_TYPE_STRING;
330 break;
331 }
332 }
333
334 /* Special (invisible rows) - Text style, weight and player id */
335 model_types[i++] = G_TYPE_INT; /* PLR_DLG_COL_STYLE. */
336 model_types[i++] = G_TYPE_INT; /* PLR_DLG_COL_WEIGHT. */
337 model_types[i++] = G_TYPE_INT; /* PLR_DLG_COL_ID. */
338 model_types[i++] = G_TYPE_STRING; /* PLR_DLG_COL_TOOLTIP */
339
340 store = gtk_list_store_newv(i, model_types);
341
342 /* Set sort order */
343 for (i = 0; i < num_player_dlg_columns; i++) {
344 if (player_dlg_columns[i].sort_func != NULL) {
345 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), i,
346 plrdlg_sort_func, GINT_TO_POINTER(i),
347 NULL);
348 }
349 }
350
351 return store;
352}
353
354/************************************************************************/
359{
360 GMenuItem *item;
361 char act_name[50];
362 struct player_dlg_column *pcol;
363
364 pcol = &player_dlg_columns[pos];
365
366 fc_snprintf(act_name, sizeof(act_name), "win.display%d(%s)",
367 pos, pcol->show ? "true" : "false");
368 item = g_menu_item_new(pcol->title, NULL);
369 g_menu_item_set_detailed_action(item, act_name);
370
371 return item;
372}
373
374/************************************************************************/
378static GMenuItem *create_dead_players_menu_item(void)
379{
380 GMenuItem *item;
381 char act_name[50];
382
383 /* TODO: Should this be gui-specific option as there's no universal
384 * player dlg setup? */
385 fc_snprintf(act_name, sizeof(act_name), "win.show_dead(%s)",
386 gui_options.player_dlg_show_dead_players ? "true" : "false");
387 item = g_menu_item_new(Q_("?show:Dead Players"), NULL);
388 g_menu_item_set_detailed_action(item, act_name);
389
390 return item;
391}
392
393/**********************************************************************/
396static void toggle_view(GSimpleAction *act, GVariant *value, gpointer data)
397{
398 int idx = GPOINTER_TO_INT(data);
399 struct player_dlg_column *pcol = &player_dlg_columns[idx];
400
401 pcol->show ^= 1;
402 update_views();
403
404 /* The menu has no 'playername' in the beginning, so menu index is one smaller
405 * then column index. */
406 g_menu_remove(display_menu, idx - 1);
407
409}
410
411/**********************************************************************/
414static void toggle_dead_players(GSimpleAction *act, GVariant *value,
415 gpointer data)
416{
417 int idx = GPOINTER_TO_INT(data);
418
421
422 /* The menu has no 'playername' in the beginning, so menu index is one smaller
423 * then column index - applies also to this even though this is not
424 * a column. */
425 g_menu_remove(display_menu, idx - 1);
426
429}
430
431/**********************************************************************/
435static GMenu *create_diplomacy_menu(GActionGroup *group)
436{
437 GMenu *menu;
438 GSimpleAction *act;
439
440 menu = g_menu_new();
441
442 act = g_simple_action_new("meet", NULL);
443 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
444 g_signal_connect(act, "activate", G_CALLBACK(players_meet_callback), NULL);
445 menu_item_append_unref(menu, g_menu_item_new(_("_Meet"), "win.meet"));
447
448 act = g_simple_action_new("cancel_treaty", NULL);
449 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
450 g_signal_connect(act, "activate", G_CALLBACK(players_war_callback), NULL);
451 menu_item_append_unref(menu, g_menu_item_new(_("Cancel _Treaty"),
452 "win.cancel_treaty"));
454
455 act = g_simple_action_new("withdraw_vision", NULL);
456 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
457 g_signal_connect(act, "activate", G_CALLBACK(players_vision_callback), NULL);
458 menu_item_append_unref(menu, g_menu_item_new(_("_Withdraw Vision"),
459 "win.withdraw_vision"));
461
462 return menu;
463}
464
465/**********************************************************************/
469static GMenu *create_intelligence_menu(GActionGroup *group)
470{
471 GMenu *menu;
472 GSimpleAction *act;
473
474 menu = g_menu_new();
475
476 act = g_simple_action_new("report", NULL);
477 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
478 g_signal_connect(act, "activate", G_CALLBACK(players_intel_callback), NULL);
479 menu_item_append_unref(menu, g_menu_item_new(_("_Report"), "win.report"));
481
482 act = g_simple_action_new("wonders", NULL);
483 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
484 g_signal_connect(act, "activate", G_CALLBACK(players_intel_wonder_callback), NULL);
485 menu_item_append_unref(menu, g_menu_item_new(_("_Wonders"), "win.wonders"));
486
487 act = g_simple_action_new("spaceship", NULL);
488 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
489 g_signal_connect(act, "activate", G_CALLBACK(players_sship_callback), NULL);
490 menu_item_append_unref(menu, g_menu_item_new(_("_Spaceship"), "win.spaceship"));
492
493 return menu;
494}
495
496/**********************************************************************/
499static GMenu *create_show_menu(GActionGroup *group)
500{
501 GVariantType *bvart = g_variant_type_new("b");
502 int i;
503 GSimpleAction *act;
504 GVariant *var;
505
506 display_menu = g_menu_new();
507
508 /* Index starting at one (1) here to force playername to always be shown */
509 for (i = 1; i < num_player_dlg_columns - 1; i++) {
510 char act_name[50];
511
512 var = g_variant_new("b", TRUE);
513 fc_snprintf(act_name, sizeof(act_name), "display%d", i);
514 act = g_simple_action_new_stateful(act_name, bvart, var);
515 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
516 g_signal_connect(act, "change-state", G_CALLBACK(toggle_view), GINT_TO_POINTER(i));
517
519 }
520
521 var = g_variant_new("b", TRUE);
522 act = g_simple_action_new_stateful("show_dead", bvart, var);
523 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
524
526 g_signal_connect(act, "change-state", G_CALLBACK(toggle_dead_players),
527 GINT_TO_POINTER(i));
528
529 g_variant_type_free(bvart);
530
531 return display_menu;
532}
533
534/**********************************************************************/
538static GMenu *create_ai_menu(GActionGroup *group)
539{
540 GMenu *menu;
541 GSimpleAction *act;
542 enum ai_level level;
543
544 menu = g_menu_new();
545
546 act = g_simple_action_new("ai_toggle", NULL);
547 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
548 g_signal_connect(act, "activate",
549 G_CALLBACK(players_ai_toggle_callback), NULL);
550
551 menu_item_append_unref(menu, g_menu_item_new(_("_Toggle AI Mode"),
552 "win.ai_toggle"));
553
554 for (level = 0; level < AI_LEVEL_COUNT; level++) {
556 const char *level_name = ai_level_translated_name(level);
557 char act_name[50];
558
559 fc_snprintf(act_name, sizeof(act_name), "ai_level%d", level);
560 act = g_simple_action_new(act_name, NULL);
561 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
562 g_signal_connect(act, "activate",
563 G_CALLBACK(players_ai_skill_callback),
564 GUINT_TO_POINTER(level));
565
566 fc_snprintf(act_name, sizeof(act_name), "win.ai_level%d", level);
567 menu_item_append_unref(menu, g_menu_item_new(level_name, act_name));
568 }
569 }
570
571 return menu;
572}
573
574/**********************************************************************/
578{
579 int i;
580 GtkWidget *sep, *sw;
581 GtkWidget *aux_menu;
582 GMenu *topmenu, *submenu;
583 GActionGroup *group;
584 GtkWidget *vgrid;
585 GtkEventController *left_controller;
586 GtkEventController *right_controller;
587 GtkGesture *gesture;
588 int grid_row = 0;
589
591 TRUE);
592 /* TRANS: Nations report title */
594
595 gui_dialog_add_button(players_dialog_shell, "window-close", _("_Close"),
596 GTK_RESPONSE_CLOSE);
597
599
601
602 players_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL
604 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(players_list),
606 gtk_widget_set_hexpand(players_list, TRUE);
607 gtk_widget_set_vexpand(players_list, TRUE);
608 g_object_unref(players_dialog_store);
609 gtk_widget_set_name(players_list, "small_font");
610
611 players_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(players_list));
612 g_signal_connect(players_selection, "changed",
613 G_CALLBACK(selection_callback), NULL);
614 gesture = gtk_gesture_click_new();
615 left_controller = GTK_EVENT_CONTROLLER(gesture);
616 g_signal_connect(left_controller, "pressed",
617 G_CALLBACK(left_button_press_callback), NULL);
618 gtk_widget_add_controller(players_list, left_controller);
619 gesture = gtk_gesture_click_new();
620 gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 3);
621 right_controller = GTK_EVENT_CONTROLLER(gesture);
622 g_signal_connect(right_controller, "pressed",
623 G_CALLBACK(right_button_press_callback), NULL);
624 gtk_widget_add_controller(players_list, right_controller);
625
626 for (i = 0; i < num_player_dlg_columns; i++) {
627 struct player_dlg_column *pcol;
628 GtkCellRenderer *renderer;
629 GtkTreeViewColumn *col;
630
631 pcol = &player_dlg_columns[i];
632 col = NULL;
633
634 switch (pcol->type) {
635 case COL_FLAG:
636 renderer = gtk_cell_renderer_pixbuf_new();
637
638 col = gtk_tree_view_column_new_with_attributes(pcol->title,
639 renderer, "pixbuf", i, NULL);
640 break;
641 case COL_BOOLEAN:
642 renderer = gtk_cell_renderer_toggle_new();
643
644 col = gtk_tree_view_column_new_with_attributes(pcol->title, renderer,
645 "active", i, NULL);
646 break;
647 case COL_COLOR:
648 renderer = gtk_cell_renderer_pixbuf_new();
649
650 col = gtk_tree_view_column_new_with_attributes(pcol->title, renderer,
651 "pixbuf", i, NULL);
652 break;
653 case COL_TEXT:
654 renderer = gtk_cell_renderer_text_new();
655 g_object_set(renderer, "style-set", TRUE, "weight-set", TRUE, NULL);
656
657 col = gtk_tree_view_column_new_with_attributes(pcol->title, renderer,
658 "text", i,
659 "style", PLR_DLG_COL_STYLE,
660 "weight", PLR_DLG_COL_WEIGHT,
661 NULL);
662 gtk_tree_view_column_set_sort_column_id(col, i);
663 break;
664 case COL_RIGHT_TEXT:
665 renderer = gtk_cell_renderer_text_new();
666 g_object_set(renderer, "style-set", TRUE, "weight-set", TRUE, NULL);
667
668 col = gtk_tree_view_column_new_with_attributes(pcol->title, renderer,
669 "text", i,
670 "style", PLR_DLG_COL_STYLE,
671 "weight", PLR_DLG_COL_WEIGHT,
672 NULL);
673 gtk_tree_view_column_set_sort_column_id(col, i);
674 g_object_set(renderer, "xalign", 1.0, NULL);
675 gtk_tree_view_column_set_alignment(col, 1.0);
676 break;
677 }
678
679 if (col) {
680 gtk_tree_view_append_column(GTK_TREE_VIEW(players_list), col);
681 }
682 }
683
684 gtk_tree_view_set_search_column(GTK_TREE_VIEW(players_list),
686
687 sw = gtk_scrolled_window_new();
688 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
689 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
690 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
691 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), players_list);
692
694
695 vgrid = gtk_grid_new();
696 gtk_orientable_set_orientation(GTK_ORIENTABLE(vgrid),
697 GTK_ORIENTATION_VERTICAL);
698
699 sep = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
700 gtk_grid_attach(GTK_GRID(vgrid), sep, 0, grid_row++, 1, 1);
701
702 aux_menu = aux_menu_new();
703 gtk_grid_attach(GTK_GRID(vgrid), aux_menu, 0, grid_row++, 1, 1);
704
706
707 group = G_ACTION_GROUP(g_simple_action_group_new());
708 topmenu = g_menu_new();
709
710 submenu = create_diplomacy_menu(group);
711 submenu_append_unref(topmenu, _("Di_plomacy"), G_MENU_MODEL(submenu));
712
713 submenu = create_intelligence_menu(group);
714 submenu_append_unref(topmenu, _("_Intelligence"), G_MENU_MODEL(submenu));
715
716 submenu = create_show_menu(group);
717 submenu_append_unref(topmenu, _("_Display"), G_MENU_MODEL(submenu));
718
719 submenu = create_ai_menu(group);
720 submenu_append_unref(topmenu, _("_AI"), G_MENU_MODEL(submenu));
721
722 gtk_widget_insert_action_group(aux_menu, "win", group);
723 gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(aux_menu), G_MENU_MODEL(topmenu));
724
726
728
729 gtk_tree_view_focus(GTK_TREE_VIEW(players_list));
730}
731
732
733/**************************************************************************
734...
735**************************************************************************/
736#define MIN_DIMENSION 5
737
738/**********************************************************************/
743GdkPixbuf *get_flag(const struct nation_type *nation)
744{
745 int x0, y0, x1, y1, w, h;
746 GdkPixbuf *im;
747 struct sprite *flag;
748
749 flag = get_nation_flag_sprite(tileset, nation);
750
751 /* calculate the bounding box ... */
752 sprite_get_bounding_box(flag, &x0, &y0, &x1, &y1);
753
754 fc_assert_ret_val(x0 != -1, NULL);
755 fc_assert_ret_val(y0 != -1, NULL);
756 fc_assert_ret_val(x1 != -1, NULL);
757 fc_assert_ret_val(y1 != -1, NULL);
758
759 w = (x1 - x0) + 1;
760 h = (y1 - y0) + 1;
761
762 /* if the flag is smaller then 5 x 5, something is wrong */
764
765 /* croping */
766 im = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
767 if (im != NULL) {
768 GdkPixbuf *pixbuf = sprite_get_pixbuf(flag);
769
770 gdk_pixbuf_copy_area(pixbuf, x0, y0, w, h,
771 im, 0, 0);
772 g_object_unref(G_OBJECT(pixbuf));
773 }
774
775 /* and finally store the scaled flag pixbuf in the static flags array */
776 return im;
777}
778
779/**********************************************************************/
783static void fill_row(GtkListStore *store, GtkTreeIter *it,
784 const struct player *pplayer)
785{
786 struct player_dlg_column *pcol;
787 GdkPixbuf *pixbuf;
788 int style = PANGO_STYLE_NORMAL, weight = PANGO_WEIGHT_NORMAL;
789 int k;
790
791 for (k = 0; k < num_player_dlg_columns; k++) {
792 pcol = &player_dlg_columns[k];
793 switch (pcol->type) {
794 case COL_TEXT:
795 case COL_RIGHT_TEXT:
796 gtk_list_store_set(store, it, k, pcol->func(pplayer), -1);
797 break;
798 case COL_FLAG:
799 pixbuf = get_flag(nation_of_player(pplayer));
800 if (pixbuf != NULL) {
801 gtk_list_store_set(store, it, k, pixbuf, -1);
802 g_object_unref(pixbuf);
803 }
804 break;
805 case COL_COLOR:
806 pixbuf = create_player_icon(pplayer);
807 if (pixbuf != NULL) {
808 gtk_list_store_set(store, it, k, pixbuf, -1);
809 g_object_unref(pixbuf);
810 }
811 break;
812 case COL_BOOLEAN:
813 gtk_list_store_set(store, it, k, pcol->bool_func(pplayer), -1);
814 break;
815 }
816 }
817
818 gtk_list_store_set(store, it, PLR_DLG_COL_TOOLTIP,
819 score_tooltip(pplayer, pplayer->score.game), -1);
820
821 /* Now add some eye candy ... */
822 if (client_has_player()) {
823 switch (player_diplstate_get(client_player(), pplayer)->type) {
824 case DS_WAR:
825 weight = PANGO_WEIGHT_NORMAL;
826 style = PANGO_STYLE_ITALIC;
827 break;
828 case DS_ALLIANCE:
829 case DS_TEAM:
830 weight = PANGO_WEIGHT_BOLD;
831 style = PANGO_STYLE_NORMAL;
832 break;
833 case DS_ARMISTICE:
834 case DS_CEASEFIRE:
835 case DS_PEACE:
836 case DS_NO_CONTACT:
837 weight = PANGO_WEIGHT_NORMAL;
838 style = PANGO_STYLE_NORMAL;
839 break;
840 case DS_LAST:
841 break;
842 }
843 }
844
845 gtk_list_store_set(store, it,
846 PLR_DLG_COL_STYLE, style,
847 PLR_DLG_COL_WEIGHT, weight,
849 -1);
850}
851
852/**********************************************************************/
855static bool player_should_be_shown(const struct player *pplayer)
856{
857 return NULL != pplayer && (gui_options.player_dlg_show_dead_players
858 || pplayer->is_alive)
859 && (!is_barbarian(pplayer));
860}
861
862/**********************************************************************/
866{
867 GtkTreeModel *model;
868 GtkTreeIter iter;
869 int selected;
870
871 if (NULL == players_dialog_shell) {
872 return;
873 }
874
875 /* Save the selection. */
876 if (gtk_tree_selection_get_selected(players_selection, &model, &iter)) {
877 gtk_tree_model_get(model, &iter, PLR_DLG_COL_ID, &selected, -1);
878 } else {
879 selected = -1;
880 }
881
882 gtk_list_store_clear(players_dialog_store);
883 players_iterate(pplayer) {
884 if (!player_should_be_shown(pplayer)) {
885 continue;
886 }
887 gtk_list_store_append(players_dialog_store, &iter);
888 fill_row(players_dialog_store, &iter, pplayer);
889 if (player_number(pplayer) == selected) {
890 /* Restore the selection. */
891 gtk_tree_selection_select_iter(players_selection, &iter);
892 }
894
895 update_views();
896}
897
898/**********************************************************************/
902void players_meet_callback(GSimpleAction *action, GVariant *parameter,
903 gpointer data)
904{
905 GtkTreeModel *model;
906 GtkTreeIter it;
907
908 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
909 gint plrno;
910
911 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
912
914 }
915}
916
917/**********************************************************************/
921static void confirm_cancel_pact(enum clause_type clause, int plrno,
922 char *title, char *question)
923{
924 GtkWidget *shell;
925
926 shell = gtk_message_dialog_new(NULL, 0,
927 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
928 "%s", question);
929 gtk_window_set_title(GTK_WINDOW(shell), title);
931 gtk_dialog_set_default_response(GTK_DIALOG(shell), GTK_RESPONSE_NO);
932
933 if (blocking_dialog(shell) == GTK_RESPONSE_YES) {
935 }
936 gtk_window_destroy(GTK_WINDOW(shell));
937 FC_FREE(title);
938 FC_FREE(question);
939}
940
941/**********************************************************************/
944void players_war_callback(GSimpleAction *action, GVariant *parameter,
945 gpointer data)
946{
947 GtkTreeModel *model;
948 GtkTreeIter it;
949
950 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
951 struct astring title = ASTRING_INIT, question = ASTRING_INIT;
952 gint plrno;
953 struct player *aplayer;
954 enum diplstate_type oldstate, newstate;
955
956 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
957 aplayer = player_by_number(plrno);
958 fc_assert_ret(aplayer != NULL);
959
960 oldstate = player_diplstate_get(client_player(), aplayer)->type;
961 newstate = cancel_pact_result(oldstate);
962
963 /* TRANS: %s is a diplomatic state: "Cancel Cease-fire" */
964 astr_set(&title, _("Cancel %s"), diplstate_type_translated_name(oldstate));
965
966 if (newstate == DS_WAR) {
967 astr_set(&question, _("Really declare war on the %s?"),
968 nation_plural_for_player(aplayer));
969 } else {
970 /* TRANS: "Cancel Belgian Alliance? ... will be Armistice." */
971 astr_set(&question, _("Cancel %s %s? New diplomatic state will be %s."),
973 diplstate_type_translated_name(oldstate),
974 diplstate_type_translated_name(newstate));
975 }
976
977 /* can be any pact clause */
978 confirm_cancel_pact(CLAUSE_CEASEFIRE, plrno,
979 astr_to_str(&title), astr_to_str(&question));
980 }
981}
982
983/**********************************************************************/
986void players_vision_callback(GSimpleAction *action, GVariant *parameter,
987 gpointer data)
988{
989 GtkTreeModel *model;
990 GtkTreeIter it;
991
992 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
993 struct astring question = ASTRING_INIT;
994 gint plrno;
995 struct player *aplayer;
996
997 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
998 aplayer = player_by_number(plrno);
999 fc_assert_ret(aplayer != NULL);
1000
1001 /* TRANS: "...from the Belgians?" */
1002 astr_set(&question, _("Withdraw shared vision from the %s?"),
1003 nation_plural_for_player(aplayer));
1004
1005 confirm_cancel_pact(CLAUSE_VISION, plrno,
1006 fc_strdup(_("Withdraw Shared Vision")),
1007 astr_to_str(&question));
1008 }
1009}
1010
1011/**********************************************************************/
1014void players_intel_callback(GSimpleAction *action, GVariant *parameter,
1015 gpointer data)
1016{
1017 GtkTreeModel *model;
1018 GtkTreeIter it;
1019
1020 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
1021 gint plrno;
1022
1023 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
1024
1027 }
1028 }
1029}
1030
1031/**********************************************************************/
1034void players_intel_wonder_callback(GSimpleAction *action, GVariant *parameter,
1035 gpointer data)
1036{
1037 GtkTreeModel *model;
1038 GtkTreeIter it;
1039
1040 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
1041 gint plrno;
1042
1043 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
1044
1046 }
1047}
1048
1049/**********************************************************************/
1052void players_sship_callback(GSimpleAction *action, GVariant *parameter,
1053 gpointer data)
1054{
1055 GtkTreeModel *model;
1056 GtkTreeIter it;
1057
1058 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
1059 gint plrno;
1060
1061 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
1063 }
1064}
1065
1066/**********************************************************************/
1069static void players_ai_toggle_callback(GSimpleAction *action,
1070 GVariant *parameter,
1071 gpointer data)
1072{
1073 GtkTreeModel *model;
1074 GtkTreeIter it;
1075
1076 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
1077 gint plrno;
1078
1079 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
1080
1081 send_chat_printf("/aitoggle \"%s\"", player_name(player_by_number(plrno)));
1082 }
1083}
1084
1085/**********************************************************************/
1088static void players_ai_skill_callback(GSimpleAction *action,
1089 GVariant *parameter,
1090 gpointer data)
1091{
1092 GtkTreeModel *model;
1093 GtkTreeIter it;
1094
1095 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
1096 gint plrno;
1097
1098 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
1099
1100 send_chat_printf("/%s %s",
1101 ai_level_cmd(GPOINTER_TO_UINT(data)),
1103 }
1104}
1105
1106/**********************************************************************/
1109static void update_views(void)
1110{
1111 int i;
1112
1113 for (i = 0; i < num_player_dlg_columns; i++) {
1114 GtkTreeViewColumn *col;
1115
1116 col = gtk_tree_view_get_column(GTK_TREE_VIEW(players_list), i);
1117 gtk_tree_view_column_set_visible(col, player_dlg_columns[i].show);
1118 }
1119}
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
char * astr_to_str(struct astring *astr)
Definition astring.c:167
#define n
Definition astring.c:77
#define ASTRING_INIT
Definition astring.h:44
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
int send_chat_printf(const char *format,...)
bool can_meet_with_player(const struct player *pplayer)
bool can_intel_with_player(const struct player *pplayer)
struct civclient client
bool can_client_issue_orders(void)
bool client_has_player(void)
#define client_player()
struct color * get_player_color(const struct tileset *t, const struct player *pplayer)
bool player_has_color(const struct player *pplayer)
struct color * get_color(const struct tileset *t, enum color_std stdcolor)
int int id
Definition editgui_g.h:28
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
static struct tile * pos
Definition finddlg.c:53
GtkWidget * top_notebook
Definition gui_main.c:128
GtkWidget * toplevel
Definition gui_main.c:124
void gtk_tree_view_focus(GtkTreeView *view)
Definition gui_stuff.c:230
void gui_dialog_destroy(struct gui_dialog *dlg)
Definition gui_stuff.c:951
void gui_dialog_present(struct gui_dialog *dlg)
Definition gui_stuff.c:834
void gui_dialog_raise(struct gui_dialog *dlg)
Definition gui_stuff.c:864
void gui_dialog_new(struct gui_dialog **pdlg, GtkNotebook *notebook, gpointer user_data, bool check_top)
Definition gui_stuff.c:504
GtkWidget * gui_dialog_add_button(struct gui_dialog *dlg, const char *text, int response)
Definition gui_stuff.c:706
void gui_dialog_show_all(struct gui_dialog *dlg)
Definition gui_stuff.c:794
void gui_dialog_set_title(struct gui_dialog *dlg, const char *title)
Definition gui_stuff.c:932
void gui_dialog_set_default_size(struct gui_dialog *dlg, int width, int height)
Definition gui_stuff.c:916
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:281
void popup_intel_dialog(struct player *p)
Definition inteldlg.c:166
void popup_intel_wonder_dialog(struct player *p)
Definition inteldlg.c:182
static struct gui_dialog * shell
Definition messagedlg.c:39
static GtkWidget * players_int_command
Definition plrdlg.c:61
static void players_war_callback(GtkMenuItem *item, gpointer data)
Definition plrdlg.c:810
void popdown_players_dialog(void)
Definition plrdlg.c:105
static void fill_row(GtkListStore *store, GtkTreeIter *it, const struct player *pplayer)
Definition plrdlg.c:650
static GtkTreeSelection * players_selection
Definition plrdlg.c:60
static void update_views(void)
Definition plrdlg.c:966
static GtkWidget * players_vision_command
Definition plrdlg.c:64
static GtkWidget * players_list
Definition plrdlg.c:59
static GtkWidget * players_sship_command
Definition plrdlg.c:65
struct gui_dialog * players_dialog_shell
Definition plrdlg.c:58
static void players_ai_toggle_callback(GtkMenuItem *item, gpointer data)
Definition plrdlg.c:930
static void players_sship_callback(GtkMenuItem *item, gpointer data)
Definition plrdlg.c:914
#define PLR_DLG_COL_ID
Definition plrdlg.c:70
#define PLR_DLG_COL_WEIGHT
Definition plrdlg.c:69
#define PLR_DLG_COL_STYLE
Definition plrdlg.c:68
void real_players_dialog_update(void *unused)
Definition plrdlg.c:732
static GtkWidget * create_diplomacy_menu(void)
Definition plrdlg.c:337
static bool player_should_be_shown(const struct player *pplayer)
Definition plrdlg.c:722
#define PLR_DLG_COL_TOTAL
Definition plrdlg.c:73
GdkPixbuf * create_player_icon(const struct player *plr)
Definition plrdlg.c:117
static GtkWidget * create_intelligence_menu(void)
Definition plrdlg.c:368
void popup_players_dialog(bool raise)
Definition plrdlg.c:91
static GtkListStore * players_dialog_store
Definition plrdlg.c:67
static void players_intel_wonder_callback(GtkMenuItem *item, gpointer data)
Definition plrdlg.c:897
static void toggle_dead_players(GtkCheckMenuItem *item, gpointer data)
Definition plrdlg.c:326
#define PLR_DLG_COL_TOOLTIP
Definition plrdlg.c:71
static void players_meet_callback(GtkMenuItem *item, gpointer data)
Definition plrdlg.c:769
static void confirm_cancel_pact(enum clause_type clause, int plrno, char *title, char *question)
Definition plrdlg.c:787
static void players_vision_callback(GtkMenuItem *item, gpointer data)
Definition plrdlg.c:851
static gint plrdlg_sort_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
Definition plrdlg.c:244
GdkPixbuf * get_flag(const struct nation_type *nation)
Definition plrdlg.c:609
#define MIN_DIMENSION
Definition plrdlg.c:602
static GtkListStore * players_dialog_store_new(void)
Definition plrdlg.c:268
static GtkWidget * players_meet_command
Definition plrdlg.c:62
static void toggle_view(GtkCheckMenuItem *item, gpointer data)
Definition plrdlg.c:315
static void players_ai_skill_callback(GtkMenuItem *item, gpointer data)
Definition plrdlg.c:947
static void create_players_dialog(void)
Definition plrdlg.c:429
static void players_intel_callback(GtkMenuItem *item, gpointer data)
Definition plrdlg.c:878
static void update_players_menu(void)
Definition plrdlg.c:156
static GtkWidget * create_show_menu(void)
Definition plrdlg.c:397
static GtkWidget * players_war_command
Definition plrdlg.c:63
static void selection_callback(GtkTreeSelection *selection, gpointer data)
Definition plrdlg.c:203
const char * title
Definition repodlgs.c:1313
GType type
Definition repodlgs.c:1312
void popup_spaceship_dialog(struct player *pplayer)
GdkPixbuf * surface_get_pixbuf(cairo_surface_t *surf, int width, int height)
Definition sprite.c:418
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
Definition sprite.c:402
void sprite_get_bounding_box(struct sprite *sprite, int *start_x, int *start_y, int *end_x, int *end_y)
Definition sprite.c:321
@ COL_TEXT
Definition unitselect.c:50
gint blocking_dialog(GtkWidget *dlg)
Definition gui_stuff.c:1126
GtkWidget * aux_menu_new(void)
Definition gui_stuff.c:243
void gui_dialog_add_content_widget(struct gui_dialog *dlg, GtkWidget *wdg)
Definition gui_stuff.c:1095
GtkWidget * gui_dialog_add_action_widget(struct gui_dialog *dlg, GtkWidget *widget)
Definition gui_stuff.c:680
#define submenu_append_unref(menu, name, submenu)
Definition gui_stuff.h:165
#define menu_item_insert_unref(menu, index, item)
Definition gui_stuff.h:142
#define menu_item_append_unref(menu, item)
Definition gui_stuff.h:149
static GMenu * display_menu
Definition plrdlg.c:95
static GMenu * create_ai_menu(GActionGroup *group)
Definition plrdlg.c:538
static gboolean right_button_press_callback(GtkGestureClick *gesture, int n_press, double x, double y)
Definition plrdlg.c:252
static GMenuItem * create_plrdlg_display_menu_item(int pos)
Definition plrdlg.c:358
static GMenuItem * create_dead_players_menu_item(void)
Definition plrdlg.c:378
static gboolean left_button_press_callback(GtkGestureClick *gesture, int n_press, double x, double y)
Definition plrdlg.c:218
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:168
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:177
struct client_options gui_options
Definition options.c:71
int dsend_packet_diplomacy_cancel_pact(struct connection *pc, int other_player_id, enum clause_type clause)
int dsend_packet_diplomacy_init_meeting_req(struct connection *pc, int counterpart)
bool is_settable_ai_level(enum ai_level level)
Definition player.c:1883
struct player * player_by_number(const int player_id)
Definition player.c:840
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1452
enum diplstate_type cancel_pact_result(enum diplstate_type oldstate)
Definition player.c:67
int player_number(const struct player *pplayer)
Definition player.c:828
const char * player_name(const struct player *pplayer)
Definition player.c:886
enum dipl_reason pplayer_can_cancel_treaty(const struct player *p1, const struct player *p2)
Definition player.c:92
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:317
bool gives_shared_vision(const struct player *me, const struct player *them)
Definition player.c:1461
#define ai_level_cmd(_level_)
Definition player.h:565
#define players_iterate_end
Definition player.h:535
@ DIPL_ERROR
Definition player.h:195
#define players_iterate(_pplayer)
Definition player.h:530
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
int player_dlg_default_sort_column(void)
struct player_dlg_column player_dlg_columns[]
const int num_player_dlg_columns
@ COL_BOOLEAN
@ COL_FLAG
@ COL_RIGHT_TEXT
@ COL_COLOR
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
@ SSHIP_NONE
Definition spaceship.h:84
struct connection conn
Definition client_main.h:96
bool player_dlg_show_dead_players
Definition options.h:212
Definition colors.h:20
GdkRGBA color
Definition colors.h:21
struct player * playing
Definition connection.h:156
Definition climisc.h:82
enum diplstate_type type
Definition player.h:201
bool(* bool_func)(const struct player *)
plr_dlg_sort_func sort_func
const char *(* func)(const struct player *)
const char * title
enum player_dlg_column_type type
enum spaceship_state state
Definition spaceship.h:108
bool is_alive
Definition player.h:268
struct player_spaceship spaceship
Definition player.h:286
struct player_score score
Definition player.h:283
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char * score_tooltip(const struct player *pplayer, int score)
Definition text.c:2157
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6467
#define show(id)
Definition widget.h:235