Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

zoom_graphic_context.cxx

Go to the documentation of this file.
00001 //  $Id: zoom_graphic_context.cxx,v 1.13 2003/01/09 22:10:24 grumbel Exp $
00002 //
00003 //  Construo - A wire-frame construction game
00004 //  Copyright (C) 2002 Ingo Ruhnke <[email protected]>
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include <iostream>
00021 #include <assert.h>
00022 #include "construo.hxx"
00023 #include "math.hxx"
00024 #include "zoom_graphic_context.hxx"
00025 
00026 ZoomGraphicContext::ZoomGraphicContext ()
00027 {
00028   x_offset = 0.0f;
00029   y_offset = 0.0f;
00030   zoom = 1.0f;
00031 
00032   x1 = y1 = 0;
00033   // FIXME: should use parent gc
00034   x2 = graphic_context->get_width();
00035   y2 = graphic_context->get_height();
00036 }
00037 
00038 ZoomGraphicContext::ZoomGraphicContext (int x1_, int y1_, int x2_, int y2_)
00039   : x1 (x1_),
00040     y1 (y1_),
00041     x2 (x2_),
00042     y2 (y2_)
00043 {
00044   x_offset   = 0;
00045   y_offset   = 0;
00046   zoom       = 1.0f;
00047   parent_gc  = NULL;
00048 }
00049 
00050 void
00051 ZoomGraphicContext::set_clip_rect (int x1_, int y1_, int x2_, int y2_)
00052 {
00053   parent_gc->set_clip_rect (x1_, y1_, x2_, y2_);
00054 }
00055 
00056 void
00057 ZoomGraphicContext::lock ()
00058 {
00059   parent_gc->set_clip_rect (x1, y1, x2, y2);
00060 }
00061 
00062 void
00063 ZoomGraphicContext::unlock ()
00064 {
00065   parent_gc->set_clip_rect (0, 0, parent_gc->get_width ()-1, parent_gc->get_height()-1);
00066 }
00067 
00068 Vector2d
00069 ZoomGraphicContext::screen_to_world (const Vector2d& pos)
00070 {
00071   return Vector2d ((pos.x / zoom) - x_offset,
00072                    (pos.y / zoom) - y_offset);  
00073 }
00074 
00075 Vector2d
00076 ZoomGraphicContext::world_to_screen (const Vector2d& pos)
00077 {
00078   return Vector2d ((pos.x + x_offset) * zoom + x1,
00079                    (pos.y + y_offset) * zoom + y1);
00080 }
00081 
00082 float
00083 ZoomGraphicContext::screen_to_world_x (float x)
00084 {
00085   return (x / zoom) - x_offset;
00086 }
00087 
00088 float
00089 ZoomGraphicContext::screen_to_world_y (float y)
00090 {
00091   return (y / zoom) - y_offset;
00092 }
00093 
00094 float
00095 ZoomGraphicContext::world_to_screen_x (float x)
00096 {
00097   return (x + x_offset) * zoom + x1;
00098 }
00099 
00100 float
00101 ZoomGraphicContext::world_to_screen_y (float y) 
00102 {
00103   return (y + y_offset) * zoom + y1;
00104 }
00105 
00106 void
00107 ZoomGraphicContext::draw_lines (std::vector<Line>& lines, Color color, int wide)
00108 {
00109   for (std::vector<Line>::iterator i = lines.begin(); i != lines.end(); ++i)
00110     {
00111       i->x1 = world_to_screen_x(i->x1);
00112       i->y1 = world_to_screen_y(i->y1);
00113       i->x2 = world_to_screen_x(i->x2);
00114       i->y2 = world_to_screen_y(i->y2);
00115     }
00116   parent_gc->draw_lines (lines, color, wide);
00117 }
00118 
00119 void
00120 ZoomGraphicContext::draw_line(float x1, float y1, float x2, float y2, Color color, int wide)
00121 {
00122   parent_gc->draw_line(world_to_screen_x(x1),
00123                        world_to_screen_y(y1),
00124                        world_to_screen_x(x2),
00125                        world_to_screen_y(y2),
00126                        color, wide);
00127 }
00128 
00129 void
00130 ZoomGraphicContext::draw_rect(float x1, float y1, float x2, float y2, Color color)
00131 {
00132   parent_gc->draw_rect(world_to_screen_x(x1),
00133                        world_to_screen_y(y1),
00134                        world_to_screen_x(x2),
00135                        world_to_screen_y(y2),
00136                        color);
00137 }
00138 
00139 void
00140 ZoomGraphicContext::draw_circles(std::vector<Circle>& circles, Color color)
00141 {
00142   for (std::vector<Circle>::iterator i = circles.begin(); i != circles.end(); ++i)
00143     {
00144       i->x = world_to_screen_x(i->x);
00145       i->y = world_to_screen_x(i->y);
00146       i->r = Math::max(2.0f, i->r * zoom);
00147     }
00148   
00149   parent_gc->draw_circles(circles, color);
00150 }
00151 
00152 void
00153 ZoomGraphicContext::draw_circle(float x, float y, float r, Color color)
00154 {
00155   parent_gc->draw_circle(world_to_screen_x(x),
00156                          world_to_screen_y(y),
00157                          Math::max(2.0f, r * zoom),
00158                          color);
00159 }
00160 
00161 void
00162 ZoomGraphicContext::draw_fill_circle(float x, float y, float r, Color color)
00163 {
00164   parent_gc->draw_fill_circle(world_to_screen_x(x),
00165                               world_to_screen_y(y),
00166                               Math::max(2.0f, r * zoom),
00167                               color);
00168 }
00169   
00170 void
00171 ZoomGraphicContext::draw_fill_rect(float x1, float y1, float x2, float y2, Color color)
00172 {
00173   parent_gc->draw_fill_rect(world_to_screen_x(x1),
00174                             world_to_screen_y(y1),
00175                             world_to_screen_x(x2),
00176                             world_to_screen_y(y2),
00177                             color);
00178 }
00179 
00180 void
00181 ZoomGraphicContext::draw_string_centered(float x, float y, const std::string& str, Color color)
00182 {
00183   parent_gc->draw_string_centered(world_to_screen_x(x),
00184                                   world_to_screen_y(y),
00185                                   str,
00186                                   color);  
00187 }
00188 
00189 void
00190 ZoomGraphicContext::draw_string(float x, float y, const std::string& str, Color color)
00191 {
00192   parent_gc->draw_string(world_to_screen_x(x),
00193                          world_to_screen_y(y),
00194                          str,
00195                          color);
00196 }
00197 
00198 void
00199 ZoomGraphicContext::set_parent_gc (GraphicContext* gc)
00200 {
00201   parent_gc = gc;
00202 }
00203 
00204 bool
00205 ZoomGraphicContext::zoom_in (int screen_x, int screen_y)
00206 {
00207   float x = screen_to_world_x (screen_x);
00208   float y = screen_to_world_y (screen_y);
00209 
00210   //std::cout << "Zoom: " << screen_x << " " << screen_y
00211   //<< " " << x << " " << y << std::endl;
00212 
00213   if (1)
00214     {
00215       float old_zoom = zoom;
00216       set_zoom(zoom * 1.2f);
00217       x_offset = screen_x/zoom - screen_x/old_zoom + x_offset;
00218       y_offset = screen_y/zoom - screen_y/old_zoom + y_offset;
00219 
00220     }
00221   else
00222     {
00223       x_offset = (x + x_offset)/1.2f - x;
00224       y_offset = (y + y_offset)/1.2f - y;
00225       zoom *= 1.2f;
00226     }
00227 
00228   return true;
00229 }
00230 bool
00231 ZoomGraphicContext::zoom_out (int screen_x, int screen_y)
00232 {
00233   float x = screen_to_world_x (screen_x);
00234   float y = screen_to_world_y (screen_y);
00235 
00236   if (1)
00237     {
00238       float old_zoom = zoom;
00239       set_zoom(zoom / 1.2f);
00240       x_offset = screen_x/zoom - screen_x/old_zoom + x_offset;
00241       y_offset = screen_y/zoom - screen_y/old_zoom + y_offset;
00242     }
00243   else
00244     {
00245       x_offset = (x + x_offset)*1.2f - x;
00246       y_offset = (y + y_offset)*1.2f - y;
00247 
00248       zoom *= (1.0f/1.2f);
00249     }
00250 
00251   return true;
00252 }
00253 
00254 void
00255 ZoomGraphicContext::move_to (float x, float y)
00256 {
00257   x_offset = (get_width()  / (2*zoom)) + x;
00258   y_offset = (get_height() / (2*zoom)) + y;
00259 }
00260 
00261 void
00262 ZoomGraphicContext::translate_offset (int x, int y)
00263 {
00264   x_offset -= x;
00265   y_offset -= y;
00266 }
00267 
00268 void
00269 ZoomGraphicContext::set_offset (float x, float y)
00270 {
00271   x_offset = x;
00272   y_offset = y;
00273 }
00274 
00275 void
00276 ZoomGraphicContext::flip (int x1, int y1, int x2, int y2)
00277 {
00278   assert (false);
00279   /*  parent_gc->flip (world_to_screen_x (x1),
00280                    world_to_screen_y (y1),
00281                    world_to_screen_x (x2),
00282                    world_to_screen_y (y2));*/
00283 }
00284 
00285 bool
00286 ZoomGraphicContext::set_zoom (const float& z)
00287 {
00288   const float max_zoom = 20.0f;
00289   const float min_zoom = 0.05f;
00290   
00291   if (z > max_zoom)
00292     {
00293       zoom = max_zoom;
00294       return false;
00295     }
00296   else if (z < min_zoom)
00297     {
00298       zoom = min_zoom;
00299       return false;
00300     }
00301   else
00302     {
00303       zoom = z;
00304       return true;
00305     }
00306 }
00307 
00308 void
00309 ZoomGraphicContext::zoom_to (int x1, int y1, int x2, int y2)
00310 {
00311   //std::cout << "Zooming to: " << x1 << " " << y1 << " " << x2 << " " << y2
00312   //<< std::endl;
00313   
00314   float center_x = (x1 + x2) / 2.0f;
00315   float center_y = (y1 + y2) / 2.0f;
00316 
00317   float width  = x2 - x1;
00318   float height = y2 - y1;
00319   float screen_relation = float(get_height())/float(get_width ());
00320   float rect_relation   = height/width; 
00321   
00322   //std::cout << "Screen: " << screen_relation << " Zoom: " << rect_relation << std::endl;
00323   if (rect_relation < screen_relation) // take width, ignore height
00324     {
00325       set_zoom(get_width()/width); 
00326     }
00327   else // take height, ignore width
00328     {
00329       set_zoom(get_height()/height);
00330     }
00331 
00332   x_offset = (get_width()  / (2*zoom)) - center_x;
00333   y_offset = (get_height() / (2*zoom)) - center_y;
00334 }
00335 
00336 int
00337 ZoomGraphicContext::get_width ()
00338 {
00339   return x2 - x1;
00340 }
00341 
00342 int
00343 ZoomGraphicContext::get_height ()
00344 {
00345   return y2 - y1;
00346 }
00347 
00348 /* EOF */

Generated on Thu Jul 24 10:24:32 2003 for Construo by doxygen1.3-rc3