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);
const list<Track3D *> &tracks = layout_3d->get_tracks();
for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
update_track_icon(**i);
+
+ edit_route(0);
}
Designer::~Designer()
}
}
-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);
}
IO::print("%s\n", e.what());
}
- show_route(*cur_route);
+ show_route(cur_route);
}
Point Designer::map_pointer_coords(int x, int y)
}
}
+void Designer::route_name_accept(const string &text)
+{
+ if(cur_route)
+ cur_route->set_name(text);
+}
+
void Designer::view_all()
{
Point minp;
return string();
}
-void Designer::show_route(const Route &route)
+void Designer::show_route(const Route *route)
{
const set<Track *> <racks = layout->get_tracks();
- const set<const Track *> &rtracks = route.get_tracks();
for(set<Track *>::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
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();
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
GLtk::Panel(d.get_ui_resources()),
designer(d)
{
- set_size(410, 40);
+ set_size(640, 40);
GLtk::Button *btn;
GLtk::Label *lbl;
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));
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<Route *> &routes = designer.get_layout()->get_routes();
+ for(set<Route *>::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();
}
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<Route *> &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<string, Route *> &routes = designer.get_layout()->get_routes();
int selected = -1;
unsigned n = 0;
- for(map<string, Route *>::const_iterator i=routes.begin(); (selected<0 && i!=routes.end()); ++i, ++n)
- if(i->second==route)
+ for(set<Route *>::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<string, Route *> &routes = designer.get_layout()->get_routes();
- map<string, Route *>::const_iterator i = routes.begin();
+ const set<Route *> &routes = designer.get_layout()->get_routes();
+ set<Route *>::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<string, Route *> &routes = designer.get_layout()->get_routes();
+ const set<Route *> &routes = designer.get_layout()->get_routes();
int selected = -1;
unsigned n = 0;
- for(map<string, Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n)
+ for(set<Route *>::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)");
#include <sigc++/trackable.h>
#include <msp/gltk/dropdown.h>
#include <msp/gltk/panel.h>
+#include "libmarklin/route.h"
class Designer;
Toolbar(Designer &);
private:
void route_selected(unsigned, const std::string &);
+ void delete_route_clicked();
+ void route_added(Marklin::Route &);
void update_routes();
};
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<string, Route *> &routes = engineer.get_layout().get_routes();
+ const set<Route *> &routes = engineer.get_layout().get_routes();
unsigned n = 1;
- for(map<string, Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
- if(!i->second->is_temporary())
+ for(set<Route *>::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;
}
{
if(drp_route->get_selected_index()>0)
{
- const map<string, Route *> &routes = engineer.get_layout().get_routes();
- map<string, Route *>::const_iterator i = routes.begin();
+ const set<Route *> &routes = engineer.get_layout().get_routes();
+ set<Route *>::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;
++i;
}
- train.set_route(i->second);
+ train.set_route(*i);
}
else
train.set_route(0);
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())
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<string, Route *>::const_iterator i = routes.find(name);
- if(i==routes.end())
- throw KeyError("Unknown route", name);
- return *i->second;
+ for(set<Route *>::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<string, Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
- i->second->update_turnouts();
+ for(set<Route *>::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);
}
writer.write(st);
}
- for(map<string, Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
+ for(set<Route *>::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);
}
}
new_tracks(false)
{
add("base", &Layout::base);
- add("route", &Loader::route);
+ add("route", static_cast<void (Loader::*)()>(&Loader::route));
+ add("route", static_cast<void (Loader::*)(const string &)>(&Loader::route));
add("track", &Loader::track);
add("train", &Loader::train);
}
(*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);
}
Loader(Layout &);
private:
virtual void finish();
+ void route();
void route(const std::string &);
void track(unsigned);
void train(unsigned, unsigned);
Driver *driver;
std::string base;
std::set<Track *> tracks;
- std::map<std::string, Route *> routes;
+ std::set<Route *> routes;
std::set<Block *> blocks;
std::map<unsigned, Train *> trains;
std::set<Vehicle *> vehicles;
void remove_block(Block &);
void add_route(Route &);
- const std::map<std::string, Route *> &get_routes() const { return routes; }
+ const std::set<Route *> &get_routes() const { return routes; }
Route &get_route(const std::string &) const;
void update_routes();
void remove_route(Route &);
return result;
}
-unsigned count = 0;
-
template<typename Pred>
Route *create_route(const Track &from, unsigned ep, const Pred &goal)
{
list<const Track *> tracks = dijkstra(from, ep, goal);
- Route *route = new Route(from.get_layout(), format("-%d-", ++count));
+ Route *route = new Route(from.get_layout());
for(list<const Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
route->add_track(**i);
+ route->set_name("Pathfinder");
route->set_temporary(true);
return route;
namespace Marklin {
-Route::Route(Layout &l, const string &n):
+Route::Route(Layout &l):
layout(l),
- name(n),
temporary(false)
{
layout.add_route(*this);
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;
void Route::save(list<DataFile::Statement> &st) const
{
+ st.push_back((DataFile::Statement("name"), name));
for(map<unsigned, int>::const_iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
st.push_back((DataFile::Statement("turnout"), i->first, i->second));
}
Route::Loader::Loader(Route &r):
DataFile::BasicLoader<Route>(r)
{
+ add("name", &Route::name);
add("turnout", &Loader::turnout);
}
void turnout(unsigned, unsigned);
};
+ sigc::signal<void, const std::string &> signal_name_changed;
+
private:
Layout &layout;
std::string name;
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; }
void Server::Connection::handshake_done()
{
- const map<string, Route *> &routes = server.layout.get_routes();
- for(map<string, Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
+ const set<Route *> &routes = server.layout.get_routes();
+ for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
{
RouteInfoPacket pkt;
- pkt.name = i->first;
+ pkt.name = (*i)->get_name();
comm.send(pkt);
}