1 // $Id: zoom_graphic_context.cxx,v 1.15 2003/07/26 00:39:31 grumbel Exp $
3 // Construo - A wire-frame construction game
4 // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "construo.hxx"
24 #include "root_graphic_context.hxx"
25 #include "zoom_graphic_context.hxx"
27 ZoomGraphicContext::ZoomGraphicContext ()
34 // FIXME: should use parent gc
35 x2
= graphic_context
->get_width();
36 y2
= graphic_context
->get_height();
39 ZoomGraphicContext::ZoomGraphicContext (int x1_
, int y1_
, int x2_
, int y2_
)
52 ZoomGraphicContext::set_clip_rect (int x1_
, int y1_
, int x2_
, int y2_
)
54 parent_gc
->set_clip_rect (x1_
, y1_
, x2_
, y2_
);
58 ZoomGraphicContext::lock ()
60 parent_gc
->set_clip_rect (x1
, y1
, x2
, y2
);
64 ZoomGraphicContext::unlock ()
66 parent_gc
->set_clip_rect (0, 0, parent_gc
->get_width ()-1, parent_gc
->get_height()-1);
70 ZoomGraphicContext::screen_to_world (const Vector2d
& pos
)
72 return Vector2d ((pos
.x
/ zoom
) - x_offset
,
73 (pos
.y
/ zoom
) - y_offset
);
77 ZoomGraphicContext::world_to_screen (const Vector2d
& pos
)
79 return Vector2d ((pos
.x
+ x_offset
) * zoom
+ x1
,
80 (pos
.y
+ y_offset
) * zoom
+ y1
);
84 ZoomGraphicContext::screen_to_world_x (float x
)
86 return (x
/ zoom
) - x_offset
;
90 ZoomGraphicContext::screen_to_world_y (float y
)
92 return (y
/ zoom
) - y_offset
;
96 ZoomGraphicContext::world_to_screen_x (float x
)
98 return (x
+ x_offset
) * zoom
+ x1
;
102 ZoomGraphicContext::world_to_screen_y (float y
)
104 return (y
+ y_offset
) * zoom
+ y1
;
108 ZoomGraphicContext::draw_lines (std::vector
<Line
>& lines
, Color color
, int wide
)
110 for (std::vector
<Line
>::iterator i
= lines
.begin(); i
!= lines
.end(); ++i
)
112 i
->x1
= world_to_screen_x(i
->x1
);
113 i
->y1
= world_to_screen_y(i
->y1
);
114 i
->x2
= world_to_screen_x(i
->x2
);
115 i
->y2
= world_to_screen_y(i
->y2
);
117 parent_gc
->draw_lines (lines
, color
, wide
);
121 ZoomGraphicContext::draw_line(float x1
, float y1
, float x2
, float y2
, Color color
, int wide
)
123 parent_gc
->draw_line(world_to_screen_x(x1
),
124 world_to_screen_y(y1
),
125 world_to_screen_x(x2
),
126 world_to_screen_y(y2
),
131 ZoomGraphicContext::draw_rect(float x1
, float y1
, float x2
, float y2
, Color color
)
133 parent_gc
->draw_rect(world_to_screen_x(x1
),
134 world_to_screen_y(y1
),
135 world_to_screen_x(x2
),
136 world_to_screen_y(y2
),
141 ZoomGraphicContext::draw_circles(std::vector
<Circle
>& circles
, Color color
)
143 for (std::vector
<Circle
>::iterator i
= circles
.begin(); i
!= circles
.end(); ++i
)
145 i
->x
= world_to_screen_x(i
->x
);
146 i
->y
= world_to_screen_x(i
->y
);
147 i
->r
= Math::max(2.0f
, i
->r
* zoom
);
150 parent_gc
->draw_circles(circles
, color
);
154 ZoomGraphicContext::draw_circle(float x
, float y
, float r
, Color color
)
156 parent_gc
->draw_circle(world_to_screen_x(x
),
157 world_to_screen_y(y
),
158 Math::max(2.0f
, r
* zoom
),
163 ZoomGraphicContext::draw_fill_circle(float x
, float y
, float r
, Color color
)
165 parent_gc
->draw_fill_circle(world_to_screen_x(x
),
166 world_to_screen_y(y
),
167 Math::max(2.0f
, r
* zoom
),
172 ZoomGraphicContext::draw_fill_rect(float x1
, float y1
, float x2
, float y2
, Color color
)
174 parent_gc
->draw_fill_rect(world_to_screen_x(x1
),
175 world_to_screen_y(y1
),
176 world_to_screen_x(x2
),
177 world_to_screen_y(y2
),
182 ZoomGraphicContext::draw_string_centered(float x
, float y
, const std::string
& str
, Color color
)
184 parent_gc
->draw_string_centered(world_to_screen_x(x
),
185 world_to_screen_y(y
),
191 ZoomGraphicContext::draw_string(float x
, float y
, const std::string
& str
, Color color
)
193 parent_gc
->draw_string(world_to_screen_x(x
),
194 world_to_screen_y(y
),
200 ZoomGraphicContext::set_parent_gc (GraphicContext
* gc
)
206 ZoomGraphicContext::zoom_in (int screen_x
, int screen_y
)
208 float x
= screen_to_world_x (screen_x
);
209 float y
= screen_to_world_y (screen_y
);
211 //std::cout << "Zoom: " << screen_x << " " << screen_y
212 //<< " " << x << " " << y << std::endl;
216 float old_zoom
= zoom
;
217 set_zoom(zoom
* 1.2f
);
218 x_offset
= screen_x
/zoom
- screen_x
/old_zoom
+ x_offset
;
219 y_offset
= screen_y
/zoom
- screen_y
/old_zoom
+ y_offset
;
224 x_offset
= (x
+ x_offset
)/1.2f
- x
;
225 y_offset
= (y
+ y_offset
)/1.2f
- y
;
233 ZoomGraphicContext::zoom_out (int screen_x
, int screen_y
)
235 float x
= screen_to_world_x (screen_x
);
236 float y
= screen_to_world_y (screen_y
);
240 float old_zoom
= zoom
;
241 set_zoom(zoom
/ 1.2f
);
242 x_offset
= screen_x
/zoom
- screen_x
/old_zoom
+ x_offset
;
243 y_offset
= screen_y
/zoom
- screen_y
/old_zoom
+ y_offset
;
247 x_offset
= (x
+ x_offset
)*1.2f
- x
;
248 y_offset
= (y
+ y_offset
)*1.2f
- y
;
257 ZoomGraphicContext::move_to (float x
, float y
)
259 x_offset
= (get_width() / (2*zoom
)) + x
;
260 y_offset
= (get_height() / (2*zoom
)) + y
;
264 ZoomGraphicContext::translate_offset (int x
, int y
)
271 ZoomGraphicContext::set_offset (float x
, float y
)
278 ZoomGraphicContext::flip (int x1
, int y1
, int x2
, int y2
)
281 /* parent_gc->flip (world_to_screen_x (x1),
282 world_to_screen_y (y1),
283 world_to_screen_x (x2),
284 world_to_screen_y (y2));*/
288 ZoomGraphicContext::set_zoom (const float& z
)
290 const float max_zoom
= 20.0f
;
291 const float min_zoom
= 0.05f
;
298 else if (z
< min_zoom
)
311 ZoomGraphicContext::zoom_to (int x1
, int y1
, int x2
, int y2
)
313 //std::cout << "Zooming to: " << x1 << " " << y1 << " " << x2 << " " << y2
316 float center_x
= (x1
+ x2
) / 2.0f
;
317 float center_y
= (y1
+ y2
) / 2.0f
;
319 float width
= x2
- x1
;
320 float height
= y2
- y1
;
321 float screen_relation
= float(get_height())/float(get_width ());
322 float rect_relation
= height
/width
;
324 //std::cout << "Screen: " << screen_relation << " Zoom: " << rect_relation << std::endl;
325 if (rect_relation
< screen_relation
) // take width, ignore height
327 set_zoom(get_width()/width
);
329 else // take height, ignore width
331 set_zoom(get_height()/height
);
334 x_offset
= (get_width() / (2*zoom
)) - center_x
;
335 y_offset
= (get_height() / (2*zoom
)) - center_y
;
339 ZoomGraphicContext::get_width ()
345 ZoomGraphicContext::get_height ()