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

worldview_select_tool.cxx

Go to the documentation of this file.
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 <[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 <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 */

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