From: Mikko Rasa Date: Mon, 6 May 2013 18:38:20 +0000 (+0300) Subject: Make designer work on generic objects X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=f950f5a77714a155e57c868101911e181a617818;p=r2c2.git Make designer work on generic objects This introduces a lot of dynamic_casts and other ugliness, since not all operations are generalized yet. They'll be worked out in the near future. --- diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index da89771..edbec38 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -198,7 +198,7 @@ void Designer::erase_tracks() if(mode!=SELECT) return; - set tracks = selection.get_tracks(); + set tracks = selection.get_objects(); selection.clear(); for(set::iterator i=tracks.begin(); i!=tracks.end(); ++i) { @@ -278,7 +278,7 @@ void Designer::add_selection_to_route() try { - cur_route->add_tracks(selection.get_tracks()); + cur_route->add_tracks(selection.get_objects()); } catch(const exception &e) { @@ -317,7 +317,7 @@ void Designer::add_selection_to_zone() try { - cur_zone->add_tracks(selection.get_tracks()); + cur_zone->add_tracks(selection.get_objects()); } catch(const exception &e) { @@ -412,7 +412,7 @@ void Designer::key_press(unsigned key) erase_tracks(); else if(key==Msp::Input::KEY_F && shift) { - const set &tracks = selection.get_tracks(); + const set &tracks = selection.get_objects(); const set <racks = layout->get_tracks(); for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) { @@ -457,14 +457,14 @@ void Designer::button_press(unsigned btn) { if(btn==1) { - Track *ctrack = pick_track(pointer); - if(ctrack) + Object *cobj = pick_object(pointer); + if(cobj) { - Track *track = new Track(*layout, ctrack->get_type()); - track->set_position(ground); + Object *obj = cobj->clone(layout); + obj->set_position(ground); selection.clear(); - selection.add_track(track); + selection.add_object(obj); mode = SELECT; } @@ -476,12 +476,12 @@ void Designer::button_press(unsigned btn) { if(btn==1) { - Track *track = pick_track(pointer); - if(track) + Object *obj = pick_object(pointer); + if(obj) { if(!shift) selection.clear(); - selection.toggle_track(track); + selection.toggle_object(obj); } } } @@ -526,13 +526,13 @@ void Designer::track_removed(Track &trk) new_tracks.erase(i); } -Track *Designer::pick_track(const Vector &pointer) +Object *Designer::pick_object(const Vector &pointer) { View3D &view = *(mode==CATALOGUE ? cat_view : main_view); const GL::Vector3 &cpos = view.get_camera().get_position(); GL::Vector4 cray = view.get_camera().unproject(GL::Vector4(pointer.x, pointer.y, 0, 0)); - return view.get_layout().get_layout().pick_track(Vector(cpos.x, cpos.y, cpos.z), Vector(cray.x, cray.y, cray.z)); + return view.get_layout().get_layout().pick_object(Vector(cpos.x, cpos.y, cpos.z), Vector(cray.x, cray.y, cray.z)); } void Designer::update_track_icon(Track3D &track) @@ -559,7 +559,7 @@ void Designer::update_track_icon(Track3D &track) void Designer::selection_changed() { - const set &tracks = selection.get_tracks(); + const set &tracks = selection.get_objects(); if(tracks.empty()) lbl_status->set_text(string()); else @@ -611,7 +611,7 @@ void Designer::arrange_toolbars() void Designer::track_properties_response(int) { - const set &tracks = selection.get_tracks(); + const set &tracks = selection.get_objects(); for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) update_track_icon(layout_3d->get_track(**i)); } @@ -630,17 +630,20 @@ void Designer::svg_export_accept(const string &text) string Designer::tooltip(int x, int y) { - if(Track *track = pick_track(Vector(x*2.0f/window.get_width()-1.0f, y*2.0f/window.get_height()-1.0f, 0))) + if(Object *obj = pick_object(Vector(x*2.0f/window.get_width()-1.0f, y*2.0f/window.get_height()-1.0f, 0))) { - const TrackType &ttype = track->get_type(); - string info = format("%d %s", ttype.get_article_number(), ttype.get_description()); - if(mode!=CATALOGUE && abs(track->get_slope())>1e-4) - info += format(" (slope %.1f%%)", abs(track->get_slope()/ttype.get_total_length()*100)); - if(track->get_turnout_id()) - info += format(" (turnout %d)", track->get_turnout_id()); - else if(track->get_sensor_id()) - info += format(" (sensor %d)", track->get_sensor_id()); - + const ObjectType &otype = obj->get_type(); + string info = format("%d %s", otype.get_article_number(), otype.get_description()); + if(Track *track = dynamic_cast(obj)) + { + const TrackType &ttype = track->get_type(); + if(mode!=CATALOGUE && abs(track->get_slope())>1e-4) + info += format(" (slope %.1f%%)", abs(track->get_slope()/ttype.get_total_length()*100)); + if(track->get_turnout_id()) + info += format(" (turnout %d)", track->get_turnout_id()); + else if(track->get_sensor_id()) + info += format(" (sensor %d)", track->get_sensor_id()); + } return info; } diff --git a/source/designer/designer.h b/source/designer/designer.h index f22b25c..5dbb067 100644 --- a/source/designer/designer.h +++ b/source/designer/designer.h @@ -115,7 +115,7 @@ private: void render(); void track_added(R2C2::Track &); void track_removed(R2C2::Track &); - R2C2::Track *pick_track(const R2C2::Vector &); + R2C2::Object *pick_object(const R2C2::Vector &); void update_track_icon(R2C2::Track3D &); void selection_changed(); void manipulation_status(const std::string &); diff --git a/source/designer/manipulator.cpp b/source/designer/manipulator.cpp index 2e16311..5b95d5c 100644 --- a/source/designer/manipulator.cpp +++ b/source/designer/manipulator.cpp @@ -58,7 +58,7 @@ bool Manipulator::start_extend() cancel(); bool ok = false; - const set &stracks = selection.get_tracks(); + const set &stracks = selection.get_objects(); for(set::const_iterator i=stracks.begin(); (!ok && i!=stracks.end()); ++i) { const vector &links = (*i)->get_links(); @@ -79,23 +79,20 @@ void Manipulator::duplicate() if(mode) cancel(); - list new_tracks; - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + list new_objs; + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - Track *track = new Track(designer.get_layout(), i->track->get_type()); - track->set_position(i->track->get_position()); - track->set_rotation(i->track->get_rotation()); - new_tracks.push_back(track); + Object *obj = i->object->clone(&designer.get_layout()); + if(Track *track = dynamic_cast(obj)) + { + for(list::iterator j=new_objs.begin(); j!=new_objs.end(); ++j) + if(Track *track2 = dynamic_cast(*j)) + track->snap_to(*track2, true); + } + new_objs.push_back(obj); } - selection.clear(); - for(list::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i) - { - selection.add_track(*i); - for(list::iterator j=i; j!=new_tracks.end(); ++j) - if(j!=i) - (*i)->snap_to(**j, true); - } + selection.replace(new_objs.begin(), new_objs.end()); } void Manipulator::flatten() @@ -103,24 +100,30 @@ void Manipulator::flatten() if(mode) cancel(); - if(tracks.empty()) return; + if(objects.empty()) + return; float z = 0; - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) - z += i->track->get_position().z+i->track->get_slope()/2; - z /= tracks.size(); + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) + { + z += i->object->get_position().z; + if(Track *track = dynamic_cast(i->object)) + z += track->get_slope()/2; + } + z /= static_cast(objects.size()); - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - Vector p = i->track->get_position(); - i->track->set_position(Vector(p.x, p.y, z)); - i->track->set_slope(0); + Vector p = i->object->get_position(); + i->object->set_position(Vector(p.x, p.y, z)); + if(Track *track = dynamic_cast(i->object)) + track->set_slope(0); } for(set::iterator i=neighbors.begin(); i!=neighbors.end(); ++i) (*i)->check_slope(); - update_tracks(); + update_objects(); } void Manipulator::even_slope(bool smooth) @@ -131,13 +134,15 @@ void Manipulator::even_slope(bool smooth) if(neighbors.size()!=2) return; - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) - if(i->track->get_type().get_endpoints().size()!=2) - return; + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) + if(Track *track = dynamic_cast(i->object)) + if(track->get_type().get_endpoints().size()!=2) + return; list tracks2; - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) - tracks2.push_back(i->track); + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) + if(Track *track = dynamic_cast(i->object)) + tracks2.push_back(track); float total_len = 0; @@ -207,12 +212,20 @@ void Manipulator::even_slope(bool smooth) for(set::iterator i=neighbors.begin(); i!=neighbors.end(); ++i) (*i)->check_slope(); - update_tracks(); + update_objects(); } void Manipulator::connect() { - if(tracks.size()!=2) + if(objects.size()!=2) + { + signal_status.emit("Exactly two tracks must be selected"); + return; + } + + Track *track1 = dynamic_cast(objects.front().object); + Track *track2 = dynamic_cast(objects.back().object); + if(!track1 || !track2) { signal_status.emit("Exactly two tracks must be selected"); return; @@ -220,10 +233,8 @@ void Manipulator::connect() float limit = designer.get_layout().get_catalogue().get_gauge()/10; - Track *track1 = tracks.front().track; Vector pos1; float dir1; - Track *track2 = tracks.back().track; bool ok = false; float gap = 0; for(unsigned i=0; iget_type().get_endpoints().size(); ++i) @@ -298,10 +309,10 @@ void Manipulator::cancel() return; mode = NONE; - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - 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); + i->object->set_position(Vector(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z)); + i->object->set_rotation(i->rot); } for(set::iterator i=neighbors.begin(); i!=neighbors.end(); ++i) @@ -332,20 +343,22 @@ void Manipulator::button_press(unsigned btn) if(m!=EXTEND) { for(set::iterator i=neighbors.begin(); i!=neighbors.end(); ++i) - for(vector::iterator j=tracks.begin(); j!=tracks.end(); ++j) - j->track->break_link(**i); + for(vector::iterator j=objects.begin(); j!=objects.end(); ++j) + if(Track *track = dynamic_cast(j->object)) + track->break_link(**i); } const set <racks = designer.get_layout().get_tracks(); for(set::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) { bool ok = true; - for(vector::iterator j=tracks.begin(); (j!=tracks.end() && ok); ++j) - ok = (j->track!=*i); + for(vector::iterator j=objects.begin(); (j!=objects.end() && ok); ++j) + ok = (j->object!=*i); if(!ok) continue; - for(vector::iterator j=tracks.begin(); j!=tracks.end(); ++j) - j->track->snap_to(**i, true); + for(vector::iterator j=objects.begin(); j!=objects.end(); ++j) + if(Track *track = dynamic_cast(j->object)) + track->snap_to(**i, true); } if(m==EXTEND) @@ -355,7 +368,7 @@ void Manipulator::button_press(unsigned btn) } else { - update_tracks(); + update_objects(); update_neighbors(); } @@ -375,42 +388,44 @@ void Manipulator::axis_motion(unsigned axis, float value, float) { 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::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - 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); + i->object->set_position(Vector(offset.x+i->pos.x, offset.y+i->pos.y, offset.z+i->pos.z)); + i->object->set_rotation(i->rot); } const set <racks = designer.get_layout().get_tracks(); float limit = max(designer.get_layout().get_catalogue().get_gauge(), designer.get_camera_controller().get_view_scale()/100.0f); - MTrack *snapped = 0; + MObject *snapped = 0; for(set::const_iterator i=ltracks.begin(); (i!=ltracks.end() && !snapped); ++i) { bool ok = true; - for(vector::iterator j=tracks.begin(); (j!=tracks.end() && ok); ++j) - ok = (j->track!=*i); - if(!ok) continue; + for(vector::iterator j=objects.begin(); (j!=objects.end() && ok); ++j) + ok = (j->object!=*i); + if(!ok) + continue; - for(vector::iterator j=tracks.begin(); (j!=tracks.end() && !snapped); ++j) - if(j->track->snap_to(**i, false, limit)) - snapped = &*j; + for(vector::iterator j=objects.begin(); (j!=objects.end() && !snapped); ++j) + if(Track *track = dynamic_cast(j->object)) + if(track->snap_to(**i, false, limit)) + snapped = &*j; } if(snapped) { - float da = snapped->track->get_rotation()-snapped->rot; + float da = snapped->object->get_rotation()-snapped->rot; float c = cos(da); float s = sin(da); - const Vector &sp = snapped->track->get_position(); - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + const Vector &sp = snapped->object->get_position(); + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { if(&*i==snapped) continue; 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); + i->object->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->object->set_rotation(i->rot+da); } } } @@ -420,12 +435,12 @@ void Manipulator::axis_motion(unsigned axis, float value, float) angle += a-rot_origin; rot_origin = a; - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { float c = cos(angle); float s = sin(angle); - 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); + i->object->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->object->set_rotation(angle+i->rot); } } else if(mode==ELEVATE && axis==1) @@ -434,8 +449,8 @@ void Manipulator::axis_motion(unsigned axis, float value, float) signal_status.emit(format("Elevation: %+.0fmm (%.0fmm)", dz*1000, (center.z+dz)*1000)); - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) - i->track->set_position(Vector(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z+dz)); + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) + i->object->set_position(Vector(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z+dz)); for(set::iterator i=neighbors.begin(); i!=neighbors.end(); ++i) (*i)->check_slope(); @@ -445,16 +460,20 @@ void Manipulator::axis_motion(unsigned axis, float value, float) Vector pos; float dir = 0; float length = 0; - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - unsigned n_endpoints = i->track->get_type().get_endpoints().size(); + Track *track = dynamic_cast(i->object); + if(!track) + continue; + + unsigned n_endpoints = track->get_type().get_endpoints().size(); for(unsigned j=0; jtrack->get_link(j)) + if(track->get_link(j)) continue; - Vector ep_pos = i->track->get_endpoint_position(j); - float ep_dir = i->track->get_endpoint_direction(j); + Vector ep_pos = track->get_endpoint_position(j); + float ep_dir = track->get_endpoint_direction(j); float c = cos(ep_dir); float s = sin(ep_dir); float dx = gpointer.x-ep_pos.x; @@ -507,51 +526,80 @@ void Manipulator::selection_changed() if(mode) cancel(); - tracks.clear(); - const set &stracks = selection.get_tracks(); - tracks.insert(tracks.end(), stracks.begin(), stracks.end()); + objects.clear(); + set pending = selection.get_objects(); + while(!pending.empty()) + { + for(set::iterator i=pending.begin(); i!=pending.end(); ) + { + if((*i)->get_parent() && pending.count((*i)->get_parent())) + ++i; + else + { + objects.push_back(*i); + pending.erase(i++); + } + } + } update_neighbors(); - update_tracks(); + update_objects(); } -void Manipulator::update_tracks() +void Manipulator::update_objects() { Vector minp, maxp; - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - unsigned n_endpoints = i->track->get_type().get_endpoints().size(); - for(unsigned j=0; j(i->object)) { - Vector p = i->track->get_endpoint_position(j); - if(i==tracks.begin() && j==0) - minp = maxp = p; - else + unsigned n_endpoints = track->get_type().get_endpoints().size(); + for(unsigned j=0; jget_endpoint_position(j); + if(i==objects.begin() && j==0) + minp = maxp = p; + else + { + minp.x = min(minp.x, p.x); + maxp.x = max(maxp.x, p.x); + minp.y = min(minp.y, p.y); + maxp.y = max(maxp.y, p.y); + minp.z = min(minp.z, p.z); + } } } + else + { + const Vector &p = i->object->get_position(); + minp.x = min(minp.x, p.x); + maxp.x = max(maxp.x, p.x); + minp.y = min(minp.y, p.y); + maxp.y = max(maxp.y, p.y); + minp.z = min(minp.z, p.z); + } } center = Vector((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, minp.z); - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - 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(); + const Vector &p = i->object->get_position(); + i->pos = Vector(p.x-center.x, p.y-center.y, p.z-center.z); + i->rot = i->object->get_rotation(); } } void Manipulator::update_neighbors() { neighbors.clear(); - for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - const vector &links = i->track->get_links(); + Track *track = dynamic_cast(i->object); + if(!track) + continue; + + const vector &links = track->get_links(); for(vector::const_iterator j=links.begin(); j!=links.end(); ++j) { if(!*j) @@ -560,8 +608,8 @@ void Manipulator::update_neighbors() continue; bool ok = true; - for(vector::iterator k=tracks.begin(); (k!=tracks.end() && ok); ++k) - ok = (k->track!=*j); + for(vector::iterator k=objects.begin(); (k!=objects.end() && ok); ++k) + ok = (k->object!=*j); if(ok) neighbors.insert(*j); @@ -666,8 +714,8 @@ vector Manipulator::create_straight(const R2C2::Vector &start, float di } -Manipulator::MTrack::MTrack(Track *t): - track(t), - pos(track->get_position()), - rot(track->get_rotation()) +Manipulator::MObject::MObject(Object *o): + object(o), + pos(object->get_position()), + rot(object->get_rotation()) { } diff --git a/source/designer/manipulator.h b/source/designer/manipulator.h index b4216ee..cb4759a 100644 --- a/source/designer/manipulator.h +++ b/source/designer/manipulator.h @@ -18,13 +18,13 @@ private: EXTEND }; - struct MTrack + struct MObject { - R2C2::Track *track; + R2C2::Object *object; R2C2::Vector pos; float rot; - MTrack(R2C2::Track *); + MObject(R2C2::Object *); }; struct TrackOrder @@ -43,7 +43,7 @@ private: Designer &designer; Msp::Input::Mouse &mouse; Selection &selection; - std::vector tracks; + std::vector objects; R2C2::Vector center; R2C2::Vector pointer; @@ -72,7 +72,7 @@ private: void button_press(unsigned); void axis_motion(unsigned, float, float); void selection_changed(); - void update_tracks(); + void update_objects(); void update_neighbors(); void set_slope(TrackOrder &, float, float); std::vector create_straight(const R2C2::Vector &, float, float, float); diff --git a/source/designer/selection.cpp b/source/designer/selection.cpp index 855b41c..c93dd36 100644 --- a/source/designer/selection.cpp +++ b/source/designer/selection.cpp @@ -6,36 +6,36 @@ using namespace std; using namespace R2C2; using namespace Msp; -Track *Selection::get_track() const +Object *Selection::get_object() const { - if(tracks.empty()) + if(objects.empty()) return 0; else - return *tracks.begin(); + return *objects.begin(); } void Selection::clear() { - tracks.clear(); + objects.clear(); signal_changed.emit(); } -void Selection::add_track(Track *t) +void Selection::add_object(Object *o) { - if(tracks.insert(t).second) + if(objects.insert(o).second) signal_changed.emit(); } -void Selection::remove_track(Track *t) +void Selection::remove_object(Object *o) { - if(tracks.erase(t)) + if(objects.erase(o)) signal_changed.emit(); } -void Selection::toggle_track(Track *t) +void Selection::toggle_object(Object *o) { - if(!tracks.erase(t)) - tracks.insert(t); + if(!objects.erase(o)) + objects.insert(o); signal_changed.emit(); } @@ -43,17 +43,18 @@ void Selection::toggle_track(Track *t) void Selection::select_more() { set new_tracks; - for(set::iterator i=tracks.begin(); i!=tracks.end(); ++i) - { - const vector &links = (*i)->get_links(); - for(vector::const_iterator j=links.begin(); j!=links.end(); ++j) - if(*j) - new_tracks.insert(*j); - } + for(set::iterator i=objects.begin(); i!=objects.end(); ++i) + if(Track *track = dynamic_cast(*i)) + { + const vector &links = track->get_links(); + for(vector::const_iterator j=links.begin(); j!=links.end(); ++j) + if(*j) + new_tracks.insert(*j); + } bool changed = false; for(set::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i) - if(tracks.insert(*i).second) + if(objects.insert(*i).second) changed = true; if(changed) @@ -63,7 +64,11 @@ void Selection::select_more() void Selection::select_linked() { bool changed = false; - list queue(tracks.begin(), tracks.end()); + list queue; + for(set::iterator i=objects.begin(); i!=objects.end(); ++i) + if(Track *track = dynamic_cast(*i)) + queue.push_back(track); + while(!queue.empty()) { Track *track = queue.front(); @@ -71,19 +76,12 @@ void Selection::select_linked() const vector &links = track->get_links(); for(vector::const_iterator j=links.begin(); j!=links.end(); ++j) - if(*j && tracks.insert(*j).second) + if(*j && objects.insert(*j).second) { queue.push_back(*j); changed = true; } } - for(set::iterator i=tracks.begin(); i!=tracks.end(); ++i) - { - const vector &links = (*i)->get_links(); - for(vector::const_iterator j=links.begin(); j!=links.end(); ++j) - if(*j && tracks.insert(*j).second) - changed = true; - } if(changed) signal_changed.emit(); @@ -92,16 +90,14 @@ void Selection::select_linked() void Selection::select_blocks() { bool changed = false; - for(set::iterator i=tracks.begin(); i!=tracks.end(); ++i) - { - const set &btracks = (*i)->get_block().get_tracks(); - for(set::iterator j=btracks.begin(); j!=btracks.end(); ++j) - if(!tracks.count(*j)) - { - tracks.insert(*j); - changed = true; - } - } + for(set::iterator i=objects.begin(); i!=objects.end(); ++i) + if(Track *track = dynamic_cast(*i)) + { + const set &btracks = track->get_block().get_tracks(); + for(set::iterator j=btracks.begin(); j!=btracks.end(); ++j) + if(objects.insert(*j).second) + changed = true; + } if(changed) signal_changed.emit(); diff --git a/source/designer/selection.h b/source/designer/selection.h index acf8bf6..89f7100 100644 --- a/source/designer/selection.h +++ b/source/designer/selection.h @@ -3,7 +3,7 @@ #include #include -#include "3d/track.h" +#include "libr2c2/object.h" class Selection { @@ -11,27 +11,47 @@ public: sigc::signal signal_changed; private: - std::set tracks; + std::set objects; public: - const std::set &get_tracks() const { return tracks; } - R2C2::Track *get_track() const; - unsigned size() const { return tracks.size(); } - bool empty() const { return tracks.empty(); } + const std::set &get_objects() const { return objects; } + R2C2::Object *get_object() const; + + template + std::set get_objects() const + { + std::set result; + for(std::set::const_iterator i=objects.begin(); i!=objects.end(); ++i) + if(T *to = dynamic_cast(*i)) + result.insert(to); + return result; + } + + template + T *get_object() const + { + for(std::set::const_iterator i=objects.begin(); i!=objects.end(); ++i) + if(T *to = dynamic_cast(*i)) + return to; + return 0; + } + + unsigned size() const { return objects.size(); } + bool empty() const { return objects.empty(); } void clear(); template void replace(Iter begin, Iter end) { - tracks.clear(); - tracks.insert(begin, end); + objects.clear(); + objects.insert(begin, end); signal_changed.emit(); } - void add_track(R2C2::Track *); - void remove_track(R2C2::Track *); - void toggle_track(R2C2::Track *); + void add_object(R2C2::Object *); + void remove_object(R2C2::Object *); + void toggle_object(R2C2::Object *); void select_more(); void select_linked(); diff --git a/source/designer/trackproperties.cpp b/source/designer/trackproperties.cpp index cdb5cb0..9753849 100644 --- a/source/designer/trackproperties.cpp +++ b/source/designer/trackproperties.cpp @@ -1,5 +1,6 @@ #include #include +#include "libr2c2/track.h" #include "libr2c2/tracktype.h" #include "selection.h" #include "trackproperties.h" @@ -42,11 +43,11 @@ TrackProperties::TrackProperties(const Selection &s): if(selection.size()==1) { - if(unsigned tid = selection.get_track()->get_turnout_id()) + if(unsigned tid = selection.get_object()->get_turnout_id()) ent_turnout_id->set_text(lexical_cast(tid)); } - const set &tracks = selection.get_tracks(); + const set &tracks = selection.get_objects(); int sensor_id = -1; for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) { @@ -69,7 +70,7 @@ void TrackProperties::on_response(int code) { if(selection.size()==1) { - Track *track = selection.get_track(); + Track *track = selection.get_object(); if(track->get_type().is_turnout()) track->set_turnout_id(lexical_cast(ent_turnout_id->get_text())); } @@ -78,7 +79,7 @@ void TrackProperties::on_response(int code) if(!sensor_id_text.empty()) { unsigned sensor_id = lexical_cast(sensor_id_text); - const set &tracks = selection.get_tracks(); + const set &tracks = selection.get_objects(); for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) if(!(*i)->get_type().is_turnout()) (*i)->set_sensor_id(sensor_id); diff --git a/source/designer/trackwrap.cpp b/source/designer/trackwrap.cpp index 523c967..863434f 100644 --- a/source/designer/trackwrap.cpp +++ b/source/designer/trackwrap.cpp @@ -37,7 +37,7 @@ void TrackWrap::render(GL::Renderer &renderer, const GL::Tag &) const void TrackWrap::selection_changed() { wraps.clear(); - const set &tracks = selection.get_tracks(); + const set &tracks = selection.get_objects(); for(set::iterator i=tracks.begin(); i!=tracks.end(); ++i) { Wrap wrap;