1 #include <msp/core/maputils.h>
2 #include <msp/core/raii.h>
3 #include <msp/gltk/button.h>
4 #include <msp/gltk/label.h>
5 #include <msp/gltk/row.h>
6 #include "libr2c2/vehicle.h"
7 #include "controlpanel.h"
9 #include "placementghost.h"
10 #include "trainview.h"
16 ControlPanel::ControlPanel(Engineer &e, Train &t):
22 Loader::WidgetMap widgets;
23 DataFile::load(*this, "data/controlpanel.ui", widgets);
25 dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_protocol"))->set_text(train.get_protocol());
26 dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_address"))->set_text(lexical_cast<string>(train.get_address()));
28 dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_place"))->signal_clicked.connect(sigc::mem_fun(this, &ControlPanel::place_clicked));
29 dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_take"))->signal_clicked.connect(sigc::mem_fun(this, &ControlPanel::take_clicked));
30 dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_view"))->signal_clicked.connect(sigc::mem_fun(this, &ControlPanel::view_clicked));
32 GLtk::Panel *pnl_functions = dynamic_cast<GLtk::Panel *>(get_item(widgets, "pnl_functions"));
34 const VehicleType::FunctionMap &funcs = train.get_vehicle(0).get_type().get_functions();
35 GLtk::Row row(*pnl_functions->get_layout());
36 for(VehicleType::FunctionMap::const_iterator i=funcs.begin(); i!=funcs.end(); ++i)
38 GLtk::Toggle *tgl = new GLtk::Toggle(i->second);
39 tgl->set_value(train.get_function(i->first));
40 tgl->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &ControlPanel::ui_function_toggled), i->first));
41 pnl_functions->add(*tgl);
42 tgl_funcs[i->first] = tgl;
45 train.signal_function_changed.connect(sigc::mem_fun(this, &ControlPanel::train_function_changed));
48 void ControlPanel::ui_function_toggled(bool value, unsigned func)
51 train.set_function(func, value);
54 void ControlPanel::train_function_changed(unsigned func, bool value)
56 SetFlag setf(updating);
57 map<unsigned, GLtk::Toggle *>::iterator i = tgl_funcs.find(func);
58 if(i!=tgl_funcs.end())
59 i->second->set_value(value);
62 void ControlPanel::place_clicked()
64 signal_grab_pointer.emit();
67 Layout3D &layout3d = engineer.get_layout_3d();
68 unsigned n_vehs = train.get_n_vehicles();
69 for(unsigned i=0; i<n_vehs; ++i)
70 ghosts.push_back(new PlacementGhost(layout3d, train.get_vehicle(i).get_type()));
73 void ControlPanel::take_clicked()
78 void ControlPanel::view_clicked()
80 TrainView *dlg = new TrainView(engineer, train);
81 find_ancestor<GLtk::Root>()->add(*dlg);
85 void ControlPanel::button_press(int x, int y, unsigned btn)
87 Panel::button_press(x, y, btn);
91 signal_ungrab_pointer.emit();
94 for(vector<PlacementGhost *>::iterator i=ghosts.begin(); i!=ghosts.end(); ++i)
98 if(btn==1 && place_location)
99 train.place(place_location);
103 void ControlPanel::pointer_motion(int x, int y)
105 Panel::pointer_motion(x, y);
111 map_coords_to_ancestor(rx, ry, *find_ancestor<GLtk::Root>());
112 Ray ray = engineer.get_main_view().create_ray(rx, ry);
113 Vector ground = ray.get_start()-ray.get_direction()*ray.get_start().z/ray.get_direction().z;
114 Track *track = engineer.get_layout().pick<Track>(ray);
117 const vector<Block::Endpoint> &eps = track->get_block().get_endpoints();
119 float closest_dist = -1;
120 for(unsigned i=0; i<eps.size(); ++i)
122 Snap sn = eps[i].track->get_snap_node(eps[i].track_ep);
123 float d = (sn.position-ground).norm();
124 if(d<closest_dist || closest_dist<0)
133 place_location = BlockIter(&track->get_block(), closest_ep);
134 ghosts.back()->place(place_location.track_iter());
135 for(unsigned i=ghosts.size()-1; i--; )
136 ghosts[i]->place_before(*ghosts[i+1]);