]> git.tdb.fi Git - r2c2.git/blob - source/engineer/trainlistdialog.cpp
Display protocol in the train list
[r2c2.git] / source / engineer / trainlistdialog.cpp
1 #include <msp/core/maputils.h>
2 #include <msp/gltk/button.h>
3 #include <msp/gltk/style.h>
4 #include "engineer.h"
5 #include "libr2c2/train.h"
6 #include "newtraindialog.h"
7 #include "traindialog.h"
8 #include "trainlistdialog.h"
9
10 using namespace std;
11 using namespace Msp;
12 using namespace R2C2;
13
14 class TrainItem: public GLtk::List::Item
15 {
16 private:
17         GLtk::Label protocol;
18         GLtk::Label address;
19         GLtk::Label name;
20
21 public: 
22         typedef R2C2::Train *ValueType;
23
24         TrainItem(ValueType);
25
26 private:
27         virtual void on_style_change();
28 };
29
30
31 TrainListDialog::TrainListDialog(Engineer &e):
32         engineer(e),
33         layout(engineer.get_layout())
34 {
35         Loader::WidgetMap widgets;
36         DataFile::load(*this, "data/trainlistdialog.ui", widgets);
37
38         lst_trains = dynamic_cast<GLtk::List *>(get_item(widgets, "lst_trains"));
39         lst_trains->set_data(trains);
40         lst_trains->set_item_type<TrainItem>();
41
42         dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_new"))->signal_clicked.connect(sigc::mem_fun(this, &TrainListDialog::new_clicked));
43         dynamic_cast<GLtk::Button *>(get_item(widgets, "btn_show"))->signal_clicked.connect(sigc::mem_fun(this, &TrainListDialog::show_clicked));
44
45         const map<unsigned, Train *> &ltrains = layout.get_trains();
46         for(map<unsigned, Train *>::const_iterator i=ltrains.begin(); i!=ltrains.end(); ++i)
47         {
48                 trains.append(i->second);
49                 i->second->signal_name_changed.connect(sigc::hide(sigc::bind(sigc::mem_fun(this, &TrainListDialog::train_name_changed), sigc::ref(*i->second))));
50         }
51
52         layout.signal_train_added.connect(sigc::mem_fun(this, &TrainListDialog::train_added));
53         layout.signal_train_removed.connect(sigc::mem_fun(this, &TrainListDialog::train_removed));
54 }
55
56 void TrainListDialog::new_clicked()
57 {
58         NewTrainDialog *dlg = new NewTrainDialog(engineer);
59         find_ancestor<GLtk::Root>()->add(*dlg);
60         dlg->autosize();
61 }
62
63 void TrainListDialog::show_clicked()
64 {
65         int index = lst_trains->get_selected_index();
66         if(index>=0)
67         {
68                 TrainDialog *dlg = new TrainDialog(engineer, *trains.get(index));
69                 find_ancestor<GLtk::Root>()->add(*dlg);
70         }
71 }
72
73 void TrainListDialog::train_added(Train &train)
74 {
75         unsigned n_items = trains.size();
76         unsigned i;
77         for(i=0; i<n_items; ++i)
78                 if(trains.get(i)->get_address()>train.get_address())
79                         break;
80         trains.insert(i, &train);
81
82         train.signal_name_changed.connect(sigc::hide(sigc::bind(sigc::mem_fun(this, &TrainListDialog::train_name_changed), sigc::ref(train))));
83 }
84
85 void TrainListDialog::train_removed(Train &train)
86 {
87         int i = trains.find(&train);
88         if(i>=0)
89                 trains.remove(i);
90 }
91
92 void TrainListDialog::train_name_changed(Train &train)
93 {
94         trains.refresh(&train);
95 }
96
97
98 TrainItem::TrainItem(ValueType train):
99         protocol(train->get_protocol()),
100         address(lexical_cast<string>(train->get_address())),
101         name(train->get_name())
102 {
103         add(protocol);
104         add(address);
105         add(name);
106 }
107
108 void TrainItem::on_style_change()
109 {
110         if(!style)
111                 return;
112
113         protocol.autosize();
114         address.autosize();
115         name.autosize();
116
117         if(const GLtk::Part *part = style->get_part("children"))
118         {
119                 const GLtk::Sides &margin = part->get_margin();
120                 protocol.set_position(margin.left, margin.bottom);
121                 address.set_position(margin.left+30, margin.bottom);
122                 name.set_position(margin.left+60, margin.bottom);
123         }
124 }