diff -Nur -Xcvs/freeciv/diff_ignore cvs/freeciv/client/gui-gtk/mapctrl.c patched/now/client/gui-gtk/mapctrl.c --- cvs/freeciv/client/gui-gtk/mapctrl.c Fri Jun 14 09:31:29 2002 +++ patched/now/client/gui-gtk/mapctrl.c Thu Jul 11 22:13:11 2002 @@ -60,16 +60,17 @@ } /************************************************************************** -... + Popup a label with information about the tile, unit, city, when the user + used the middle mouse button on the map. **************************************************************************/ static void popit(GdkEventButton *event, int xtile, int ytile) { GtkWidget *p, *b; static struct map_position cross_list[2 + 1]; struct map_position *cross_head = cross_list; - int i, count = 0; - int popx, popy; + int i; char s[512]; + static struct t_popup_pos popup_pos; struct city *pcity; struct unit *punit; struct tile *ptile = map_get_tile(xtile, ytile); @@ -83,26 +84,22 @@ my_snprintf(s, sizeof(s), _("Location: (%d, %d)"), xtile, ytile); gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", s, NULL); - count++; #endif /* DEBUG */ my_snprintf(s, sizeof(s), _("Terrain: %s"), map_get_tile_info_text(xtile, ytile)); gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", s, NULL); - count++; my_snprintf(s, sizeof(s), _("Food/Prod/Trade: %s"), map_get_tile_fpt_text(xtile, ytile)); gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", s, NULL); - count++; if (tile_has_special(ptile, S_HUT)) { gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", _("Minor Tribe Village"), NULL); - count++; } if((pcity = map_get_city(xtile, ytile))) { @@ -110,12 +107,10 @@ get_nation_name(city_owner(pcity)->nation)); gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", s, NULL); - count++; if (city_got_citywalls(pcity)) { gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", _("with City Walls"), NULL); - count++; } } @@ -124,14 +119,12 @@ sz_strlcat(s, map_get_infrastructure_text(ptile->special)); gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", s, NULL); - count++; } sz_strlcpy(s, _("Activity: ")); if (concat_tile_activity_text(s, sizeof(s), xtile, ytile)) { gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", s, NULL); - count++; } if((punit = find_visible_unit(ptile)) && !pcity) { @@ -148,7 +141,6 @@ get_nation_name(unit_owner(punit)->nation), cn); gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", s, NULL); - count++; if(punit->owner == game.player_idx) { char uc[64] = ""; @@ -174,7 +166,6 @@ } gtk_widget_new(GTK_TYPE_LABEL, "GtkWidget::parent", b, "GtkLabel::label", s, NULL); - count++; } cross_head->x = xtile; @@ -191,12 +182,14 @@ GTK_SIGNAL_FUNC(popupinfo_popdown_callback), cross_list); - /* displace popup so as not to obscure it by the mouse cursor */ - popx = event->x_root + 16; - popy = event->y_root - (8 * count); - if (popy < 0) - popy = 0; - gtk_widget_popup(p, popx, popy); + popup_pos.xroot = event->x_root; + popup_pos.yroot = event->y_root; + + gtk_signal_connect(GTK_OBJECT(p), "size-allocate", + GTK_SIGNAL_FUNC(popupinfo_positioning_callback), + &popup_pos); + + gtk_widget_show(p); gdk_pointer_grab(p->window, TRUE, GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time); gtk_grab_add(p); @@ -216,6 +209,28 @@ while (cross_list->x >= 0) { refresh_tile_mapcanvas(cross_list->x, cross_list->y, TRUE); cross_list++; + } +} + +/************************************************************************** + Put the popup on the correct position, after the real size is allocated + to the widget. The correct position is left beneath the cursor if within + the right half of the map, and vice versa. Also, displace the popup so + as not to obscure it by the mouse cursor. +**************************************************************************/ +void popupinfo_positioning_callback(GtkWidget *w, GtkAllocation *alloc, + gpointer data) +{ + struct t_popup_pos *popup_pos = (struct t_popup_pos *)data; + gint x, y; + + gdk_window_get_origin(map_canvas->window, &x, &y); + if ((map_canvas->allocation.width / 2 + x) > popup_pos->xroot) { + gtk_widget_set_uposition(w, popup_pos->xroot + 16, + popup_pos->yroot - (alloc->height / 2)); + } else { + gtk_widget_set_uposition(w, popup_pos->xroot - alloc->width - 16, + popup_pos->yroot - (alloc->height / 2)); } } diff -Nur -Xcvs/freeciv/diff_ignore cvs/freeciv/client/gui-gtk/mapctrl.h patched/now/client/gui-gtk/mapctrl.h --- cvs/freeciv/client/gui-gtk/mapctrl.h Thu Feb 7 19:21:10 2002 +++ patched/now/client/gui-gtk/mapctrl.h Thu Jul 11 22:15:04 2002 @@ -18,6 +18,7 @@ #include "mapctrl_g.h" struct unit; +struct t_popup_pos {int xroot, yroot;}; void key_city_workers(GtkWidget *w, GdkEventKey *ev); void adjust_workers(GtkWidget *widget, GdkEventButton *ev); @@ -31,6 +32,8 @@ void center_on_unit(void); void focus_to_next_unit(void); void popupinfo_popdown_callback(GtkWidget *w, gpointer data); +void popupinfo_positioning_callback(GtkWidget *w, GtkAllocation *alloc, + gpointer user_data); /* Color to use to display the workers */ extern int city_workers_color;