[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]
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
- [Freeciv-Dev] (PR#3529) Map Control patch, Jason Short, 2003/03/02
- Message not available
- Message not available
- [Freeciv-Dev] Re: (PR#3727) Rectangular selection with right-click-and-drag, a-l@xxxxxxx, 2003/03/20
- Message not available
- [Freeciv-Dev] Re: (PR#3727) Rectangular selection with right-click-and-drag, Jason Short, 2003/03/20
- Message not available
- [Freeciv-Dev] Re: (PR#3727) Rectangular selection with right-click-and-drag, rwetmore@xxxxxxxxxxxx, 2003/03/21
- Message not available
- [Freeciv-Dev] Re: (PR#3727) Rectangular selection with right-click-and-drag, a-l@xxxxxxx, 2003/03/23
- Message not available
- [Freeciv-Dev] Re: (PR#3727) Rectangular selection with right-click-and-drag, Jason Short, 2003/03/23
|
|