Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2003:
[Freeciv-Dev] Re: (PR#3727) Rectangular selection with right-click-and-d
Home

[Freeciv-Dev] Re: (PR#3727) Rectangular selection with right-click-and-d

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: a-l@xxxxxxx
Subject: [Freeciv-Dev] Re: (PR#3727) Rectangular selection with right-click-and-drag
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 20 Mar 2003 10:43:32 -0800
Reply-to: rt@xxxxxxxxxxxxxx

Mike Kaufman wrote:

> attached is my solution for the civworld code. it should work for all
> topologies [that we are considering].

...

> static void draw_bounding_rectangle()
> {
>   if(is_isometric){
>     int Nx, Ny, Sx, Sy, Wx, Wy, Ex, Ey;
> 
>     get_canvas_xy(first_x, first_y, &Nx, &Ny); /* not necessarily N & S at */
>     get_canvas_xy(last_x, last_y, &Sx, &Sy);   /* this point */
> 
>     if (last_x >= first_x && last_y >= first_y) { /* normal */
>       get_canvas_xy(first_x, last_y, &Wx, &Wy);
>       get_canvas_xy(last_x, first_y, &Ex, &Ey);
>     } else if(last_x <= first_x && last_y <= first_y) { /* switch N & S */
>       Ex = Nx; Ey = Ny;
>       Nx = Sx; Ny = Sy;
>       Sx = Ex; Sy = Ey;
>       get_canvas_xy(first_x, last_y, &Ex, &Ey);
>       get_canvas_xy(last_x, first_y, &Wx, &Wy);
>     } else if(last_x < first_x) { /* start must be eastmost */
>       Ex = Nx; Ey = Ny;
>       Wx = Sx; Wy = Sy;
>       get_canvas_xy(first_x, last_y, &Sx, &Sy);
>       get_canvas_xy(last_x, first_y, &Nx, &Ny);
>     } else { /* start must be westmost */
>       Ex = Sx; Ey = Sy;
>       Wx = Nx; Wy = Ny;
>       get_canvas_xy(first_x, last_y, &Nx, &Ny);
>       get_canvas_xy(last_x, first_y, &Sx, &Sy);
>     }
> 
>     Nx += NORMAL_TILE_WIDTH / 2;
>     Sx += NORMAL_TILE_WIDTH / 2;
>     Sy += NORMAL_TILE_HEIGHT;
>     Wy += NORMAL_TILE_HEIGHT / 2;
>     Ex += NORMAL_TILE_WIDTH;
>     Ey += NORMAL_TILE_HEIGHT / 2;
> 
>     gdk_draw_line(GTK_WIDGET(map_canvas)->window, rubberband_line_gc, 
>                   Nx, Ny, Ex, Ey);
>     gdk_draw_line(GTK_WIDGET(map_canvas)->window, rubberband_line_gc, 
>                   Ex, Ey, Sx, Sy);
>     gdk_draw_line(GTK_WIDGET(map_canvas)->window, rubberband_line_gc, 
>                   Wx, Wy, Nx, Ny);
>     gdk_draw_line(GTK_WIDGET(map_canvas)->window, rubberband_line_gc, 
>                   Sx, Sy, Wx, Wy);
>   }else{
>     int x1, y1, x2, y2; /* the 1's are the start tile, 2's are the end tile */
> 
>     get_canvas_xy(first_x, first_y, &x1, &y1);
>     get_canvas_xy(last_x, last_y, &x2, &y2); 
> 
>     if(x1 < x2)
>       x2 += NORMAL_TILE_WIDTH - 1;
>     else
>       x1 += NORMAL_TILE_WIDTH - 1;
>     if(y1 < y2)
>       y2 += NORMAL_TILE_HEIGHT - 1;
>     else
>       y1 += NORMAL_TILE_HEIGHT - 1;
> 
>     /* draw new rectangle */
>     gdk_draw_line(GTK_WIDGET(map_canvas)->window, rubberband_line_gc,
>                   x1, y1, x1, y2);
>     gdk_draw_line(GTK_WIDGET(map_canvas)->window, rubberband_line_gc,
>                   x1, y1, x2, y1);
>     gdk_draw_line(GTK_WIDGET(map_canvas)->window, rubberband_line_gc,
>                   x2, y2, x2, y1);
>     gdk_draw_line(GTK_WIDGET(map_canvas)->window, rubberband_line_gc,
>                   x2, y2, x1, y2);
>   }
> }

I'm not sure, but I don't think this will always work.

One pathological case is where the rectangle covers the entire map with 
the current topology.  Now we'll end up with what should be a huge 
rectangle but we'll think it is a tiny rectangle.

   map.xsize = 80
   map.ysize = 50
   (x0,y0,w,h) = (5, 0, 81, 50)
   (x0,y0,x1,y1) = (5,0,6,50)

I think this can happen even in reasonable conditions with a wrapping 
isometric map.  Here you can wrap around and get a situation like above 
even without having a huge rectangle.

None of this will be a problem as long as the mapview doesn't scroll and 
all positions are visible on the mapview.  But this isn't the case...

I think the best solution is to track width and height rather than 
last_x and last_y.

jason




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