]> git.tdb.fi Git - r2c2.git/blobdiff - source/designer/extendtool.cpp
Move gauge to TrackAppearance
[r2c2.git] / source / designer / extendtool.cpp
index ec4e7f685e9cb037d2b22182df965f68f8bd956d..54d3d10b8081dca2610f5f418470c6f0504f64e7 100644 (file)
@@ -7,25 +7,38 @@ using namespace std;
 using namespace Msp;
 using namespace R2C2;
 
-ExtendTool::ExtendTool(Designer &d, Input::Mouse &m, const set<Object *> &o):
-       Tool(d, m),
-       objects(o),
-       accepted(false)
+ExtendTool::ExtendTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, const set<Object *> &objects):
+       Tool(d, k, m),
+       max_preference(0)
 {
-       bool ok = false;
-       for(set<Object *>::const_iterator i=objects.begin(); (!ok && i!=objects.end()); ++i)
-               if(Track *track = dynamic_cast<Track *>(*i))
+       for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
+               if(Track *t = dynamic_cast<Track *>(*i))
                {
-                       const vector<Track *> &links = track->get_links();
-                       for(vector<Track *>::const_iterator j=links.begin(); (!ok && j!=links.end()); ++j)
-                               ok = !*j;
+                       unsigned nls = t->get_n_link_slots();
+                       for(unsigned j=0; j<nls; ++j)
+                               if(!t->get_link(j))
+                                       unlinked_endpoints.push_back(TrackIter(t, j));
                }
 
-       if(!ok)
+       if(unlinked_endpoints.empty())
        {
-               done = true;
                set_status("No free endpoints");
+               set_done(false);
        }
+
+       const Catalogue::ObjectMap &object_types = designer.get_catalogue().get_all();
+       for(Catalogue::ObjectMap::const_iterator i=object_types.begin(); i!=object_types.end(); ++i)
+               if(const TrackType *tt = dynamic_cast<const TrackType *>(i->second))
+               {
+                       const vector<TrackPart> &parts = tt->get_parts();
+                       if(parts.size()!=1)
+                               continue;
+                       if(parts.front().is_curved() || parts.front().is_dead_end())
+                               continue;
+
+                       types_by_length[parts.front().get_length()] = tt;
+                       max_preference = max(max_preference, tt->get_autofit_preference());
+               }
 }
 
 ExtendTool::~ExtendTool()
@@ -39,50 +52,31 @@ ExtendTool::~ExtendTool()
 
 void ExtendTool::connect()
 {
-       if(objects.size()!=2)
-       {
-               signal_status.emit("Exactly two tracks must be selected");
-               return;
-       }
+       float limit;
 
-       Track *track1 = dynamic_cast<Track *>(*objects.begin());
-       Track *track2 = dynamic_cast<Track *>(*--objects.end());
-       if(!track1 || !track2)
-       {
-               signal_status.emit("Exactly two tracks must be selected");
-               return;
-       }
-
-       float limit = designer.get_layout().get_catalogue().get_gauge()/10;
-
-       Snap sn1;
+       Track *start_track = 0;
+       Track *end_track = 0;
+       Snap start_sn;
        bool ok = false;
        float gap = 0;
-       unsigned nls1 = track1->get_n_link_slots();
-       unsigned nls2 = track2->get_n_link_slots();
-       for(unsigned i=0; i<nls1; ++i)
+       for(vector<TrackIter>::const_iterator i=unlinked_endpoints.begin(); i!=unlinked_endpoints.end(); ++i)
        {
-               if(track1->get_link(i))
-                       continue;
-
-               sn1 = track1->get_snap_node(i);
+               start_sn = (*i)->get_snap_node(i->entry());
+               limit = (*i)->get_type().get_appearance().get_gauge()/10;
                
-               for(unsigned j=0; j<nls2; ++j)
+               for(vector<TrackIter>::const_iterator j=i; ++j!=unlinked_endpoints.end(); )
                {
-                       if(track2->get_link(j))
-                               continue;
-
-                       Snap sn2 = track2->get_snap_node(j);
+                       Snap end_sn = (*j)->get_snap_node(j->entry());
 
-                       float dz = sn2.position.z-sn1.position.z;
+                       float dz = end_sn.position.z-start_sn.position.z;
                        if(abs(dz)>0.02)
                                continue;
 
-                       Angle adiff = wrap_balanced(sn1.rotation+Angle::half_turn()-sn2.rotation);
+                       Angle adiff = wrap_balanced(start_sn.rotation+Angle::half_turn()-end_sn.rotation);
                        if(abs(adiff).radians()>0.01)
                                continue;
 
-                       Vector delta = rotated_vector(sn2.position-sn1.position, -sn1.rotation);
+                       Vector delta = rotated_vector(end_sn.position-start_sn.position, -start_sn.rotation);
                        if(abs(delta.y)>limit)
                                continue;
 
@@ -100,64 +94,42 @@ void ExtendTool::connect()
        if(!ok)
        {
                set_status("No aligned endpoints found");
+               set_done(false);
                return;
        }
 
-       extend_tracks = create_straight(sn1.position, sn1.rotation, gap, limit);
+       extend_tracks = create_straight(start_sn.position, start_sn.rotation, gap, limit);
 
        if(extend_tracks.empty())
        {
                set_status("No connection possible");
+               set_done(false);
                return;
        }
 
-       extend_tracks.front()->link_to(*track1);
-       extend_tracks.back()->link_to(*track2);
+       extend_tracks.front()->link_to(*start_track);
+       extend_tracks.back()->link_to(*end_track);
 
-       accepted = true;
-       set_done();
+       set_done(true);
 }
 
-void ExtendTool::button_press(unsigned btn)
+void ExtendTool::pointer_motion()
 {
-       if(btn==1)
-       {
-               for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
-                       if(extend_tracks.front()->link_to(**i))
-                               break;
-               accepted = true;
-               set_done();
-       }
-       else if(btn==3)
-               set_done();
-}
-
-void ExtendTool::axis_motion(unsigned axis, float value, float rel)
-{
-       Tool::axis_motion(axis, value, rel);
-
        Vector pos;
        Angle dir;
        float length = 0;
 
-       for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
+       for(vector<TrackIter>::const_iterator i=unlinked_endpoints.begin(); i!=unlinked_endpoints.end(); ++i)
        {
-               unsigned nls = (*i)->get_n_link_slots();
-               for(unsigned j=0; j<nls; ++j)
-               {
-                       if((*i)->get_link(j))
-                               continue;
+               Snap sn = (*i)->get_snap_node(i->entry());
+               Vector delta = rotated_vector(ground_pointer-sn.position, -sn.rotation);
 
-                       Snap sn = (*i)->get_snap_node(j);
-                       Vector delta = rotated_vector(ground_pointer-sn.position, -sn.rotation);
-
-                       if(delta.x<length)
-                               continue;
+               if(delta.x<length)
+                       continue;
 
-                       pos = sn.position;
-                       dir = sn.rotation;
-                       length = delta.x;
-               }
+               pos = sn.position;
+               dir = sn.rotation;
+               length = delta.x;
        }
 
        if(length)
@@ -191,24 +163,20 @@ void ExtendTool::axis_motion(unsigned axis, float value, float rel)
        }
 }
 
-vector<Track *> ExtendTool::create_straight(const Vector &start, const Angle &dir, float length, float limit)
+void ExtendTool::finish()
 {
-       const Catalogue::TrackMap &track_types = designer.get_catalogue().get_tracks();
-       map<float, const TrackType *> types_by_length;
-       unsigned preference = 0;
-       for(Catalogue::TrackMap::const_iterator i=track_types.begin(); i!=track_types.end(); ++i)
+       if(!extend_tracks.empty())
        {
-               const vector<TrackPart> &parts = i->second->get_parts();
-               if(parts.size()!=1)
-                       continue;
-               if(parts.front().is_curved() || parts.front().is_dead_end())
-                       continue;
-
-               types_by_length[parts.front().get_length()] = i->second;
-               preference = max(preference, i->second->get_autofit_preference());
+               for(vector<TrackIter>::const_iterator i=unlinked_endpoints.begin(); i!=unlinked_endpoints.end(); ++i)
+                       if(extend_tracks.front()->link_to(**i))
+                               break;
        }
+}
 
+vector<Track *> ExtendTool::create_straight(const Vector &start, const Angle &dir, float length, float limit)
+{
        vector<float> lengths;
+       unsigned preference = max_preference;
        float removed = 0;
        while(length>limit)
        {
@@ -272,5 +240,6 @@ vector<Track *> ExtendTool::create_straight(const Vector &start, const Angle &di
 
 void ExtendTool::update_selection(Selection &sel) const
 {
-       sel.replace(extend_tracks.begin(), extend_tracks.end());
+       if(accepted)
+               sel.replace(extend_tracks.begin(), extend_tracks.end());
 }