00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00211
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
00280
00281
00282
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
00312
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
00323 if (rect_relation < screen_relation)
00324 {
00325 set_zoom(get_width()/width);
00326 }
00327 else
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