Fixed includes and bugs so that it compiles
[construo.git] / zoom_graphic_context.cxx
blobb1ae97844b271a56dfaba26f581b9366d092e4a8
1 // $Id: zoom_graphic_context.cxx,v 1.15 2003/07/26 00:39:31 grumbel Exp $
2 //
3 // Construo - A wire-frame construction game
4 // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
5 //
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.
20 #include <iostream>
21 #include <assert.h>
22 #include "construo.hxx"
23 #include "math.hxx"
24 #include "root_graphic_context.hxx"
25 #include "zoom_graphic_context.hxx"
27 ZoomGraphicContext::ZoomGraphicContext ()
29 x_offset = 0.0f;
30 y_offset = 0.0f;
31 zoom = 1.0f;
33 x1 = y1 = 0;
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_)
40 : x1 (x1_),
41 y1 (y1_),
42 x2 (x2_),
43 y2 (y2_)
45 x_offset = 0;
46 y_offset = 0;
47 zoom = 1.0f;
48 parent_gc = NULL;
51 void
52 ZoomGraphicContext::set_clip_rect (int x1_, int y1_, int x2_, int y2_)
54 parent_gc->set_clip_rect (x1_, y1_, x2_, y2_);
57 void
58 ZoomGraphicContext::lock ()
60 parent_gc->set_clip_rect (x1, y1, x2, y2);
63 void
64 ZoomGraphicContext::unlock ()
66 parent_gc->set_clip_rect (0, 0, parent_gc->get_width ()-1, parent_gc->get_height()-1);
69 Vector2d
70 ZoomGraphicContext::screen_to_world (const Vector2d& pos)
72 return Vector2d ((pos.x / zoom) - x_offset,
73 (pos.y / zoom) - y_offset);
76 Vector2d
77 ZoomGraphicContext::world_to_screen (const Vector2d& pos)
79 return Vector2d ((pos.x + x_offset) * zoom + x1,
80 (pos.y + y_offset) * zoom + y1);
83 float
84 ZoomGraphicContext::screen_to_world_x (float x)
86 return (x / zoom) - x_offset;
89 float
90 ZoomGraphicContext::screen_to_world_y (float y)
92 return (y / zoom) - y_offset;
95 float
96 ZoomGraphicContext::world_to_screen_x (float x)
98 return (x + x_offset) * zoom + x1;
101 float
102 ZoomGraphicContext::world_to_screen_y (float y)
104 return (y + y_offset) * zoom + y1;
107 void
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);
120 void
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),
127 color, wide);
130 void
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),
137 color);
140 void
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);
153 void
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),
159 color);
162 void
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),
168 color);
171 void
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),
178 color);
181 void
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),
186 str,
187 color);
190 void
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),
195 str,
196 color);
199 void
200 ZoomGraphicContext::set_parent_gc (GraphicContext* gc)
202 parent_gc = gc;
205 bool
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;
214 if (1)
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;
222 else
224 x_offset = (x + x_offset)/1.2f - x;
225 y_offset = (y + y_offset)/1.2f - y;
226 zoom *= 1.2f;
229 return true;
232 bool
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);
238 if (1)
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;
245 else
247 x_offset = (x + x_offset)*1.2f - x;
248 y_offset = (y + y_offset)*1.2f - y;
250 zoom *= (1.0f/1.2f);
253 return true;
256 void
257 ZoomGraphicContext::move_to (float x, float y)
259 x_offset = (get_width() / (2*zoom)) + x;
260 y_offset = (get_height() / (2*zoom)) + y;
263 void
264 ZoomGraphicContext::translate_offset (int x, int y)
266 x_offset -= x;
267 y_offset -= y;
270 void
271 ZoomGraphicContext::set_offset (float x, float y)
273 x_offset = x;
274 y_offset = y;
277 void
278 ZoomGraphicContext::flip (int x1, int y1, int x2, int y2)
280 assert (false);
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));*/
287 bool
288 ZoomGraphicContext::set_zoom (const float& z)
290 const float max_zoom = 20.0f;
291 const float min_zoom = 0.05f;
293 if (z > max_zoom)
295 zoom = max_zoom;
296 return false;
298 else if (z < min_zoom)
300 zoom = min_zoom;
301 return false;
303 else
305 zoom = z;
306 return true;
310 void
311 ZoomGraphicContext::zoom_to (int x1, int y1, int x2, int y2)
313 //std::cout << "Zooming to: " << x1 << " " << y1 << " " << x2 << " " << y2
314 //<< std::endl;
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 ()
341 return x2 - x1;
345 ZoomGraphicContext::get_height ()
347 return y2 - y1;
350 /* EOF */