item "Depart";
};
- label "lbl_zone"
+ label "lbl_target"
{
text "No selection";
};
#include <msp/core/maputils.h>
#include <msp/gltk/button.h>
#include <msp/gltk/root.h>
+#include <msp/input/keys.h>
#include <msp/strings/format.h>
#include <msp/strings/regex.h>
#include "libr2c2/zone.h"
TimetablePanel::TimetablePanel(Engineer &e, R2C2::Train &t):
engineer(e),
train(t),
- zone(0),
- zone_pick(false),
- picked_zone(0),
+ target(0),
+ target_pick(false),
+ picked_target(0),
pick_highlight(0)
{
Loader::WidgetMap widgets;
lst_timetable->signal_item_selected.connect(sigc::mem_fun(this, &TimetablePanel::row_selected));
drp_type = dynamic_cast<GLtk::Dropdown *>(get_item(widgets, "drp_type"));
- lbl_zone = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_zone"));
+ lbl_target = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_target"));
ent_time = dynamic_cast<GLtk::Entry *>(get_item(widgets, "ent_time"));
dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_pick"))->signal_clicked.connect(sigc::mem_fun(this, &TimetablePanel::pick_clicked));
Timetable::Row row;
row.type = static_cast<Timetable::RowType>(drp_type->get_selected_index()+1);
- row.zone = zone;
+ row.target = target;
Regex r_time("([01]?[0-9]|2[0-3]):([0-5][0-9])(:([0-5][0-9]))?");
RegMatch m = r_time.match(ent_time->get_text());
if(row)
{
drp_type->set_selected_index(row->type-1);
- if(row->zone)
- lbl_zone->set_text(row->zone->get_name());
+ if(row->target)
+ lbl_target->set_text(row->target->get_name());
ent_time->set_text(format_time(row->time));
}
}
void TimetablePanel::pick_clicked()
{
- zone_pick = true;
- picked_zone = 0;
+ target_pick = true;
+ picked_target = 0;
+ shift = false;
signal_grab_pointer.emit();
}
timetable->modify_row(index, create_row());
}
+void TimetablePanel::key_press(unsigned key, unsigned mod)
+{
+ Panel::key_press(key, mod);
+
+ if(key==Input::KEY_SHIFT_R || key==Input::KEY_SHIFT_L)
+ shift = true;
+}
+
+void TimetablePanel::key_release(unsigned key, unsigned mod)
+{
+ Panel::key_release(key, mod);
+
+ if(key==Input::KEY_SHIFT_R || key==Input::KEY_SHIFT_L)
+ shift = false;
+}
+
void TimetablePanel::button_press(int x, int y, unsigned btn)
{
Panel::button_press(x, y, btn);
- if(zone_pick)
+ if(target_pick)
{
signal_ungrab_pointer.emit();
- zone_pick = false;
+ target_pick = false;
delete pick_highlight;
pick_highlight = 0;
- if(picked_zone && btn==1)
+ if(picked_target && btn==1)
{
- zone = picked_zone;
- lbl_zone->set_text(zone->get_name());
+ target = picked_target;
+ lbl_target->set_text(target->get_name());
}
}
}
{
Panel::pointer_motion(x, y);
- if(zone_pick)
+ if(target_pick)
{
int rx = x;
int ry = y;
Track *track = engineer.get_layout().pick<Track>(ray);
if(track)
{
- const set<Zone *> &zones = engineer.get_layout().get_all<Zone>();
- Zone *track_zone = 0;
- for(set<Zone *>::const_iterator i=zones.begin(); (!track_zone && i!=zones.end()); ++i)
- if((*i)->has_track(*track))
- track_zone = *i;
- if(track_zone!=picked_zone)
+ TrackChain *t = 0;
+ if(!shift)
+ {
+ const set<Zone *> &zones = engineer.get_layout().get_all<Zone>();
+ for(set<Zone *>::const_iterator i=zones.begin(); (!t && i!=zones.end()); ++i)
+ if((*i)->has_track(*track))
+ t = *i;
+ }
+
+ if(!t)
+ t = &track->get_block();
+
+ if(t!=picked_target)
{
- picked_zone = track_zone;
+ picked_target = t;
delete pick_highlight;
- if(picked_zone)
- pick_highlight = new TrackChain3D(engineer.get_layout_3d(), *track_zone);
- else
- pick_highlight = 0;
+ pick_highlight = new TrackChain3D(engineer.get_layout_3d(), *picked_target);
}
}
}
if(row)
{
add(*new GLtk::Label(format_time(row->time)));
- if(row->zone)
+ if(row->target)
{
string type;
switch(row->type)
case Timetable::ARRIVE: type = "Arrive at "; break;
case Timetable::DEPART: type = "Depart from "; break;
}
- add(*new GLtk::Label(type+row->zone->get_name()));
+ add(*new GLtk::Label(type+row->target->get_name()));
}
else
add(*new GLtk::Label);
R2C2::Timetable *timetable;
Msp::GLtk::List *lst_timetable;
Msp::GLtk::Dropdown *drp_type;
- R2C2::Zone *zone;
- Msp::GLtk::Label *lbl_zone;
+ R2C2::TrackChain *target;
+ Msp::GLtk::Label *lbl_target;
Msp::GLtk::Entry *ent_time;
Msp::GLtk::BasicListData<const R2C2::Timetable::Row *> rows;
- bool zone_pick;
- R2C2::Zone *picked_zone;
+ bool target_pick;
+ R2C2::TrackChain *picked_target;
R2C2::TrackChain3D *pick_highlight;
+ bool shift;
public:
TimetablePanel(Engineer &, R2C2::Train &);
void delete_clicked();
void apply_clicked();
+ virtual void key_press(unsigned, unsigned);
+ virtual void key_release(unsigned, unsigned);
virtual void button_press(int, int, unsigned);
virtual void pointer_motion(int, int);
};
signal_name_changed.emit(name);
}
+DataFile::Statement Block::save_reference() const
+{
+ return (DataFile::Statement("block"), id);
+}
+
Block::Endpoint::Endpoint(Track *t, unsigned e):
track(t),
Train *get_train() const { return train; }
private:
void determine_id();
+
+public:
+ virtual Msp::DataFile::Statement save_reference() const;
};
} // namespace R2C2
st.push_back((DataFile::Statement("turnout"), i->first, i->second));
}
+DataFile::Statement Route::save_reference() const
+{
+ return (DataFile::Statement("route"), name);
+}
+
Route *Route::find(const TrackIter &from, Track &to)
{
return create_route(from, TrackMatch(to));
public:
void save(std::list<Msp::DataFile::Statement> &) const;
+ virtual Msp::DataFile::Statement save_reference() const;
static Route *find(const TrackIter &, Track &);
static Route *find(const TrackIter &, const Route &);
Timetable::Row::Row():
type(ARRIVE),
- zone(0)
+ target(0)
{ }
void Timetable::Row::save(list<DataFile::Statement> &st) const
{
st.push_back((DataFile::Statement("type"), type));
st.push_back((DataFile::Statement("time"), time.raw()));
- st.push_back((DataFile::Statement("zone"), zone->get_group(), zone->get_number()));
+ st.push_back(target->save_reference());
}
DataFile::ObjectLoader<Timetable::Row>(r),
layout(l)
{
- add("zone", &Loader::zone);
+ add("block", &Loader::block);
add("time", &Loader::time);
add("type", &Row::type);
+ add("zone", &Loader::zone);
}
-void Timetable::Row::Loader::zone(const string &name, unsigned number)
+void Timetable::Row::Loader::block(unsigned id)
{
- obj.zone = &layout.get_zone(name, number);
+ obj.target = &layout.get_block(id);
}
void Timetable::Row::Loader::time(Time::RawTime t)
obj.time = Time::TimeDelta(t);
}
+void Timetable::Row::Loader::zone(const string &name, unsigned number)
+{
+ obj.target = &layout.get_zone(name, number);
+}
+
void operator<<(LexicalConverter &conv, Timetable::RowType rt)
{
namespace R2C2 {
class Layout;
-class Zone;
+class TrackChain;
class Timetable: public TrainAI
{
Loader(Row &, Layout &);
private:
- void zone(const std::string &, unsigned);
+ void block(unsigned);
void time(Msp::Time::RawTime);
+ void zone(const std::string &, unsigned);
};
RowType type;
- Zone *zone;
+ TrackChain *target;
Msp::Time::TimeDelta time;
Row();
#include <set>
#include <stdexcept>
#include <sigc++/trackable.h>
+#include <msp/datafile/statement.h>
#include "trackiter.h"
namespace R2C2 {
private:
void object_removed(Object &);
+
+public:
+ virtual Msp::DataFile::Statement save_reference() const = 0;
};
} // namespace R2C2
st.push_back((DataFile::Statement("block"), *i));
}
+DataFile::Statement Zone::save_reference() const
+{
+ return (DataFile::Statement("zone"), group, number);
+}
+
Zone::Loader::Loader(Zone &z):
DataFile::ObjectLoader<Zone>(z)
unsigned get_number() const { return number; }
void save(std::list<Msp::DataFile::Statement> &) const;
+ virtual Msp::DataFile::Statement save_reference() const;
};
} // namespace R2C2