Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2004:
[Freeciv-Dev] (PR#8427) better client interface for transported units
Home

[Freeciv-Dev] (PR#8427) better client interface for transported units

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#8427) better client interface for transported units
From: "Vasco Alexandre da Silva Costa" <vasc@xxxxxxxxxxxxxx>
Date: Wed, 31 Mar 2004 06:58:40 -0800
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=8427 >

This patch shows the units in a tile in tree form so it is more obvious
if they are being transported or not. The patch to add transport
functions will be made next.

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.77
diff -u -r1.77 citydlg.c
--- client/gui-gtk-2.0/citydlg.c        8 Mar 2004 07:20:49 -0000       1.77
+++ client/gui-gtk-2.0/citydlg.c        31 Mar 2004 14:39:00 -0000
@@ -1359,7 +1359,8 @@
 *****************************************************************/
 static void city_dialog_update_map(struct city_dialog *pdialog)
 {
-  struct canvas store = {pdialog->map_canvas_store};
+  struct canvas store = {.type = CANVAS_PIXMAP,
+                        .v.pixmap = pdialog->map_canvas_store};
 
   city_dialog_redraw_map(pdialog->pcity, &store);
 
Index: client/gui-gtk-2.0/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/dialogs.c,v
retrieving revision 1.59
diff -u -r1.59 dialogs.c
--- client/gui-gtk-2.0/dialogs.c        8 Feb 2004 21:56:51 -0000       1.59
+++ client/gui-gtk-2.0/dialogs.c        31 Mar 2004 14:39:03 -0000
@@ -78,21 +78,14 @@
 static int         sabotage_improvement;
 
 /******************************************************************/
-#define NUM_SELECT_UNIT_COLS 6
 #define SELECT_UNIT_READY  1
 #define SELECT_UNIT_SENTRY 2
 
-struct unit_select_node {
-  GtkWidget *cmd;
-  GtkWidget *pix;
-};
-
 static GtkWidget *unit_select_dialog_shell;
-static GtkWidget *unit_select_table;
-static struct unit_select_node *unit_select_nodes;
-static int unit_select_no;
+static GtkTreeStore *unit_select_store;
+static GtkWidget *unit_select_view;
+static GtkTreePath *unit_select_path;
 static struct tile *unit_select_ptile;
-static GtkTooltips *unit_select_tips;
 
 static void select_random_race(void);
   
@@ -1437,11 +1430,16 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static void unit_select_callback(GtkWidget *w, int id)
+static void unit_select_row_activated(GtkTreeView *view, GtkTreePath *path)
 {
-  struct unit *punit = player_find_unit_by_id(game.player_ptr, id);
+  GtkTreeIter it;
+  struct unit *punit;
+  gint id;
 
-  if (punit) {
+  gtk_tree_model_get_iter(GTK_TREE_MODEL(unit_select_store), &it, path);
+  gtk_tree_model_get(GTK_TREE_MODEL(unit_select_store), &it, 0, &id, -1);
+ 
+  if ((punit = player_find_unit_by_id(game.player_ptr, id))) {
     set_unit_focus(punit);
   }
 
@@ -1451,80 +1449,70 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static int number_of_rows(int n)
-{
-  return (n-1)/NUM_SELECT_UNIT_COLS+1;
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-static void refresh_unit_select_dialog(void)
+static void unit_select_append(struct unit *punit, GtkTreeIter *it,
+                              GtkTreeIter *parent)
 {
-  if (unit_select_dialog_shell) {
-    struct tile *ptile;
-    int i, n, r;
-
-    ptile = unit_select_ptile;
+  GdkPixbuf *pix;
+  struct unit_type *ptype = unit_type(punit);
 
-    n = unit_list_size(&ptile->units);
-    r = number_of_rows(n);
+  pix = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
+      UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
 
-    for (i=n; i<unit_select_no; i++) {
-      gtk_widget_destroy(unit_select_nodes[i].cmd);
-    }
-
-    gtk_table_resize(GTK_TABLE(unit_select_table), r, NUM_SELECT_UNIT_COLS);
+  {
+    struct canvas canvas_store = {.type = CANVAS_PIXBUF, .v.pixbuf = pix};
 
-    unit_select_nodes =
-      fc_realloc(unit_select_nodes, n * sizeof(*unit_select_nodes));
+    gdk_pixbuf_fill(pix, 0x00000000);
+    put_unit_full(punit, &canvas_store, 0, 0);
+  }
 
-    for (i=unit_select_no; i<n; i++) {
-      GtkWidget *cmd, *pix;
+  gtk_tree_store_append(unit_select_store, it, parent);
+  gtk_tree_store_set(unit_select_store, it,
+      0, punit->id,
+      1, pix,
+      2, _(ptype->name),
+      -1);
+  g_object_unref(pix);
 
-      cmd = gtk_button_new();
-      unit_select_nodes[i].cmd = cmd;
+  if (punit == get_unit_in_focus()) {
+    unit_select_path =
+      gtk_tree_model_get_path(GTK_TREE_MODEL(unit_select_store), it);
+  }
+}
 
-      pix = gtk_pixcomm_new(UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
-      unit_select_nodes[i].pix = pix;
+/**************************************************************************
+...
+**************************************************************************/
+static void unit_select_recurse(int root_id, GtkTreeIter *it_root)
+{
+  unit_list_iterate(unit_select_ptile->units, pleaf) {
+    GtkTreeIter it_leaf;
 
-      gtk_container_add(GTK_CONTAINER(cmd), pix);
-      gtk_table_attach_defaults(GTK_TABLE(unit_select_table),
-                                cmd,
-                               (i % NUM_SELECT_UNIT_COLS), 
-                               (i % NUM_SELECT_UNIT_COLS) + 1,
-                               (i / NUM_SELECT_UNIT_COLS),
-                               (i / NUM_SELECT_UNIT_COLS) + 1);
+    if (pleaf->transported_by == root_id) {
+      unit_select_append(pleaf, &it_leaf, it_root);
+      if (pleaf->occupy > 0) {
+       unit_select_recurse(pleaf->id, &it_leaf);
+      }
     }
+  } unit_list_iterate_end;
+}
 
-    gtk_tooltips_disable(unit_select_tips);
-
-    for (i=0; i<n; i++) {
-      GtkWidget *cmd, *pix;
-      struct unit *punit = unit_list_get(&ptile->units, i);
-
-      cmd = unit_select_nodes[i].cmd;
-      pix = unit_select_nodes[i].pix;
-
-      put_unit_gpixmap(punit, GTK_PIXCOMM(pix));
-
-      g_signal_handlers_disconnect_matched(cmd,
-        G_SIGNAL_MATCH_FUNC,
-        0, 0, NULL, unit_select_callback, NULL);
-
-      g_signal_connect(cmd, "clicked",
-        G_CALLBACK(unit_select_callback), GINT_TO_POINTER(punit->id));
+/**************************************************************************
+...
+**************************************************************************/
+static void refresh_unit_select_dialog(void)
+{
+  if (unit_select_dialog_shell) {
+    gtk_tree_store_clear(unit_select_store);
 
-      gtk_tooltips_set_tip(unit_select_tips,
-        cmd, unit_description(punit), "");
+    unit_select_recurse(-1, NULL);
+    gtk_tree_view_expand_all(GTK_TREE_VIEW(unit_select_view));
 
-      gtk_widget_show(pix);
-      gtk_widget_show(cmd);
+    if (unit_select_path) {
+      gtk_tree_view_set_cursor(GTK_TREE_VIEW(unit_select_view),
+         unit_select_path, NULL, FALSE);
+      gtk_tree_path_free(unit_select_path);
+      unit_select_path = NULL;
     }
-
-    gtk_tooltips_enable(unit_select_tips);
-
-    unit_select_no = n;
   }
 }
 
@@ -1533,18 +1521,6 @@
 *****************************************************************/
 static void unit_select_destroy_callback(GtkObject *object, gpointer data)
 {
-  if (unit_select_tips) {
-    g_object_unref(unit_select_tips);
-  }
-  unit_select_tips = NULL;
-
-  if (unit_select_nodes) {
-    free(unit_select_nodes);
-  }
-  unit_select_nodes = NULL;
-
-  unit_select_no = 0;
-
   unit_select_dialog_shell = NULL;
 }
 
@@ -1599,12 +1575,29 @@
 /****************************************************************
 ...
 *****************************************************************/
+#define NUM_UNIT_SELECT_COLUMNS 2
+
 void popup_unit_select_dialog(struct tile *ptile)
 {
   if (!unit_select_dialog_shell) {
-    GtkWidget *shell, *align, *table;
+    GtkTreeStore *store;
+    GtkWidget *shell, *view, *sw, *hbox;
     GtkWidget *ready_cmd, *sentry_cmd, *close_cmd;
 
+    static char *titles[NUM_UNIT_SELECT_COLUMNS] = {
+      N_("Unit"),
+      N_("Name")
+    };
+    static bool titles_done;
+
+    GType types[NUM_UNIT_SELECT_COLUMNS+1] = {
+      G_TYPE_INT,
+      GDK_TYPE_PIXBUF,
+      G_TYPE_STRING
+    };
+    int i;
+
+
     shell = gtk_dialog_new_with_buttons(_("Unit selection"),
       NULL,
       0,
@@ -1617,27 +1610,60 @@
     gtk_window_set_type_hint(GTK_WINDOW(shell),
                             GDK_WINDOW_TYPE_HINT_NORMAL);
 
-    unit_select_tips = gtk_tooltips_new();
-    g_object_ref(unit_select_tips);
-    gtk_object_sink(GTK_OBJECT(unit_select_tips));
-
     g_signal_connect(shell, "destroy",
       G_CALLBACK(unit_select_destroy_callback), NULL);
     gtk_window_set_position(GTK_WINDOW(shell), GTK_WIN_POS_MOUSE);
     g_signal_connect(shell, "response",
       G_CALLBACK(unit_select_cmd_callback), NULL);
 
-    align = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
-    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(shell)->vbox), align);
+    hbox = gtk_hbox_new(FALSE, 0);
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(shell)->vbox), hbox);
+
+    intl_slist(ARRAY_SIZE(titles), titles, &titles_done);
+
+    store = gtk_tree_store_newv(ARRAY_SIZE(types), types);
+    unit_select_store = store;
+
+    view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+    unit_select_view = view;
+    g_object_unref(store);
+ 
+    for (i = 1; i < ARRAY_SIZE(types); i++) {
+      GtkTreeViewColumn *column;
+      GtkCellRenderer *render;
+
+      column = gtk_tree_view_column_new();
+      gtk_tree_view_column_set_title(column, titles[i-1]);
+
+      switch (types[i]) {
+       case G_TYPE_STRING:
+         render = gtk_cell_renderer_text_new();
+         gtk_tree_view_column_pack_start(column, render, TRUE);
+         gtk_tree_view_column_set_attributes(column, render, "text", i, NULL);
+         break;
+       default:
+         render = gtk_cell_renderer_pixbuf_new();
+         gtk_tree_view_column_pack_start(column, render, FALSE);
+         gtk_tree_view_column_set_attributes(column, render,
+             "pixbuf", i, NULL);
+         break;
+      }
+      gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
+    }
+
+    g_signal_connect(view, "row_activated",
+       G_CALLBACK(unit_select_row_activated), NULL);
+
 
-    table = gtk_table_new(NUM_SELECT_UNIT_COLS, 0, FALSE);
-    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
-    gtk_table_set_col_spacings(GTK_TABLE(table), 2);
-    gtk_container_add(GTK_CONTAINER(align), table);
-    unit_select_table = table;
+    sw = gtk_scrolled_window_new(NULL, NULL);
+    gtk_widget_set_size_request(sw, -1, 300);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
+       GTK_SHADOW_ETCHED_IN);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+       GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+    gtk_container_add(GTK_CONTAINER(sw), view);
+    gtk_box_pack_start(GTK_BOX(hbox), sw, TRUE, TRUE, 0);
 
-    gtk_widget_show(align);
-    gtk_widget_show(table);
 
     ready_cmd =
     gtk_dialog_add_button(GTK_DIALOG(shell),
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.12
diff -u -r1.12 gui_main.h
--- client/gui-gtk-2.0/gui_main.h       8 Mar 2004 07:20:49 -0000       1.12
+++ client/gui-gtk-2.0/gui_main.h       31 Mar 2004 14:39:03 -0000
@@ -18,10 +18,21 @@
 #include "gtkpixcomm.h"
 #include "gui_main_g.h"
 
+enum canvas_type {
+  CANVAS_PIXMAP,
+  CANVAS_PIXCOMM,
+  CANVAS_PIXBUF
+};
+
 struct canvas
 {
-  GdkPixmap *pixmap;   /* if NULL, the pixcomm is drawn to instead. */
-  GtkPixcomm *pixcomm;
+  enum canvas_type type;
+
+  union {
+    GdkPixmap *pixmap;
+    GtkPixcomm *pixcomm;
+    GdkPixbuf *pixbuf;
+  } v;
 };
 
 /* network string charset conversion */
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.110
diff -u -r1.110 mapview.c
--- client/gui-gtk-2.0/mapview.c        30 Mar 2004 02:01:27 -0000      1.110
+++ client/gui-gtk-2.0/mapview.c        31 Mar 2004 14:39:03 -0000
@@ -51,7 +51,7 @@
 #include "citydlg.h" /* For reset_city_dialogs() */
 #include "mapview.h"
 
-#define map_canvas_store (mapview_canvas.store->pixmap)
+#define map_canvas_store (mapview_canvas.store->v.pixmap)
 
 static void pixmap_put_overlay_tile(GdkDrawable *pixmap,
                                    int canvas_x, int canvas_y,
@@ -330,8 +330,8 @@
 {
   struct canvas *result = fc_malloc(sizeof(*result));
 
-  result->pixmap = gdk_pixmap_new(root_window, width, height, -1);
-  result->pixcomm = NULL;
+  result->type = CANVAS_PIXMAP;
+  result->v.pixmap = gdk_pixmap_new(root_window, width, height, -1);
   return result;
 }
 
@@ -340,8 +340,8 @@
 **************************************************************************/
 void canvas_free(struct canvas *store)
 {
-  g_object_unref(store->pixmap);
-  assert(store->pixcomm == NULL);
+  assert(store->type == CANVAS_PIXMAP);
+  g_object_unref(store->v.pixmap);
   free(store);
 }
 
@@ -352,8 +352,8 @@
 {
   static struct canvas store;
 
-  store.pixmap = overview_canvas->window;
-
+  store.type = CANVAS_PIXMAP;
+  store.v.pixmap = overview_canvas->window;
   return &store;
 }
 
@@ -482,7 +482,7 @@
                      int width, int height, int height_unit,
                      enum draw_type draw, bool citymode)
 {
-  pixmap_put_tile_iso(pcanvas->pixmap,
+  pixmap_put_tile_iso(pcanvas->v.pixmap,
                      map_x, map_y, canvas_x, canvas_y,
                      citymode,
                      offset_x, offset_y, offset_y_unit,
@@ -656,7 +656,7 @@
 **************************************************************************/
 void put_unit_gpixmap(struct unit *punit, GtkPixcomm *p)
 {
-  struct canvas canvas_store = {NULL, p};
+  struct canvas canvas_store = {.type = CANVAS_PIXCOMM, .v.pixcomm = p};
 
   gtk_pixcomm_freeze(p);
   gtk_pixcomm_clear(p);
@@ -675,7 +675,7 @@
 **************************************************************************/
 void put_unit_gpixmap_city_overlays(struct unit *punit, GtkPixcomm *p)
 {
-  struct canvas store = {NULL, p};
+  struct canvas store = {.type = CANVAS_PIXCOMM, .v.pixcomm = p};
  
   gtk_pixcomm_freeze(p);
 
@@ -735,13 +735,23 @@
                       struct Sprite *sprite,
                       int offset_x, int offset_y, int width, int height)
 {
-  if (pcanvas->pixmap) {
-    pixmap_put_sprite(pcanvas->pixmap, canvas_x, canvas_y,
-                     sprite, offset_x, offset_y, width, height);
-  } else {
-    gtk_pixcomm_copyto(pcanvas->pixcomm, sprite, canvas_x, canvas_y);
-  }
-} 
+  switch (pcanvas->type) {
+    case CANVAS_PIXMAP:
+      pixmap_put_sprite(pcanvas->v.pixmap, canvas_x, canvas_y,
+         sprite, offset_x, offset_y, width, height);
+      break;
+    case CANVAS_PIXCOMM:
+      gtk_pixcomm_copyto(pcanvas->v.pixcomm, sprite, canvas_x, canvas_y);
+      break;
+    case CANVAS_PIXBUF:
+      gdk_pixbuf_composite(sprite_get_pixbuf(sprite), pcanvas->v.pixbuf,
+         offset_x, offset_y, width, height, canvas_x, canvas_y, 1.0, 1.0,
+         GDK_INTERP_NEAREST, 255);
+      break;
+    default:
+      break;
+  } 
+}
 
 /**************************************************************************
   Draw a full sprite onto the mapview or citydialog canvas.
@@ -762,12 +772,23 @@
                          enum color_std color,
                          int canvas_x, int canvas_y, int width, int height)
 {
-  if (pcanvas->pixmap) {
-    gdk_gc_set_foreground(fill_bg_gc, colors_standard[color]);
-    gdk_draw_rectangle(pcanvas->pixmap, fill_bg_gc, TRUE,
-                      canvas_x, canvas_y, width, height);
-  } else {
-    gtk_pixcomm_fill(pcanvas->pixcomm, colors_standard[color]);
+  GdkColor *col = colors_standard[color];
+
+  switch (pcanvas->type) {
+    case CANVAS_PIXMAP:
+      gdk_gc_set_foreground(fill_bg_gc, col);
+      gdk_draw_rectangle(pcanvas->v.pixmap, fill_bg_gc, TRUE,
+         canvas_x, canvas_y, width, height);
+      break;
+    case CANVAS_PIXCOMM:
+      gtk_pixcomm_fill(pcanvas->v.pixcomm, col);
+      break;
+    case CANVAS_PIXBUF:
+      gdk_pixbuf_fill(pcanvas->v.pixbuf,
+         col->red >> 24 | col->green >> 16 | col->blue >> 8 | 0xFF);
+      break;
+    default:
+      break;
   }
 }
 
@@ -796,7 +817,7 @@
   }
 
   gdk_gc_set_foreground(gc, colors_standard[color]);
-  gdk_draw_line(pcanvas->pixmap, gc,
+  gdk_draw_line(pcanvas->v.pixmap, gc,
                start_x, start_y, start_x + dx, start_y + dy);
 }
 
@@ -807,7 +828,7 @@
                 int src_x, int src_y, int dest_x, int dest_y,
                 int width, int height)
 {
-  gdk_draw_drawable(dest->pixmap, fill_bg_gc, src->pixmap,
+  gdk_draw_drawable(dest->v.pixmap, fill_bg_gc, src->v.pixmap,
                    src_x, src_y, dest_x, dest_y, width, height);
 }
 
@@ -865,7 +886,7 @@
 {
   int canvas_x, canvas_y;
   static struct city *last_pcity=NULL;
-  struct canvas store = {map_canvas->window, NULL};
+  struct canvas store = {.type = CANVAS_PIXMAP, .v.pixmap = 
map_canvas->window};
 
   if (color==-1) {
     if (pcity!=last_pcity)
@@ -1078,7 +1099,7 @@
   enum tile_special_type special;
   int count, i;
   bool solid_bg, fog, tile_hilited;
-  struct canvas canvas_store = {pm};
+  struct canvas canvas_store = {.type = CANVAS_PIXMAP, .v.pixmap = pm};
 
   if (!width || !(height || height_unit))
     return;

[Prev in Thread] Current Thread [Next in Thread]