Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2003:
[Freeciv-Dev] (PR#4626) new mapview_common function: get_mapview_clippin
Home

[Freeciv-Dev] (PR#4626) new mapview_common function: get_mapview_clippin

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#4626) new mapview_common function: get_mapview_clipping_window
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 19 Jul 2003 16:21:24 -0700
Reply-to: rt@xxxxxxxxxxxxxx

Generally we think of the mapview as an imaginary "window" floating on 
top of the underlying map.  The window wraps at the edge of the map 
(along edges that wrap), but cannot extend past a non-wrapping edge.

However, we have to extend a little bit past a non-wrapping edge in some 
situations.  First is because the last row of tiles on the mapview map 
not be complete, so we can't count on this row to be able to show us 
critical information (like the last row of positions on the map). 
Second is that an iso-view mapview doesn't line up with the underlying 
map, so we have to be able to stick past the edges a fixed amount to be 
able to see them properly.

Currently this is all coded individually everywhere it's used.  In the 
GUI code this means the scrollbars.  The concept is the same everywhere: 
the mapview window is given dimensions of 
(mapview_canvas.tile_width,mapview_canvas.tile_height) and its clipping 
window (the bounding box for where it is allowed to move) is 
((0,0),(map.xsize,map.ysize+EXTRA_BOTTOM_ROW)).

Why would we want to change this, you ask?  Well, one reason is for 
gen-topologies: the current code assumes that the map wraps in only the 
Y direction.  But a more immediate reason is that the current code is 
buggy.  For iso-view EXTRA_BOTTOM_ROW is a hack to make things work; it 
is not conceptually sound (it gives non-symmetrical results that depend 
heavily on the dimensions of the mapview).  Also in iso-view the 
dimensions of the mapview window are wrong.

My solution is to add a common-code function that returns the dimensions 
of the clipping and mapview rectangle.  In most cases these values can 
just be dropped in in place of the existing hard-coded values.  Doing so 
hides the ugliness of EXTRA_BOTTOM_ROW, and makes it far easier to make 
changes to this algorithm in the future.

jason

? core.18894
? core.19297
? rc
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.50
diff -u -r1.50 mapview_common.c
--- client/mapview_common.c     2003/07/18 21:06:26     1.50
+++ client/mapview_common.c     2003/07/19 22:58:02
@@ -31,6 +31,11 @@
 
 #include "mapview_common.h"
 
+/* We need to be able to scroll a little bit down past the end of the map,
+ * since the bottom row of tiles may not fit completely on the mapview.
+ * In iso-view we have to scroll even further past. */
+#define EXTRA_BOTTOM_ROW (is_isometric ? 6 : 1)
+
 struct canvas mapview_canvas;
 
 /* Coordinates of the upper left corner of the map overview. */
@@ -295,6 +300,21 @@
   *map_y += mapview_canvas.map_y0;
 
   return normalize_map_pos(map_x, map_y);
+}
+
+/**************************************************************************
+  Return the range of values that the mapview origin can take.  Useful
+  for scrollbars or when manually clipping the window.
+**************************************************************************/
+void get_mapview_clipping_window(int *xmin, int *ymin,
+                                int *xmax, int *ymax,
+                                int *xsize, int *ysize)
+{
+  *xmin = *ymin = 0;
+  *xmax = map.xsize;
+  *ymax = map.ysize + EXTRA_BOTTOM_ROW;
+  *xsize = mapview_canvas.tile_width;
+  *ysize = mapview_canvas.tile_height;
 }
 
 /**************************************************************************
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.33
diff -u -r1.33 mapview_common.h
--- client/mapview_common.h     2003/07/18 21:06:26     1.33
+++ client/mapview_common.h     2003/07/19 22:58:02
@@ -48,12 +48,6 @@
 -Thue
 */
 
-/* If we have isometric view we need to be able to scroll a little
- *  extra down.  The places that needs to be adjusted are the same as
- *  above. 
-*/
-#define EXTRA_BOTTOM_ROW (is_isometric ? 6 : 1)
-
 /* 
  * When drawing a tile (currently only in isometric mode), there are
  * six relevant parts we can draw.  Each of these is a rectangle of
@@ -139,6 +133,10 @@
 
 bool map_to_canvas_pos(int *canvas_x, int *canvas_y, int map_x, int map_y);
 bool canvas_to_map_pos(int *map_x, int *map_y, int canvas_x, int canvas_y);
+
+void get_mapview_clipping_window(int *xmin, int *ymin,
+                                int *xmax, int *ymax,
+                                int *xsize, int *ysize);
 
 void get_center_tile_mapcanvas(int *map_x, int *map_y);
 void center_tile_mapcanvas(int map_x, int map_y);
Index: client/gui-gtk/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v
retrieving revision 1.174
diff -u -r1.174 mapview.c
--- client/gui-gtk/mapview.c    2003/07/18 21:06:26     1.174
+++ client/gui-gtk/mapview.c    2003/07/19 22:58:02
@@ -1163,10 +1163,13 @@
 **************************************************************************/
 void update_map_canvas_scrollbars_size(void)
 {
-  map_hadj=gtk_adjustment_new(-1, 0, map.xsize, 1,
-          map_canvas_store_twidth, map_canvas_store_twidth);
-  map_vadj=gtk_adjustment_new(-1, 0, map.ysize+EXTRA_BOTTOM_ROW, 1,
-          map_canvas_store_theight, map_canvas_store_theight);
+  int xmin, ymin, xmax, ymax, xsize, ysize;
+
+  get_mapview_clipping_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+
+  map_hadj = gtk_adjustment_new(-1, xmin, xmax, 1, xsize, xsize);
+  map_vadj = gtk_adjustment_new(-1, ymin, ymax, 1, ysize, ysize);
+
   gtk_range_set_adjustment(GTK_RANGE(map_horizontal_scrollbar),
        GTK_ADJUSTMENT(map_hadj));
   gtk_range_set_adjustment(GTK_RANGE(map_vertical_scrollbar),
@@ -1201,11 +1204,6 @@
     map_view_x0=percent;
   else {
     map_view_y0=percent;
-    map_view_y0=(map_view_y0<0) ? 0 : map_view_y0;
-    map_view_y0=
-      (map_view_y0>map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight) ? 
-      map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight :
-      map_view_y0;
   }
 
   if (last_map_view_x0!=map_view_x0 || last_map_view_y0!=map_view_y0) {
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.68
diff -u -r1.68 mapview.c
--- client/gui-gtk-2.0/mapview.c        2003/07/19 02:04:30     1.68
+++ client/gui-gtk-2.0/mapview.c        2003/07/19 22:58:02
@@ -1245,10 +1245,13 @@
 **************************************************************************/
 void update_map_canvas_scrollbars_size(void)
 {
-  map_hadj=gtk_adjustment_new(-1, 0, map.xsize, 1,
-          map_canvas_store_twidth, map_canvas_store_twidth);
-  map_vadj=gtk_adjustment_new(-1, 0, map.ysize+EXTRA_BOTTOM_ROW, 1,
-          map_canvas_store_theight, map_canvas_store_theight);
+  int xmin, ymin, xmax, ymax, xsize, ysize;
+
+  get_mapview_clipping_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+
+  map_hadj = gtk_adjustment_new(-1, xmin, xmax, 1, xsize, xsize);
+  map_vadj = gtk_adjustment_new(-1, ymin, ymax, 1, ysize, ysize);
+
   gtk_range_set_adjustment(GTK_RANGE(map_horizontal_scrollbar),
        GTK_ADJUSTMENT(map_hadj));
   gtk_range_set_adjustment(GTK_RANGE(map_vertical_scrollbar),
@@ -1283,11 +1286,6 @@
     map_view_x0=percent;
   else {
     map_view_y0=percent;
-    map_view_y0=(map_view_y0<0) ? 0 : map_view_y0;
-    map_view_y0=
-      (map_view_y0>map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight) ? 
-      map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight :
-      map_view_y0;
   }
 
   if (last_map_view_x0!=map_view_x0 || last_map_view_y0!=map_view_y0) {
Index: client/gui-win32/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/mapview.c,v
retrieving revision 1.73
diff -u -r1.73 mapview.c
--- client/gui-win32/mapview.c  2003/07/18 21:06:26     1.73
+++ client/gui-win32/mapview.c  2003/07/19 22:58:02
@@ -586,8 +586,12 @@
 **************************************************************************/
 void update_map_canvas_scrollbars_size(void)
 {
-  ScrollBar_SetRange(map_scroll_h,0,map.xsize,TRUE);
-  ScrollBar_SetRange(map_scroll_v,0,map.ysize+EXTRA_BOTTOM_ROW,TRUE);
+  int xmin, ymin, xmax, ymax, xsize, ysize;
+
+  get_mapview_clipping_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+
+  ScrollBar_SetRange(map_scroll_h, xmin, xmax, TRUE);
+  ScrollBar_SetRange(map_scroll_v, ymin, ymax, TRUE);
 }
 
 /**************************************************************************
@@ -1022,10 +1026,15 @@
 **************************************************************************/
 void map_handle_hscroll(int pos)
 {
+  int xmin, ymin, xmax, ymax, xsize, ysize;
+
   if (!can_client_change_view()) {
     return;
   }
-  map_view_x=pos;
+
+  get_mapview_clipping_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+  map_view_x = CLIP(xmin, pos, xmax - xsize);
+
   update_map_canvas_visible();
   refresh_overview_viewrect();                                                
 }
@@ -1035,14 +1044,15 @@
 **************************************************************************/
 void map_handle_vscroll(int pos)
 {
+  int xmin, ymin, xmax, ymax, xsize, ysize;
+
   if (!can_client_change_view()) {
     return;
   }
-  map_view_y=pos;
-  map_view_y=(map_view_y<0)?0:map_view_y;
-  map_view_y= (map_view_y>map.ysize+EXTRA_BOTTOM_ROW-map_view_height) ?
-        map.ysize+EXTRA_BOTTOM_ROW-map_view_height :
-        map_view_y;
+
+  get_mapview_clipping_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+  map_view_y = CLIP(ymin, pos, ymax - ysize);
+
   update_map_canvas_visible();
   refresh_overview_viewrect();
 }
Index: client/gui-xaw/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapview.c,v
retrieving revision 1.141
diff -u -r1.141 mapview.c
--- client/gui-xaw/mapview.c    2003/07/19 01:43:26     1.141
+++ client/gui-xaw/mapview.c    2003/07/19 22:58:02
@@ -744,11 +744,17 @@
 **************************************************************************/
 void update_map_canvas_scrollbars(void)
 {
-  float shown_h=(float)map_canvas_store_twidth/(float)map.xsize;
-  float top_h=(float)map_view_x0/(float)map.xsize;
-  float 
shown_v=(float)map_canvas_store_theight/((float)map.ysize+EXTRA_BOTTOM_ROW);
-  float top_v=(float)map_view_y0/((float)map.ysize+EXTRA_BOTTOM_ROW);
+  float shown_h, top_h, shown_v, top_v;
+  int xmin, ymin, xmax, ymax, xsize, ysize;
 
+  get_mapview_clipping_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+
+  top_h = (float)(map_view_x0 - xmin) / (float)(xmax - xmin);
+  top_v = (float)(map_view_y0 - ymin) / (float)(ymax - ymin);
+
+  shown_h = (float)xsize / (float)(xmax - xmin);
+  shown_v = (float)ysize / (float)(ymax - ymin);
+
   XawScrollbarSetThumb(map_horizontal_scrollbar, top_h, shown_h);
   XawScrollbarSetThumb(map_vertical_scrollbar, top_v, shown_v);
 }
@@ -1022,20 +1028,20 @@
                             XtPointer percent_ptr)
 {
   float percent=*(float*)percent_ptr;
+  int xmin, ymin, xmax, ymax, xsize, ysize;
 
+  get_mapview_clipping_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+
   if (!can_client_change_view()) {
     return;
   }
 
-  if(w==map_horizontal_scrollbar)
-    map_view_x0=percent*map.xsize;
-  else {
-    map_view_y0=percent*(map.ysize+EXTRA_BOTTOM_ROW);
-    map_view_y0=(map_view_y0<0) ? 0 : map_view_y0;
-    map_view_y0=
-      (map_view_y0>map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight) ? 
-       map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight :
-       map_view_y0;
+  if(w==map_horizontal_scrollbar) {
+    map_view_x0 = xmin + (percent * (xmax - xmin));
+    map_view_x0 = CLIP(xmin, map_view_x0, xmax - xsize);
+  } else {
+    map_view_y0 = ymin + (percent * (ymax - ymin));
+    map_view_y0 = CLIP(ymin, map_view_y0, ymax - ysize);
   }
 
   update_map_canvas_visible();
@@ -1051,27 +1057,31 @@
 void scrollbar_scroll_callback(Widget w, XtPointer client_data,
                             XtPointer position_val)
 {
-  int position = XTPOINTER_TO_INT(position_val), is_real;
+  int position = XTPOINTER_TO_INT(position_val);
+  int xmin, ymin, xmax, ymax, xsize, ysize;
 
+  get_mapview_clipping_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+
   if (!can_client_change_view()) {
     return;
   }
 
   if(w==map_horizontal_scrollbar) {
-    if(position>0) 
+    if (position > 0) {
       map_view_x0++;
-    else
+    } else {
       map_view_x0--;
+    }
+    map_view_x0 = CLIP(xmin, map_view_x0, xmax - xsize);
   }
   else {
-    if(position>0 && 
map_view_y0<map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight)
+    if (position > 0) {
       map_view_y0++;
-    else if(position<0 && map_view_y0>0)
+    } else {
       map_view_y0--;
+    }
+    map_view_y0 = CLIP(ymin, map_view_y0, ymax - ysize);
   }
-
-  is_real = normalize_map_pos(&map_view_x0, &map_view_y0);
-  assert(is_real);
 
   update_map_canvas_visible();
   update_map_canvas_scrollbars();

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#4626) new mapview_common function: get_mapview_clipping_window, Jason Short <=