--- /dev/null
+#include "libr2c2/layout.h"
+#include "designer.h"
+#include "movetool.h"
+
+using namespace std;
+using namespace Msp;
+using namespace R2C2;
+
+MoveTool::MoveTool(Designer &d, Input::Mouse &m, const set<Object *> &o):
+ Manipulator(d, m, o),
+ origin(ground_pointer)
+{ }
+
+void MoveTool::axis_motion(unsigned axis, float value, float rel)
+{
+ Manipulator::axis_motion(axis, value, rel);
+
+ Vector offset = center+ground_pointer-origin;
+ for(vector<MObject>::iterator i=objects.begin(); i!=objects.end(); ++i)
+ {
+ i->object->set_position(offset+i->original_position);
+ i->object->set_rotation(i->original_rotation);
+ }
+
+ const set<Track *> <racks = designer.get_layout().get_all<Track>();
+ float limit = max(designer.get_layout().get_catalogue().get_gauge(),
+ designer.get_camera_controller().get_view_scale()/100.0f);
+ MObject *snapped = 0;
+ for(set<Track *>::const_iterator i=ltracks.begin(); (i!=ltracks.end() && !snapped); ++i)
+ {
+ bool ok = true;
+ for(ObjectArray::iterator j=objects.begin(); (j!=objects.end() && ok); ++j)
+ ok = (j->object!=*i);
+ if(!ok)
+ continue;
+
+ for(ObjectArray::iterator j=objects.begin(); (j!=objects.end() && !snapped); ++j)
+ if(j->object->snap_to(**i, limit))
+ snapped = &*j;
+ }
+
+ if(snapped)
+ {
+ Angle da = snapped->object->get_rotation()-snapped->original_rotation;
+ Transform trans = Transform::rotation(da, Vector(0, 0, 1));
+ const Vector &sp = snapped->object->get_position();
+ for(ObjectArray::iterator i=objects.begin(); i!=objects.end(); ++i)
+ {
+ if(&*i==snapped)
+ continue;
+
+ i->object->set_position(sp+trans.transform(i->original_position-snapped->original_position));
+ i->object->set_rotation(i->original_rotation+da);
+ }
+ }
+}