1 // $Id: worldview_insert_tool.cxx,v 1.13 2003/07/28 09:23:46 grumbel Exp $
3 // Construo - A wire-frame construction gamee
4 // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "particle_factory.hxx"
23 #include "input_context.hxx"
24 #include "graphic_context.hxx"
26 #include "controller.hxx"
27 #include "worldview_component.hxx"
28 #include "worldview_insert_tool.hxx"
29 #include "world_gui_manager.hxx"
31 WorldViewInsertTool::WorldViewInsertTool ()
37 WorldViewInsertTool::~WorldViewInsertTool ()
42 WorldViewInsertTool::draw_background (ZoomGraphicContext
* gc
)
44 float x
= WorldViewComponent::instance()->get_gc()->screen_to_world_x (input_context
->get_mouse_x ());
45 float y
= WorldViewComponent::instance()->get_gc()->screen_to_world_y (input_context
->get_mouse_y ());
47 World
& world
= *Controller::instance()->get_world();
49 Particle
* selected_particle
= world
.get_particle (x
, y
);
50 if (selected_particle
)
52 selected_particle
->draw_highlight(gc
);
57 WorldViewInsertTool::draw_foreground (ZoomGraphicContext
* gc
)
59 World
& world
= *Controller::instance()->get_world();
61 Vector2d click_pos
= WorldViewComponent::instance()->get_gc()->screen_to_world (input_context
->get_mouse_pos ());
63 Vector2d new_particle_pos
;
65 if (WorldViewComponent::instance()->uses_grid())
66 new_particle_pos
= Vector2d(Math::round_to(click_pos
.x
, 10),
67 Math::round_to(click_pos
.y
, 10));
69 new_particle_pos
= Vector2d(click_pos
.x
, click_pos
.y
);
71 Spring
* selected_spring
= world
.get_spring (click_pos
.x
, click_pos
.y
);
75 selected_spring
->draw_highlight (gc
);
80 gc
->GraphicContext::draw_line (current_particle
->pos
, new_particle_pos
,
81 Colors::new_spring
, 2);
84 float x
= WorldViewComponent::instance()->get_gc()->screen_to_world_x(input_context
->get_mouse_x ());
85 float y
= WorldViewComponent::instance()->get_gc()->screen_to_world_y(input_context
->get_mouse_y ());
87 Particle
* selected_particle
= world
.get_particle (x
, y
);
88 if (selected_particle
)
90 selected_particle
->draw_infos (gc
);
94 gc
->draw_fill_circle(new_particle_pos
.x
,
102 WorldViewInsertTool::on_primary_button_press (int screen_x
, int screen_y
)
104 World
& world
= *Controller::instance()->get_world ();
105 float x
= WorldViewComponent::instance()->get_gc()->screen_to_world_x (screen_x
);
106 float y
= WorldViewComponent::instance()->get_gc()->screen_to_world_y (screen_y
);
108 if (current_particle
)
110 // We are going to place a second particle and convert the last an
111 // the new one with a spring
112 Particle
* new_current_particle
= world
.get_particle (x
, y
);
113 if (new_current_particle
!= current_particle
)
115 if (new_current_particle
) // connect to particles
117 world
.add_spring (current_particle
, new_current_particle
);
119 else // add a new particle and connect it with the current one
121 Vector2d new_particle_pos
;
122 if (WorldViewComponent::instance()->uses_grid())
123 new_particle_pos
= Vector2d(Math::round_to(x
, 10),
124 Math::round_to(y
, 10));
126 new_particle_pos
= Vector2d(x
, y
);
128 new_current_particle
= world
.get_particle_mgr()->add_particle(new_particle_pos
,
131 world
.add_spring (current_particle
, new_current_particle
);
133 // Lower the spring links count, since we have increased it
134 // at insertion and now connected it to a real spring, so
135 // its no longer needed
136 current_particle
->spring_links
-= 1;
138 current_particle
= 0;
140 WorldGUIManager::instance()->ungrab_mouse (WorldViewComponent::instance());
144 // We are going to create a new particle and making it the
145 // current one, so that the next click would result in a new
147 current_particle
= world
.get_particle (x
, y
);
149 if (current_particle
)
151 // We have clicked on a particle and made it the current
155 Vector2d new_particle_pos
;
157 if (WorldViewComponent::instance()->uses_grid())
158 new_particle_pos
= Vector2d(Math::round_to(x
, 10),
159 Math::round_to(y
, 10));
161 new_particle_pos
= Vector2d(x
, y
);
163 Particle
* p
= world
.get_particle_mgr()->add_particle(new_particle_pos
,
166 current_particle
= p
;
167 // Increase the spring count so that the particle isn't cleaned up
168 current_particle
->spring_links
+= 1;
169 WorldGUIManager::instance()->grab_mouse (WorldViewComponent::instance());
175 WorldViewInsertTool::on_primary_button_release (int x
, int y
)
180 WorldViewInsertTool::on_secondary_button_press (int screen_x
, int screen_y
)
182 on_delete_press (screen_x
, screen_y
);
186 WorldViewInsertTool::on_secondary_button_release (int screen_x
, int screen_y
)
191 WorldViewInsertTool::on_delete_press (int screen_x
, int screen_y
)
193 World
& world
= *Controller::instance()->get_world ();
195 float x
= WorldViewComponent::instance()->get_gc()->screen_to_world_x (screen_x
);
196 float y
= WorldViewComponent::instance()->get_gc()->screen_to_world_y (screen_y
);
198 if (current_particle
)
199 { // We are currently creating a new spring, abort that
200 current_particle
->spring_links
-= 1;
201 current_particle
= 0;
202 WorldGUIManager::instance()->ungrab_mouse (WorldViewComponent::instance());
206 Spring
* spring
= world
.get_spring (x
, y
);
207 Particle
* particle
= world
.get_particle (x
, y
);
211 Controller::instance()->push_undo();
212 world
.remove_particle (particle
);
216 Controller::instance()->push_undo();
217 world
.remove_spring(spring
);
223 WorldViewInsertTool::on_fix_press (int screen_x
, int screen_y
)
225 float x
= WorldViewComponent::instance()->get_gc()->screen_to_world_x (screen_x
);
226 float y
= WorldViewComponent::instance()->get_gc()->screen_to_world_y (screen_y
);
228 Particle
* particle
= Controller::instance()->get_world ()->get_particle (x
, y
);
231 particle
->set_fixed (!particle
->get_fixed ());