Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2002:
[Freeciv-Dev] (PR#2418) tileset switching fixes for gtk2
Home

[Freeciv-Dev] (PR#2418) tileset switching fixes for gtk2

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#2418) tileset switching fixes for gtk2
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Tue, 26 Nov 2002 01:48:50 -0800
Reply-to: rt@xxxxxxxxxxxxxx

This patch fixes for gui-gtk-2.0 the city dialogs and unit table
problems when switching tilesets.  It is nearly identical to what's
already been applied/proposed for gui-gtk.

jason

Index: client/gui-gtk-2.0/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.c,v
retrieving revision 1.14
diff -u -r1.14 citydlg.c
--- client/gui-gtk-2.0/citydlg.c        2002/11/15 23:40:05     1.14
+++ client/gui-gtk-2.0/citydlg.c        2002/11/26 09:39:07
@@ -320,17 +320,11 @@
 static void switch_city_callback(GtkWidget * w, gpointer data);
 
 /****************************************************************
-...
+  Called to set the dimensions of the city dialog, both on
+  startup and if the tileset is changed.
 *****************************************************************/
-static void initialize_city_dialogs(void)
+static void init_citydlg_dimensions(void)
 {
-  int i;
-  GdkColor orange = { 0, 65535, 32768, 0 };    /* not currently used */
-  GdkColor red = { 0, 65535, 0, 0 };
-
-  assert(!city_dialogs_have_been_initialised);
-
-  dialog_list_init(&dialog_list);
   if (is_isometric) {
     canvas_width = 4 * NORMAL_TILE_WIDTH;
     canvas_height = 4 * NORMAL_TILE_HEIGHT;
@@ -340,6 +334,21 @@
     canvas_height = 5 * NORMAL_TILE_HEIGHT;
     MAX_UNIT_ROWS = (int) (100 / (UNIT_TILE_HEIGHT + 6));
   }
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void initialize_city_dialogs(void)
+{
+  int i;
+  GdkColor orange = { 0, 65535, 32768, 0 };    /* not currently used */
+  GdkColor red = { 0, 65535, 0, 0 };
+
+  assert(!city_dialogs_have_been_initialised);
+
+  dialog_list_init(&dialog_list);
+  init_citydlg_dimensions();
 
   NUM_UNITS_SHOWN = (int) (MAX_UNIT_ROWS * 500) / (UNIT_TILE_WIDTH);
 
@@ -355,6 +364,27 @@
   info_label_style[RED]->fg[GTK_STATE_NORMAL] = red;
 
   city_dialogs_have_been_initialised = TRUE;
+}
+
+/****************************************************************
+  Called when the tileset changes.
+*****************************************************************/
+void reset_city_dialogs(void)
+{
+  if (!city_dialogs_have_been_initialised) {
+    return;
+  }
+
+  init_citydlg_dimensions();
+
+  dialog_list_iterate(dialog_list, pdialog) {
+    /* There's no reasonable way to resize a GtkPixcomm, so we don't try.
+       Instead we just redraw the overview within the existing area.  The
+       player has to close and reopen the dialog to fix this. */
+    city_dialog_update_map(pdialog);
+  } dialog_list_iterate_end;
+
+  popdown_all_city_dialogs();
 }
 
 /****************************************************************
Index: client/gui-gtk-2.0/citydlg.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.h,v
retrieving revision 1.1
diff -u -r1.1 citydlg.h
--- client/gui-gtk-2.0/citydlg.h        2002/03/11 23:09:41     1.1
+++ client/gui-gtk-2.0/citydlg.h        2002/11/26 09:39:07
@@ -15,4 +15,6 @@
 
 #include "citydlg_g.h"
 
+void reset_city_dialogs(void);
+
 #endif                         /* FC__CITYDLG_H */
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.32
diff -u -r1.32 gui_main.c
--- client/gui-gtk-2.0/gui_main.c       2002/11/14 09:14:55     1.32
+++ client/gui-gtk-2.0/gui_main.c       2002/11/26 09:39:08
@@ -119,6 +119,7 @@
 GtkWidget *unit_info_label;
 GtkWidget *unit_info_frame;
 
+static GtkWidget *unit_pixmap_table;
 static GtkWidget *unit_pixmap;
 static GtkWidget *unit_pixmap_button;
 static GtkWidget *unit_below_pixmap[MAX_NUM_UNITS_BELOW];
@@ -540,6 +541,104 @@
 }
 
 /**************************************************************************
+  Called to build the unit_below pixmap table.  This is the table on the
+  left of the screen that shows all of the inactive units in the current
+  tile.
+
+  It may be called again if the tileset changes.
+**************************************************************************/
+static void populate_unit_pixmap_table(void)
+{
+  int i;
+  GtkWidget *table = unit_pixmap_table;
+ 
+  /* 135 below is rough value (could be more intelligent) --dwp */
+  num_units_below = 135 / (int) NORMAL_TILE_WIDTH;
+  num_units_below = CLIP(1, num_units_below, MAX_NUM_UNITS_BELOW);
+
+  gtk_table_resize(GTK_TABLE(table), 2, num_units_below);
+
+  /* Note, we ref this and other widgets here so that we can unref them
+   * in reset_unit_table. */
+  unit_pixmap = gtk_pixcomm_new(UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
+  gtk_widget_ref(unit_pixmap);
+  gtk_pixcomm_clear(GTK_PIXCOMM(unit_pixmap));
+  unit_pixmap_button = gtk_event_box_new();
+  gtk_widget_ref(unit_pixmap_button);
+  gtk_container_add(GTK_CONTAINER(unit_pixmap_button), unit_pixmap);
+  gtk_table_attach_defaults(GTK_TABLE(table), unit_pixmap_button, 0, 1, 0, 1);
+  gtk_signal_connect(GTK_OBJECT(unit_pixmap_button), "button_press_event",
+                     GTK_SIGNAL_FUNC(select_unit_pixmap_callback), 
+                     GINT_TO_POINTER(-1));
+
+  for (i = 0; i < num_units_below; i++) {
+    unit_below_pixmap[i] = gtk_pixcomm_new(UNIT_TILE_WIDTH,
+                                           UNIT_TILE_HEIGHT);
+    gtk_widget_ref(unit_below_pixmap[i]);
+    unit_below_pixmap_button[i] = gtk_event_box_new();
+    gtk_widget_ref(unit_below_pixmap_button[i]);
+    gtk_container_add(GTK_CONTAINER(unit_below_pixmap_button[i]),
+                      unit_below_pixmap[i]);
+    gtk_signal_connect(GTK_OBJECT(unit_below_pixmap_button[i]),
+                      "button_press_event",
+                       GTK_SIGNAL_FUNC(select_unit_pixmap_callback),
+                       GINT_TO_POINTER(i));
+      
+    gtk_table_attach_defaults(GTK_TABLE(table), unit_below_pixmap_button[i],
+                              i, i + 1, 1, 2);
+    gtk_widget_set_usize(unit_below_pixmap[i],
+                        UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
+    gtk_pixcomm_clear(GTK_PIXCOMM(unit_below_pixmap[i]));
+  }
+
+  more_arrow_pixmap = gtk_pixmap_new(sprites.right_arrow->pixmap, NULL);
+  gtk_widget_ref(more_arrow_pixmap);
+  gtk_pixmap_set_build_insensitive(GTK_PIXMAP(more_arrow_pixmap), FALSE);
+  gtk_table_attach_defaults(GTK_TABLE(table), more_arrow_pixmap, 4, 5, 1, 2);
+
+  gtk_widget_show_all(table);
+}
+
+/**************************************************************************
+  Called when the tileset is changed to reset the unit pixmap table.
+**************************************************************************/
+void reset_unit_table(void)
+{
+  int i;
+
+  /* Unreference all of the widgets that we're about to reallocate, thus
+   * avoiding a memory leak. Remove them from the container first, just
+   * to be safe. Note, the widgets are ref'd in
+   * populatate_unit_pixmap_table. */
+  gtk_container_remove(GTK_CONTAINER(unit_pixmap_table),
+                      unit_pixmap_button);
+  gtk_widget_unref(unit_pixmap);
+  gtk_widget_unref(unit_pixmap_button);
+  for (i = 0; i < num_units_below; i++) {
+    gtk_container_remove(GTK_CONTAINER(unit_pixmap_table),
+                        unit_below_pixmap_button[i]);
+    gtk_widget_unref(unit_below_pixmap[i]);
+    gtk_widget_unref(unit_below_pixmap_button[i]);
+  }
+  gtk_container_remove(GTK_CONTAINER(unit_pixmap_table),
+                      more_arrow_pixmap);
+  gtk_widget_unref(more_arrow_pixmap);
+
+  populate_unit_pixmap_table();
+
+  /* We have to force a redraw of the units.  And we explicitly have
+   * to force a redraw of the focus unit, which is normally only
+   * redrawn when the focus changes. We also have to force the 'more'
+   * arrow to go away, both by expicitly hiding it and telling it to
+   * do so (this will be reset immediately afterwards if necessary,
+   * but we have to make the *internal* state consistent). */
+  gtk_widget_hide(more_arrow_pixmap);
+  set_unit_icons_more_arrow(FALSE);
+  set_unit_icon(-1, get_unit_in_focus());
+  update_unit_pix_label(get_unit_in_focus());
+}
+
+/**************************************************************************
  do the heavy lifting for the widget setup.
 **************************************************************************/
 static void setup_widgets(void)
@@ -699,38 +798,15 @@
   box = gtk_hbox_new(FALSE,0);
   gtk_box_pack_start(GTK_BOX(avbox), box, FALSE, FALSE, 0);
 
-  table = gtk_table_new(2, num_units_below, FALSE);
+  table = gtk_table_new(0, 0, FALSE);
   gtk_box_pack_start(GTK_BOX(box), table, FALSE, FALSE, 5);
 
   gtk_table_set_row_spacings(GTK_TABLE(table), 2);
   gtk_table_set_col_spacings(GTK_TABLE(table), 2);
 
-  unit_pixmap = gtk_pixcomm_new(UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
-  unit_pixmap_button = gtk_event_box_new();
-  gtk_container_add(GTK_CONTAINER(unit_pixmap_button), unit_pixmap);
-  gtk_table_attach_defaults(GTK_TABLE(table), unit_pixmap_button, 0, 1, 0, 1);
-  g_signal_connect(unit_pixmap_button, "button_press_event",
-                   G_CALLBACK(select_unit_pixmap_callback), 
-                   GINT_TO_POINTER(-1));
+  unit_pixmap_table = table;
+  populate_unit_pixmap_table();
 
-  for(i = 0; i < num_units_below; i++) {
-    unit_below_pixmap[i] = gtk_pixcomm_new(UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
-    unit_below_pixmap_button[i] = gtk_event_box_new();
-    gtk_container_add(GTK_CONTAINER(unit_below_pixmap_button[i]),
-                      unit_below_pixmap[i]);
-    g_signal_connect(unit_below_pixmap_button[i],
-                     "button_press_event",
-                      G_CALLBACK(select_unit_pixmap_callback),
-                      GINT_TO_POINTER(i));
-      
-    gtk_table_attach_defaults(GTK_TABLE(table), unit_below_pixmap_button[i],
-                              i, i + 1, 1, 2);
-  }
-
-  more_arrow_pixmap = gtk_image_new_from_pixmap(sprites.right_arrow->pixmap,
-                                               NULL);
-  gtk_table_attach_defaults(GTK_TABLE(table), more_arrow_pixmap, 4, 5, 1, 2);
-
   /* Map canvas and scrollbars */
 
   table = gtk_table_new(2, 2, FALSE);
@@ -977,11 +1053,6 @@
 
   tilespec_load_tiles();
 
-  /* 135 below is rough value (could be more intelligent) --dwp */
-  num_units_below = 135 / (int) NORMAL_TILE_WIDTH;
-  num_units_below = MIN(num_units_below, MAX_NUM_UNITS_BELOW);
-  num_units_below = MAX(num_units_below, 1);
-  
   setup_widgets();
   load_intro_gfx();
   load_cursors();
Index: client/gui-gtk-2.0/gui_main.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.h,v
retrieving revision 1.3
diff -u -r1.3 gui_main.h
--- client/gui-gtk-2.0/gui_main.h       2002/06/27 02:02:46     1.3
+++ client/gui-gtk-2.0/gui_main.h       2002/11/26 09:39:08
@@ -64,4 +64,6 @@
 extern GtkWidget *      map_vertical_scrollbar;
 extern GdkWindow *      root_window;
 
+void reset_unit_table(void);
+
 #endif  /* FC__GUI_MAIN_H */
Index: client/gui-gtk-2.0/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.c,v
retrieving revision 1.24
diff -u -r1.24 mapview.c
--- client/gui-gtk-2.0/mapview.c        2002/11/24 11:43:40     1.24
+++ client/gui-gtk-2.0/mapview.c        2002/11/26 09:39:09
@@ -46,6 +46,7 @@
 #include "options.h"
 #include "tilespec.h"
 
+#include "citydlg.h" /* For reset_city_dialogs() */
 #include "mapview.h"
 
 /* contains the x0, y0 coordinates of the upper left corner block */
@@ -2249,8 +2250,6 @@
 **************************************************************************/
 void tileset_changed(void)
 {
-  /* PORTME */
-  /* Here you should do any necessary redraws (for instance, the city
-   * dialogs usually need to be resized).
-   */
+  reset_city_dialogs();
+  reset_unit_table();
 }

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#2418) tileset switching fixes for gtk2, Jason Short via RT <=