From: Mikko Rasa Date: Fri, 15 Oct 2010 17:32:53 +0000 (+0000) Subject: Do not require unique names for routes X-Git-Url: http://git.tdb.fi/?p=r2c2.git;a=commitdiff_plain;h=707a611dae600333f3a9bd6421176f242fe49907 Do not require unique names for routes Support renaming routes Add delete and rename buttons for routes in designer's toolbar --- diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index 396cb07..7fbab1f 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -86,6 +86,7 @@ Designer::Designer(int argc, char **argv): pipeline->add_renderable_for_pass(layout_3d->get_scene(), 0); if(base_object) pipeline->add_renderable_for_pass(*base_object, 0); + pipeline->add_renderable_for_pass(layout_3d->get_path_scene(), "unlit"); pipeline->add_renderable_for_pass(layout_3d->get_endpoint_scene(), "unlit"); light.set_position(0, -0.259, 0.966, 0); @@ -129,6 +130,8 @@ Designer::Designer(int argc, char **argv): const list &tracks = layout_3d->get_tracks(); for(list::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) update_track_icon(**i); + + edit_route(0); } Designer::~Designer() @@ -202,12 +205,18 @@ void Designer::set_sensor_id() } } -void Designer::edit_route(Route &r) +void Designer::rename_route() { if(!cur_route) - pipeline->add_renderable_for_pass(layout_3d->get_path_scene(), "unlit"); + return; + + InputDialog *input = new InputDialog(*this, "Route name", cur_route->get_name()); + input->signal_accept.connect(sigc::mem_fun(this, &Designer::route_name_accept)); +} - cur_route = &r; +void Designer::edit_route(Route *r) +{ + cur_route = r; show_route(r); } @@ -227,7 +236,7 @@ void Designer::add_selection_to_route() IO::print("%s\n", e.what()); } - show_route(*cur_route); + show_route(cur_route); } Point Designer::map_pointer_coords(int x, int y) @@ -545,6 +554,12 @@ void Designer::sensor_id_accept(const string &text) } } +void Designer::route_name_accept(const string &text) +{ + if(cur_route) + cur_route->set_name(text); +} + void Designer::view_all() { Point minp; @@ -590,20 +605,19 @@ string Designer::tooltip(int x, int y) return string(); } -void Designer::show_route(const Route &route) +void Designer::show_route(const Route *route) { const set <racks = layout->get_tracks(); - const set &rtracks = route.get_tracks(); for(set::iterator i=ltracks.begin(); i!=ltracks.end(); ++i) { Track3D &t3d = layout_3d->get_track(**i); - if(rtracks.count(*i)) + if(route && route->get_tracks().count(*i)) { t3d.get_path().set_color(GL::Color(0.5, 0.8, 1.0)); if((*i)->get_type().is_turnout()) { unsigned tid = (*i)->get_turnout_id(); - int path = (tid ? route.get_turnout(tid) : -1); + int path = (tid ? route->get_turnout(tid) : -1); if(path>=0) t3d.get_path().set_path(path); else diff --git a/source/designer/designer.h b/source/designer/designer.h index 5d22afb..5cb0c78 100644 --- a/source/designer/designer.h +++ b/source/designer/designer.h @@ -91,8 +91,9 @@ public: void new_track(); void set_turnout_id(); void set_sensor_id(); + void rename_route(); - void edit_route(Marklin::Route &); + void edit_route(Marklin::Route *); Marklin::Route *get_current_route() const { return cur_route; } void add_selection_to_route(); @@ -112,9 +113,10 @@ private: void measure_done(); void turnout_id_accept(const std::string &); void sensor_id_accept(const std::string &); + void route_name_accept(const std::string &); void view_all(); std::string tooltip(int, int); - void show_route(const Marklin::Route &); + void show_route(const Marklin::Route *); }; #endif diff --git a/source/designer/toolbar.cpp b/source/designer/toolbar.cpp index ee990dd..ec18adb 100644 --- a/source/designer/toolbar.cpp +++ b/source/designer/toolbar.cpp @@ -20,7 +20,7 @@ Toolbar::Toolbar(Designer &d): GLtk::Panel(d.get_ui_resources()), designer(d) { - set_size(410, 40); + set_size(640, 40); GLtk::Button *btn; GLtk::Label *lbl; @@ -40,7 +40,7 @@ Toolbar::Toolbar(Designer &d): btn->set_tooltip("Exit Designer"); btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::quit)); - add(*(btn=new GLtk::Button(res, "NewT"))); + add(*(btn=new GLtk::Button(res, "+Trk"))); btn->set_geometry(GLtk::Geometry(135, 10, 40, 24)); btn->set_tooltip("Add a track piece"); btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::new_track)); @@ -59,18 +59,33 @@ Toolbar::Toolbar(Designer &d): lbl->set_geometry(GLtk::Geometry(265, 22, 40, 13)); add(*(drp_routes=new GLtk::Dropdown(res))); - drp_routes->set_geometry(GLtk::Geometry(265, 5, 100, 17)); + drp_routes->set_geometry(GLtk::Geometry(265, 5, 250, 17)); drp_routes->set_tooltip("Select route to edit"); drp_routes->append("(new route)"); drp_routes->signal_item_selected.connect(sigc::mem_fun(this, &Toolbar::route_selected)); - add(*(btn=new GLtk::Button(res, "AddT"))); - btn->set_geometry(GLtk::Geometry(365, 10, 40, 24)); + add(*(btn=new GLtk::Button(res, "Del"))); + btn->set_geometry(GLtk::Geometry(515, 10, 40, 24)); + btn->set_tooltip("Delete the current route"); + btn->signal_clicked.connect(sigc::mem_fun(this, &Toolbar::delete_route_clicked)); + + add(*(btn=new GLtk::Button(res, "Name"))); + btn->set_geometry(GLtk::Geometry(555, 10, 40, 24)); + btn->set_tooltip("Rename the current route"); + btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::rename_route)); + + add(*(btn=new GLtk::Button(res, "Add"))); + btn->set_geometry(GLtk::Geometry(595, 10, 40, 24)); btn->set_tooltip("Add selected tracks to current route"); btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_route)); - designer.get_layout()->signal_route_added.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes))); + designer.get_layout()->signal_route_added.connect(sigc::mem_fun(this, &Toolbar::route_added)); designer.get_layout()->signal_route_removed.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes))); + + const set &routes = designer.get_layout()->get_routes(); + for(set::const_iterator i=routes.begin(); i!=routes.end(); ++i) + (*i)->signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes))); + update_routes(); } @@ -79,36 +94,50 @@ void Toolbar::route_selected(unsigned index, const string &) if(index==drp_routes->get_n_items()-1) { Layout &layout = *designer.get_layout(); - Route *route = new Route(layout, format("Route %d", layout.get_routes().size()+1)); - designer.edit_route(*route); + const set &routes = designer.get_layout()->get_routes(); + Route *route = new Route(layout); + route->set_name(format("Route %d", routes.size())); + designer.edit_route(route); - const map &routes = designer.get_layout()->get_routes(); int selected = -1; unsigned n = 0; - for(map::const_iterator i=routes.begin(); (selected<0 && i!=routes.end()); ++i, ++n) - if(i->second==route) + for(set::const_iterator i=routes.begin(); (selected<0 && i!=routes.end()); ++i, ++n) + if(*i==route) selected = n; drp_routes->set_selected_index(selected); } else { - const map &routes = designer.get_layout()->get_routes(); - map::const_iterator i = routes.begin(); + const set &routes = designer.get_layout()->get_routes(); + set::const_iterator i = routes.begin(); advance(i, index); - designer.edit_route(*i->second); + designer.edit_route(*i); } } +void Toolbar::delete_route_clicked() +{ + Route *route = designer.get_current_route(); + designer.edit_route(0); + delete route; +} + +void Toolbar::route_added(Route &r) +{ + r.signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes))); + update_routes(); +} + void Toolbar::update_routes() { drp_routes->clear(); - const map &routes = designer.get_layout()->get_routes(); + const set &routes = designer.get_layout()->get_routes(); int selected = -1; unsigned n = 0; - for(map::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n) + for(set::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n) { - drp_routes->append(i->second->get_name()); - if(i->second==designer.get_current_route()) + drp_routes->append((*i)->get_name()); + if(*i==designer.get_current_route()) selected = n; } drp_routes->append("(new route)"); diff --git a/source/designer/toolbar.h b/source/designer/toolbar.h index a41f968..2a935d3 100644 --- a/source/designer/toolbar.h +++ b/source/designer/toolbar.h @@ -11,6 +11,7 @@ Distributed under the GPL #include #include #include +#include "libmarklin/route.h" class Designer; @@ -24,6 +25,8 @@ public: Toolbar(Designer &); private: void route_selected(unsigned, const std::string &); + void delete_route_clicked(); + void route_added(Marklin::Route &); void update_routes(); }; diff --git a/source/engineer/routeselect.cpp b/source/engineer/routeselect.cpp index c285f35..6cda460 100644 --- a/source/engineer/routeselect.cpp +++ b/source/engineer/routeselect.cpp @@ -30,13 +30,13 @@ RouteSelect::RouteSelect(Engineer &e, const GLtk::Resources &r, Train &t): drp_route->set_geometry(GLtk::Geometry(10, geom.h-50, geom.w-20, 20)); drp_route->append("(none)"); drp_route->set_selected_index(0); - const map &routes = engineer.get_layout().get_routes(); + const set &routes = engineer.get_layout().get_routes(); unsigned n = 1; - for(map::const_iterator i=routes.begin(); i!=routes.end(); ++i) - if(!i->second->is_temporary()) + for(set::const_iterator i=routes.begin(); i!=routes.end(); ++i) + if(!(*i)->is_temporary()) { - drp_route->append(i->second->get_name()); - if(i->second==train.get_route()) + drp_route->append((*i)->get_name()); + if(*i==train.get_route()) drp_route->set_selected_index(n); ++n; } @@ -46,12 +46,12 @@ void RouteSelect::on_ok_clicked() { if(drp_route->get_selected_index()>0) { - const map &routes = engineer.get_layout().get_routes(); - map::const_iterator i = routes.begin(); + const set &routes = engineer.get_layout().get_routes(); + set::const_iterator i = routes.begin(); unsigned n = drp_route->get_selected_index()-1; while(i!=routes.end()) { - if(!i->second->is_temporary()) + if(!(*i)->is_temporary()) { if(!n) break; @@ -60,7 +60,7 @@ void RouteSelect::on_ok_clicked() ++i; } - train.set_route(i->second); + train.set_route(*i); } else train.set_route(0); diff --git a/source/libmarklin/layout.cpp b/source/libmarklin/layout.cpp index a495a21..d327815 100644 --- a/source/libmarklin/layout.cpp +++ b/source/libmarklin/layout.cpp @@ -41,7 +41,7 @@ Layout::~Layout() while(!trains.empty()) delete trains.begin()->second; while(!routes.empty()) - delete routes.begin()->second; + delete *routes.begin(); while(!tracks.empty()) delete *tracks.begin(); while(!blocks.empty()) @@ -148,30 +148,27 @@ void Layout::remove_block(Block &b) void Layout::add_route(Route &r) { - if(routes.count(r.get_name())) - throw KeyError("Duplicate route name", r.get_name()); - - routes[r.get_name()] = &r; - signal_route_added.emit(r); + if(routes.insert(&r).second) + signal_route_added.emit(r); } Route &Layout::get_route(const string &name) const { - map::const_iterator i = routes.find(name); - if(i==routes.end()) - throw KeyError("Unknown route", name); - return *i->second; + for(set::const_iterator i=routes.begin(); i!=routes.end(); ++i) + if((*i)->get_name()==name) + return **i; + throw KeyError("Unknown route", name); } void Layout::update_routes() { - for(map::iterator i=routes.begin(); i!=routes.end(); ++i) - i->second->update_turnouts(); + for(set::iterator i=routes.begin(); i!=routes.end(); ++i) + (*i)->update_turnouts(); } void Layout::remove_route(Route &r) { - if(routes.erase(r.get_name())) + if(routes.erase(&r)) signal_route_removed.emit(r); } @@ -249,14 +246,13 @@ void Layout::save(const string &fn) writer.write(st); } - for(map::iterator i=routes.begin(); i!=routes.end(); ++i) + for(set::iterator i=routes.begin(); i!=routes.end(); ++i) { - if(i->second->is_temporary()) + if((*i)->is_temporary()) continue; DataFile::Statement st("route"); - st.append(i->first); - i->second->save(st.sub); + (*i)->save(st.sub); writer.write(st); } } @@ -296,7 +292,8 @@ Layout::Loader::Loader(Layout &l): new_tracks(false) { add("base", &Layout::base); - add("route", &Loader::route); + add("route", static_cast(&Loader::route)); + add("route", static_cast(&Loader::route)); add("track", &Loader::track); add("train", &Loader::train); } @@ -307,9 +304,16 @@ void Layout::Loader::finish() (*i)->check_slope(); } +void Layout::Loader::route() +{ + Route *rte = new Route(obj); + load_sub(*rte); +} + void Layout::Loader::route(const string &n) { - Route *rte = new Route(obj, n); + Route *rte = new Route(obj); + rte->set_name(n); load_sub(*rte); } diff --git a/source/libmarklin/layout.h b/source/libmarklin/layout.h index f820cb5..4e7bcd9 100644 --- a/source/libmarklin/layout.h +++ b/source/libmarklin/layout.h @@ -35,6 +35,7 @@ public: Loader(Layout &); private: virtual void finish(); + void route(); void route(const std::string &); void track(unsigned); void train(unsigned, unsigned); @@ -57,7 +58,7 @@ private: Driver *driver; std::string base; std::set tracks; - std::map routes; + std::set routes; std::set blocks; std::map trains; std::set vehicles; @@ -87,7 +88,7 @@ public: void remove_block(Block &); void add_route(Route &); - const std::map &get_routes() const { return routes; } + const std::set &get_routes() const { return routes; } Route &get_route(const std::string &) const; void update_routes(); void remove_route(Route &); diff --git a/source/libmarklin/route.cpp b/source/libmarklin/route.cpp index cdbcf1d..6cd5841 100644 --- a/source/libmarklin/route.cpp +++ b/source/libmarklin/route.cpp @@ -119,17 +119,16 @@ list dijkstra(const Track &from, unsigned ep, const Pred &goal) return result; } -unsigned count = 0; - template Route *create_route(const Track &from, unsigned ep, const Pred &goal) { list tracks = dijkstra(from, ep, goal); - Route *route = new Route(from.get_layout(), format("-%d-", ++count)); + Route *route = new Route(from.get_layout()); for(list::iterator i=tracks.begin(); i!=tracks.end(); ++i) route->add_track(**i); + route->set_name("Pathfinder"); route->set_temporary(true); return route; @@ -140,9 +139,8 @@ Route *create_route(const Track &from, unsigned ep, const Pred &goal) namespace Marklin { -Route::Route(Layout &l, const string &n): +Route::Route(Layout &l): layout(l), - name(n), temporary(false) { layout.add_route(*this); @@ -154,6 +152,12 @@ Route::~Route() layout.remove_route(*this); } +void Route::set_name(const string &n) +{ + name = n; + signal_name_changed.emit(name); +} + void Route::set_temporary(bool t) { temporary = t; @@ -302,6 +306,7 @@ void Route::update_turnouts() void Route::save(list &st) const { + st.push_back((DataFile::Statement("name"), name)); for(map::const_iterator i=turnouts.begin(); i!=turnouts.end(); ++i) st.push_back((DataFile::Statement("turnout"), i->first, i->second)); } @@ -377,6 +382,7 @@ Route *Route::find(const Track &from, unsigned ep, const Route &to) Route::Loader::Loader(Route &r): DataFile::BasicLoader(r) { + add("name", &Route::name); add("turnout", &Loader::turnout); } diff --git a/source/libmarklin/route.h b/source/libmarklin/route.h index 6b36f46..7c188b0 100644 --- a/source/libmarklin/route.h +++ b/source/libmarklin/route.h @@ -36,6 +36,8 @@ public: void turnout(unsigned, unsigned); }; + sigc::signal signal_name_changed; + private: Layout &layout; std::string name; @@ -44,9 +46,10 @@ private: TurnoutMap turnouts; public: - Route(Layout &, const std::string &); + Route(Layout &); ~Route(); + void set_name(const std::string &); const std::string &get_name() const { return name; } void set_temporary(bool); bool is_temporary() const { return temporary; } diff --git a/source/network/server.cpp b/source/network/server.cpp index 8db6871..d276839 100644 --- a/source/network/server.cpp +++ b/source/network/server.cpp @@ -119,11 +119,11 @@ Server::Connection::~Connection() void Server::Connection::handshake_done() { - const map &routes = server.layout.get_routes(); - for(map::const_iterator i=routes.begin(); i!=routes.end(); ++i) + const set &routes = server.layout.get_routes(); + for(set::const_iterator i=routes.begin(); i!=routes.end(); ++i) { RouteInfoPacket pkt; - pkt.name = i->first; + pkt.name = (*i)->get_name(); comm.send(pkt); }