X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCockpit%2Fpanel_io.cxx;h=0e395a31c08a2cf29a49739f81dd16eaf15ad733;hb=29275ce1ecf9c4ea302aacca8c5ae5d4d3319a17;hp=0bc50368b5fcbb54384a1b6c7903e28c6f54b13e;hpb=830b17c6efc0f3bbdb84fc7e2981130e2b0818a3;p=flightgear.git diff --git a/src/Cockpit/panel_io.cxx b/src/Cockpit/panel_io.cxx index 0bc50368b..0e395a31c 100644 --- a/src/Cockpit/panel_io.cxx +++ b/src/Cockpit/panel_io.cxx @@ -27,23 +27,74 @@ #endif #include + #include #include #include -#include -#include -#include +#include STL_IOSTREAM +#include STL_FSTREAM +#include STL_STRING -#include
+#include
+#include
#include "panel.hxx" #include "steam.hxx" #include "panel_io.hxx" -using std::istream; -using std::ifstream; -using std::string; +#if !defined (FG_HAVE_NATIVE_SGI_COMPILERS) +FG_USING_STD(istream); +FG_USING_STD(ifstream); +#endif +FG_USING_STD(string); + + + +//////////////////////////////////////////////////////////////////////// +// Default panel, instrument, and layer for when things go wrong... +//////////////////////////////////////////////////////////////////////// + +static FGCroppedTexture defaultTexture("Textures/default.rgb"); + + +/** + * Default layer: the default texture. + */ +class DefaultLayer : public FGTexturedLayer +{ +public: + DefaultLayer () : FGTexturedLayer(defaultTexture) + { + } + +}; + +/** + * Default instrument: a single default layer. + */ +class DefaultInstrument : public FGLayeredInstrument +{ +public: + DefaultInstrument (int x, int y, int w, int h) + : FGLayeredInstrument(x, y, w, h) + { + addLayer(new DefaultLayer()); + } +}; + + +/** + * Default panel: the default texture. + */ +class DefaultPanel : public FGPanel +{ +public: + DefaultPanel (int x, int y, int w, int h) : FGPanel(x, y, w, h) + { + setBackground(defaultTexture.getTexture()); + } +}; @@ -66,7 +117,7 @@ public: FGMagRibbon::FGMagRibbon (int w, int h) : FGTexturedLayer(w, h) { - CroppedTexture texture("Textures/Panel/compass-ribbon.rgb"); + FGCroppedTexture texture("Aircraft/c172/Instruments/Textures/compass-ribbon.rgb"); setTexture(texture); } @@ -103,11 +154,8 @@ FGMagRibbon::draw () // Adjust to put the number in the centre xoffset -= 0.25; - CroppedTexture &t = getTexture(); - t.minX = xoffset; - t.minY = yoffset; - t.maxX = xoffset + 0.5; - t.maxY = yoffset + 0.25; + FGCroppedTexture &t = getTexture(); + t.setCrop(xoffset, yoffset, xoffset + 0.5, yoffset + 0.25); FGTexturedLayer::draw(); } @@ -167,15 +215,15 @@ FGMagRibbon::draw () * ending position. For example, to use the bottom-left quarter of a * texture, x1=0.0, y1=0.0, x2=0.5, y2=0.5. */ -static CroppedTexture -readTexture (SGPropertyNode node) +static FGCroppedTexture +readTexture (const SGPropertyNode * node) { - 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()); + FGCroppedTexture 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; } @@ -206,18 +254,18 @@ readTexture (SGPropertyNode node) * being drawn at its regular size. */ static FGPanelAction * -readAction (SGPropertyNode node, float hscale, float vscale) +readAction (const SGPropertyNode * node, float hscale, float vscale) { FGPanelAction * action = 0; - string name = node.getStringValue("name"); - string type = node.getStringValue("type"); + string name = node->getStringValue("name"); + string type = node->getStringValue("type"); - int button = node.getIntValue("button"); - int x = int(node.getIntValue("x") * hscale); - int y = int(node.getIntValue("y") * vscale); - int w = int(node.getIntValue("w") * hscale); - int h = int(node.getIntValue("h") * vscale); + int button = node->getIntValue("button"); + int x = int(node->getIntValue("x") * hscale); + int y = int(node->getIntValue("y") * vscale); + int w = int(node->getIntValue("w") * hscale); + int h = int(node->getIntValue("h") * vscale); if (type == "") { FG_LOG(FG_INPUT, FG_ALERT, @@ -227,14 +275,14 @@ readAction (SGPropertyNode node, float hscale, float vscale) // 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); + string propName = node->getStringValue("property"); + SGValue * value = fgGetValue(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() + 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); @@ -242,17 +290,17 @@ readAction (SGPropertyNode node, float hscale, float vscale) // 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); + string propName1 = node->getStringValue("property1"); + string propName2 = node->getStringValue("property2"); + SGValue * value1 = fgGetValue(propName1, true); + SGValue * value2 = fgGetValue(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); + string propName = node->getStringValue("property"); + SGValue * value = fgGetValue(propName, true); action = new FGToggleAction(button, x, y, w, h, value); } @@ -292,13 +340,13 @@ readAction (SGPropertyNode node, float hscale, float vscale) * appear to be applied backwards. */ static FGPanelTransformation * -readTransformation (SGPropertyNode node, float hscale, float vscale) +readTransformation (const SGPropertyNode * node, float hscale, float vscale) { FGPanelTransformation * t = new FGPanelTransformation; - string name = node.getName(); - string type = node.getStringValue("type"); - string propName = node.getStringValue("property", ""); + string name = node->getName(); + string type = node->getStringValue("type"); + string propName = node->getStringValue("property", ""); SGValue * value = 0; if (type == "") { @@ -308,15 +356,15 @@ readTransformation (SGPropertyNode node, float hscale, float vscale) type = "rotation"; } - if (propName != "") { - value = current_properties.getValue(propName, true); + if (propName != (string)"") { + value = fgGetValue(propName, true); } t->value = value; - t->min = node.getFloatValue("min", -9999999); - t->max = node.getFloatValue("max", 99999999); - t->factor = node.getFloatValue("scale", 1.0); - t->offset = node.getFloatValue("offset", 0.0); + t->min = node->getFloatValue("min", -9999999); + t->max = node->getFloatValue("max", 99999999); + t->factor = node->getFloatValue("scale", 1.0); + t->offset = node->getFloatValue("offset", 0.0); // Move the layer horizontally. if (type == "x-shift") { @@ -369,12 +417,12 @@ readTransformation (SGPropertyNode node, float hscale, float vscale) * All three may also include a printf-style format string. */ FGTextLayer::Chunk * -readTextChunk (SGPropertyNode node) +readTextChunk (const SGPropertyNode * node) { FGTextLayer::Chunk * chunk; - string name = node.getStringValue("name"); - string type = node.getStringValue("type"); - string format = node.getStringValue("format"); + string name = node->getStringValue("name"); + string type = node->getStringValue("type"); + string format = node->getStringValue("format"); // Default to literal text. if (type == "") { @@ -385,22 +433,22 @@ readTextChunk (SGPropertyNode node) // A literal text string. if (type == "literal") { - string text = node.getStringValue("text"); + string text = node->getStringValue("text"); chunk = new FGTextLayer::Chunk(text, format); } // The value of a string property. else if (type == "text-value") { SGValue * value = - current_properties.getValue(node.getStringValue("property"), true); + fgGetValue(node->getStringValue("property"), true); chunk = new FGTextLayer::Chunk(FGTextLayer::TEXT_VALUE, value, format); } // The value of a float property. else if (type == "number-value") { - string propName = node.getStringValue("property"); - float scale = node.getFloatValue("scale", 1.0); - SGValue * value = current_properties.getValue(propName, true); + string propName = node->getStringValue("property"); + float scale = node->getFloatValue("scale", 1.0); + SGValue * value = fgGetValue(propName, true); chunk = new FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE, value, format, scale); } @@ -438,13 +486,13 @@ readTextChunk (SGPropertyNode node) * Currently, the only built-in layer class is "compass-ribbon". */ static FGInstrumentLayer * -readLayer (SGPropertyNode node, float hscale, float vscale) +readLayer (const SGPropertyNode * node, float hscale, float vscale) { - FGInstrumentLayer * layer; - string name = node.getStringValue("name"); - string type = node.getStringValue("type"); - int w = node.getIntValue("w", -1); - int h = node.getIntValue("h", -1); + FGInstrumentLayer * layer = NULL; + string name = node->getStringValue("name"); + string type = node->getStringValue("type"); + int w = node->getIntValue("w", -1); + int h = node->getIntValue("h", -1); if (w != -1) w = int(w * hscale); if (h != -1) @@ -461,7 +509,7 @@ readLayer (SGPropertyNode node, float hscale, float vscale) // A textured instrument layer. if (type == "texture") { - CroppedTexture texture = readTexture(node.getSubNode("texture")); + FGCroppedTexture texture = readTexture(node->getNode("texture")); layer = new FGTexturedLayer(texture, w, h); } @@ -471,45 +519,47 @@ readLayer (SGPropertyNode node, float hscale, float vscale) FGTextLayer * tlayer = new FGTextLayer(w, h); // FIXME // Set the text color. - float red = node.getFloatValue("color/red", 0.0); - float green = node.getFloatValue("color/green", 0.0); - float blue = node.getFloatValue("color/blue", 0.0); + float red = node->getFloatValue("color/red", 0.0); + float green = node->getFloatValue("color/green", 0.0); + float blue = node->getFloatValue("color/blue", 0.0); tlayer->setColor(red, green, blue); // Set the point size. - float pointSize = node.getFloatValue("point-size", 10.0) * hscale; + float pointSize = node->getFloatValue("point-size", 10.0) * hscale; tlayer->setPointSize(pointSize); // Set the font. // TODO - SGPropertyNode chunk_group = node.getSubNode("chunks"); - int nChunks = chunk_group.size(); - for (int i = 0; i < nChunks; i++) { - FGTextLayer::Chunk * chunk = readTextChunk(chunk_group.getChild(i)); - if (chunk == 0) { - delete layer; - return 0; + const SGPropertyNode * chunk_group = node->getNode("chunks"); + if (chunk_group != 0) { + int nChunks = chunk_group->nChildren(); + for (int i = 0; i < nChunks; i++) { + FGTextLayer::Chunk * chunk = readTextChunk(chunk_group->getChild(i)); + if (chunk == 0) { + delete layer; + return 0; + } + tlayer->addChunk(chunk); } - tlayer->addChunk(chunk); + layer = tlayer; } - layer = tlayer; } // A switch instrument layer. else if (type == "switch") { SGValue * value = - current_properties.getValue(node.getStringValue("property")); + fgGetValue(node->getStringValue("property"), true); FGInstrumentLayer * layer1 = - readLayer(node.getSubNode("layer1"), hscale, vscale); + readLayer(node->getNode("layer1"), hscale, vscale); FGInstrumentLayer * layer2 = - readLayer(node.getSubNode("layer2"), hscale, vscale); + readLayer(node->getNode("layer2"), hscale, vscale); layer = new FGSwitchLayer(w, h, value, layer1, layer2); } // A built-in instrument layer. else if (type == "built-in") { - string layerclass = node.getStringValue("class"); + string layerclass = node->getStringValue("class"); if (layerclass == "mag-ribbon") { layer = new FGMagRibbon(w, h); @@ -538,16 +588,18 @@ readLayer (SGPropertyNode node, float hscale, float vscale) // // 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), - hscale, vscale); - if (t == 0) { - delete layer; - return 0; + const SGPropertyNode * trans_group = node->getNode("transformations"); + if (trans_group != 0) { + int nTransformations = trans_group->nChildren(); + for (int i = 0; i < nTransformations; i++) { + FGPanelTransformation * t = readTransformation(trans_group->getChild(i), + hscale, vscale); + if (t == 0) { + delete layer; + return 0; + } + layer->addTransformation(t); } - layer->addTransformation(t); } FG_LOG(FG_INPUT, FG_INFO, "Read layer " << name); @@ -567,23 +619,22 @@ readLayer (SGPropertyNode node, float hscale, float vscale) * scaled automatically if the instrument is not at its preferred size. */ static FGPanelInstrument * -readInstrument (SGPropertyNode node, int x, int y, int real_w, int real_h) +readInstrument (const SGPropertyNode * node, int x, int y, + int real_w, int real_h) { - int w = node.getIntValue("w"); - int h = node.getIntValue("h"); - const string &name = node.getStringValue("name"); + int w = node->getIntValue("w"); + int h = node->getIntValue("h"); + const string &name = node->getStringValue("name"); float hscale = 1.0; float vscale = 1.0; if (real_w != -1) { hscale = float(real_w) / float(w); w = real_w; - cerr << "hscale is " << hscale << endl; } if (real_h != -1) { vscale = float(real_h) / float(h); h = real_h; - cerr << "vscale is " << hscale << endl; } FG_LOG(FG_INPUT, FG_INFO, "Reading instrument " << name); @@ -594,33 +645,37 @@ readInstrument (SGPropertyNode node, int x, int y, int real_w, int real_h) // // Get the actions for the instrument. // - SGPropertyNode action_group = node.getSubNode("actions"); - int nActions = action_group.size(); - for (int j = 0; j < nActions; j++) { - FGPanelAction * action = readAction(action_group.getChild(j), - hscale, vscale); - if (action == 0) { - delete instrument; - return 0; + const SGPropertyNode * action_group = node->getNode("actions"); + if (action_group != 0) { + int nActions = action_group->nChildren(); + for (int i = 0; i < nActions; i++) { + FGPanelAction * action = readAction(action_group->getChild(i), + hscale, vscale); + if (action == 0) { + delete instrument; + return new DefaultInstrument(x, y, w, h); + } + instrument->addAction(action); } - 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), - hscale, vscale); - if (layer == 0) { - delete instrument; - return 0; + const SGPropertyNode * layer_group = node->getNode("layers"); + if (layer_group != 0) { + int nLayers = layer_group->nChildren(); + for (int i = 0; i < nLayers; i++) { + FGInstrumentLayer * layer = readLayer(layer_group->getChild(i), + hscale, vscale); + if (layer == 0) { + delete instrument; + return new DefaultInstrument(x, y, w, h); + } + instrument->addLayer(layer); } - instrument->addLayer(layer); } - + FG_LOG(FG_INPUT, FG_INFO, "Done reading instrument " << name); return instrument; } @@ -639,28 +694,56 @@ readInstrument (SGPropertyNode node, int x, int y, int real_w, int real_h) FGPanel * fgReadPanel (istream &input) { - SGPropertyList props; + SGPropertyNode root; // // Read the property list from disk. // - if (!readPropertyList(input, &props)) { + if (!readProperties(input, &root)) { FG_LOG(FG_INPUT, FG_ALERT, "Malformed property list for panel."); return 0; } FG_LOG(FG_INPUT, FG_INFO, "Read properties for panel " << - props.getStringValue("/name")); + root.getStringValue("name")); // // Construct a new, empty panel. // FGPanel * panel = new FGPanel(0, 0, 1024, 768);// FIXME: use variable size + + // + // Grab the panel's dimensions, default to 1024x443. + // + int panel_w = (root.hasValue("w") ? root.getIntValue("w") : 1024); + int panel_h = (root.hasValue("h") ? root.getIntValue("h") : 443); + panel->setWidth(panel_w); + panel->setHeight(panel_h); + + // + // Grab the visible external viewing area, default to + // + panel->setViewHeight(root.hasValue("view-height") ? + root.getIntValue("view-height") : + 768 - panel_h + 2); + + // + // Grab the panel's initial offsets, default to 0, 0. + // + int xoffset = (root.hasValue("x-offset") ? + root.getIntValue("x-offset") : + 0); + int yoffset = (root.hasValue("y-offset") ? + root.getIntValue("y-offset") : + 0); + panel->setXOffset(xoffset); + panel->setYOffset(yoffset); + // // Assign the background texture, if any, or a bogus chequerboard. // - string bgTexture = props.getStringValue("/background"); + string bgTexture = root.getStringValue("background"); if (bgTexture == "") bgTexture = "FOO"; panel->setBackground(FGTextureManager::createTexture(bgTexture.c_str())); @@ -671,44 +754,46 @@ fgReadPanel (istream &input) // Create each instrument. // FG_LOG(FG_INPUT, FG_INFO, "Reading panel instruments"); - SGPropertyNode instrument_group("/instruments", &props); - int nInstruments = instrument_group.size(); - for (int i = 0; i < nInstruments; i++) { - SGPropertyList props2; - SGPropertyNode node = instrument_group.getChild(i); - - FGPath path(current_options.get_fg_root()); - path.append(node.getStringValue("path")); - - FG_LOG(FG_INPUT, FG_INFO, "Reading instrument " - << node.getName() - << " from " - << path.str()); - - int x = node.getIntValue("x", -1); - int y = node.getIntValue("y", -1); - int w = node.getIntValue("w", -1); - int h = node.getIntValue("h", -1); - - if (x == -1 || y == -1) { - FG_LOG(FG_INPUT, FG_ALERT, "x and y positions must be specified and >0"); - delete panel; - return 0; - } - - if (!readPropertyList(path.str(), &props2)) { - delete panel; - return 0; - } + const SGPropertyNode * instrument_group = root.getChild("instruments"); + if (instrument_group != 0) { + int nInstruments = instrument_group->nChildren(); + for (int i = 0; i < nInstruments; i++) { + const SGPropertyNode * node = instrument_group->getChild(i); + + FGPath path( globals->get_fg_root() ); + path.append(node->getStringValue("path")); + + FG_LOG(FG_INPUT, FG_INFO, "Reading instrument " + << node->getName() + << " from " + << path.str()); + + int x = node->getIntValue("x", -1); + int y = node->getIntValue("y", -1); + int w = node->getIntValue("w", -1); + int h = node->getIntValue("h", -1); + + if (x == -1 || y == -1) { + FG_LOG(FG_INPUT, FG_ALERT, "x and y positions must be specified and >0"); + delete panel; + return 0; + } - FGPanelInstrument * instrument = - readInstrument(SGPropertyNode("/", &props2), x, y, w, h); - if (instrument == 0) { - delete instrument; - delete panel; - return 0; + // Read the instrument from + // a separate file. + FGPanelInstrument * instrument = 0; + + SGPropertyNode root2; + + if (readProperties(path.str(), &root2)) { + cerr << "Read " << root2.nChildren() << " top-level nodes from " + << path.c_str() << endl; + instrument = readInstrument(&root2, x, y, w, h); + } + if (instrument == 0) + instrument = new DefaultInstrument(x, y, w, h); + panel->addInstrument(instrument); } - panel->addInstrument(instrument); } FG_LOG(FG_INPUT, FG_INFO, "Done reading panel instruments"); @@ -729,16 +814,19 @@ fgReadPanel (istream &input) FGPanel * fgReadPanel (const string &relative_path) { - FGPath path(current_options.get_fg_root()); + FGPanel * panel = 0; + FGPath path(globals->get_fg_root()); path.append(relative_path); ifstream input(path.c_str()); if (!input.good()) { FG_LOG(FG_INPUT, FG_ALERT, "Cannot read panel configuration from " << path.str()); - return 0; + } else { + panel = fgReadPanel(input); + input.close(); } - FGPanel * panel = fgReadPanel(input); - input.close(); + if (panel == 0) + panel = new DefaultPanel(0, 0, 1024, 768); return panel; }