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>
43 ////////////////////////////////////////////////////////////////////////
44 // Read and construct a panel.
45 ////////////////////////////////////////////////////////////////////////
49 * Read a cropped texture.
52 readTexture (SGPropertyNode node)
54 CroppedTexture texture(node.getStringValue("path"),
55 node.getFloatValue("x1"),
56 node.getFloatValue("y1"),
57 node.getFloatValue("x2", 1.0),
58 node.getFloatValue("y2", 1.0));
59 FG_LOG(FG_INPUT, FG_INFO, "Read texture " << node.getName());
67 static FGPanelAction *
68 readAction (SGPropertyNode node)
70 FGPanelAction * action = 0;
72 cerr << "Reading action\n";
74 string type = node.getStringValue("type");
76 int button = node.getIntValue("button");
77 int x = node.getIntValue("x");
78 int y = node.getIntValue("y");
79 int w = node.getIntValue("w");
80 int h = node.getIntValue("h");
82 // Adjust a property value
83 if (type == "adjust") {
84 string propName = node.getStringValue("property");
85 SGValue * value = current_properties.getValue(propName, true);
86 float increment = node.getFloatValue("increment", 1.0);
87 float min = node.getFloatValue("min", 0.0);
88 float max = node.getFloatValue("max", 0.0);
89 bool wrap = node.getBoolValue("wrap", false);
91 FG_LOG(FG_INPUT, FG_ALERT, "Action " << node.getName()
92 << " has same min and max value");
93 action = new FGAdjustAction(button, x, y, w, h, value,
94 increment, min, max, wrap);
97 // Swap two property values
98 else if (type == "swap") {
99 string propName1 = node.getStringValue("property1");
100 string propName2 = node.getStringValue("property2");
101 SGValue * value1 = current_properties.getValue(propName1, true);
102 SGValue * value2 = current_properties.getValue(propName2, true);
103 action = new FGSwapAction(button, x, y, w, h, value1, value2);
106 // Toggle a boolean value
107 else if (type == "toggle") {
108 string propName = node.getStringValue("property");
109 SGValue * value = current_properties.getValue(propName, true);
110 action = new FGToggleAction(button, x, y, w, h, value);
114 else if (type == "") {
115 FG_LOG(FG_INPUT, FG_ALERT, "No type specified for action "
122 FG_LOG(FG_INPUT, FG_ALERT, "Unrecognized action type " << node.getName());
131 * Read a single transformation.
133 static FGPanelTransformation *
134 readTransformation (SGPropertyNode node)
136 FGPanelTransformation * t = new FGPanelTransformation;
138 string name = node.getName();
139 string type = node.getStringValue("type");
140 string propName = node.getStringValue("property", "");
143 if (propName != "") {
144 value = current_properties.getValue(propName, true);
148 t->min = node.getFloatValue("min", 0.0);
149 t->max = node.getFloatValue("max", 1.0);
150 t->factor = node.getFloatValue("factor", 1.0);
151 t->offset = node.getFloatValue("offset", 0.0);
152 if (type == "x-shift") {
153 t->type = FGPanelTransformation::XSHIFT;
154 } else if (type == "y-shift") {
155 t->type = FGPanelTransformation::YSHIFT;
156 } else if (type == "rotation") {
157 t->type = FGPanelTransformation::ROTATION;
158 } else if (type == "") {
159 FG_LOG(FG_INPUT, FG_ALERT,
160 "'type' must be specified for transformation");
164 FG_LOG(FG_INPUT, FG_ALERT, "Unrecognized transformation: " << type);
169 FG_LOG(FG_INPUT, FG_INFO, "Read transformation " << name);
175 * Read a single layer of an instrument.
177 static FGInstrumentLayer *
178 readLayer (SGPropertyNode node)
180 FGInstrumentLayer * l;
181 string name = node.getName();
183 CroppedTexture texture = readTexture(node.getSubNode("texture"));
184 l = new FGTexturedLayer(texture,
185 node.getIntValue("w", -1),
186 node.getIntValue("h", -1));
189 // Get the transformations for each layer.
191 SGPropertyNode trans_group = node.getSubNode("transformations");
192 int nTransformations = trans_group.size();
193 for (int k = 0; k < nTransformations; k++) {
194 FGPanelTransformation * t = readTransformation(trans_group.getChild(k));
199 l->addTransformation(t);
202 FG_LOG(FG_INPUT, FG_INFO, "Read layer " << name);
208 * Read an instrument.
210 static FGPanelInstrument *
211 readInstrument (SGPropertyNode node)
213 const string &name = node.getStringValue("name");
215 FG_LOG(FG_INPUT, FG_INFO, "Reading instrument " << name);
217 FGLayeredInstrument * instrument =
218 new FGLayeredInstrument(0, 0,
219 node.getIntValue("w"),
220 node.getIntValue("h"));
223 // Get the actions for the instrument.
225 SGPropertyNode action_group = node.getSubNode("actions");
226 int nActions = action_group.size();
227 cerr << "There are " << nActions << " actions\n";
228 for (int j = 0; j < nActions; j++) {
229 FGPanelAction * action = readAction(action_group.getChild(j));
234 instrument->addAction(action);
238 // Get the layers for the instrument.
240 SGPropertyNode layer_group = node.getSubNode("layers");
241 int nLayers = layer_group.size();
242 for (int j = 0; j < nLayers; j++) {
243 FGInstrumentLayer * layer = readLayer(layer_group.getChild(j));
248 instrument->addLayer(layer);
251 FG_LOG(FG_INPUT, FG_INFO, "Done reading instrument " << name);
257 * Read a property list defining an instrument panel.
259 * Returns 0 if the read fails for any reason.
262 fgReadPanel (istream &input)
264 SGPropertyList props;
268 // Read the property list from disk.
270 if (!readPropertyList(input, &props)) {
271 FG_LOG(FG_INPUT, FG_ALERT, "Malformed property list for panel.");
274 FG_LOG(FG_INPUT, FG_INFO, "Read properties for panel " <<
275 props.getStringValue("/name"));
278 // Construct a new, empty panel.
280 FGPanel * panel = new FGPanel(0, 0, 1024, 768);// FIXME: use variable size
283 // Assign the background texture, if any, or a bogus chequerboard.
285 string bgTexture = props.getStringValue("/background");
288 panel->setBackground(FGTextureManager::createTexture(bgTexture.c_str()));
289 FG_LOG(FG_INPUT, FG_INFO, "Set background texture to " << bgTexture);
293 // Create each instrument.
295 FG_LOG(FG_INPUT, FG_INFO, "Reading panel instruments");
296 SGPropertyNode instrument_group("/instruments", &props);
297 int nInstruments = instrument_group.size();
298 for (int i = 0; i < nInstruments; i++) {
299 SGPropertyList props2;
300 SGPropertyNode node = instrument_group.getChild(i);
302 string path = node.getStringValue("path");
303 int x = node.getIntValue("x");
304 int y = node.getIntValue("y");
305 int w = node.getIntValue("w");
306 int h = node.getIntValue("h");
308 FG_LOG(FG_INPUT, FG_INFO, "Reading instrument "
313 if (!readPropertyList(path, &props2)) {
318 FGPanelInstrument * instrument =
319 readInstrument(SGPropertyNode("/", &props2));
320 if (instrument == 0) {
325 instrument->setPosition(x, y);
326 panel->addInstrument(instrument);
328 FG_LOG(FG_INPUT, FG_INFO, "Done reading panel instruments");
332 // Return the new panel.
338 // end of panel_io.cxx