This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
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 <grumbel@gmx.de> 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 */