]> git.tdb.fi Git - r2c2.git/blob - source/engineer/traindialog.cpp
Complete rewrite of the engineer UI
[r2c2.git] / source / engineer / traindialog.cpp
1 #include <msp/core/maputils.h>
2 #include <msp/core/raii.h>
3 #include <msp/gltk/stack.h>
4 #include <msp/strings/format.h>
5 #include "libr2c2/aicontrol.h"
6 #include "libr2c2/catalogue.h"
7 #include "libr2c2/layout.h"
8 #include "libr2c2/trainstatus.h"
9 #include "controlpanel.h"
10 #include "routerpanel.h"
11 #include "traindialog.h"
12 #include "vehiclespanel.h"
13
14 using namespace std;
15 using namespace Msp;
16 using namespace R2C2;
17
18 TrainDialog::TrainDialog(Engineer &e, R2C2::Train &t):
19         engineer(e),
20         train(t),
21         updating(false)
22 {
23         Loader::WidgetMap widgets;
24         DataFile::load(*this, "data/traindialog.ui", widgets);
25
26         lbl_title = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_title"));
27         lbl_title->set_text(t.get_name());
28
29         btn_expand = dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_expand"));
30         btn_expand->signal_clicked.connect(sigc::mem_fun(this, &TrainDialog::expand_clicked));
31         lbl_speed = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_speed"));
32         sld_speed = dynamic_cast<GLtk::Slider *>(get_item(widgets, "sld_speed"));
33         sld_speed->signal_value_changed.connect(sigc::mem_fun(this, &TrainDialog::ui_speed_changed));
34         tgl_forward = dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_forward"));
35         tgl_forward->signal_toggled.connect(sigc::mem_fun(this, &TrainDialog::ui_forward_toggled));
36         lbl_status = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_status"));
37         pnl_expander = dynamic_cast<GLtk::Panel *>(get_item(widgets, "pnl_expander"));
38
39         Panel *pnl;
40
41         GLtk::Stack stack(*pnl_expander->get_layout());
42         stack.arrange(*get_item(widgets, "lbl_detail_placeholder"));
43
44         pnl_expander->add(*(pnl = new VehiclesPanel(train)));
45         panels.push_back(pnl);
46         dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_vehicles"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainDialog::toggle_panel), pnl));
47
48         pnl_expander->add(*(pnl = new ControlPanel(engineer, train)));
49         pnl->set_visible(false);
50         panels.push_back(pnl);
51         dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_control"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainDialog::toggle_panel), pnl));
52
53         pnl_expander->add(*(pnl = new RouterPanel(engineer, train)));
54         pnl->set_visible(false);
55         panels.push_back(pnl);
56         dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_router"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainDialog::toggle_panel), pnl));
57
58         AIControl *control = train.get_ai_of_type<AIControl>();
59         if(!control)
60                 control = new AIControl(train);
61         update_forward(!control->get_reverse());
62         update_speed_display(control->get_target_speed());
63
64         TrainStatus *status = train.get_ai_of_type<TrainStatus>();
65         if(!status)
66                 status = new TrainStatus(train);
67         lbl_status->set_text(status->get_status());
68
69         train.signal_ai_event.connect(sigc::mem_fun(this, &TrainDialog::ai_event));
70 }
71
72 void TrainDialog::ai_event(TrainAI &, const TrainAI::Message &msg)
73 {
74         if(msg.type=="status-changed")
75                 lbl_status->set_text(msg.value.value<string>());
76         else if(msg.type=="target-speed-changed")
77                 update_speed_display(msg.value.value<float>());
78         else if(msg.type=="reverse-changed")
79                 update_forward(!msg.value.value<bool>());
80 }
81
82 void TrainDialog::update_speed_display(float speed)
83 {
84         SetFlag setf(updating);
85         float scale_speed = speed*3.6/train.get_layout().get_catalogue().get_scale();
86         lbl_speed->set_text(format("%3.0f", scale_speed));
87         sld_speed->set_value(scale_speed);
88 }
89
90 void TrainDialog::ui_speed_changed(double value)
91 {
92         if(!updating)
93         {
94                 float real_speed = value/3.6*train.get_layout().get_catalogue().get_scale();
95                 train.ai_message(TrainAI::Message("set-target-speed", real_speed));
96         }
97 }
98
99 void TrainDialog::update_forward(bool value)
100 {
101         SetFlag setf(updating);
102         tgl_forward->set_value(value);
103 }
104
105 void TrainDialog::ui_forward_toggled(bool value)
106 {
107         if(!updating)
108                 train.ai_message(TrainAI::Message("set-reverse", !value));
109 }
110
111 void TrainDialog::expand_clicked()
112 {
113         pnl_expander->set_visible(!pnl_expander->is_visible());
114         btn_expand->set_style(pnl_expander->is_visible() ? "arrow_up" : "arrow_down");
115         GLtk::Geometry ageom = geom;
116         ageom.h = 0;
117         layout->autosize(ageom);
118         ageom.y = geom.y+geom.h-ageom.h;
119         set_geometry(ageom);
120 }
121
122 void TrainDialog::toggle_panel(bool show, GLtk::Panel *panel)
123 {
124         panel->set_visible(show);
125 }