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: worldview_select_tool.cxx,v 1.17 2003/01/11 19:07:48 grumbel Exp $ 00002 // 00003 // Construo - A wire-frame construction gamee 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 <math.h> 00021 #include "math.hxx" 00022 #include "world.hxx" 00023 #include "colors.hxx" 00024 #include "controller.hxx" 00025 #include "worldview_component.hxx" 00026 #include "particle.hxx" 00027 #include "world_gui_manager.hxx" 00028 #include "rect.hxx" 00029 #include "worldview_select_tool.hxx" 00030 00031 WorldViewSelectTool::WorldViewSelectTool () 00032 { 00033 mode = IDLE_MODE; 00034 } 00035 00036 WorldViewSelectTool::~WorldViewSelectTool () 00037 { 00038 } 00039 00040 void 00041 WorldViewSelectTool::draw_background (ZoomGraphicContext* gc) 00042 { 00043 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i) 00044 { 00045 (*i)->draw_velocity_vector (gc); 00046 (*i)->draw_highlight (gc); 00047 } 00048 } 00049 00050 void 00051 WorldViewSelectTool::draw_foreground (ZoomGraphicContext* gc) 00052 { 00053 float x = WorldViewComponent::instance()->get_gc()->screen_to_world_x (input_context->get_mouse_x ()); 00054 float y = WorldViewComponent::instance()->get_gc()->screen_to_world_y (input_context->get_mouse_y ()); 00055 00056 if (mode == GETTING_SELECTION_MODE) 00057 { 00058 gc->draw_rect (Math::min(x, click_pos.x), 00059 Math::min(y, click_pos.y), 00060 Math::max(x, click_pos.x), 00061 Math::max(y, click_pos.y), 00062 Colors::selection_rect); 00063 } 00064 00065 if (!selection.empty()) 00066 { 00067 Particle& p = **selection.begin(); 00068 Rect<float> selection_box (p.pos.x, p.pos.y, p.pos.x, p.pos.y); 00069 00070 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i) 00071 { 00072 selection_box.x1 = Math::min(selection_box.x1, (*i)->pos.x); 00073 selection_box.y1 = Math::min(selection_box.y1, (*i)->pos.y); 00074 00075 selection_box.x2 = Math::max(selection_box.x2, (*i)->pos.x); 00076 selection_box.y2 = Math::max(selection_box.y2, (*i)->pos.y); 00077 } 00078 00079 float border = 20.0f / gc->get_zoom(); 00080 gc->draw_rect (selection_box.x1 - border, selection_box.y1 - border, 00081 selection_box.x2 + border, selection_box.y2 + border, 00082 Colors::new_spring); 00083 00084 if (0) // draw selection rect 00085 { 00086 float rsize = 5.0f / gc->get_zoom(); 00087 gc->draw_fill_rect (selection_box.x1 - border - rsize, selection_box.y1 - border - rsize, 00088 selection_box.x1 - border + rsize, selection_box.y1 - border + rsize, 00089 Colors::selection_resizer); 00090 gc->draw_fill_rect (selection_box.x2 + border - rsize, selection_box.y1 - border - rsize, 00091 selection_box.x2 + border + rsize, selection_box.y1 - border + rsize, 00092 Colors::selection_resizer); 00093 gc->draw_fill_rect (selection_box.x1 - border - rsize, selection_box.y2 + border - rsize, 00094 selection_box.x1 - border + rsize, selection_box.y2 + border + rsize, 00095 Colors::selection_resizer); 00096 gc->draw_fill_rect (selection_box.x2 + border - rsize, selection_box.y2 + border - rsize, 00097 selection_box.x2 + border + rsize, selection_box.y2 + border + rsize, 00098 Colors::selection_resizer); 00099 } 00100 00101 gc->get_parent_gc()->draw_circle(gc->world_to_screen(selection.get_center ()), 00102 8.0f, Colors::selection_rect); 00103 gc->get_parent_gc()->draw_circle(gc->world_to_screen(selection.get_center ()), 00104 16.0f, Colors::selection_rect); 00105 } 00106 } 00107 00108 void 00109 WorldViewSelectTool::activate () 00110 { 00111 } 00112 00113 void 00114 WorldViewSelectTool::deactivate () 00115 { 00116 selection.clear (); 00117 } 00118 00119 void 00120 WorldViewSelectTool::on_primary_button_press (int screen_x, int screen_y) 00121 { 00122 float x = WorldViewComponent::instance()->get_gc()->screen_to_world_x (screen_x); 00123 float y = WorldViewComponent::instance()->get_gc()->screen_to_world_y (screen_y); 00124 00125 World& world = *Controller::instance()->get_world (); 00126 00127 WorldGUIManager::instance()->grab_mouse (WorldViewComponent::instance()); 00128 00129 mode = GETTING_SELECTION_MODE; 00130 00131 // If the mouse clicks on a particle from the selection, we move the selection 00132 Particle* new_current_particle = world.get_particle (x, y); 00133 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i) 00134 { 00135 if (new_current_particle == *i) 00136 { 00137 Controller::instance()->push_undo(); 00138 mode = MOVING_SELECTION_MODE; 00139 break; 00140 } 00141 } 00142 00143 // If mouse clicks into empty space, we make a new selection 00144 if (mode == GETTING_SELECTION_MODE) 00145 { 00146 selection.clear (); 00147 click_pos.x = x; 00148 click_pos.y = y; 00149 } 00150 } 00151 00152 void 00153 WorldViewSelectTool::on_primary_button_release (int x, int y) 00154 { 00155 WorldGUIManager::instance()->ungrab_mouse (WorldViewComponent::instance()); 00156 00157 if (mode == GETTING_SELECTION_MODE) 00158 { 00159 selection.select_particles(click_pos, 00160 WorldViewComponent::instance()->get_gc()->screen_to_world (Vector2d(x,y))); 00161 mode = IDLE_MODE; 00162 } 00163 else if (mode == MOVING_SELECTION_MODE) 00164 { 00165 mode = IDLE_MODE; 00166 } 00167 } 00168 00169 void 00170 WorldViewSelectTool::on_secondary_button_press (int screen_x, int screen_y) 00171 { 00172 Controller::instance()->push_undo(); 00173 00174 mode = ROTATING_SELECTION_MODE; 00175 WorldGUIManager::instance()->grab_mouse (WorldViewComponent::instance()); 00176 00177 click_pos = WorldViewComponent::instance()->get_gc()->screen_to_world(Vector2d(screen_x, screen_y)); 00178 00179 if (!selection.empty()) 00180 { 00181 rotate_center = selection.get_center(); 00182 } 00183 else 00184 { 00185 } 00186 } 00187 00188 void 00189 WorldViewSelectTool::on_secondary_button_release (int x, int y) 00190 { 00191 WorldGUIManager::instance()->ungrab_mouse (WorldViewComponent::instance()); 00192 mode = IDLE_MODE; 00193 } 00194 00195 void 00196 WorldViewSelectTool::on_delete_press (int x, int y) 00197 { 00198 Controller::instance()->push_undo(); 00199 00200 World& world = *Controller::instance()->get_world (); 00201 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i) 00202 { 00203 world.remove_particle(*i); 00204 } 00205 00206 selection.clear (); 00207 } 00208 00209 void 00210 WorldViewSelectTool::on_fix_press (int x, int y) 00211 { 00212 bool mark_all = false; 00213 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i) 00214 { 00215 if (!(*i)->get_fixed()) 00216 { 00217 mark_all = true; 00218 } 00219 } 00220 00221 if (mark_all) 00222 { 00223 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i) 00224 { 00225 (*i)->set_fixed (true); 00226 } 00227 } 00228 else 00229 { 00230 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i) 00231 { 00232 (*i)->set_fixed (!(*i)->get_fixed()); 00233 } 00234 } 00235 } 00236 00237 void 00238 WorldViewSelectTool::on_mouse_move (int screen_x, int screen_y, int of_x, int of_y) 00239 { 00240 World& world = *Controller::instance()->get_world (); 00241 00242 switch (mode) 00243 { 00244 case MOVING_SELECTION_MODE: 00245 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i) 00246 { 00247 // Will lead to round errors 00248 (*i)->pos.x += of_x / WorldViewComponent::instance()->get_gc ()->get_zoom(); 00249 (*i)->pos.y += of_y / WorldViewComponent::instance()->get_gc ()->get_zoom(); 00250 00251 std::vector<Spring*>& spring_mgr = world.get_spring_mgr(); 00252 for (std::vector<Spring*>::iterator j = spring_mgr.begin (); 00253 j != spring_mgr.end (); ++j) 00254 { 00255 if ((*j)->particles.first == *i 00256 || (*j)->particles.second == *i) 00257 { 00258 (*j)->recalc_length (); 00259 } 00260 } 00261 } 00262 break; 00263 case ROTATING_SELECTION_MODE: 00264 { 00265 Vector2d new_pos(WorldViewComponent::instance()->get_gc()->screen_to_world_x (screen_x), 00266 WorldViewComponent::instance()->get_gc()->screen_to_world_y (screen_y)); 00267 00268 float new_angle = atan2(new_pos.y - rotate_center.y, 00269 new_pos.x - rotate_center.x); 00270 float old_angle = atan2(click_pos.y - rotate_center.y, 00271 click_pos.x - rotate_center.x); 00272 float rot_angle = new_angle - old_angle; 00273 00274 selection.rotate (rot_angle, rotate_center); 00275 00276 click_pos = new_pos; 00277 } 00278 break; 00279 default: 00280 break; 00281 } 00282 } 00283 00284 void 00285 WorldViewSelectTool::on_duplicate_press (int x, int y) 00286 { 00287 selection.duplicate (); 00288 } 00289 00290 void 00291 WorldViewSelectTool::on_button_press (int button_id, int x, int y) 00292 { 00293 Vector2d pos = WorldViewComponent::instance()->get_gc()->screen_to_world(Vector2d(x, y)); 00294 00295 switch (button_id) 00296 { 00297 case BUTTON_SETVELOCITY: 00298 selection.set_velocity (pos - selection.get_center ()); 00299 break; 00300 case BUTTON_FLIP: 00301 selection.flip(); 00302 break; 00303 break; 00304 default: 00305 break; 00306 } 00307 } 00308 00309 /* EOF */