]> git.tdb.fi Git - r2c2.git/blobdiff - source/engineer/traindialog.cpp
Complete rewrite of the engineer UI
[r2c2.git] / source / engineer / traindialog.cpp
diff --git a/source/engineer/traindialog.cpp b/source/engineer/traindialog.cpp
new file mode 100644 (file)
index 0000000..4d1d492
--- /dev/null
@@ -0,0 +1,125 @@
+#include <msp/core/maputils.h>
+#include <msp/core/raii.h>
+#include <msp/gltk/stack.h>
+#include <msp/strings/format.h>
+#include "libr2c2/aicontrol.h"
+#include "libr2c2/catalogue.h"
+#include "libr2c2/layout.h"
+#include "libr2c2/trainstatus.h"
+#include "controlpanel.h"
+#include "routerpanel.h"
+#include "traindialog.h"
+#include "vehiclespanel.h"
+
+using namespace std;
+using namespace Msp;
+using namespace R2C2;
+
+TrainDialog::TrainDialog(Engineer &e, R2C2::Train &t):
+       engineer(e),
+       train(t),
+       updating(false)
+{
+       Loader::WidgetMap widgets;
+       DataFile::load(*this, "data/traindialog.ui", widgets);
+
+       lbl_title = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_title"));
+       lbl_title->set_text(t.get_name());
+
+       btn_expand = dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_expand"));
+       btn_expand->signal_clicked.connect(sigc::mem_fun(this, &TrainDialog::expand_clicked));
+       lbl_speed = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_speed"));
+       sld_speed = dynamic_cast<GLtk::Slider *>(get_item(widgets, "sld_speed"));
+       sld_speed->signal_value_changed.connect(sigc::mem_fun(this, &TrainDialog::ui_speed_changed));
+       tgl_forward = dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_forward"));
+       tgl_forward->signal_toggled.connect(sigc::mem_fun(this, &TrainDialog::ui_forward_toggled));
+       lbl_status = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_status"));
+       pnl_expander = dynamic_cast<GLtk::Panel *>(get_item(widgets, "pnl_expander"));
+
+       Panel *pnl;
+
+       GLtk::Stack stack(*pnl_expander->get_layout());
+       stack.arrange(*get_item(widgets, "lbl_detail_placeholder"));
+
+       pnl_expander->add(*(pnl = new VehiclesPanel(train)));
+       panels.push_back(pnl);
+       dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_vehicles"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainDialog::toggle_panel), pnl));
+
+       pnl_expander->add(*(pnl = new ControlPanel(engineer, train)));
+       pnl->set_visible(false);
+       panels.push_back(pnl);
+       dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_control"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainDialog::toggle_panel), pnl));
+
+       pnl_expander->add(*(pnl = new RouterPanel(engineer, train)));
+       pnl->set_visible(false);
+       panels.push_back(pnl);
+       dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_router"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainDialog::toggle_panel), pnl));
+
+       AIControl *control = train.get_ai_of_type<AIControl>();
+       if(!control)
+               control = new AIControl(train);
+       update_forward(!control->get_reverse());
+       update_speed_display(control->get_target_speed());
+
+       TrainStatus *status = train.get_ai_of_type<TrainStatus>();
+       if(!status)
+               status = new TrainStatus(train);
+       lbl_status->set_text(status->get_status());
+
+       train.signal_ai_event.connect(sigc::mem_fun(this, &TrainDialog::ai_event));
+}
+
+void TrainDialog::ai_event(TrainAI &, const TrainAI::Message &msg)
+{
+       if(msg.type=="status-changed")
+               lbl_status->set_text(msg.value.value<string>());
+       else if(msg.type=="target-speed-changed")
+               update_speed_display(msg.value.value<float>());
+       else if(msg.type=="reverse-changed")
+               update_forward(!msg.value.value<bool>());
+}
+
+void TrainDialog::update_speed_display(float speed)
+{
+       SetFlag setf(updating);
+       float scale_speed = speed*3.6/train.get_layout().get_catalogue().get_scale();
+       lbl_speed->set_text(format("%3.0f", scale_speed));
+       sld_speed->set_value(scale_speed);
+}
+
+void TrainDialog::ui_speed_changed(double value)
+{
+       if(!updating)
+       {
+               float real_speed = value/3.6*train.get_layout().get_catalogue().get_scale();
+               train.ai_message(TrainAI::Message("set-target-speed", real_speed));
+       }
+}
+
+void TrainDialog::update_forward(bool value)
+{
+       SetFlag setf(updating);
+       tgl_forward->set_value(value);
+}
+
+void TrainDialog::ui_forward_toggled(bool value)
+{
+       if(!updating)
+               train.ai_message(TrainAI::Message("set-reverse", !value));
+}
+
+void TrainDialog::expand_clicked()
+{
+       pnl_expander->set_visible(!pnl_expander->is_visible());
+       btn_expand->set_style(pnl_expander->is_visible() ? "arrow_up" : "arrow_down");
+       GLtk::Geometry ageom = geom;
+       ageom.h = 0;
+       layout->autosize(ageom);
+       ageom.y = geom.y+geom.h-ageom.h;
+       set_geometry(ageom);
+}
+
+void TrainDialog::toggle_panel(bool show, GLtk::Panel *panel)
+{
+       panel->set_visible(show);
+}