00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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)
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
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
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
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