#include <iostream>
#include <string>
-#include <map>
#include "panel.hxx"
using std::istream;
-using std::hash_map;
using std::string;
\f
////////////////////////////////////////////////////////////////////////
-// Instruments.
+// Read and construct a panel.
////////////////////////////////////////////////////////////////////////
-struct ActionData
+
+/**
+ * Read a cropped texture.
+ */
+static CroppedTexture
+readTexture (SGPropertyNode node)
{
- FGPanelAction * action;
- int button, x, y, w, h;
-};
+ CroppedTexture texture(node.getStringValue("path"),
+ node.getFloatValue("x1"),
+ node.getFloatValue("y1"),
+ node.getFloatValue("x2", 1.0),
+ node.getFloatValue("y2", 1.0));
+ FG_LOG(FG_INPUT, FG_INFO, "Read texture " << node.getName());
+ return texture;
+}
-struct TransData
+
+/**
+ * Read an action.
+ */
+static FGPanelAction *
+readAction (SGPropertyNode node)
{
- enum Type {
- End = 0,
- Rotation,
- XShift,
- YShift
- };
- Type type;
- const char * propName;
- float min, max, factor, offset;
-};
-
-struct LayerData
+ FGPanelAction * action = 0;
+
+ cerr << "Reading action\n";
+
+ string type = node.getStringValue("type");
+
+ int button = node.getIntValue("button");
+ int x = node.getIntValue("x");
+ int y = node.getIntValue("y");
+ int w = node.getIntValue("w");
+ int h = node.getIntValue("h");
+
+ // Adjust a property value
+ if (type == "adjust") {
+ string propName = node.getStringValue("property");
+ SGValue * value = current_properties.getValue(propName, true);
+ float increment = node.getFloatValue("increment", 1.0);
+ float min = node.getFloatValue("min", 0.0);
+ float max = node.getFloatValue("max", 0.0);
+ bool wrap = node.getBoolValue("wrap", false);
+ if (min == max)
+ FG_LOG(FG_INPUT, FG_ALERT, "Action " << node.getName()
+ << " has same min and max value");
+ action = new FGAdjustAction(button, x, y, w, h, value,
+ increment, min, max, wrap);
+ }
+
+ // Swap two property values
+ else if (type == "swap") {
+ string propName1 = node.getStringValue("property1");
+ string propName2 = node.getStringValue("property2");
+ SGValue * value1 = current_properties.getValue(propName1, true);
+ SGValue * value2 = current_properties.getValue(propName2, true);
+ action = new FGSwapAction(button, x, y, w, h, value1, value2);
+ }
+
+ // Toggle a boolean value
+ else if (type == "toggle") {
+ string propName = node.getStringValue("property");
+ SGValue * value = current_properties.getValue(propName, true);
+ action = new FGToggleAction(button, x, y, w, h, value);
+ }
+
+ // No type supplied
+ else if (type == "") {
+ FG_LOG(FG_INPUT, FG_ALERT, "No type specified for action "
+ << node.getName());
+ return 0;
+ }
+
+ // Unrecognized type
+ else {
+ FG_LOG(FG_INPUT, FG_ALERT, "Unrecognized action type " << node.getName());
+ return 0;
+ }
+
+ return action;
+}
+
+
+/**
+ * Read a single transformation.
+ */
+static FGPanelTransformation *
+readTransformation (SGPropertyNode node)
{
- FGInstrumentLayer * layer;
- TransData transformations[16];
-};
+ FGPanelTransformation * t = new FGPanelTransformation;
+
+ string name = node.getName();
+ string type = node.getStringValue("type");
+ string propName = node.getStringValue("property", "");
+ SGValue * value = 0;
+
+ if (propName != "") {
+ value = current_properties.getValue(propName, true);
+ }
+
+ t->value = value;
+ t->min = node.getFloatValue("min", 0.0);
+ t->max = node.getFloatValue("max", 1.0);
+ t->factor = node.getFloatValue("factor", 1.0);
+ t->offset = node.getFloatValue("offset", 0.0);
+ if (type == "x-shift") {
+ t->type = FGPanelTransformation::XSHIFT;
+ } else if (type == "y-shift") {
+ t->type = FGPanelTransformation::YSHIFT;
+ } else if (type == "rotation") {
+ t->type = FGPanelTransformation::ROTATION;
+ } else if (type == "") {
+ FG_LOG(FG_INPUT, FG_ALERT,
+ "'type' must be specified for transformation");
+ delete t;
+ return 0;
+ } else {
+ FG_LOG(FG_INPUT, FG_ALERT, "Unrecognized transformation: " << type);
+ delete t;
+ return 0;
+ }
-struct InstrumentData
+ FG_LOG(FG_INPUT, FG_INFO, "Read transformation " << name);
+ return t;
+}
+
+
+/**
+ * Read a single layer of an instrument.
+ */
+static FGInstrumentLayer *
+readLayer (SGPropertyNode node)
{
- const char * name;
- int x, y, w, h;
- ActionData actions[16];
- LayerData layers[16];
-};
+ FGInstrumentLayer * l;
+ string name = node.getName();
+
+ CroppedTexture texture = readTexture(node.getSubNode("texture"));
+ l = new FGTexturedLayer(texture,
+ node.getIntValue("w", -1),
+ node.getIntValue("h", -1));
+
+ //
+ // Get the transformations for each layer.
+ //
+ SGPropertyNode trans_group = node.getSubNode("transformations");
+ int nTransformations = trans_group.size();
+ for (int k = 0; k < nTransformations; k++) {
+ FGPanelTransformation * t = readTransformation(trans_group.getChild(k));
+ if (t == 0) {
+ delete l;
+ return 0;
+ }
+ l->addTransformation(t);
+ }
+
+ FG_LOG(FG_INPUT, FG_INFO, "Read layer " << name);
+ return l;
+}
-\f
-////////////////////////////////////////////////////////////////////////
-// Read and construct a panel.
-////////////////////////////////////////////////////////////////////////
+/**
+ * Read an instrument.
+ */
+static FGPanelInstrument *
+readInstrument (SGPropertyNode node)
+{
+ const string &name = node.getStringValue("name");
+
+ FG_LOG(FG_INPUT, FG_INFO, "Reading instrument " << name);
+
+ FGLayeredInstrument * instrument =
+ new FGLayeredInstrument(0, 0,
+ node.getIntValue("w"),
+ node.getIntValue("h"));
+
+ //
+ // Get the actions for the instrument.
+ //
+ SGPropertyNode action_group = node.getSubNode("actions");
+ int nActions = action_group.size();
+ cerr << "There are " << nActions << " actions\n";
+ for (int j = 0; j < nActions; j++) {
+ FGPanelAction * action = readAction(action_group.getChild(j));
+ if (action == 0) {
+ delete instrument;
+ return 0;
+ }
+ instrument->addAction(action);
+ }
+
+ //
+ // Get the layers for the instrument.
+ //
+ SGPropertyNode layer_group = node.getSubNode("layers");
+ int nLayers = layer_group.size();
+ for (int j = 0; j < nLayers; j++) {
+ FGInstrumentLayer * layer = readLayer(layer_group.getChild(j));
+ if (layer == 0) {
+ delete instrument;
+ return 0;
+ }
+ instrument->addLayer(layer);
+ }
+
+ FG_LOG(FG_INPUT, FG_INFO, "Done reading instrument " << name);
+ return instrument;
+}
/**
fgReadPanel (istream &input)
{
SGPropertyList props;
- map<string,CroppedTexture> textures;
//
FG_LOG(FG_INPUT, FG_INFO, "Read properties for panel " <<
props.getStringValue("/name"));
- //
- // Read the cropped textures from the property list.
- //
- SGPropertyNode texture_group("/textures", &props);
- int nTextures = texture_group.size();
- cout << "There are " << nTextures << " textures" << endl;
- for (int i = 0; i < nTextures; i++) {
- SGPropertyNode tex = texture_group.getChild(i);
- const string &name = tex.getName();
- textures[name] = CroppedTexture(tex.getStringValue("path"),
- tex.getFloatValue("x1"),
- tex.getFloatValue("y1"),
- tex.getFloatValue("x2", 1.0),
- tex.getFloatValue("y2", 1.0));
- FG_LOG(FG_INPUT, FG_INFO, "Read texture " << name);
- }
-
-
//
// Construct a new, empty panel.
//
FGPanel * panel = new FGPanel(0, 0, 1024, 768);// FIXME: use variable size
-
//
// Assign the background texture, if any, or a bogus chequerboard.
//
string bgTexture = props.getStringValue("/background");
- if (bgTexture == "") {
- panel->setBackground(FGTextureManager::createTexture("FOO"));
- } else {
- panel->setBackground(textures[bgTexture].texture);
- }
+ if (bgTexture == "")
+ bgTexture = "FOO";
+ panel->setBackground(FGTextureManager::createTexture(bgTexture.c_str()));
FG_LOG(FG_INPUT, FG_INFO, "Set background texture to " << bgTexture);
FG_LOG(FG_INPUT, FG_INFO, "Reading panel instruments");
SGPropertyNode instrument_group("/instruments", &props);
int nInstruments = instrument_group.size();
- cout << "There are " << nInstruments << " instruments" << endl;
for (int i = 0; i < nInstruments; i++) {
- SGPropertyNode inst = instrument_group.getChild(i);
- const string &name = inst.getName();
- FGLayeredInstrument * instrument =
- new FGLayeredInstrument(inst.getIntValue("x"),
- inst.getIntValue("y"),
- inst.getIntValue("w"),
- inst.getIntValue("h"));
-
-
- //
- // Get the layers for each instrument.
- //
- SGPropertyNode layer_group = inst.getSubNode("layers");
- SGPropertyNode layer;
- int nLayers = layer_group.size();
- cout << "There are " << nLayers << " layers" << endl;
- for (int j = 0; j < nLayers; j++) {
- layer = layer_group.getChild(j);
- FGInstrumentLayer * l;
- string name = layer.getName();
-
- string tex = layer.getStringValue("texture");
- if (tex != "") {
- l = new FGTexturedLayer(textures[tex],
- layer.getIntValue("w", -1),
- layer.getIntValue("h", -1));
- } else {
- FG_LOG(FG_INPUT, FG_ALERT, "No texture for layer " << name);
- return 0;
- }
-
- //
- // Get the transformations for each layer.
- //
- SGPropertyNode trans_group = layer.getSubNode("transformations");
- SGPropertyNode trans;
- int nTransformations = trans_group.size();
- cout << "There are " << nTransformations << " transformations" << endl;
- for (int k = 0; k < nTransformations; k++) {
- trans = trans_group.getChild(k);
- string name = trans.getName();
- string type = trans.getStringValue("type");
- string propName = trans.getStringValue("property", "");
- SGValue * value = 0;
- cout << "Type is " << type << endl;
- if (propName != "") {
- value = current_properties.getValue(propName, true);
- }
- if (type == "x-shift") {
- l->addTransformation(FGInstrumentLayer::XSHIFT,
- value,
- trans.getFloatValue("min", 0.0),
- trans.getFloatValue("max", 1.0),
- trans.getFloatValue("factor", 1.0),
- trans.getFloatValue("offset", 0.0));
- } else if (type == "y-shift") {
- l->addTransformation(FGInstrumentLayer::YSHIFT,
- value,
- trans.getFloatValue("min", 0.0),
- trans.getFloatValue("max", 1.0),
- trans.getFloatValue("factor", 1.0),
- trans.getFloatValue("offset", 0.0));
- } else if (type == "rotation") {
- l->addTransformation(FGInstrumentLayer::ROTATION,
- value,
- trans.getFloatValue("min", -360.0),
- trans.getFloatValue("max", 360.0),
- trans.getFloatValue("factor", 1.0),
- trans.getFloatValue("offset", 0.0));
- } else if (type == "") {
- FG_LOG(FG_INPUT, FG_ALERT,
- "'type' must be specified for transformation");
- return 0;
- } else {
- FG_LOG(FG_INPUT, FG_ALERT, "Unrecognized transformation: " << type);
- return 0;
- }
- FG_LOG(FG_INPUT, FG_INFO, "Read transformation " << name);
- }
-
- instrument->addLayer(l);
- FG_LOG(FG_INPUT, FG_INFO, "Read layer " << name);
+ SGPropertyList props2;
+ SGPropertyNode node = instrument_group.getChild(i);
+
+ string path = node.getStringValue("path");
+ int x = node.getIntValue("x");
+ int y = node.getIntValue("y");
+ int w = node.getIntValue("w");
+ int h = node.getIntValue("h");
+
+ FG_LOG(FG_INPUT, FG_INFO, "Reading instrument "
+ << node.getName()
+ << " from "
+ << path);
+
+ if (!readPropertyList(path, &props2)) {
+ delete panel;
+ return 0;
}
+ FGPanelInstrument * instrument =
+ readInstrument(SGPropertyNode("/", &props2));
+ if (instrument == 0) {
+ delete instrument;
+ delete panel;
+ return 0;
+ }
+ instrument->setPosition(x, y);
panel->addInstrument(instrument);
- FG_LOG(FG_INPUT, FG_INFO, "Read instrument " << name);
}
+ FG_LOG(FG_INPUT, FG_INFO, "Done reading panel instruments");
//
//
return panel;
}
+
+
+// end of panel_io.cxx