]> git.tdb.fi Git - r2c2.git/blob - source/designer/objectproperties.cpp
Penalize running against the preferred direction when planning routes
[r2c2.git] / source / designer / objectproperties.cpp
1 #include <msp/gltk/button.h>
2 #include <msp/gltk/column.h>
3 #include <msp/gltk/label.h>
4 #include <msp/gltk/row.h>
5 #include "libr2c2/track.h"
6 #include "libr2c2/tracktype.h"
7 #include "objectproperties.h"
8 #include "selection.h"
9
10 using namespace std;
11 using namespace Msp;
12 using namespace R2C2;
13
14 ObjectProperties::ObjectProperties(const Selection &selection):
15         properties(0),
16         prev_widget(0)
17 {
18         set_layout(new GLtk::Layout);
19         GLtk::Column col(*layout);
20
21         GLtk::Label *lbl_title;
22
23         add(*(lbl_title = new GLtk::Label("Object properties")));
24         lbl_title->set_style("title");
25         layout->set_expand(*lbl_title, true, false);
26
27         Object *object = selection.get_object();
28         if(Track *track = dynamic_cast<Track *>(object))
29         {
30                 if(track->get_type().is_turnout())
31                 {
32                         if(selection.size()==1)
33                         {
34                                 lbl_title->set_text("Turnout properties");
35                                 properties = new TurnoutProperties(*this, *track);
36                         }
37                 }
38                 else
39                 {
40                         set<Track *> tracks = selection.get_objects<Track>();
41                         if(tracks.size()==selection.size())
42                         {
43                                 bool all_linear = true;
44                                 for(set<Track *>::iterator i=tracks.begin(); (all_linear && i!=tracks.end()); ++i)
45                                         all_linear = !(*i)->get_type().is_turnout();
46                                 if(all_linear)
47                                 {
48                                         lbl_title->set_text("Track properties");
49                                         properties = new TrackCircuitProperties(*this, tracks);
50                                 }
51                         }
52                 }
53         }
54         else if(selection.size()==1)
55         {
56                 if(Signal *signal = dynamic_cast<Signal *>(object))
57                 {
58                         lbl_title->set_text("Signal properties");
59                         properties = new SignalProperties(*this, *signal);
60                 }
61                 else if(BeamGate *gate = dynamic_cast<BeamGate *>(object))
62                 {
63                         lbl_title->set_text("Beam gate properties");
64                         properties = new BeamGateProperties(*this, *gate);
65                 }
66                 else if(Terrain *terrain = dynamic_cast<Terrain *>(object))
67                 {
68                         lbl_title->set_text("Terrain properties");
69                         properties = new TerrainProperties(*this, *terrain);
70                 }
71         }
72
73         if(!properties)
74                 add(*(new GLtk::Label("No properties available")));
75
76         GLtk::Button *btn;
77
78         {
79                 GLtk::Row row(*layout);
80                 row.split();
81                 add_button(*(btn = new GLtk::Button("Cncl")), 0);
82                 btn->set_style("red");
83
84                 add_button(*(btn = new GLtk::Button("OK")), 1);
85                 btn->set_style("green");
86         }
87 }
88
89 GLtk::Entry *ObjectProperties::add_property(const string &label, const string &value, unsigned size)
90 {
91         GLtk::Row row(*layout);
92         add(*(new GLtk::Label(label)));
93
94         GLtk::Entry *entry = new GLtk::Entry(value);
95         add(*entry);
96         if(size)
97                 entry->set_edit_size(size, 1);
98
99         if(prev_widget)
100                 layout->add_constraint(*entry, GLtk::Layout::ALIGN_LEFT, *prev_widget);
101         prev_widget = entry;
102
103         return entry;
104 }
105
106 void ObjectProperties::on_response(int code)
107 {
108         if(code==1 && properties)
109                 properties->apply();
110 }
111
112
113 ObjectProperties::TurnoutProperties::TurnoutProperties(ObjectProperties &p, Track &t):
114         track(t),
115         ent_address(p.add_property("Turnout address", lexical_cast<string>(track.get_turnout_address()), 5))
116 { }
117
118 void ObjectProperties::TurnoutProperties::apply()
119 {
120         track.set_turnout_address(lexical_cast<unsigned>(ent_address->get_text()));
121 }
122
123
124 ObjectProperties::TrackCircuitProperties::TrackCircuitProperties(ObjectProperties &p, const set<Track *> &t):
125         tracks(t),
126         ent_address(p.add_property("Sensor address", string(), 5))
127 {
128         int addr = -1;
129         for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
130         {
131                 int a = (*i)->get_sensor_address();
132                 if(a!=addr)
133                 {
134                         if(addr==-1)
135                                 addr = a;
136                         else
137                                 addr = -2;
138                 }
139         }
140
141         if(addr>=0)
142                 ent_address->set_text(lexical_cast<string>(addr));
143 }
144
145 void ObjectProperties::TrackCircuitProperties::apply()
146 {
147         const string &text = ent_address->get_text();
148         if(!text.empty())
149         {
150                 unsigned addr = lexical_cast<unsigned>(text);
151                 for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
152                         (*i)->set_sensor_address(addr);
153         }
154 }
155
156
157 ObjectProperties::SignalProperties::SignalProperties(ObjectProperties &p, Signal &s):
158         signal(s),
159         ent_address(p.add_property("Signal address", lexical_cast<string>(signal.get_address()), 5))
160 { }
161
162 void ObjectProperties::SignalProperties::apply()
163 {
164         signal.set_address(lexical_cast<unsigned>(ent_address->get_text()));
165 }
166
167
168 ObjectProperties::BeamGateProperties::BeamGateProperties(ObjectProperties &p, BeamGate &g):
169         gate(g),
170         ent_address(p.add_property("Sensor address", lexical_cast<string>(gate.get_address()), 5))
171 { }
172
173 void ObjectProperties::BeamGateProperties::apply()
174 {
175         gate.set_address(lexical_cast<unsigned>(ent_address->get_text()));
176 }
177
178
179 ObjectProperties::TerrainProperties::TerrainProperties(ObjectProperties &p, Terrain &t):
180         terrain(t),
181         ent_width(p.add_property("Width", lexical_cast<string>(terrain.get_width()), 4)),
182         ent_height(p.add_property("Height", lexical_cast<string>(terrain.get_height()), 4))
183 { }
184
185 void ObjectProperties::TerrainProperties::apply()
186 {
187         unsigned width = lexical_cast<unsigned>(ent_width->get_text());
188         unsigned height = lexical_cast<unsigned>(ent_height->get_text());
189         terrain.set_size(width, height);
190 }