1 #include <msp/core/maputils.h>
2 #include <msp/gltk/button.h>
3 #include <msp/gltk/root.h>
4 #include <msp/strings/format.h>
5 #include <msp/strings/regex.h>
6 #include "libr2c2/zone.h"
8 #include "timetablepanel.h"
14 class TimetableRowItem: public GLtk::List::MultiColumnItem
17 typedef const Timetable::Row *ValueType;
19 TimetableRowItem(ValueType);
23 string format_time(const Time::TimeDelta &time)
25 unsigned second = time/Time::sec;
26 unsigned hour = second/3600;
27 unsigned minute = second/60%60;
29 return format("%02d:%02d:%02d", hour, minute, second);
33 TimetablePanel::TimetablePanel(Engineer &e, R2C2::Train &t):
41 Loader::WidgetMap widgets;
42 DataFile::load(*this, "data/timetablepanel.ui", widgets);
44 lst_timetable = dynamic_cast<GLtk::List *>(get_item(widgets, "lst_timetable"));
45 lst_timetable->set_data(rows);
46 lst_timetable->set_item_type<TimetableRowItem>();
47 lst_timetable->signal_item_selected.connect(sigc::mem_fun(this, &TimetablePanel::row_selected));
49 drp_type = dynamic_cast<GLtk::Dropdown *>(get_item(widgets, "drp_type"));
50 lbl_zone = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_zone"));
51 ent_time = dynamic_cast<GLtk::Entry *>(get_item(widgets, "ent_time"));
53 dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_pick"))->signal_clicked.connect(sigc::mem_fun(this, &TimetablePanel::pick_clicked));
54 dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_insert"))->signal_clicked.connect(sigc::mem_fun(this, &TimetablePanel::insert_clicked));
55 dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_delete"))->signal_clicked.connect(sigc::mem_fun(this, &TimetablePanel::delete_clicked));
56 dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_apply"))->signal_clicked.connect(sigc::mem_fun(this, &TimetablePanel::apply_clicked));
58 timetable = train.get_ai_of_type<Timetable>();
60 timetable = new Timetable(train);
62 unsigned length = timetable->get_length();
63 for(unsigned i=0; i<length; ++i)
64 rows.append(&timetable->get_row(i));
66 timetable->signal_row_added.connect(sigc::mem_fun(this, &TimetablePanel::row_added));
67 timetable->signal_row_modified.connect(sigc::mem_fun(this, &TimetablePanel::row_modified));
68 timetable->signal_row_removed.connect(sigc::mem_fun(this, &TimetablePanel::row_removed));
71 void TimetablePanel::row_added(unsigned i, const Timetable::Row &row)
76 void TimetablePanel::row_modified(unsigned i, const Timetable::Row &)
81 void TimetablePanel::row_removed(unsigned i)
86 Timetable::Row TimetablePanel::create_row()
90 row.type = static_cast<Timetable::RowType>(drp_type->get_selected_index()+1);
93 Regex r_time("([01]?[0-9]|2[0-3]):([0-5][0-9])(:([0-5][0-9]))?");
94 RegMatch m = r_time.match(ent_time->get_text());
97 row.time = lexical_cast<unsigned>(m[1].str)*Time::hour;
98 row.time += lexical_cast<unsigned>(m[2].str)*Time::min;
100 row.time += lexical_cast<unsigned>(m[4].str)*Time::sec;
106 void TimetablePanel::row_selected(unsigned i)
108 const Timetable::Row *row = rows.get(i);
111 drp_type->set_selected_index(row->type-1);
113 lbl_zone->set_text(row->zone->get_name());
114 ent_time->set_text(format_time(row->time));
118 void TimetablePanel::pick_clicked()
122 signal_grab_pointer.emit();
125 void TimetablePanel::insert_clicked()
127 int index = lst_timetable->get_selected_index();
129 index = timetable->get_length();
130 timetable->insert_row(index, create_row());
133 void TimetablePanel::delete_clicked()
135 int index = lst_timetable->get_selected_index();
137 timetable->remove_row(index);
140 void TimetablePanel::apply_clicked()
142 int index = lst_timetable->get_selected_index();
144 timetable->modify_row(index, create_row());
147 void TimetablePanel::button_press(int x, int y, unsigned btn)
149 Panel::button_press(x, y, btn);
153 signal_ungrab_pointer.emit();
156 delete pick_highlight;
159 if(picked_zone && btn==1)
162 lbl_zone->set_text(zone->get_name());
167 void TimetablePanel::pointer_motion(int x, int y)
169 Panel::pointer_motion(x, y);
175 map_coords_to_ancestor(rx, ry, *find_ancestor<GLtk::Root>());
176 Ray ray = engineer.get_main_view().create_ray(rx, ry);
177 Track *track = engineer.get_layout().pick<Track>(ray);
180 const set<Zone *> &zones = engineer.get_layout().get_all<Zone>();
181 Zone *track_zone = 0;
182 for(set<Zone *>::const_iterator i=zones.begin(); (!track_zone && i!=zones.end()); ++i)
183 if((*i)->has_track(*track))
185 if(track_zone!=picked_zone)
187 picked_zone = track_zone;
188 delete pick_highlight;
190 pick_highlight = new TrackChain3D(engineer.get_layout_3d(), *track_zone);
199 TimetableRowItem::TimetableRowItem(ValueType row)
203 add(*new GLtk::Label(format_time(row->time)));
209 case Timetable::ARRIVE: type = "Arrive at "; break;
210 case Timetable::DEPART: type = "Depart from "; break;
212 add(*new GLtk::Label(type+row->zone->get_name()));
215 add(*new GLtk::Label);
219 add(*new GLtk::Label("--:--:--"));
220 add(*new GLtk::Label("End of timetable"));