[Freeciv-Dev] (PR#15688) gtk2 client needs pregame observer support
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=15688 >
This patch implements the next step of pregame observer control.
Right-clicking on a connection or menu brings up a useful little menu.
-jason
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
--- client/gui-gtk-2.0/gui_main.c (revision 11680)
+++ client/gui-gtk-2.0/gui_main.c (working copy)
@@ -220,7 +220,6 @@
static gboolean select_unit_pixmap_callback(GtkWidget *w, GdkEvent *ev,
gpointer data);
static gint timer_callback(gpointer data);
-gboolean show_conn_popup(GtkWidget *view, GdkEventButton *ev, gpointer data);
static gboolean quit_dialog_callback(void);
@@ -1401,6 +1400,7 @@
gtk_tree_store_clear(conn_model);
players_iterate(pplayer) {
enum cmdlevel_id access_level = ALLOW_NONE;
+ int conn_id = -1;
conn_list_iterate(pplayer->connections, pconn) {
access_level = MAX(pconn->access_level, access_level);
@@ -1461,6 +1461,13 @@
}
}
+ conn_list_iterate(game.est_connections, pconn) {
+ if (pconn->player == pplayer && !pconn->observer) {
+ assert(conn_id == -1);
+ conn_id = pconn->id;
+ }
+ } conn_list_iterate_end;
+
gtk_tree_store_append(conn_model, &it[pplayer->player_no], NULL);
gtk_tree_store_set(conn_model, &it[pplayer->player_no],
0, pplayer->player_no,
@@ -1471,6 +1478,7 @@
5, team,
6, record_text,
7, rating_text,
+ 8, conn_id,
-1);
} players_iterate_end;
conn_list_iterate(game.est_connections, pconn) {
@@ -1494,74 +1502,13 @@
3, leader,
4, nation,
5, team,
+ 8, pconn->id,
-1);
} conn_list_iterate_end;
}
}
/**************************************************************************
- Show details about a user in the Connected Users dialog in a popup.
-**************************************************************************/
-gboolean show_conn_popup(GtkWidget *view, GdkEventButton *ev, gpointer data)
-{
- GtkTreePath *path;
- GtkTreeIter it;
- GtkWidget *popup, *table, *label;
- gchar *name;
- struct connection *pconn;
-
- /* Get the current selection in the Connected Users list */
- if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(view),
- ev->x, ev->y, &path, NULL, NULL, NULL)) {
- return FALSE;
- }
-
- gtk_tree_model_get_iter(GTK_TREE_MODEL(conn_model), &it, path);
- gtk_tree_path_free(path);
-
- gtk_tree_model_get(GTK_TREE_MODEL(conn_model), &it, 1, &name, -1);
- pconn = find_conn_by_user(name);
-
- if (!pconn) {
- return FALSE;
- }
-
- /* Show popup. */
- popup = gtk_window_new(GTK_WINDOW_POPUP);
- gtk_widget_set_app_paintable(popup, TRUE);
- gtk_container_set_border_width(GTK_CONTAINER(popup), 4);
- gtk_window_set_position(GTK_WINDOW(popup), GTK_WIN_POS_MOUSE);
-
- table = gtk_table_new(2, 2, FALSE);
- gtk_table_set_col_spacings(GTK_TABLE(table), 6);
- gtk_container_add(GTK_CONTAINER(popup), table);
-
- label = gtk_label_new(_("Name:"));
- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
- label = gtk_label_new(pconn->username);
- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
- gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 0, 1);
-
- label = gtk_label_new(_("Host:"));
- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
- gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
- label = gtk_label_new(pconn->addr);
- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
- gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2);
-
- gtk_widget_show_all(table);
- gtk_widget_show(popup);
-
- gdk_pointer_grab(popup->window, TRUE, GDK_BUTTON_RELEASE_MASK,
- NULL, NULL, ev->time);
- gtk_grab_add(popup);
- g_signal_connect_after(popup, "button_release_event",
- G_CALLBACK(show_info_button_release), NULL);
- return FALSE;
-}
-
-/**************************************************************************
obvious...
**************************************************************************/
void sound_bell(void)
Index: client/gui-gtk-2.0/gui_main.h
===================================================================
--- client/gui-gtk-2.0/gui_main.h (revision 11680)
+++ client/gui-gtk-2.0/gui_main.h (working copy)
@@ -76,7 +76,6 @@
void enable_menus(bool enable);
gboolean inputline_handler(GtkWidget *w, GdkEventKey *ev);
-gboolean show_conn_popup(GtkWidget *view, GdkEventButton *ev, gpointer data);
void reset_unit_table(void);
void popup_quit_dialog(void);
Index: client/gui-gtk-2.0/pages.c
===================================================================
--- client/gui-gtk-2.0/pages.c (revision 11680)
+++ client/gui-gtk-2.0/pages.c (working copy)
@@ -1009,61 +1009,181 @@
send_new_aifill_to_server = old;
}
-static struct player *team_menu_player;
+static struct player *conn_menu_player;
+static struct connection *conn_menu_conn;
/****************************************************************************
- Callback for when a team is chosen from the team menu.
+ Callback for when a team is chosen from the conn menu.
****************************************************************************/
-static void team_menu_entry_chosen(GtkMenuItem *menuitem, gpointer data)
+static void conn_menu_team_chosen(GtkMenuItem *menuitem, gpointer data)
{
struct team *pteam = data;
char buf[1024];
- if (pteam != team_menu_player->team) {
+ if (pteam != conn_menu_player->team) {
my_snprintf(buf, sizeof(buf), "/team \"%s\" \"%s\"",
- team_menu_player->name, team_get_name_orig(pteam));
+ conn_menu_player->name, team_get_name_orig(pteam));
send_chat(buf);
}
}
/****************************************************************************
- Called when you click on a player's team; this function pops up a menu
+ Callback for when the "ready" entry is chosen from the conn menu.
+****************************************************************************/
+static void conn_menu_ready_chosen(GtkMenuItem *menuitem, gpointer data)
+{
+ struct player *pplayer = conn_menu_player;
+
+ dsend_packet_player_ready(&aconnection,
+ pplayer->player_no, !pplayer->is_ready);
+}
+
+/****************************************************************************
+ Callback for when the pick-nation entry is chosen from the conn menu.
+****************************************************************************/
+static void conn_menu_nation_chosen(GtkMenuItem *menuitem, gpointer data)
+{
+ popup_races_dialog(conn_menu_player);
+}
+
+/****************************************************************************
+ Callback for when the "observe" entry is chosen from the conn menu.
+****************************************************************************/
+static void conn_menu_observe_chosen(GtkMenuItem *menuitem, gpointer data)
+{
+ char buf[1024];
+
+ my_snprintf(buf, sizeof(buf), "/observe \"%s\"",
+ conn_menu_player->name);
+ send_chat(buf);
+}
+
+/**************************************************************************
+ Show details about a user in the Connected Users dialog in a popup.
+**************************************************************************/
+static void show_conn_popup(struct player *pplayer, struct connection *pconn)
+{
+ GtkWidget *popup;
+ char buf[1024] = "";
+
+ cat_snprintf(buf, sizeof(buf), _("Player name: %s"),
+ pconn ? pconn->username : pplayer->name);
+ cat_snprintf(buf, sizeof(buf), "\n");
+ if (pconn) {
+ cat_snprintf(buf, sizeof(buf), _("Host: %s"), pconn->addr);
+ }
+ cat_snprintf(buf, sizeof(buf), "\n");
+
+ /* Show popup. */
+ popup = gtk_message_dialog_new(NULL, 0,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, buf);
+ gtk_window_set_title(GTK_WINDOW(popup), _("Player/conn info"));
+ setup_dialog(popup, toplevel);
+ g_signal_connect(popup, "response", G_CALLBACK(gtk_widget_destroy), NULL);
+ gtk_window_present(GTK_WINDOW(popup));
+}
+
+/****************************************************************************
+ Callback for when the "info" entry is chosen from the conn menu.
+****************************************************************************/
+static void conn_menu_info_chosen(GtkMenuItem *menuitem, gpointer data)
+{
+ show_conn_popup(conn_menu_player, conn_menu_conn);
+}
+
+/****************************************************************************
+ Called when you click on a player; this function pops up a menu
to allow changing the team.
****************************************************************************/
-static GtkWidget *create_team_menu(struct player *pplayer)
+static GtkWidget *create_conn_menu(struct player *pplayer,
+ struct connection *pconn)
{
GtkWidget *menu;
GtkWidget *entry;
- const int count = pplayer->team ? pplayer->team->players : 0;
- bool need_empty_team = (count != 1);
- int index;
+ char buf[128];
menu = gtk_menu_new();
- /* Can't use team_iterate here since it skips empty teams. */
- for (index = 0; index < MAX_NUM_TEAMS; index++) {
- struct team *pteam = team_get_by_id(index);
+ my_snprintf(buf, sizeof(buf), _("%s info"),
+ pconn ? pconn->username : pplayer->name);
+ entry = gtk_menu_item_new_with_label(buf);
+ g_object_set_data_full(G_OBJECT(menu),
+ "info", entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_container_add(GTK_CONTAINER(menu), entry);
+ g_signal_connect(GTK_OBJECT(entry), "activate",
+ GTK_SIGNAL_FUNC(conn_menu_info_chosen), NULL);
- if (pteam->players == 0) {
- if (!need_empty_team) {
- continue;
- }
- need_empty_team = FALSE;
- }
+ entry = gtk_menu_item_new_with_label(_("Toggle player ready"));
+ gtk_widget_set_sensitive(entry, pplayer && !pplayer->ai.control);
+ g_object_set_data_full(G_OBJECT(menu),
+ "ready", entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_container_add(GTK_CONTAINER(menu), entry);
+ g_signal_connect(GTK_OBJECT(entry), "activate",
+ GTK_SIGNAL_FUNC(conn_menu_ready_chosen), NULL);
- entry = gtk_menu_item_new_with_label(team_get_name(pteam));
+ entry = gtk_menu_item_new_with_label(_("Pick nation"));
+ gtk_widget_set_sensitive(entry,
+ pplayer
+ && can_conn_edit_players_nation(&aconnection,
+ pplayer));
+ g_object_set_data_full(G_OBJECT(menu),
+ "nation", entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_container_add(GTK_CONTAINER(menu), entry);
+ g_signal_connect(GTK_OBJECT(entry), "activate",
+ GTK_SIGNAL_FUNC(conn_menu_nation_chosen), NULL);
+
+ entry = gtk_menu_item_new_with_label(_("Observe this player"));
+ g_object_set_data_full(G_OBJECT(menu),
+ "observe", entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_container_add(GTK_CONTAINER(menu), entry);
+ g_signal_connect(GTK_OBJECT(entry), "activate",
+ GTK_SIGNAL_FUNC(conn_menu_observe_chosen), NULL);
+
+ if (pplayer && game.info.is_new_game) {
+ const int count = pplayer->team ? pplayer->team->players : 0;
+ bool need_empty_team = (count != 1);
+ int index;
+
+ entry = gtk_separator_menu_item_new();
g_object_set_data_full(G_OBJECT(menu),
- team_get_name_orig(pteam), entry,
+ "sep1", entry,
(GtkDestroyNotify) gtk_widget_unref);
- gtk_widget_show(entry);
gtk_container_add(GTK_CONTAINER(menu), entry);
- g_signal_connect(GTK_OBJECT(entry), "activate",
- GTK_SIGNAL_FUNC(team_menu_entry_chosen),
- pteam);
+
+ /* Can't use team_iterate here since it skips empty teams. */
+ for (index = 0; index < MAX_NUM_TEAMS; index++) {
+ struct team *pteam = team_get_by_id(index);
+ char text[128];
+
+ if (pteam->players == 0) {
+ if (!need_empty_team) {
+ continue;
+ }
+ need_empty_team = FALSE;
+ }
+
+ /* TRANS: e.g., "Put on Team 5" */
+ my_snprintf(text, sizeof(text), _("Put on %s"), team_get_name(pteam));
+ entry = gtk_menu_item_new_with_label(text);
+ g_object_set_data_full(G_OBJECT(menu),
+ team_get_name_orig(pteam), entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_container_add(GTK_CONTAINER(menu), entry);
+ g_signal_connect(GTK_OBJECT(entry), "activate",
+ GTK_SIGNAL_FUNC(conn_menu_team_chosen),
+ pteam);
+ }
}
- team_menu_player = pplayer;
+ conn_menu_player = pplayer;
+ conn_menu_conn = pconn;
+ gtk_widget_show_all(menu);
+
return menu;
}
@@ -1078,10 +1198,12 @@
GtkTreeIter iter;
GtkTreePath *path = NULL;
GtkTreeViewColumn *column = NULL;
- int player_no;
+ int player_no, conn_id;
struct player *pplayer;
+ struct connection *pconn;
if (event->type != GDK_BUTTON_PRESS
+ || event->button != 3
|| !gtk_tree_view_get_path_at_pos(tree,
event->x, event->y,
&path, &column, NULL, NULL)) {
@@ -1092,36 +1214,16 @@
gtk_tree_path_free(path);
gtk_tree_model_get(model, &iter, 0, &player_no, -1);
pplayer = get_player(player_no);
+ gtk_tree_model_get(model, &iter, 8, &conn_id, -1);
+ pconn = find_conn_by_id(conn_id);
- if (column == nation_col) {
- if (!pplayer || !can_conn_edit_players_nation(&aconnection, pplayer)) {
- return FALSE;
- }
-
- popup_races_dialog(pplayer);
- return TRUE;
- } else if (column == ready_col) {
- gboolean is_ready;
-
- if (!pplayer) {
- return FALSE;
- }
-
- gtk_tree_model_get(model, &iter, 2, &is_ready, -1);
- dsend_packet_player_ready(&aconnection, pplayer->player_no, !is_ready);
- return TRUE;
- } else if (column == team_col) {
- if (pplayer && game.info.is_new_game) {
- GtkWidget *menu = create_team_menu(pplayer);
-
- gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
- event->button, 0);
- return TRUE;
- }
- return FALSE;
- } else {
- return show_conn_popup(widget, event, data);
- }
+ gtk_menu_popup(GTK_MENU(create_conn_menu(pplayer, pconn)),
+ NULL, NULL, NULL, NULL,
+ event->button, 0);
+ return TRUE;
+#if 0
+ return show_conn_popup(widget, event, data);
+#endif
}
/**************************************************************************
@@ -1223,11 +1325,12 @@
gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, FALSE, 8);
- conn_model = gtk_tree_store_new(8, G_TYPE_INT,
+ conn_model = gtk_tree_store_new(9, G_TYPE_INT,
G_TYPE_STRING, G_TYPE_BOOLEAN,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_STRING);
+ G_TYPE_STRING,
+ G_TYPE_INT);
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(conn_model));
g_object_unref(conn_model);
- [Freeciv-Dev] (PR#15688) gtk2 client needs pregame observer support,
Jason Short <=
|
|