Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2006:
[Freeciv-Dev] (PR#15877) Editor: place units with unittype
Home

[Freeciv-Dev] (PR#15877) Editor: place units with unittype

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#15877) Editor: place units with unittype
From: "Mike Kaufman" <kaufman@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 12 Mar 2006 08:42:11 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=15877 >

See subject. It's a bit messy right now. some code is simply commented out.
It seems that you can also now place cities without crashing.

Thanks to vasc for the list store combo box code.

-mike

Index: client/gui-gtk-2.0/editdlg.c
===================================================================
--- client/gui-gtk-2.0/editdlg.c        (revision 11774)
+++ client/gui-gtk-2.0/editdlg.c        (working copy)
@@ -30,9 +30,12 @@
 
 #include "game.h"
 #include "government.h"
+#include "movement.h"
 #include "packets.h"
 
 #include "editor.h"
+#include "plrdlg.h"
+#include "tilespec.h"
 
 #include "editdlg.h"
 #include "gui_main.h"
@@ -79,17 +82,22 @@
 };
 
 static char *tool_names[ETOOL_LAST] = {
-  N_("Paint"), N_("Unit"), N_("City"), N_("Player"), N_("Delete")
+  N_("Paint"), N_("Select"), N_("Unit"), N_("City"), N_("Delete")
 };
 
 #define SPECIALS_NUM ARRAY_SIZE(specials)
 
 static GtkWidget *toolwin;
 static GtkWidget *notebook;
+static GtkTooltips *tooltips;
 
 static GList *tool_group;
 static GList *map_group;
+static GList *unit_group;
 
+/* helper array for tool_toggled */
+static int tool_notebook_position[ETOOL_LAST];
+
 /****************************************************************************
   handle the toggle buttons' toggle events
 ****************************************************************************/
@@ -97,7 +105,12 @@
 {
   editor_set_selected_tool_type(tool);
   /* switch pages if necessary */
-  gtk_notebook_set_page(GTK_NOTEBOOK(notebook), tool);
+  if (tool_notebook_position[tool] >= 0) {
+    gtk_widget_set_sensitive(notebook, TRUE);
+    gtk_notebook_set_page(GTK_NOTEBOOK(notebook), 
tool_notebook_position[tool]);
+  } else {
+    gtk_widget_set_sensitive(notebook, FALSE);
+  }
 }
 
 /****************************************************************************
@@ -252,6 +265,20 @@
 #endif
 
 /****************************************************************************
+ ...
+*****************************************************************************/
+static void set_new_unittype(GtkWidget *w, gpointer data)
+{
+  struct unit_type *new_type = (struct unit_type *) data;
+  struct unit *punit = editor_get_new_unit();
+
+  if (punit) {
+    punit->type = new_type;
+  }
+}
+
+
+/****************************************************************************
   Create the palette for the editor terrain/special paint tool.
 ****************************************************************************/
 static GtkWidget *create_map_palette(void)
@@ -321,49 +348,78 @@
 ****************************************************************************/
 static GtkWidget *create_units_palette(void)
 {
-  GtkWidget *hbox, *vbox, *label, *sb;
-  GtkSizeGroup *label_group, *sb_group;
-  GtkAdjustment *adj;
-  int i;
-  struct unit *punit = editor_get_selected_unit();
+  GtkWidget *vbox, *table;
+  enum { NON, LAND, SEA, AIR, NUM_CAT };
+  int cat[NUM_CAT] = { 0, 0, 0, 0 }; /* categories */
+  int end, i, j = 0; 
+  int per_row = 6;
+  bool flag = TRUE;
+  struct unit_type *u[game.control.num_unit_types];
 
-  const char *names[UPARAM_LAST] = { _("Owner"),
-                                    _("Type"),
-                                    _("Moves Left"),
-                                    _("Activity"),
-                                    _("Activity Target"),
-                                    _("Activity Count") };
-  int inits[UPARAM_LAST][3] = {
-    {punit->owner->player_no, 0, game.info.nplayers - 1},
-    {punit->type->index, 0, game.control.num_unit_types - 1},
-    {punit->moves_left, 0, 200},
-    {punit->activity, 0, ACTIVITY_LAST},
-    {punit->activity_target, 0, S_LAST},
-    {punit->activity_count, 0, 200}
-  };
+  /* fill unit types for each button */
+  for(i = 0; i < NUM_CAT; i++) {
+    unit_type_iterate(type) {
+      bool mil = !unit_type_flag(type, F_NONMIL);
+      if (i == NON && !mil) {
+        cat[NON]++;
+        u[j++] = type;
+      } else if (i == LAND && is_ground_unittype(type) && mil) {
+        cat[LAND]++;
+        u[j++] = type;
+      } else if (i == SEA && is_sailing_unittype(type) && mil) {
+        cat[SEA]++;
+        u[j++] = type;
+      } else if (i == AIR && (is_heli_unittype(type) || is_air_unittype(type))
+                 && mil) {
+        cat[AIR]++;
+        u[j++] = type;
+      }
+    } unit_type_iterate_end;
+  }
 
-  vbox = gtk_vbox_new(FALSE, 5);
+  vbox = gtk_vbox_new(FALSE, 0);
 
-  label_group = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
-  sb_group = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
+  /* create tables for each category */
+  for(j = 0, i = 0; i < NUM_CAT; i++) {
+    int t; /* iterates over the table row/col */
+    table = gtk_table_new(per_row, ((cat[i] - 1) / per_row) + 1, FALSE);
+    int sig;
 
-  for (i = 0; i < UPARAM_LAST; i++) {
-    adj = GTK_ADJUSTMENT(gtk_adjustment_new(inits[i][0], inits[i][1], 
-                                           inits[i][2], 1.0, 5.0, 5.0));
-    hbox = gtk_hbox_new(FALSE, 5);
-    sb = gtk_spin_button_new(adj, 1, 0);
-    gtk_size_group_add_widget(label_group, sb);
-    label = gtk_label_new(names[i]);
-    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-    gtk_size_group_add_widget(label_group, label);
-    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(hbox), sb, TRUE, TRUE, 0);
+    end = j + cat[i];
+    for(t = 0; j < end; t++, j++){
+      GtkWidget *button = gtk_toggle_button_new();
+      const char *tiptext = (char*)get_unit_name(u[j]);
+      struct sprite *s = crop_blankspace(get_unittype_sprite(tileset, u[j]));
+      GdkPixbuf *pix = sprite_get_pixbuf(s);
+      GtkWidget *image = gtk_image_new_from_pixbuf(pix);
+      g_object_unref(pix);
 
-    g_signal_connect(sb, "value-changed", G_CALLBACK(unit_callback),
-                     GINT_TO_POINTER(i));
+      if (flag) {
+        gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
+        flag = FALSE; /* only set the 1st button of the 1st table down */
+      }
+
+      gtk_tooltips_set_tip(tooltips, button, tiptext, NULL);
+      gtk_container_add(GTK_CONTAINER(button), image);
+      gtk_table_attach_defaults(GTK_TABLE(table), button,
+                                t % per_row, t % per_row + 1, 
+                                t / per_row, t / per_row + 1);
+
+      sig = g_signal_connect(button, "toggled", 
+                             G_CALLBACK(set_new_unittype), (gpointer)u[j]);
+
+      /* add this button to a group */
+      unit_group = g_list_append(unit_group, button);
+
+      /* add this group and the signal id to widget internal data */
+      g_signal_connect(button, "toggled",
+                       G_CALLBACK(toggle_group_callback), 
(gpointer)unit_group);
+      g_object_set_data(G_OBJECT(button), "sigid", GINT_TO_POINTER(sig));
+    }
+    gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 4);
   }
 
+  gtk_widget_show_all(vbox);
   return vbox;
 }
 
@@ -375,6 +431,7 @@
   GtkWidget *hbox, *vbox, *label, *sb;
   GtkAdjustment *adj;
   int i;
+#if 0
   struct city *pcity = editor_get_selected_city();
 
   const char *names[CPARAM_LAST] = { _("Owner"), };
@@ -382,7 +439,6 @@
     {pcity->owner->player_no, 0, game.info.nplayers - 1},
   };
 
-  vbox = gtk_vbox_new(FALSE, 5);
 
   for (i = 0; i < CPARAM_LAST; i++) {
     adj = GTK_ADJUSTMENT(gtk_adjustment_new(inits[i][0], inits[i][1], 
@@ -397,6 +453,8 @@
     g_signal_connect(sb, "value-changed", G_CALLBACK(city_callback),
                      GINT_TO_POINTER(i));
   }
+#endif
+  vbox = gtk_vbox_new(FALSE, 5);
 
   return vbox;
 }
@@ -415,6 +473,22 @@
 }
 #endif
 
+/****************************************************************
+...
+*****************************************************************/
+static void owner_callback(GtkWidget *w, GtkListStore *store)
+{
+  GtkTreeIter iter;
+  int player_no;
+
+  if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(w), &iter)) {
+    GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(w));
+
+    gtk_tree_model_get(model, &iter, 2, &player_no, -1);
+    editor_set_owner(get_player(player_no));
+  }
+}
+
 /****************************************************************************
   Create the tools dialog.
 
@@ -423,13 +497,15 @@
 ****************************************************************************/
 static void create_toolsdlg(void)
 {
-  GtkWidget *vbox;
+  GtkWidget *vbox, *ownerbox, *label, *combo;
+  GtkListStore *store;
+  GtkCellRenderer *rend;
 
   if (toolwin) {
     return;
   }
 
-  editor_init_tools();
+  update_editor_data();
 
   toolwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   setup_dialog(toolwin, toplevel);
@@ -445,6 +521,9 @@
   vbox = gtk_vbox_new(FALSE, 0);
   gtk_container_add(GTK_CONTAINER(toolwin), vbox);
 
+  tooltips = gtk_tooltips_new();
+  gtk_tooltips_set_delay(tooltips, 750);
+
   create_tools(toolwin, vbox);
   notebook = gtk_notebook_new();
   gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), FALSE, FALSE, 2);
@@ -453,17 +532,75 @@
   gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
   gtk_box_pack_start(GTK_BOX(vbox), notebook, FALSE, FALSE, 0);
 
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                          create_map_palette(), NULL);
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                          create_units_palette(), NULL);
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                          create_city_palette(), NULL);
+  gtk_notebook_insert_page(GTK_NOTEBOOK(notebook),
+                          create_map_palette(), NULL, 0);
+  gtk_notebook_insert_page(GTK_NOTEBOOK(notebook),
+                          create_units_palette(), NULL, 1);
+  gtk_notebook_insert_page(GTK_NOTEBOOK(notebook),
+                          create_city_palette(), NULL, 2);
 #if 0
   gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
                           create_player_palette(), NULL);
 #endif
 
+  tool_notebook_position[ETOOL_PAINT] = 0;
+  tool_notebook_position[ETOOL_SELECT] = -1;
+  tool_notebook_position[ETOOL_UNIT] = 1;
+  tool_notebook_position[ETOOL_CITY] = 2;
+  tool_notebook_position[ETOOL_DELETE] = -1;
+  
+
+  ownerbox = gtk_vbox_new(FALSE, 2);
+  gtk_container_add(GTK_CONTAINER(vbox), ownerbox);
+
+  /* create the owner's combo box */
+  store = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);
+
+  combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+  g_object_unref(store);
+  g_signal_connect(combo, "changed", G_CALLBACK(owner_callback), store);
+
+  gtk_cell_layout_clear(GTK_CELL_LAYOUT(combo));
+
+  rend = gtk_cell_renderer_pixbuf_new();
+  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), rend, TRUE);
+  gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), rend, "pixbuf", 0, 
NULL);
+  g_object_set(rend, "xalign", 0.0, NULL);                              
+
+  rend = gtk_cell_renderer_text_new();
+  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), rend, TRUE);
+  gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), rend, "text", 1, 
NULL);
+
+  label = g_object_new(GTK_TYPE_LABEL,
+      "label", _("Owner:"),
+      "xalign", 0.0,
+      "yalign", 0.5,
+      NULL);
+  gtk_box_pack_start(GTK_BOX(ownerbox), label, FALSE, FALSE, 0);  
+  gtk_box_pack_start(GTK_BOX(ownerbox), combo, TRUE, TRUE, 0);
+
+  g_signal_connect(toolwin, "delete_event",
+                   G_CALLBACK(editdlg_hide_tools), NULL);
+
+  gtk_list_store_clear(store);
+  players_iterate(pplayer) {
+    GtkTreeIter iter;
+    struct nation_type *nation;
+    GdkPixbuf *pixbuf;
+
+    nation = pplayer->nation;
+    pixbuf = get_flag(pplayer->nation);
+
+    gtk_list_store_append(store, &iter);
+    gtk_list_store_set(store, &iter,
+       0, pixbuf,
+       1, get_nation_name(nation),
+       2, pplayer->player_no,
+       -1);
+    g_object_unref(pixbuf);
+  } players_iterate_end;
+  gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
+
   gtk_widget_show_all(toolwin);
 }
 
Index: client/packhand.c
===================================================================
--- client/packhand.c   (revision 11774)
+++ client/packhand.c   (working copy)
@@ -1402,6 +1402,7 @@
   }
   update_unit_focus();
   update_menus();
+  update_editor_data();
   update_players_dialog();
   if (update_aifill_button) {
     update_start_page();
Index: client/editor.c
===================================================================
--- client/editor.c     (revision 11774)
+++ client/editor.c     (working copy)
@@ -38,17 +38,23 @@
 static enum editor_paint_type selected_paint_type = EPAINT_LAST;
 static struct unit *selected_unit;
 static struct city *selected_city;
+static struct unit *new_unit;
+static struct city *new_city;
 
+/* a pointer to the player whose units and cities will be created */
+static struct player *owner = NULL;
+
 /****************************************************************************
   Initialize the editor tools data.
 
   FIXME: This absolutely has to be called anew each time we connect to a
   new server, since the ruleset may be different and data needs to be reset.
 ****************************************************************************/
-void editor_init_tools(void)
+void update_editor_data(void)
 { 
-  struct player *pplayer = game.player_ptr ? game.player_ptr : get_player(0);
+ // struct player *pplayer = game.player_ptr ? game.player_ptr : get_player(0);
 
+#if 0
   if (selected_unit) {
     destroy_unit_virtual(selected_unit);
   }
@@ -58,11 +64,21 @@
     destroy_city_virtual(selected_city);
   }
   selected_city = create_city_virtual(pplayer, NULL, "");
+#endif
 
   selected_tool = ETOOL_PAINT;
   selected_special = S_LAST;
   selected_paint_type = EPAINT_LAST;
-  selected_terrain = NULL;
+
+//  selected_terrain = NULL;
+#if 1
+  if (!selected_terrain) {
+    terrain_type_iterate(pterrain) {
+      selected_terrain = pterrain;
+      break;
+    } terrain_type_iterate_end;
+  }
+#endif
 }
 
 /****************************************************************************
@@ -98,6 +114,50 @@
 }
 
 /****************************************************************************
+  Sets the default owner of new cities and units, if we haven't yet 
+  created new_city and new_unit because the owner has been NULL, do so now
+****************************************************************************/
+void editor_set_owner(struct player *new_owner)
+{ 
+  struct player *old_owner = owner;
+
+  owner = new_owner;
+
+  if (!old_owner && new_owner) {
+    if (new_unit) {
+      destroy_unit_virtual(new_unit);
+    }
+    new_unit = create_unit_virtual(owner, 0, get_unit_type(0), 0);
+
+    if (new_city) {
+      destroy_city_virtual(new_city);
+    }
+    new_city = create_city_virtual(owner, NULL, "");
+  }
+
+  if (old_owner) {
+    new_unit->owner = owner;
+    new_city->owner = owner;
+  }
+}
+
+/****************************************************************************
+  Returns the new unit.
+****************************************************************************/
+struct unit *editor_get_new_unit(void)
+{
+  return new_unit;
+}
+
+/****************************************************************************
+  Returns the new city.
+****************************************************************************/
+struct city *editor_get_new_city(void)
+{
+  return new_city;
+}
+
+/****************************************************************************
   Returns the selected unit.
 ****************************************************************************/
 struct unit *editor_get_selected_unit(void)
@@ -121,28 +181,32 @@
 {
   struct packet_edit_unit packet;
 
+  if (!new_unit) {
+    return;
+  }
+
   packet.create_new = TRUE; /* ? */
   packet.delete = FALSE;
 
-  packet.id = selected_unit->id;
-  packet.owner = selected_unit->owner->player_no;
+  packet.id = new_unit->id;
+  packet.owner = new_unit->owner->player_no;
 
   packet.x = ptile->x;
   packet.y = ptile->y;
 
-  packet.homecity = selected_unit->homecity;
+  packet.homecity = new_unit->homecity;
 
-  packet.veteran = selected_unit->veteran;
-  packet.paradropped = selected_unit->paradropped;
+  packet.veteran = new_unit->veteran;
+  packet.paradropped = new_unit->paradropped;
 
-  packet.type = selected_unit->type->index;
-  packet.transported_by = selected_unit->transported_by;
+  packet.type = new_unit->type->index;
+  packet.transported_by = new_unit->transported_by;
 
-  packet.movesleft = selected_unit->moves_left;
-  packet.hp = selected_unit->hp;
-  packet.fuel = selected_unit->fuel;
+  packet.movesleft = new_unit->moves_left;
+  packet.hp = new_unit->hp;
+  packet.fuel = new_unit->fuel;
 
-  packet.activity_count = selected_unit->activity_count;
+  packet.activity_count = new_unit->activity_count;
 
   send_packet_edit_unit(&aconnection, &packet);
 }
@@ -152,12 +216,16 @@
 ****************************************************************************/
 static void do_city(struct tile *ptile)
 {
-  struct packet_edit_create_city packet = {
-    .owner = selected_city->owner->player_no,
-    .x = ptile->x,
-    .y = ptile->y
-  };
+  struct packet_edit_create_city packet;
 
+  if (!new_city) {
+    return;
+  }
+
+  packet.owner = new_city->owner->player_no;
+  packet.x = ptile->x;
+  packet.y= ptile->y;
+
   send_packet_edit_create_city(&aconnection, &packet);
 }
 
@@ -231,9 +299,11 @@
   case ETOOL_CITY:
     do_city(ptile);
     break;
-  case ETOOL_PLAYER:
+  case ETOOL_SELECT:
   case ETOOL_DELETE:
   case ETOOL_LAST:
     break;
+  default:
+    break;
   }
 }
Index: client/editor.h
===================================================================
--- client/editor.h     (revision 11774)
+++ client/editor.h     (working copy)
@@ -18,9 +18,9 @@
 
 enum editor_tool_type {
   ETOOL_PAINT,
+  ETOOL_SELECT,
   ETOOL_UNIT,
   ETOOL_CITY,
-  ETOOL_PLAYER,
   ETOOL_DELETE,
   ETOOL_LAST
 };
@@ -33,9 +33,13 @@
 
 typedef void (*ToolFunction)(struct tile *ptile);
 
-void editor_init_tools(void);
+void update_editor_data(void);
 void editor_show_tools(void);
+void editor_set_owner(struct player *new_owner);
 
+struct unit *editor_get_new_unit(void);
+struct city *editor_get_new_city(void);
+
 void editor_set_selected_tool_type(enum editor_tool_type type);
 void editor_set_selected_paint_type(enum editor_paint_type type);
 void editor_set_selected_terrain(struct terrain *pterrain);

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#15877) Editor: place units with unittype, Mike Kaufman <=