style "list"
{
- font_color 0.0 0.0 0.0;
-
part
{
graphic NORMAL "sunken_white_bg";
};
- part "selection"
- {
- graphic NORMAL "selection";
- fill 1.0 1.0;
- margin { vertical 2; right 13; left 2; };
- };
-
part "items"
{
margin { vertical 2; right 13; left 2; };
};
};
+style "listitem"
+{
+ part
+ {
+ graphic ACTIVE "selection";
+ fill 1.0 1.0;
+ };
+
+ part "children"
+ {
+ margin { vertical 1; horizontal 2; };
+ };
+};
+
style "dropdown"
{
font_color 0.0 0.0 0.0;
#include <GL/gl.h>
#include <msp/gl/texture.h>
#include <msp/gltk/button.h>
-#include <msp/gltk/mixedrows.h>
+#include <msp/gltk/column.h>
+#include <msp/gltk/row.h>
#include <msp/input/keys.h>
#include "designer.h"
#include "input.h"
InputDialog::InputDialog(Designer &d, const string &title, const string &text):
designer(d)
{
- GLtk::MixedRows *rows = new GLtk::MixedRows;
- set_layout(rows);
+ set_layout(new GLtk::Layout);
+ GLtk::Column col(*layout);
GLtk::Label *lbl;
add(*(lbl=new GLtk::Label(title)));
- layout->set_expand(*lbl, true, false);
lbl->set_style("title");
- rows->start_row();
add(*(entry=new GLtk::Entry(text)));
entry->set_edit_size(60, 1);
GLtk::Button *btn;
- rows->start_row();
- rows->split_columns();
- add_button(*(btn=new GLtk::Button("Cncl")), 0);
- btn->set_style("red");
+ {
+ GLtk::Row row(*layout);
+ row.split();
+ add_button(*(btn=new GLtk::Button("Cncl")), 0);
+ btn->set_style("red");
- add_button(*(btn=new GLtk::Button("OK")), 1);
- btn->set_style("green");
+ add_button(*(btn=new GLtk::Button("OK")), 1);
+ btn->set_style("green");
+ }
entry->set_focus();
}
using namespace Msp;
using namespace R2C2;
+string route_name(Route *const &route)
+{
+ return route ? route->get_name() : "(new route)";
+}
+
Routebar::Routebar(Designer &d):
Toolbar("Route"),
- designer(d)
+ designer(d),
+ routes(&route_name)
{
- pnl_content->add(*(drp_routes = new GLtk::Dropdown));
+ pnl_content->add(*(drp_routes = new GLtk::Dropdown(routes)));
drp_routes->set_tooltip("Select route to edit");
- drp_routes->append("(new route)");
drp_routes->signal_item_selected.connect(sigc::mem_fun(this, &Routebar::route_selected));
GLtk::Button *btn;
btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_route));
designer.get_layout().signal_track_chain_added.connect(sigc::mem_fun(this, &Routebar::track_chain_added));
- designer.get_layout().signal_track_chain_removed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
+ designer.get_layout().signal_track_chain_removed.connect(sigc::mem_fun(this, &Routebar::track_chain_removed));
- const set<Route *> &routes = designer.get_layout().get_all<Route>();
- for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
- (*i)->signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
+ const set<Route *> &lroutes = designer.get_layout().get_all<Route>();
+ for(set<Route *>::const_iterator i=lroutes.begin(); i!=lroutes.end(); ++i)
+ {
+ routes.append(*i);
+ (*i)->signal_name_changed.connect(sigc::bind(sigc::mem_fun(this, &Routebar::route_name_changed), *i));
+ }
- update_routes();
+ routes.append(0);
}
-void Routebar::route_selected(unsigned index, const string &)
+void Routebar::route_selected(unsigned index)
{
- if(index==drp_routes->get_n_items()-1)
+ if(index==routes.size()-1)
{
Layout &rlayout = designer.get_layout();
Route *route = new Route(rlayout);
- const set<Route *> &routes = rlayout.get_all<Route>();
- route->set_name(format("Route %d", routes.size()));
+ route->set_name(format("Route %d", index+1));
designer.edit_route(route);
- int selected = -1;
- unsigned n = 0;
- 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);
+ for(unsigned i=0; i<routes.size(); ++i)
+ if(routes.get(i)==route)
+ drp_routes->set_selected_index(i);
}
else
- {
- const set<Route *> &routes = designer.get_layout().get_all<Route>();
- set<Route *>::const_iterator i = routes.begin();
- advance(i, index);
- designer.edit_route(*i);
- }
+ designer.edit_route(routes.get(index));
}
void Routebar::delete_route_clicked()
{
if(Route *r = dynamic_cast<Route *>(&tc))
{
- r->signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
- update_routes();
+ r->signal_name_changed.connect(sigc::bind(sigc::mem_fun(this, &Routebar::route_name_changed), r));
+ routes.insert(routes.size()-1, r);
}
}
-void Routebar::update_routes()
+void Routebar::track_chain_removed(TrackChain &tc)
{
- drp_routes->clear();
- const set<Route *> &routes = designer.get_layout().get_all<Route>();
- int selected = -1;
- unsigned n = 0;
- for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n)
+ if(Route *r = dynamic_cast<Route *>(&tc))
{
- drp_routes->append((*i)->get_name());
- if(*i==designer.get_current_route())
- selected = n;
+ for(unsigned i=0; i<routes.size(); ++i)
+ if(routes.get(i)==r)
+ {
+ routes.remove(i);
+ break;
+ }
}
- drp_routes->append("(new route)");
- drp_routes->set_selected_index(selected);
+}
+
+void Routebar::route_name_changed(const string &, Route *route)
+{
+ routes.refresh(route);
}
{
private:
Designer &designer;
+ Msp::GLtk::FunctionListData<R2C2::Route *> routes;
Msp::GLtk::Dropdown *drp_routes;
public:
Routebar(Designer &);
private:
- void route_selected(unsigned, const std::string &);
+ void route_selected(unsigned);
void delete_route_clicked();
void track_chain_added(R2C2::TrackChain &);
- void update_routes();
+ void track_chain_removed(R2C2::TrackChain &);
+ void route_name_changed(const std::string &, R2C2::Route *);
};
#endif
expanded(true)
{
set_focusable(false);
- set_layout(new GLtk::Row);
+ set_layout(new GLtk::Layout);
+ GLtk::Row row(*layout);
layout->set_margin(GLtk::Sides(6, 10));
layout->set_column_spacing(10);
add(*(pnl_content = new GLtk::Panel));
pnl_content->set_style("group");
- GLtk::Layout *content_layout = new GLtk::Row;
+ GLtk::Layout *content_layout = new GLtk::Layout;
+ // XXX This needs to get deleted somehow
+ new GLtk::Row(*content_layout);
pnl_content->set_layout(content_layout);
content_layout->set_margin(0);
}
#include <msp/gltk/button.h>
+#include <msp/gltk/column.h>
#include <msp/gltk/label.h>
-#include <msp/gltk/mixedrows.h>
+#include <msp/gltk/row.h>
#include "libr2c2/track.h"
#include "libr2c2/tracktype.h"
#include "selection.h"
TrackProperties::TrackProperties(const Selection &s):
selection(s)
{
- GLtk::MixedRows *rows = new GLtk::MixedRows;
- set_layout(rows);
+ set_layout(new GLtk::Layout);
+ GLtk::Column col(*layout);
GLtk::Label *lbl1, *lbl2;
add(*(lbl1 = new GLtk::Label("Track properties")));
- layout->set_expand(*lbl1, true, false);
lbl1->set_style("title");
- rows->start_row();
- add(*(lbl1 = new GLtk::Label("Turnout ID")));
- add(*(ent_turnout_id = new GLtk::Entry));
- ent_turnout_id->set_edit_size(5, 1);
+ {
+ GLtk::Row row(*layout);
+ add(*(lbl1 = new GLtk::Label("Turnout ID")));
+ add(*(ent_turnout_id = new GLtk::Entry));
+ ent_turnout_id->set_edit_size(5, 1);
+ }
- rows->start_row();
- add(*(lbl2 = new GLtk::Label("Sensor ID")));
- rows->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
- add(*(ent_sensor_id = new GLtk::Entry));
- ent_sensor_id->set_edit_size(5, 1);
+ {
+ GLtk::Row row(*layout);
+ add(*(lbl2 = new GLtk::Label("Sensor ID")));
+ layout->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
+ add(*(ent_sensor_id = new GLtk::Entry));
+ ent_sensor_id->set_edit_size(5, 1);
+ }
GLtk::Button *btn;
- rows->start_row();
- rows->split_columns();
- add_button(*(btn = new GLtk::Button("Cncl")), 0);
- btn->set_style("red");
+ {
+ GLtk::Row row(*layout);
+ row.split();
+ add_button(*(btn = new GLtk::Button("Cncl")), 0);
+ btn->set_style("red");
- add_button(*(btn = new GLtk::Button("OK")), 1);
- btn->set_style("green");
+ add_button(*(btn = new GLtk::Button("OK")), 1);
+ btn->set_style("green");
+ }
if(selection.size()==1)
{
using namespace Msp;
using namespace R2C2;
+string zone_detail(Zone *const &zone)
+{
+ return zone ? format("%s %d", zone->get_qualifier(), zone->get_number()) : "(new)";
+}
+
Zonebar::Zonebar(Designer &d):
Toolbar("Zone"),
- designer(d)
+ designer(d),
+ zones(&zone_detail)
{
- pnl_content->add(*(drp_groups = new GLtk::Dropdown));
+ pnl_content->add(*(drp_groups = new GLtk::Dropdown(groups)));
drp_groups->set_tooltip("Select zone group to edit");
drp_groups->signal_item_selected.connect(sigc::mem_fun(this, &Zonebar::group_selected));
- pnl_content->add(*(drp_numbers = new GLtk::Dropdown));
+ pnl_content->add(*(drp_numbers = new GLtk::Dropdown(zones)));
drp_groups->set_tooltip("Select zone to edit");
drp_numbers->signal_item_selected.connect(sigc::mem_fun(this, &Zonebar::number_selected));
Layout &rlayout = designer.get_layout();
rlayout.signal_track_chain_added.connect(sigc::mem_fun(this, &Zonebar::track_chain_added));
- rlayout.signal_track_chain_removed.connect(sigc::hide(sigc::mem_fun(this, &Zonebar::update_groups)));
+ rlayout.signal_track_chain_removed.connect(sigc::mem_fun(this, &Zonebar::track_chain_removed));
- const set<Zone *> &zones = rlayout.get_all<Zone>();
- for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
- (*i)->signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
-
- update_groups();
+ const set<Zone *> &lzones = rlayout.get_all<Zone>();
+ set<string> group_names;
+ for(set<Zone *>::const_iterator i=lzones.begin(); i!=lzones.end(); ++i)
+ {
+ (*i)->signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Zonebar::zone_renamed), sigc::ref(**i)));
+ if(!group_names.count((*i)->get_group()))
+ {
+ groups.append((*i)->get_group());
+ group_names.insert((*i)->get_group());
+ }
+ }
+ groups.append("(new)");
}
void Zonebar::track_chain_added(TrackChain &chain)
+{
+ if(Zone *zone = dynamic_cast<Zone *>(&chain))
+ zone->signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Zonebar::zone_renamed), sigc::ref(*zone)));
+}
+
+void Zonebar::track_chain_removed(TrackChain &chain)
{
if(Zone *zone = dynamic_cast<Zone *>(&chain))
{
- zone->signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
- update_groups();
+ bool keep_group = false;
+ const set<Zone *> &lzones = designer.get_layout().get_all<Zone>();
+ for(set<Zone *>::const_iterator j=lzones.begin(); (!keep_group && j!=lzones.end()); ++j)
+ keep_group = (*j)->get_group()==zone->get_group();
+
+ if(!keep_group)
+ {
+ for(unsigned i=0; i<groups.size(); ++i)
+ if(groups.get(i)==zone->get_group())
+ {
+ groups.remove(i);
+ break;
+ }
+ }
+
+ for(unsigned i=0; i<zones.size(); ++i)
+ if(zones.get(i)==zone)
+ {
+ zones.remove(i);
+ break;
+ }
}
}
-void Zonebar::zone_renamed(const string &, const string &, unsigned)
+void Zonebar::zone_renamed(Zone &zone, const string &group, const string &, unsigned)
{
- update_groups();
+ const set<Zone *> &lzones = designer.get_layout().get_all<Zone>();
+ set<string> group_names;
+ for(set<Zone *>::const_iterator i=lzones.begin(); i!=lzones.end(); ++i)
+ group_names.insert((*i)->get_group());
+
+ bool new_group = true;
+ for(unsigned i=0; i+1<groups.size(); )
+ {
+ if(group_names.count(groups.get(i)))
+ {
+ if(groups.get(i)==group)
+ new_group = false;
+ ++i;
+ }
+ else
+ groups.remove(i);
+ }
+
+ if(new_group)
+ groups.insert(groups.size()-1, group);
+
+ int sel = drp_groups->get_selected_index();
+ if(sel>=0 && groups.get(sel)==group)
+ {
+ int i = zones.find(&zone);
+ if(i<0)
+ zones.insert(zones.size()-1, &zone);
+ else
+ zones.refresh(i);
+ }
}
-void Zonebar::group_selected(unsigned index, const string &group)
+void Zonebar::group_selected(unsigned index)
{
- if(index==drp_groups->get_n_items()-1)
+ if(index==groups.size()-1)
{
Zone *zone = new Zone(designer.get_layout());
zone->set_name("New zone", "track", 1);
+
+ for(unsigned i=0; i<groups.size(); ++i)
+ if(groups.get(i)=="New zone")
+ {
+ drp_groups->set_selected_index(i);
+ break;
+ }
+
+ for(unsigned i=0; i<zones.size(); ++i)
+ if(zones.get(i)==zone)
+ {
+ drp_numbers->set_selected_index(i);
+ break;
+ }
+
designer.edit_zone(zone);
- update_groups();
}
else
{
Zone *cur = designer.get_current_zone();
- if(cur && group==cur->get_group())
+ if(cur && groups.get(index)==cur->get_group())
return;
designer.edit_zone(0);
- update_numbers(group);
+
+ zones.clear();
+ Layout::ZoneArray lzones = designer.get_layout().get_zones(groups.get(index));
+ for(Layout::ZoneArray::iterator i=lzones.begin(); i!=lzones.end(); ++i)
+ zones.append(*i);
+ zones.append(0);
}
}
-void Zonebar::number_selected(unsigned index, const string &)
+void Zonebar::number_selected(unsigned index)
{
if(drp_groups->get_selected_index()<0)
return;
- string group = drp_groups->get_selected();
- Layout::ZoneArray zones = designer.get_layout().get_zones(group);
- if(index==drp_numbers->get_n_items()-1)
+ string group = groups.get(drp_groups->get_selected_index());
+ if(index==zones.size()-1)
{
Zone *cur = designer.get_current_zone();
string qualifier = (cur ? cur->get_qualifier() : "track");
Zone *zone = new Zone(designer.get_layout());
- zone->set_name(group, qualifier, zones.size()+1);
+ zone->set_name(group, qualifier, index+1);
designer.edit_zone(zone);
- if(cur)
- update_numbers(group);
- else
- update_groups();
+
+ for(unsigned i=0; i<zones.size(); ++i)
+ if(zones.get(i)==zone)
+ {
+ drp_numbers->set_selected_index(i);
+ break;
+ }
}
- else if(index<zones.size())
- designer.edit_zone(zones[index]);
+ else
+ designer.edit_zone(zones.get(index));
}
void Zonebar::delete_zone_clicked()
designer.edit_zone(0);
delete cur;
}
-
-void Zonebar::update_groups()
-{
- const set<Zone *> &zones = designer.get_layout().get_all<Zone>();
- set<string> groups;
- for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
- groups.insert((*i)->get_group());
-
- Zone *cur = designer.get_current_zone();
-
- drp_groups->clear();
- int selected = -1;
- unsigned n = 0;
- for(set<string>::iterator i=groups.begin(); i!=groups.end(); ++i, ++n)
- {
- drp_groups->append(*i);
- if(cur && *i==cur->get_group())
- selected = n;
- }
- drp_groups->append("(new)");
- drp_groups->set_selected_index(selected);
-
- if(cur)
- update_numbers(cur->get_group());
- else
- drp_numbers->clear();
-}
-
-void Zonebar::update_numbers(const string &group)
-{
- Layout::ZoneArray zones = designer.get_layout().get_zones(group);
- Zone *cur = designer.get_current_zone();
-
- drp_numbers->clear();
- int selected = -1;
- unsigned n = 0;
- for(Layout::ZoneArray::iterator i=zones.begin(); i!=zones.end(); ++i, ++n)
- {
- drp_numbers->append(format("%s %d", (*i)->get_qualifier(), (*i)->get_number()));
- if(cur && *i==cur)
- selected = n;
- }
- drp_numbers->append("(new)");
- drp_numbers->set_selected_index(selected);
-}
{
private:
Designer &designer;
+ Msp::GLtk::BasicListData<std::string> groups;
Msp::GLtk::Dropdown *drp_groups;
+ Msp::GLtk::FunctionListData<R2C2::Zone *> zones;
Msp::GLtk::Dropdown *drp_numbers;
public:
private:
void track_chain_added(R2C2::TrackChain &);
- void zone_renamed(const std::string &, const std::string &, unsigned);
- void group_selected(unsigned, const std::string &);
- void number_selected(unsigned, const std::string &);
+ void track_chain_removed(R2C2::TrackChain &);
+ void zone_renamed(R2C2::Zone &, const std::string &, const std::string &, unsigned);
+ void group_selected(unsigned);
+ void number_selected(unsigned);
void delete_zone_clicked();
- void update_groups();
- void update_numbers(const std::string &);
};
#endif
#include <msp/gltk/button.h>
+#include <msp/gltk/column.h>
#include <msp/gltk/label.h>
-#include <msp/gltk/mixedrows.h>
+#include <msp/gltk/row.h>
#include "zoneproperties.h"
using namespace std;
ZoneProperties::ZoneProperties(Zone &z):
zone(z)
{
- GLtk::MixedRows *rows = new GLtk::MixedRows;
- set_layout(rows);
+ set_layout(new GLtk::Layout);
+ GLtk::Column col(*layout);
GLtk::Label *lbl1, *lbl2;
add(*(lbl1 = new GLtk::Label("Zone properties")));
- layout->set_expand(*lbl1, true, false);
lbl1->set_style("title");
- rows->start_row();
- add(*(lbl1 = new GLtk::Label("Group")));
- add(*(ent_group = new GLtk::Entry(zone.get_group())));
- ent_group->set_edit_size(30, 1);
-
- rows->start_row();
- add(*(lbl2 = new GLtk::Label("Qualifier")));
- rows->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
+ {
+ GLtk::Row row(*layout);
+ add(*(lbl1 = new GLtk::Label("Group")));
+ add(*(ent_group = new GLtk::Entry(zone.get_group())));
+ ent_group->set_edit_size(30, 1);
+ }
- add(*(drp_qualifier = new GLtk::Dropdown));
- const char *qualifiers[] = { "track", "platform", "siding", 0 };
- for(unsigned i=0; qualifiers[i]; ++i)
{
- drp_qualifier->append(qualifiers[i]);
- if(zone.get_qualifier()==qualifiers[i])
- drp_qualifier->set_selected_index(i);
+ GLtk::Row row(*layout);
+ add(*(lbl2 = new GLtk::Label("Qualifier")));
+ layout->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
+
+ add(*(drp_qualifier = new GLtk::Dropdown));
+ GLtk::ListDataStore<string> &data = dynamic_cast<GLtk::ListDataStore<string> &>(drp_qualifier->get_data());
+ const char *qualifiers[] = { "track", "platform", "siding", 0 };
+ for(unsigned i=0; qualifiers[i]; ++i)
+ {
+ data.append(qualifiers[i]);
+ if(zone.get_qualifier()==qualifiers[i])
+ drp_qualifier->set_selected_index(i);
+ }
}
- rows->start_row();
- add(*(lbl1 = new GLtk::Label("Number")));
- rows->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
- add(*(ent_number = new GLtk::Entry(lexical_cast<string>(zone.get_number()))));
- ent_number->set_edit_size(4, 1);
+ {
+ GLtk::Row row(*layout);
+ add(*(lbl1 = new GLtk::Label("Number")));
+ layout->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
+ add(*(ent_number = new GLtk::Entry(lexical_cast<string>(zone.get_number()))));
+ ent_number->set_edit_size(4, 1);
+ }
GLtk::Button *btn;
- rows->start_row();
- rows->split_columns();
- add_button(*(btn = new GLtk::Button("Cncl")), 0);
- btn->set_style("red");
+ {
+ GLtk::Row row(*layout);
+ row.split();
+ add_button(*(btn = new GLtk::Button("Cncl")), 0);
+ btn->set_style("red");
- add_button(*(btn = new GLtk::Button("OK")), 1);
- btn->set_style("green");
+ add_button(*(btn = new GLtk::Button("OK")), 1);
+ btn->set_style("green");
+ }
}
void ZoneProperties::on_response(int code)
if(code==1)
{
string qualifier;
- if(drp_qualifier->get_selected_index()>=0)
- qualifier = drp_qualifier->get_selected();
+ int sel = drp_qualifier->get_selected_index();
+ if(sel>=0)
+ qualifier = drp_qualifier->get_data().get_string(sel);
unsigned number = lexical_cast<unsigned>(ent_number->get_text());
zone.set_name(ent_group->get_text(), qualifier, number);
}