# include <windows.h>
#endif
-#include <simgear/compiler.h>
-#include <simgear/misc/exception.hxx>
+#include <string.h> // for strcmp()
-#include <simgear/misc/sg_path.hxx>
+#include <simgear/compiler.h>
+#include <simgear/structure/exception.hxx>
#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/props.hxx>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/props/props.hxx>
#include STL_IOSTREAM
#include STL_FSTREAM
#include <GUI/gui.h>
-#include "panel.hxx"
-#include "steam.hxx"
+// #include "panel.hxx"
#include "panel_io.hxx"
-#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS)
+//built-in layers
+#include "built_in/FGMagRibbon.hxx"
+
SG_USING_STD(istream);
SG_USING_STD(ifstream);
-#endif
SG_USING_STD(string);
-\f
-////////////////////////////////////////////////////////////////////////
-// 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;
- }
-
- 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();
-}
-
-
\f
////////////////////////////////////////////////////////////////////////
// Read and construct a panel.
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.
+ */
+\f
+////////////////////////////////////////////////////////////////////////
+// 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) );
}
static FGPanelAction *
readAction (const SGPropertyNode * node, float w_scale, float h_scale)
{
- FGPanelAction * action = 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";
- }
-
- // 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);
- }
+ FGPanelAction * action = new FGPanelAction(button, x, y, w, h, repeatable);
- // 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);
- }
+ vector<SGPropertyNode_ptr>bindings = node->getChildren("binding");
- // 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);
- }
+ unsigned int i;
+ for (i = 0; i < bindings.size(); i++) {
+ SG_LOG(SG_INPUT, SG_INFO, "Reading binding "
+ << bindings[i]->getStringValue("command"));
+ action->addBinding(new FGBinding(bindings[i]), 0);
+ }
- // Unrecognized type
- else {
- SG_LOG( SG_COCKPIT, SG_ALERT, "Unrecognized action type " << type );
- return 0;
+ if (node->hasChild("mod-up")) {
+ bindings = node->getChild("mod-up")->getChildren("binding");
+ for (i = 0; i < bindings.size(); i++) {
+ action->addBinding(new FGBinding(bindings[i]), 1);
+ }
}
+ readConditions(action, node);
return action;
}
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);
t->table = new SGInterpTable();
for(int i = 0; i < trans_table->nChildren(); i++) {
const SGPropertyNode * node = trans_table->getChild(i);
- if (node->getName() == "entry") {
+ if (!strcmp(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 "
return 0;
}
+ readConditions(t, node);
SG_LOG( SG_COCKPIT, SG_DEBUG, "Read transformation " << name );
return t;
}
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";
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.
return 0;
}
+ readConditions(chunk, node);
return chunk;
}
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";
layer = new FGTexturedLayer(texture, w, h);
}
+ // 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));
+ }
+ }
+
// A textual instrument layer.
else if (type == "text") {
tlayer->setPointSize(pointSize);
// Set the font.
- // TODO
+ string fontName = node->getStringValue("font", "default");
+ 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);
// 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.
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;
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);
}
}
}
-
+
+ readConditions(layer, node);
SG_LOG( SG_COCKPIT, SG_DEBUG, "Read layer " << name );
return layer;
}
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);
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);
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);
}
}
}
-
+
+ readConditions(instrument, node);
SG_LOG( SG_COCKPIT, SG_DEBUG, "Done reading instrument " << name );
return instrument;
}
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));
// 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.
int nInstruments = instrument_group->nChildren();
for (int i = 0; i < nInstruments; i++) {
const SGPropertyNode * node = instrument_group->getChild(i);
- if (node->getName() == "instrument") {
+ if (!strcmp(node->getName(), "instrument")) {
FGPanelInstrument * instrument = readInstrument(node);
if (instrument != 0)
panel->addInstrument(instrument);
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);
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);
// end of panel_io.cxx
+
+
+