X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCockpit%2Fpanel_io.cxx;h=dd1f1036155c0df275f02c9f1e1ed391a0ebe5e4;hb=b07ad149aebeb1d060bc9a0d505fdc1ca1081654;hp=456d2d82ff6b41a9b7c7bc2a1ace92a6cb9f2ac4;hpb=70044757321d8acf5dd7744934cb2965cfbaec89;p=flightgear.git diff --git a/src/Cockpit/panel_io.cxx b/src/Cockpit/panel_io.cxx index 456d2d82f..dd1f10361 100644 --- a/src/Cockpit/panel_io.cxx +++ b/src/Cockpit/panel_io.cxx @@ -11,10 +11,10 @@ // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -22,98 +22,33 @@ # include #endif -#ifdef HAVE_WINDOWS_H -# include -#endif +#include // for strcmp() #include -#include - -#include +#include #include -#include +#include +#include -#include STL_IOSTREAM -#include STL_FSTREAM -#include STL_STRING +#include +#include +#include #include
#include
#include -#include "panel.hxx" -#include "steam.hxx" +// #include "panel.hxx" #include "panel_io.hxx" +#include -#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS) -SG_USING_STD(istream); -SG_USING_STD(ifstream); -#endif -SG_USING_STD(string); - - - -//////////////////////////////////////////////////////////////////////// -// Built-in layer for the magnetic compass ribbon layer. -// -// TODO: move this out into a special directory for built-in -// layers of various sorts. -//////////////////////////////////////////////////////////////////////// - -class FGMagRibbon : public FGTexturedLayer -{ -public: - FGMagRibbon (int w, int h); - virtual ~FGMagRibbon () {} - - virtual void draw (); -}; - -FGMagRibbon::FGMagRibbon (int w, int h) - : FGTexturedLayer(w, h) -{ - FGCroppedTexture texture("Aircraft/c172/Instruments/Textures/compass-ribbon.rgb"); - setTexture(texture); -} - -void -FGMagRibbon::draw () -{ - double heading = FGSteam::get_MH_deg(); - double xoffset, yoffset; - - while (heading >= 360.0) { - heading -= 360.0; - } - while (heading < 0.0) { - heading += 360.0; - } +//built-in layers +#include "built_in/FGMagRibbon.hxx" - if (heading >= 60.0 && heading <= 180.0) { - xoffset = heading / 240.0; - yoffset = 0.75; - } else if (heading >= 150.0 && heading <= 270.0) { - xoffset = (heading - 90.0) / 240.0; - yoffset = 0.50; - } else if (heading >= 240.0 && heading <= 360.0) { - xoffset = (heading - 180.0) / 240.0; - yoffset = 0.25; - } else { - if (heading < 270.0) - heading += 360.0; - xoffset = (heading - 270.0) / 240.0; - yoffset = 0.0; - } - - xoffset = 1.0 - xoffset; - // Adjust to put the number in the centre - xoffset -= 0.25; - - FGCroppedTexture &t = getTexture(); - t.setCrop(xoffset, yoffset, xoffset + 0.5, yoffset + 0.25); - FGTexturedLayer::draw(); -} +using std::istream; +using std::ifstream; +using std::string; @@ -174,13 +109,32 @@ FGMagRibbon::draw () static FGCroppedTexture readTexture (const SGPropertyNode * node) { - FGCroppedTexture texture(node->getStringValue("path"), - node->getFloatValue("x1"), - node->getFloatValue("y1"), - node->getFloatValue("x2", 1.0), - node->getFloatValue("y2", 1.0)); - SG_LOG(SG_COCKPIT, SG_DEBUG, "Read texture " << node->getName()); - return texture; + FGCroppedTexture texture(node->getStringValue("path"), + node->getFloatValue("x1"), + node->getFloatValue("y1"), + node->getFloatValue("x2", 1.0), + node->getFloatValue("y2", 1.0)); + SG_LOG(SG_COCKPIT, SG_DEBUG, "Read texture " << node->getName()); + return texture; +} + + +/** + * Test for a condition in the current node. + */ + +//////////////////////////////////////////////////////////////////////// +// Read a condition and use it if necessary. +//////////////////////////////////////////////////////////////////////// + +static void +readConditions (SGConditional *component, const SGPropertyNode *node) +{ + const SGPropertyNode * conditionNode = node->getChild("condition"); + if (conditionNode != 0) + // The top level is implicitly AND + component->setCondition(sgReadCondition(globals->get_props(), + conditionNode) ); } @@ -213,60 +167,59 @@ readTexture (const SGPropertyNode * node) static FGPanelAction * readAction (const SGPropertyNode * node, float w_scale, float h_scale) { - FGPanelAction * action = 0; + unsigned int i, j; + SGPropertyNode *binding; + vectorbindings = node->getChildren("binding"); + + // button-less actions are fired initially + if (!node->hasValue("w") || !node->hasValue("h")) { + for (i = 0; i < bindings.size(); i++) { + SGBinding b(bindings[i], globals->get_props()); + b.fire(); + } + return 0; + } string name = node->getStringValue("name"); - string type = node->getStringValue("type"); int button = node->getIntValue("button"); int x = int(node->getIntValue("x") * w_scale); int y = int(node->getIntValue("y") * h_scale); int w = int(node->getIntValue("w") * w_scale); int h = int(node->getIntValue("h") * h_scale); + bool repeatable = node->getBoolValue("repeatable", true); - if (type == "") { - SG_LOG(SG_COCKPIT, SG_ALERT, - "No type supplied for action " << name << " assuming \"adjust\""); - type = "adjust"; - } + FGPanelAction * action = new FGPanelAction(button, x, y, w, h, repeatable); - // Adjust a property value - if (type == "adjust") { - string propName = node->getStringValue("property"); - SGPropertyNode * target = fgGetNode(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) - SG_LOG(SG_COCKPIT, SG_ALERT, "Action " << node->getName() - << " has same min and max value"); - action = new FGAdjustAction(button, x, y, w, h, target, - increment, min, max, wrap); - } + SGPropertyNode * dest = fgGetNode("/sim/bindings/panel", true); - // Swap two property values - else if (type == "swap") { - string propName1 = node->getStringValue("property1"); - string propName2 = node->getStringValue("property2"); - SGPropertyNode * target1 = fgGetNode(propName1, true); - SGPropertyNode * target2 = fgGetNode(propName2, true); - action = new FGSwapAction(button, x, y, w, h, target1, target2); - } + for (i = 0; i < bindings.size(); i++) { + SG_LOG(SG_INPUT, SG_INFO, "Reading binding " + << bindings[i]->getStringValue("command")); - // Toggle a boolean value - else if (type == "toggle") { - string propName = node->getStringValue("property"); - SGPropertyNode * target = fgGetNode(propName, true); - action = new FGToggleAction(button, x, y, w, h, target); - } + j = 0; + while (dest->getChild("binding", j)) + j++; - // Unrecognized type - else { - SG_LOG( SG_COCKPIT, SG_ALERT, "Unrecognized action type " << type ); - return 0; + binding = dest->getChild("binding", j, true); + copyProperties(bindings[i], binding); + action->addBinding(new SGBinding(binding, globals->get_props()), 0); } + if (node->hasChild("mod-up")) { + bindings = node->getChild("mod-up")->getChildren("binding"); + for (i = 0; i < bindings.size(); i++) { + j = 0; + while (dest->getChild("binding", j)) + j++; + + binding = dest->getChild("binding", j, true); + copyProperties(bindings[i], binding); + action->addBinding(new SGBinding(binding, globals->get_props()), 1); + } + } + + readConditions(action, node); return action; } @@ -306,20 +259,23 @@ readTransformation (const SGPropertyNode * node, float w_scale, float h_scale) string propName = node->getStringValue("property", ""); SGPropertyNode * target = 0; - if (type == "") { - SG_LOG( SG_COCKPIT, SG_ALERT, + if (type.empty()) { + SG_LOG( SG_COCKPIT, SG_INFO, "No type supplied for transformation " << name << " assuming \"rotation\"" ); type = "rotation"; } - if (propName != (string)"") { - target = fgGetNode(propName, true); + if (!propName.empty()) { + target = fgGetNode(propName.c_str(), true); } t->node = target; t->min = node->getFloatValue("min", -9999999); t->max = node->getFloatValue("max", 99999999); + t->has_mod = node->hasChild("modulator"); + if (t->has_mod) + t->mod = node->getFloatValue("modulator"); t->factor = node->getFloatValue("scale", 1.0); t->offset = node->getFloatValue("offset", 0.0); @@ -327,21 +283,8 @@ readTransformation (const SGPropertyNode * node, float w_scale, float h_scale) const SGPropertyNode * trans_table = node->getNode("interpolation"); if (trans_table != 0) { SG_LOG( SG_COCKPIT, SG_INFO, "Found interpolation table with " - << trans_table->nChildren() << "children" ); - t->table = new SGInterpTable(); - for(int i = 0; i < trans_table->nChildren(); i++) { - const SGPropertyNode * node = trans_table->getChild(i); - if (node->getName() == "entry") { - double ind = node->getDoubleValue("ind", 0.0); - double dep = node->getDoubleValue("dep", 0.0); - SG_LOG( SG_COCKPIT, SG_INFO, "Adding interpolation entry " - << ind << "==>" << dep ); - t->table->addEntry(ind, dep); - } else { - SG_LOG( SG_COCKPIT, SG_INFO, "Skipping " << node->getName() - << " in interpolation" ); - } - } + << trans_table->nChildren() << " children" ); + t->table = new SGInterpTable(trans_table); } else { t->table = 0; } @@ -377,6 +320,7 @@ readTransformation (const SGPropertyNode * node, float w_scale, float h_scale) return 0; } + readConditions(t, node); SG_LOG( SG_COCKPIT, SG_DEBUG, "Read transformation " << name ); return t; } @@ -407,7 +351,7 @@ readTextChunk (const SGPropertyNode * node) string format = node->getStringValue("format"); // Default to literal text. - if (type == "") { + if (type.empty()) { SG_LOG( SG_COCKPIT, SG_INFO, "No type provided for text chunk " << name << " assuming \"literal\""); type = "literal"; @@ -430,9 +374,11 @@ readTextChunk (const SGPropertyNode * node) else if (type == "number-value") { string propName = node->getStringValue("property"); float scale = node->getFloatValue("scale", 1.0); - SGPropertyNode * target = fgGetNode(propName, true); + float offset = node->getFloatValue("offset", 0.0); + bool truncation = node->getBoolValue("truncate", false); + SGPropertyNode * target = fgGetNode(propName.c_str(), true); chunk = new FGTextLayer::Chunk(FGTextLayer::DOUBLE_VALUE, target, - format, scale); + format, scale, offset, truncation); } // Unknown type. @@ -442,6 +388,7 @@ readTextChunk (const SGPropertyNode * node) return 0; } + readConditions(chunk, node); return chunk; } @@ -475,14 +422,15 @@ readLayer (const SGPropertyNode * node, float w_scale, float h_scale) string type = node->getStringValue("type"); int w = node->getIntValue("w", -1); int h = node->getIntValue("h", -1); + bool emissive = node->getBoolValue("emissive", false); if (w != -1) w = int(w * w_scale); if (h != -1) h = int(h * h_scale); - if (type == "") { - SG_LOG( SG_COCKPIT, SG_ALERT, + if (type.empty()) { + SG_LOG( SG_COCKPIT, SG_INFO, "No type supplied for layer " << name << " assuming \"texture\"" ); type = "texture"; @@ -493,6 +441,21 @@ readLayer (const SGPropertyNode * node, float w_scale, float h_scale) if (type == "texture") { FGCroppedTexture texture = readTexture(node->getNode("texture")); layer = new FGTexturedLayer(texture, w, h); + if (emissive) { + FGTexturedLayer *tl=(FGTexturedLayer*)layer; + tl->setEmissive(true); + } + + } + + // A group of sublayers. + else if (type == "group") { + layer = new FGGroupLayer(); + for (int i = 0; i < node->nChildren(); i++) { + const SGPropertyNode * child = node->getChild(i); + if (!strcmp(child->getName(), "layer")) + ((FGGroupLayer *)layer)->addLayer(readLayer(child, w_scale, h_scale)); + } } @@ -511,14 +474,15 @@ readLayer (const SGPropertyNode * node, float w_scale, float h_scale) tlayer->setPointSize(pointSize); // Set the font. - // TODO + string fontName = node->getStringValue("font", "Helvetica"); + tlayer->setFontName(fontName); const SGPropertyNode * chunk_group = node->getNode("chunks"); if (chunk_group != 0) { int nChunks = chunk_group->nChildren(); for (int i = 0; i < nChunks; i++) { const SGPropertyNode * node = chunk_group->getChild(i); - if (node->getName() == "chunk") { + if (!strcmp(node->getName(), "chunk")) { FGTextLayer::Chunk * chunk = readTextChunk(node); if (chunk != 0) tlayer->addChunk(chunk); @@ -533,13 +497,12 @@ readLayer (const SGPropertyNode * node, float w_scale, float h_scale) // A switch instrument layer. else if (type == "switch") { - SGPropertyNode * target = - fgGetNode(node->getStringValue("property"), true); - FGInstrumentLayer * layer1 = - readLayer(node->getNode("layer1"), w_scale, h_scale); - FGInstrumentLayer * layer2 = - readLayer(node->getNode("layer2"), w_scale, h_scale); - layer = new FGSwitchLayer(w, h, target, layer1, layer2); + layer = new FGSwitchLayer(); + for (int i = 0; i < node->nChildren(); i++) { + const SGPropertyNode * child = node->getChild(i); + if (!strcmp(child->getName(), "layer")) + ((FGGroupLayer *)layer)->addLayer(readLayer(child, w_scale, h_scale)); + } } // A built-in instrument layer. @@ -550,7 +513,7 @@ readLayer (const SGPropertyNode * node, float w_scale, float h_scale) layer = new FGMagRibbon(w, h); } - else if (layerclass == "") { + else if (layerclass.empty()) { SG_LOG( SG_COCKPIT, SG_ALERT, "No class provided for built-in layer " << name ); return 0; @@ -578,7 +541,7 @@ readLayer (const SGPropertyNode * node, float w_scale, float h_scale) int nTransformations = trans_group->nChildren(); for (int i = 0; i < nTransformations; i++) { const SGPropertyNode * node = trans_group->getChild(i); - if (node->getName() == "transformation") { + if (!strcmp(node->getName(), "transformation")) { FGPanelTransformation * t = readTransformation(node, w_scale, h_scale); if (t != 0) layer->addTransformation(t); @@ -588,7 +551,8 @@ readLayer (const SGPropertyNode * node, float w_scale, float h_scale) } } } - + + readConditions(layer, node); SG_LOG( SG_COCKPIT, SG_DEBUG, "Read layer " << name ); return layer; } @@ -608,7 +572,7 @@ readLayer (const SGPropertyNode * node, float w_scale, float h_scale) static FGPanelInstrument * readInstrument (const SGPropertyNode * node) { - const string &name = node->getStringValue("name"); + const string name = node->getStringValue("name"); int x = node->getIntValue("x", -1); int y = node->getIntValue("y", -1); int real_w = node->getIntValue("w", -1); @@ -646,7 +610,7 @@ readInstrument (const SGPropertyNode * node) int nActions = action_group->nChildren(); for (int i = 0; i < nActions; i++) { const SGPropertyNode * node = action_group->getChild(i); - if (node->getName() == "action") { + if (!strcmp(node->getName(), "action")) { FGPanelAction * action = readAction(node, w_scale, h_scale); if (action != 0) instrument->addAction(action); @@ -665,7 +629,7 @@ readInstrument (const SGPropertyNode * node) int nLayers = layer_group->nChildren(); for (int i = 0; i < nLayers; i++) { const SGPropertyNode * node = layer_group->getChild(i); - if (node->getName() == "layer") { + if (!strcmp(node->getName(), "layer")) { FGInstrumentLayer * layer = readLayer(node, w_scale, h_scale); if (layer != 0) instrument->addLayer(layer); @@ -675,7 +639,8 @@ readInstrument (const SGPropertyNode * node) } } } - + + readConditions(instrument, node); SG_LOG( SG_COCKPIT, SG_DEBUG, "Done reading instrument " << name ); return instrument; } @@ -706,18 +671,75 @@ readPanel (const SGPropertyNode * root) if (!fgHasNode("/sim/panel/x-offset")) fgSetInt("/sim/panel/x-offset", root->getIntValue("x-offset", 0)); + // conditional removed by jim wilson to allow panel xml code + // with y-offset defined to work... if (!fgHasNode("/sim/panel/y-offset")) fgSetInt("/sim/panel/y-offset", root->getIntValue("y-offset", 0)); + panel->setAutohide(root->getBoolValue("autohide", true)); + // // Assign the background texture, if any, or a bogus chequerboard. // string bgTexture = root->getStringValue("background"); - if (bgTexture == "") + if (bgTexture.empty()) bgTexture = "FOO"; panel->setBackground(FGTextureManager::createTexture(bgTexture.c_str())); SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << bgTexture ); + // + // Get multibackground if any... + // + string mbgTexture = root->getStringValue("multibackground[0]"); + if (!mbgTexture.empty()) { + panel->setMultiBackground(FGTextureManager::createTexture(mbgTexture.c_str()), 0); + SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << mbgTexture ); + + mbgTexture = root->getStringValue("multibackground[1]"); + if (mbgTexture.empty()) + mbgTexture = "FOO"; + panel->setMultiBackground(FGTextureManager::createTexture(mbgTexture.c_str()), 1); + SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << mbgTexture ); + + mbgTexture = root->getStringValue("multibackground[2]"); + if (mbgTexture.empty()) + mbgTexture = "FOO"; + panel->setMultiBackground(FGTextureManager::createTexture(mbgTexture.c_str()), 2); + SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << mbgTexture ); + + mbgTexture = root->getStringValue("multibackground[3]"); + if (mbgTexture.empty()) + mbgTexture = "FOO"; + panel->setMultiBackground(FGTextureManager::createTexture(mbgTexture.c_str()), 3); + SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << mbgTexture ); + + mbgTexture = root->getStringValue("multibackground[4]"); + if (mbgTexture.empty()) + mbgTexture = "FOO"; + panel->setMultiBackground(FGTextureManager::createTexture(mbgTexture.c_str()), 4); + SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << mbgTexture ); + + mbgTexture = root->getStringValue("multibackground[5]"); + if (mbgTexture.empty()) + mbgTexture = "FOO"; + panel->setMultiBackground(FGTextureManager::createTexture(mbgTexture.c_str()), 5); + SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << mbgTexture ); + + mbgTexture = root->getStringValue("multibackground[6]"); + if (mbgTexture.empty()) + mbgTexture = "FOO"; + panel->setMultiBackground(FGTextureManager::createTexture(mbgTexture.c_str()), 6); + SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << mbgTexture ); + + mbgTexture = root->getStringValue("multibackground[7]"); + if (mbgTexture.empty()) + mbgTexture = "FOO"; + panel->setMultiBackground(FGTextureManager::createTexture(mbgTexture.c_str()), 7); + SG_LOG( SG_COCKPIT, SG_INFO, "Set background texture to " << mbgTexture ); + + } + + // // Create each instrument. @@ -728,13 +750,58 @@ readPanel (const SGPropertyNode * root) int nInstruments = instrument_group->nChildren(); for (int i = 0; i < nInstruments; i++) { const SGPropertyNode * node = instrument_group->getChild(i); - if (node->getName() == "instrument") { - FGPanelInstrument * instrument = readInstrument(node); - if (instrument != 0) - panel->addInstrument(instrument); + if (!strcmp(node->getName(), "instrument")) { + FGPanelInstrument * instrument = readInstrument(node); + if (instrument != 0) + panel->addInstrument(instrument); + } else if (!strcmp(node->getName(), "special-instrument")) { + //cout << "Special instrument found in instruments section!\n"; + const string name = node->getStringValue("name"); + if (name == "KLN89 GPS") { + //cout << "Special instrument is KLN89\n"; + + int x = node->getIntValue("x", -1); + int y = node->getIntValue("y", -1); + int real_w = node->getIntValue("w", -1); + int real_h = node->getIntValue("h", -1); + int w = node->getIntValue("w-base", -1); + int h = node->getIntValue("h-base", -1); + + if (x == -1 || y == -1) { + SG_LOG( SG_COCKPIT, SG_ALERT, + "x and y positions must be specified and > 0" ); + return 0; + } + + float w_scale = 1.0; + float h_scale = 1.0; + if (real_w != -1) { + w_scale = float(real_w) / float(w); + w = real_w; + } + if (real_h != -1) { + h_scale = float(real_h) / float(h); + h = real_h; + } + + SG_LOG( SG_COCKPIT, SG_DEBUG, "Reading instrument " << name ); + + // Warning - hardwired size!!! + RenderArea2D* instrument = new RenderArea2D(158, 40, 158, 40, x, y); + KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); + if (gps == NULL) { + gps = new KLN89(instrument); + globals->add_subsystem("kln89", gps); + } + //gps->init(); // init seems to get called automagically. + FGSpecialInstrument* gpsinst = new FGSpecialInstrument(gps); + panel->addInstrument(gpsinst); + } else { + SG_LOG( SG_COCKPIT, SG_WARN, "Unknown special instrument found" ); + } } else { - SG_LOG( SG_COCKPIT, SG_INFO, "Skipping " << node->getName() - << " in instruments section" ); + SG_LOG( SG_COCKPIT, SG_INFO, "Skipping " << node->getName() + << " in instruments section" ); } } } @@ -765,12 +832,8 @@ fgReadPanel (istream &input) try { readProperties(input, &root); - } catch (const sg_io_exception &e) { - string message = e.getMessage(); - message += "\n at "; - message += e.getLocation().asString(); - SG_LOG(SG_INPUT, SG_ALERT, message); - mkDialog(message.c_str()); + } catch (const sg_exception &e) { + guiErrorMessage("Error reading panel: ", e); return 0; } return readPanel(&root); @@ -792,12 +855,8 @@ fgReadPanel (const string &relative_path) try { readProperties(path.str(), &root); - } catch (const sg_io_exception &e) { - string message = e.getMessage(); - message += "\n at "; - message += e.getLocation().asString(); - SG_LOG(SG_INPUT, SG_ALERT, message); - mkDialog(message.c_str()); + } catch (const sg_exception &e) { + guiErrorMessage("Error reading panel: ", e); return 0; } return readPanel(&root); @@ -806,3 +865,6 @@ fgReadPanel (const string &relative_path) // end of panel_io.cxx + + +