]> git.tdb.fi Git - r2c2.git/blobdiff - source/designer/manipulator.cpp
Rename Point to Vector
[r2c2.git] / source / designer / manipulator.cpp
index e9d6b955f05619e678223200398a8ea8db3b0c85..359fbbb5e0b8d05feb884ac4ada0fb3707ebaceb 100644 (file)
@@ -1,6 +1,6 @@
 /* $Id$
 
-This file is part of the MSP Märklin suite
+This file is part of R²C²
 Copyright © 2006-2010  Mikkosoft Productions, Mikko Rasa
 Distributed under the GPL
 */
@@ -8,13 +8,13 @@ Distributed under the GPL
 #include <algorithm>
 #include <cmath>
 #include <msp/strings/formatter.h>
-#include "libmarklin/tracktype.h"
+#include "libr2c2/tracktype.h"
 #include "designer.h"
 #include "manipulator.h"
 #include "selection.h"
 
 using namespace std;
-using namespace Marklin;
+using namespace R2C2;
 using namespace Msp;
 
 Manipulator::Manipulator(Designer &d, Graphics::EventSource &es, Selection &s):
@@ -59,12 +59,26 @@ void Manipulator::start_elevate()
        mode = ELEVATE;
 }
 
-void Manipulator::start_extend()
+bool Manipulator::start_extend()
 {
        if(mode)
                cancel();
 
-       mode = EXTEND;
+       bool ok = false;
+       const set<Track *> &stracks = selection.get_tracks();
+       for(set<Track *>::const_iterator i=stracks.begin(); (!ok && i!=stracks.end()); ++i)
+       {
+               const vector<Track *> &links = (*i)->get_links();
+               for(vector<Track *>::const_iterator j=links.begin(); (!ok && j!=links.end()); ++j)
+                       ok = !*j;
+       }
+
+       if(ok)
+               mode = EXTEND;
+       else
+               signal_status.emit("No free endpoints");
+
+       return ok;
 }
 
 void Manipulator::duplicate()
@@ -105,8 +119,8 @@ void Manipulator::flatten()
 
        for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
-               Point p = i->track->get_position();
-               i->track->set_position(Point(p.x, p.y, z));
+               Vector p = i->track->get_position();
+               i->track->set_position(Vector(p.x, p.y, z));
                i->track->set_slope(0);
        }
 
@@ -211,10 +225,10 @@ void Manipulator::connect()
                return;
        }
 
-       float limit = 0.001;
+       float limit = designer.get_layout().get_catalogue().get_gauge()/10;
 
        Track *track1 = tracks.front().track;
-       Point pos1;
+       Vector pos1;
        float dir1;
        Track *track2 = tracks.back().track;
        bool ok = false;
@@ -232,7 +246,7 @@ void Manipulator::connect()
                        if(track2->get_link(j))
                                continue;
 
-                       Point pos2 = track2->get_endpoint_position(j);
+                       Vector pos2 = track2->get_endpoint_position(j);
                        float dir2 = track2->get_endpoint_direction(j);
 
                        float dz = pos2.z-pos1.z;
@@ -293,7 +307,7 @@ void Manipulator::cancel()
 
        for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
-               i->track->set_position(Point(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z));
+               i->track->set_position(Vector(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z));
                i->track->set_rotation(i->rot);
        }
 
@@ -358,20 +372,22 @@ void Manipulator::button_press(int, int, unsigned btn, unsigned)
 
 void Manipulator::pointer_motion(int x, int y)
 {
-       pointer_y = y;
-       gpointer = designer.map_pointer_to_ground(x, event_source.get_height()-1-y);
+       pointer_y = event_source.get_height()-1-y;
+       gpointer = designer.map_pointer_to_ground(x, pointer_y);
 
        if(mode==MOVE)
        {
-               Point delta(gpointer.x-move_origin.x, gpointer.y-move_origin.y, 0);
-               Point offset(center.x+delta.x, center.y+delta.y, center.z);
+               Vector delta(gpointer.x-move_origin.x, gpointer.y-move_origin.y, 0);
+               Vector offset(center.x+delta.x, center.y+delta.y, center.z);
                for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
-                       i->track->set_position(Point(offset.x+i->pos.x, offset.y+i->pos.y, offset.z+i->pos.z));
+                       i->track->set_position(Vector(offset.x+i->pos.x, offset.y+i->pos.y, offset.z+i->pos.z));
                        i->track->set_rotation(i->rot);
                }
 
                const set<Track *> &ltracks = designer.get_layout().get_tracks();
+               float limit = max(designer.get_layout().get_catalogue().get_gauge(),
+                       designer.get_camera_controller().get_view_scale()*5/event_source.get_height());
                MTrack *snapped = 0;
                for(set<Track *>::const_iterator i=ltracks.begin(); (i!=ltracks.end() && !snapped); ++i)
                {
@@ -381,7 +397,7 @@ void Manipulator::pointer_motion(int x, int y)
                        if(!ok) continue;
 
                        for(vector<MTrack>::iterator j=tracks.begin(); (j!=tracks.end() && !snapped); ++j)
-                               if(j->track->snap_to(**i, false))
+                               if(j->track->snap_to(**i, false, limit))
                                        snapped = &*j;
                }
 
@@ -390,14 +406,14 @@ void Manipulator::pointer_motion(int x, int y)
                        float da = snapped->track->get_rotation()-snapped->rot;
                        float c = cos(da);
                        float s = sin(da);
-                       const Point &sp = snapped->track->get_position();
+                       const Vector &sp = snapped->track->get_position();
                        for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                        {
                                if(&*i==snapped)
                                        continue;
 
-                               Point dp(i->pos.x-snapped->pos.x, i->pos.y-snapped->pos.y, 0);
-                               i->track->set_position(Point(sp.x+c*dp.x-s*dp.y, sp.y+s*dp.x+c*dp.y, sp.z+i->pos.z-snapped->pos.z));
+                               Vector dp(i->pos.x-snapped->pos.x, i->pos.y-snapped->pos.y, 0);
+                               i->track->set_position(Vector(sp.x+c*dp.x-s*dp.y, sp.y+s*dp.x+c*dp.y, sp.z+i->pos.z-snapped->pos.z));
                                i->track->set_rotation(i->rot+da);
                        }
                }
@@ -412,25 +428,25 @@ void Manipulator::pointer_motion(int x, int y)
                {
                        float c = cos(angle);
                        float s = sin(angle);
-                       i->track->set_position(Point(center.x+c*i->pos.x-s*i->pos.y, center.y+s*i->pos.x+c*i->pos.y, center.z+i->pos.z));
+                       i->track->set_position(Vector(center.x+c*i->pos.x-s*i->pos.y, center.y+s*i->pos.x+c*i->pos.y, center.z+i->pos.z));
                        i->track->set_rotation(angle+i->rot);
                }
        }
        else if(mode==ELEVATE)
        {
-               float dz = (y-elev_origin)/1000.;
+               float dz = (pointer_y-elev_origin)/1000.;
 
                signal_status.emit(format("Elevation: %+.0fmm (%.0fmm)", dz*1000, (center.z+dz)*1000));
 
                for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
-                       i->track->set_position(Point(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z+dz));
+                       i->track->set_position(Vector(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z+dz));
 
                for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
                        (*i)->check_slope();
        }
        else if(mode==EXTEND)
        {
-               Point pos;
+               Vector pos;
                float dir = 0;
                float length = 0;
                for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
@@ -441,7 +457,7 @@ void Manipulator::pointer_motion(int x, int y)
                                if(i->track->get_link(j))
                                        continue;
 
-                               Point ep_pos = i->track->get_endpoint_position(j);
+                               Vector ep_pos = i->track->get_endpoint_position(j);
                                float ep_dir = i->track->get_endpoint_direction(j);
                                float c = cos(ep_dir);
                                float s = sin(ep_dir);
@@ -493,13 +509,13 @@ void Manipulator::selection_changed()
 
 void Manipulator::update_tracks()
 {
-       Point minp, maxp;
+       Vector minp, maxp;
        for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                unsigned n_endpoints = i->track->get_type().get_endpoints().size();
                for(unsigned j=0; j<n_endpoints; ++j)
                {
-                       Point p = i->track->get_endpoint_position(j);
+                       Vector p = i->track->get_endpoint_position(j);
                        if(i==tracks.begin() && j==0)
                                minp = maxp = p;
                        else
@@ -513,11 +529,11 @@ void Manipulator::update_tracks()
                }
        }
 
-       center = Point((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, minp.z);
+       center = Vector((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, minp.z);
        for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
-               const Point &tp = i->track->get_position();
-               i->pos = Point(tp.x-center.x, tp.y-center.y, tp.z-center.z);
+               const Vector &tp = i->track->get_position();
+               i->pos = Vector(tp.x-center.x, tp.y-center.y, tp.z-center.z);
                i->rot = i->track->get_rotation();
        }
 }
@@ -547,20 +563,20 @@ void Manipulator::update_neighbors()
 
 void Manipulator::set_slope(TrackOrder &track, float z, float dz)
 {
-       const Point &p = track.track->get_position();
+       const Vector &p = track.track->get_position();
        if(track.rev)
        {
-               track.track->set_position(Point(p.x, p.y, z+dz));
+               track.track->set_position(Vector(p.x, p.y, z+dz));
                track.track->set_slope(-dz);
        }
        else
        {
-               track.track->set_position(Point(p.x, p.y, z));
+               track.track->set_position(Vector(p.x, p.y, z));
                track.track->set_slope(dz);
        }
 }
 
-vector<Track *> Manipulator::create_straight(const Marklin::Point &start, float dir, float length, float limit)
+vector<Track *> Manipulator::create_straight(const R2C2::Vector &start, float dir, float length, float limit)
 {
        const Catalogue::TrackMap &track_types = designer.get_catalogue().get_tracks();
        std::map<float, const TrackType *> types_by_length;
@@ -620,7 +636,7 @@ vector<Track *> Manipulator::create_straight(const Marklin::Point &start, float
 
        if(!lengths.empty())
        {
-               Point pos = start;
+               Vector pos = start;
                float c = cos(dir);
                float s = sin(dir);
                for(vector<float>::iterator i=lengths.begin(); i!=lengths.end(); ++i)