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

[Freeciv-Dev] Re: (PR#8427) better client interface for transported unit

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#8427) better client interface for transported units
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 30 Mar 2004 15:17:53 -0800
Reply-to: rt@xxxxxxxxxxx

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

Jason Short wrote:

> In the short term, however, it would be an improvement if transported 
> units are shown immediately after the unit they are transported by.

Here's a patch that does this.  A common function (in mapctrl_common; 
there is no dialogs_common) sorts the units.  The gtk2 client is tested; 
the XAW, gtk, and win32 clients are changed but untested.

> In the long term in the unit popup you should be able to right-click on 
> a unit to get a little menu for actions for that unit.  For transported 
> units, one such action would be "unload".  For a non-transported unit, 
> you could "load into..." (with the possible targets available in a 
> sub-menu).  Other actions include the standard choices for units.  This 
> isn't possible yet because there is no "load" command.

Drag-and-drop would also be nice here.

jason

? cma_weirdness
? data/civ3
? data/womoks
Index: client/mapctrl_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.c,v
retrieving revision 1.30
diff -u -r1.30 mapctrl_common.c
--- client/mapctrl_common.c     29 Mar 2004 19:17:06 -0000      1.30
+++ client/mapctrl_common.c     30 Mar 2004 23:15:24 -0000
@@ -656,6 +656,60 @@
   return TRUE;
 }
 
+/****************************************************************************
+  We sort according to the following logic:
+
+  - Transported units should immediately follow their transporter (note that
+    transporting may be recursive).
+  - Otherwise we sort by ID (which is what the list is originally sorted by).
+****************************************************************************/
+static int unit_list_compare(const void *a, const void *b)
+{
+  const struct unit *punit1 = *(struct unit **)a;
+  const struct unit *punit2 = *(struct unit **)b;
+
+  if (punit1->transported_by == punit2->transported_by) {
+    /* For units with the same transporter or no transporter: sort by id. */
+    /* Perhaps we should sort by name instead? */
+    return punit1->id - punit2->id;
+  } else if (punit1->transported_by == punit2->id) {
+    return 1;
+  } else if (punit2->transported_by == punit1->id) {
+    return -1;
+  } else {
+    /* If the transporters aren't the same, put in order by the
+     * transporters. */
+    const struct unit *ptrans1 = find_unit_by_id(punit1->transported_by);
+    const struct unit *ptrans2 = find_unit_by_id(punit2->transported_by);
+
+    if (!ptrans1) {
+      ptrans1 = punit1;
+    }
+    if (!ptrans2) {
+      ptrans2 = punit2;
+    }
+
+    return unit_list_compare(&ptrans1, &ptrans2);
+  }
+}
+
+/****************************************************************************
+  Fill and sort the list of units on the tile.
+****************************************************************************/
+void fill_tile_unit_list(struct tile *ptile, struct unit **unit_list)
+{
+  int i = 0;
+
+  /* First populate the unit list. */
+  unit_list_iterate(ptile->units, punit) {
+    unit_list[i] = punit;
+    i++;
+  } unit_list_iterate_end;
+
+  /* Then sort it. */
+  qsort(unit_list, i, sizeof(*unit_list), unit_list_compare);
+}
+
 static void add_line(char* buf, size_t bufsz, char *format, ...)
                      fc__attribute((format(printf, 3, 4)));
 
Index: client/mapctrl_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.h,v
retrieving revision 1.15
diff -u -r1.15 mapctrl_common.h
--- client/mapctrl_common.h     7 Jan 2004 16:31:14 -0000       1.15
+++ client/mapctrl_common.h     30 Mar 2004 23:15:24 -0000
@@ -59,6 +59,8 @@
 bool get_chance_to_win(int *att_chance, int *def_chance,
                       int map_x, int map_y);
 
+void fill_tile_unit_list(struct tile *ptile, struct unit **unit_list);
+
 extern struct city *city_workers_display;
 
 #endif /* FC__MAPCTRL_COMMON_H */
Index: client/gui-gtk/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/dialogs.c,v
retrieving revision 1.137
diff -u -r1.137 dialogs.c
--- client/gui-gtk/dialogs.c    8 Feb 2004 21:56:51 -0000       1.137
+++ client/gui-gtk/dialogs.c    30 Mar 2004 23:15:25 -0000
@@ -1651,6 +1651,7 @@
   GtkWidget *pix, *hbox, *table;
   GtkWidget *unit_select_all_command, *unit_select_close_command;
   bool can_ready = FALSE;
+  struct unit *unit_list[unit_list_size(&ptile->units)];
 
   if (!unit_select_dialog_shell){
   gtk_widget_set_sensitive(top_vbox, FALSE);
@@ -1670,8 +1671,10 @@
   gtk_container_add(GTK_CONTAINER(GTK_DIALOG(unit_select_dialog_shell)->vbox),
        table);  
 
+  fill_tile_unit_list(ptile, unit_list);
+
   for(i=0; i<n; i++) {
-    struct unit *punit=unit_list_get(&ptile->units, i);
+    struct unit *punit = unit_list[i];
     struct unit_type *punittemp=unit_type(punit);
     struct city *pcity;
 
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        30 Mar 2004 23:15:25 -0000
@@ -35,6 +35,8 @@
 #include "rand.h"
 #include "support.h"
 
+#include "mapctrl_common.h"
+
 #include "chatline.h"
 #include "citydlg.h"
 #include "civclient.h"
@@ -1462,13 +1464,11 @@
 static void refresh_unit_select_dialog(void)
 {
   if (unit_select_dialog_shell) {
-    struct tile *ptile;
-    int i, n, r;
-
-    ptile = unit_select_ptile;
-
-    n = unit_list_size(&ptile->units);
-    r = number_of_rows(n);
+    struct tile *ptile = unit_select_ptile;
+    int i;
+    const int n = unit_list_size(&ptile->units);
+    const int r = number_of_rows(n);
+    struct unit *unit_list[n];
 
     for (i=n; i<unit_select_no; i++) {
       gtk_widget_destroy(unit_select_nodes[i].cmd);
@@ -1499,9 +1499,11 @@
 
     gtk_tooltips_disable(unit_select_tips);
 
+    fill_tile_unit_list(ptile, unit_list);
+
     for (i=0; i<n; i++) {
       GtkWidget *cmd, *pix;
-      struct unit *punit = unit_list_get(&ptile->units, i);
+      struct unit *punit = unit_list[i];
 
       cmd = unit_select_nodes[i].cmd;
       pix = unit_select_nodes[i].pix;
Index: client/gui-win32/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/dialogs.c,v
retrieving revision 1.43
diff -u -r1.43 dialogs.c
--- client/gui-win32/dialogs.c  8 Mar 2004 07:20:50 -0000       1.43
+++ client/gui-win32/dialogs.c  30 Mar 2004 23:15:25 -0000
@@ -716,7 +716,9 @@
   RECT rc,rc2;
   HBITMAP old;
   static HDC unitsel_dc;
+  struct unit *unit_list[unit_list_size(&ptile->units)];
   
+  fill_tile_unit_list(ptile, unit_list);
   
   /* unit select box might already be open; if so, close it */
   if (unit_select_main) {
@@ -744,7 +746,7 @@
   max_height=0;
   for(i=0;i<n;i++)
     {
-      struct unit *punit=unit_list_get(&ptile->units, i);
+      struct unit *punit = unit_list[i];
       struct unit_type *punittemp=unit_type(punit);
       struct city *pcity;
       unit_select_ids[i]=punit->id;
Index: client/gui-xaw/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/dialogs.c,v
retrieving revision 1.92
diff -u -r1.92 dialogs.c
--- client/gui-xaw/dialogs.c    8 Mar 2004 07:20:50 -0000       1.92
+++ client/gui-xaw/dialogs.c    30 Mar 2004 23:15:26 -0000
@@ -1555,6 +1555,7 @@
   Widget unit_select_all_command, unit_select_close_command;
   Widget firstcolumn=0,column=0;
   Pixel bg;
+  struct unit *unit_list[unit_list_size(&ptile->units)];
 
   XtSetSensitive(main_form, FALSE);
 
@@ -1573,8 +1574,10 @@
   n = MIN(MAX_SELECT_UNITS, unit_list_size(&ptile->units));
   r = number_of_rows(n);
 
+  fill_tile_unit_list(ptile, unit_list);
+
   for(i=0; i<n; i++) {
-    struct unit *punit=unit_list_get(&ptile->units, i);
+    struct unit *punit = unit_list[i];
     struct unit_type *punittemp=unit_type(punit);
     struct city *pcity;
     struct canvas store;

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