]> git.tdb.fi Git - r2c2.git/blobdiff - source/engineer/timetablepanel.cpp
Allow direction to be specified for routing waypoints
[r2c2.git] / source / engineer / timetablepanel.cpp
index 6104873fc7096ffe7b49078e694727dd050e25f1..5932176b0536e55518fc9753e06fde28abd2f4a5 100644 (file)
@@ -1,6 +1,7 @@
 #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"
@@ -33,9 +34,9 @@ string format_time(const Time::TimeDelta &time)
 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;
@@ -47,8 +48,9 @@ TimetablePanel::TimetablePanel(Engineer &e, R2C2::Train &t):
        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"));
+       drp_direction = dynamic_cast<GLtk::Dropdown *>(get_item(widgets, "drp_direction"));
 
        dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_pick"))->signal_clicked.connect(sigc::mem_fun(this, &TimetablePanel::pick_clicked));
        dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_insert"))->signal_clicked.connect(sigc::mem_fun(this, &TimetablePanel::insert_clicked));
@@ -88,7 +90,8 @@ Timetable::Row TimetablePanel::create_row()
        Timetable::Row row;
 
        row.type = static_cast<Timetable::RowType>(drp_type->get_selected_index()+1);
-       row.zone = zone;
+       row.target = target;
+       row.direction = static_cast<TrackChain::Direction>(drp_direction->get_selected_index());
 
        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());
@@ -109,16 +112,19 @@ void TimetablePanel::row_selected(unsigned i)
        if(row)
        {
                drp_type->set_selected_index(row->type-1);
-               if(row->zone)
-                       lbl_zone->set_text(row->zone->get_name());
+               target = row->target;
+               if(target)
+                       lbl_target->set_text(target->get_name());
+               drp_direction->set_selected_index(row->direction);
                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();
 }
 
@@ -144,22 +150,38 @@ void TimetablePanel::apply_clicked()
                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());
                }
        }
 }
@@ -168,7 +190,7 @@ void TimetablePanel::pointer_motion(int x, int y)
 {
        Panel::pointer_motion(x, y);
 
-       if(zone_pick)
+       if(target_pick)
        {
                int rx = x;
                int ry = y;
@@ -177,19 +199,23 @@ void TimetablePanel::pointer_motion(int x, int 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)
                        {
-                               picked_zone = track_zone;
+                               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_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);
                        }
                }
        }
@@ -201,15 +227,25 @@ TimetableRowItem::TimetableRowItem(ValueType row)
        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;
+                       case Timetable::THROUGH: type = "Go through "; break;
                        }
-                       add(*new GLtk::Label(type+row->zone->get_name()));
+
+                       string dir;
+                       switch(row->direction)
+                       {
+                       case TrackChain::UP: dir = " up"; break;
+                       case TrackChain::DOWN: dir = " down"; break;
+                       default:;
+                       }
+
+                       add(*new GLtk::Label(type+row->target->get_name()+dir));
                }
                else
                        add(*new GLtk::Label);