1 // panel_io.cxx - I/O for 2D panel.
3 // Written by David Megginson, started January 2000.
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <simgear/compiler.h>
30 #include <simgear/debug/logstream.hxx>
31 #include <simgear/misc/props.hxx>
45 ////////////////////////////////////////////////////////////////////////
47 ////////////////////////////////////////////////////////////////////////
51 FGPanelAction * action;
52 int button, x, y, w, h;
64 const char * propName;
65 float min, max, factor, offset;
70 FGInstrumentLayer * layer;
71 TransData transformations[16];
78 ActionData actions[16];
84 ////////////////////////////////////////////////////////////////////////
85 // Read and construct a panel.
86 ////////////////////////////////////////////////////////////////////////
90 * Read a property list defining an instrument panel.
92 * Returns 0 if the read fails for any reason.
95 fgReadPanel (istream &input)
98 map<string,CroppedTexture> textures;
102 // Read the property list from disk.
104 if (!readPropertyList(input, &props)) {
105 FG_LOG(FG_INPUT, FG_ALERT, "Malformed property list for panel.");
108 FG_LOG(FG_INPUT, FG_INFO, "Read properties for panel " <<
109 props.getStringValue("/name"));
112 // Read the cropped textures from the property list.
114 SGPropertyNode texture_group("/textures", &props);
115 int nTextures = texture_group.size();
116 cout << "There are " << nTextures << " textures" << endl;
117 for (int i = 0; i < nTextures; i++) {
118 SGPropertyNode tex = texture_group.getChild(i);
119 const string &name = tex.getName();
120 textures[name] = CroppedTexture(tex.getStringValue("path"),
121 tex.getFloatValue("x1"),
122 tex.getFloatValue("y1"),
123 tex.getFloatValue("x2", 1.0),
124 tex.getFloatValue("y2", 1.0));
125 FG_LOG(FG_INPUT, FG_INFO, "Read texture " << name);
130 // Construct a new, empty panel.
132 FGPanel * panel = new FGPanel(0, 0, 1024, 768);// FIXME: use variable size
136 // Assign the background texture, if any, or a bogus chequerboard.
138 string bgTexture = props.getStringValue("/background");
139 if (bgTexture == "") {
140 panel->setBackground(FGTextureManager::createTexture("FOO"));
142 panel->setBackground(textures[bgTexture].texture);
144 FG_LOG(FG_INPUT, FG_INFO, "Set background texture to " << bgTexture);
148 // Create each instrument.
150 FG_LOG(FG_INPUT, FG_INFO, "Reading panel instruments");
151 SGPropertyNode instrument_group("/instruments", &props);
152 int nInstruments = instrument_group.size();
153 cout << "There are " << nInstruments << " instruments" << endl;
154 for (int i = 0; i < nInstruments; i++) {
155 SGPropertyNode inst = instrument_group.getChild(i);
156 const string &name = inst.getName();
157 FGLayeredInstrument * instrument =
158 new FGLayeredInstrument(inst.getIntValue("x"),
159 inst.getIntValue("y"),
160 inst.getIntValue("w"),
161 inst.getIntValue("h"));
165 // Get the layers for each instrument.
167 SGPropertyNode layer_group = inst.getSubNode("layers");
168 SGPropertyNode layer;
169 int nLayers = layer_group.size();
170 cout << "There are " << nLayers << " layers" << endl;
171 for (int j = 0; j < nLayers; j++) {
172 layer = layer_group.getChild(j);
173 FGInstrumentLayer * l;
174 string name = layer.getName();
176 string tex = layer.getStringValue("texture");
178 l = new FGTexturedLayer(textures[tex],
179 layer.getIntValue("w", -1),
180 layer.getIntValue("h", -1));
182 FG_LOG(FG_INPUT, FG_ALERT, "No texture for layer " << name);
187 // Get the transformations for each layer.
189 SGPropertyNode trans_group = layer.getSubNode("transformations");
190 SGPropertyNode trans;
191 int nTransformations = trans_group.size();
192 cout << "There are " << nTransformations << " transformations" << endl;
193 for (int k = 0; k < nTransformations; k++) {
194 trans = trans_group.getChild(k);
195 string name = trans.getName();
196 string type = trans.getStringValue("type");
197 string propName = trans.getStringValue("property", "");
199 cout << "Type is " << type << endl;
200 if (propName != "") {
201 value = current_properties.getValue(propName, true);
203 if (type == "x-shift") {
204 l->addTransformation(FGInstrumentLayer::XSHIFT,
206 trans.getFloatValue("min", 0.0),
207 trans.getFloatValue("max", 1.0),
208 trans.getFloatValue("factor", 1.0),
209 trans.getFloatValue("offset", 0.0));
210 } else if (type == "y-shift") {
211 l->addTransformation(FGInstrumentLayer::YSHIFT,
213 trans.getFloatValue("min", 0.0),
214 trans.getFloatValue("max", 1.0),
215 trans.getFloatValue("factor", 1.0),
216 trans.getFloatValue("offset", 0.0));
217 } else if (type == "rotation") {
218 l->addTransformation(FGInstrumentLayer::ROTATION,
220 trans.getFloatValue("min", -360.0),
221 trans.getFloatValue("max", 360.0),
222 trans.getFloatValue("factor", 1.0),
223 trans.getFloatValue("offset", 0.0));
224 } else if (type == "") {
225 FG_LOG(FG_INPUT, FG_ALERT,
226 "'type' must be specified for transformation");
229 FG_LOG(FG_INPUT, FG_ALERT, "Unrecognized transformation: " << type);
232 FG_LOG(FG_INPUT, FG_INFO, "Read transformation " << name);
235 instrument->addLayer(l);
236 FG_LOG(FG_INPUT, FG_INFO, "Read layer " << name);
239 panel->addInstrument(instrument);
240 FG_LOG(FG_INPUT, FG_INFO, "Read instrument " << name);
245 // Return the new panel.