// fg_commands.cxx - internal FGFS commands.
+#include <string.h> // strcmp()
+
#include <simgear/compiler.h>
#include <simgear/misc/exception.hxx>
virtual SGPropertyNode * getProp2 () const { return _prop2; }
virtual const SGPropertyNode * getValue () const
{ return _value ? _value : &_dummy_0; }
+ virtual const bool hasStep () const { return _step != 0; }
virtual const SGPropertyNode * getStep () const
{ return _step ? _step : &_dummy_0; }
+ virtual const SGPropertyNode * getMin () const { return _min; }
+ virtual const SGPropertyNode * getMax () const { return _max; }
+ virtual const SGPropertyNode * getWrap () const
+ { return _wrap ? _wrap : &_dummy_0; }
virtual const SGPropertyNode * getFactor () const
{ return _factor ? _factor : &_dummy_1; }
+ virtual const SGPropertyNode * getSquared () const
+ { return _squared ? _squared : &_dummy_1; }
virtual const SGPropertyNode * getSetting () const
{ return _setting ? _setting : &_dummy_0; }
virtual const SGPropertyNode * getOffset () const
mutable SGPropertyNode * _prop2;
const SGPropertyNode * _value;
const SGPropertyNode * _step;
+ const SGPropertyNode * _min;
+ const SGPropertyNode * _max;
+ const SGPropertyNode * _wrap;
const SGPropertyNode * _factor;
+ const SGPropertyNode * _squared;
const SGPropertyNode * _setting;
const SGPropertyNode * _offset;
};
_prop2(fgGetNode(arg->getStringValue("property[1]", "/null"), true)),
_value(arg->getNode("value")),
_step(arg->getNode("step")),
+ _min(arg->getNode("min")),
+ _max(arg->getNode("max")),
+ _wrap(arg->getNode("wrap")),
_factor(arg->getNode("factor")),
+ _squared(arg->getNode("squared")),
_setting(arg->getNode("setting")),
_offset(arg->getNode("offset"))
{
do_save (const SGPropertyNode * arg, SGCommandState ** state)
{
const string &file = arg->getStringValue("file", "fgfs.sav");
+ bool write_all = arg->getBoolValue("write-all", false);
SG_LOG(SG_INPUT, SG_INFO, "Saving flight");
ofstream output(file.c_str());
- if (output.good() && fgSaveFlight(output)) {
+ if (output.good() && fgSaveFlight(output, write_all)) {
output.close();
SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file);
return true;
}
+/**
+ * Built-in command: pass a mouse click to the panel.
+ *
+ * button: the mouse button number, zero-based.
+ * is-down: true if the button is down, false if it is up.
+ * x-pos: the x position of the mouse click.
+ * y-pos: the y position of the mouse click.
+ */
+static bool
+do_panel_mouse_click (const SGPropertyNode * arg, SGCommandState ** state)
+{
+ if (current_panel != 0)
+ return current_panel
+ ->doMouseAction(arg->getIntValue("button"),
+ arg->getBoolValue("is-down") ? PU_DOWN : PU_UP,
+ arg->getIntValue("x-pos"),
+ arg->getIntValue("y-pos"));
+ else
+ return false;
+}
+
+
/**
* Built-in command: (re)load preferences.
*
<< props_path.str());
try {
readProperties(props_path.str(), globals->get_props());
- } catch (const sg_io_exception &e) {
- string message = "Error reading global preferences: ";
- 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 global preferences: ", e);
return false;
}
SG_LOG(SG_INPUT, SG_INFO, "Successfully read global preferences.");
static bool
do_view_cycle (const SGPropertyNode * arg, SGCommandState ** state)
{
- globals->get_current_view()->set_view_offset(0.0);
- globals->set_current_view(globals->get_viewmgr()->next_view());
+ globals->get_current_view()->setHeadingOffset_deg(0.0);
+ globals->get_viewmgr()->next_view();
+ if ( !strcmp(fgGetString("/sim/flight-model"), "ada") ) {
+ globals->get_props()->setBoolValue( "/sim/hud/visibility", true );
+ if ( globals->get_viewmgr()->get_current() == 1 ) {
+ globals->get_props()->setBoolValue( "/sim/hud/visibility", false );
+ }
+ }
// fgReshape(fgGetInt("/sim/startup/xsize"), fgGetInt("/sim/startup/ysize"));
return true;
}
static bool
do_tile_cache_reload (const SGPropertyNode * arg, SGCommandState ** state)
{
- bool freeze = globals->get_freeze();
- SG_LOG(SG_INPUT, SG_INFO, "ReIniting TileCache");
- if ( !freeze )
- globals->set_freeze( true );
- BusyCursor(0);
- if ( global_tile_mgr.init() ) {
- // Load the local scenery data
- global_tile_mgr.update(fgGetDouble("/position/longitude-deg"),
- fgGetDouble("/position/latitude-deg"));
- } else {
- SG_LOG( SG_GENERAL, SG_ALERT,
- "Error in Tile Manager initialization!" );
- exit(-1);
- }
- BusyCursor(1);
- if ( !freeze )
- globals->set_freeze( false );
- return true;
+ static const SGPropertyNode *master_freeze
+ = fgGetNode("/sim/freeze/master");
+ bool freeze = master_freeze->getBoolValue();
+ SG_LOG(SG_INPUT, SG_INFO, "ReIniting TileCache");
+ if ( !freeze ) {
+ fgSetBool("/sim/freeze/master", true);
+ }
+ // BusyCursor(0);
+ if ( global_tile_mgr.init() ) {
+ // Load the local scenery data
+ global_tile_mgr.update(fgGetDouble("/position/longitude-deg"),
+ fgGetDouble("/position/latitude-deg"));
+ } else {
+ SG_LOG( SG_GENERAL, SG_ALERT,
+ "Error in Tile Manager initialization!" );
+ exit(-1);
+ }
+ // BusyCursor(1);
+ if ( !freeze ) {
+ fgSetBool("/sim/freeze/master", false);
+ }
+ return true;
}
* Built-in command: increment or decrement a property value.
*
* property: the name of the property to increment or decrement.
- * step: the amount of the increment or decrement.
+ * step: the amount of the increment or decrement (default: 0).
+ * offset: a normalized amount to offset by (if step is not present).
+ * factor: the amount by which to multiply the offset (if step is not present).
+ * min: the minimum allowed value (default: no minimum).
+ * max: the maximum allowed value (default: no maximum).
+ * wrap: true if the value should be wrapped when it passes min or max;
+ * both min and max must be present for this to work (default:
+ * false).
*/
static bool
do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
{
if (*state == 0)
*state = new PropertyCommandState(arg);
+ bool hasStep = ((PropertyCommandState *)(*state))->hasStep();
SGPropertyNode * prop = ((PropertyCommandState *)(*state))->getProp();
const SGPropertyNode * step = ((PropertyCommandState *)(*state))->getStep();
+ const SGPropertyNode * offset =
+ ((PropertyCommandState *)(*state))->getOffset();
+ const SGPropertyNode * factor =
+ ((PropertyCommandState *)(*state))->getFactor();
+ const SGPropertyNode * min = ((PropertyCommandState *)(*state))->getMin();
+ const SGPropertyNode * max = ((PropertyCommandState *)(*state))->getMax();
+ bool wrap = ((PropertyCommandState *)(*state))->getWrap()->getBoolValue();
+
+ double amount = 0;
+ if (!hasStep) {
+ amount = offset->getDoubleValue() * factor->getDoubleValue();
+ }
+
switch (prop->getType()) {
case SGPropertyNode::BOOL:
- if (step->getBoolValue())
+ bool value;
+ if (hasStep)
+ value = step->getBoolValue();
+ else
+ value = amount;
+ if (value)
return prop->setBoolValue(!prop->getBoolValue());
else
return true;
- case SGPropertyNode::INT:
- return prop->setIntValue(prop->getIntValue()
- + step->getIntValue());
- case SGPropertyNode::LONG:
- return prop->setLongValue(prop->getLongValue()
- + step->getLongValue());
- case SGPropertyNode::FLOAT:
- return prop->setFloatValue(prop->getFloatValue()
- + step->getFloatValue());
+ case SGPropertyNode::INT: {
+ int value;
+ if (hasStep)
+ value = prop->getIntValue() + step->getIntValue();
+ else
+ value = prop->getIntValue() + int(amount);
+ if (min && (value < min->getIntValue())) {
+ if (wrap && max)
+ value = max->getIntValue();
+ else
+ value = min->getIntValue();
+ }
+ if (max && value > max->getIntValue()) {
+ if (wrap && min)
+ value = min->getIntValue();
+ else
+ value = max->getIntValue();
+ }
+ return prop->setIntValue(value);
+ }
+ case SGPropertyNode::LONG: {
+ long value;
+ if (hasStep)
+ value = prop->getLongValue() + step->getLongValue();
+ else
+ value = prop->getLongValue() + long(amount);
+ if (min && (value < min->getLongValue())) {
+ if (wrap && max)
+ value = max->getLongValue();
+ else
+ value = min->getLongValue();
+ }
+ if (max && value > max->getLongValue()) {
+ if (wrap && min)
+ value = min->getLongValue();
+ else
+ value = max->getLongValue();
+ }
+ return prop->setLongValue(value);
+ }
+ case SGPropertyNode::FLOAT: {
+ float value;
+ if (hasStep)
+ value = prop->getFloatValue() + step->getFloatValue();
+ else
+ value = prop->getFloatValue() + float(amount);
+ if (min && (value < min->getFloatValue())) {
+ if (wrap && max)
+ value = max->getFloatValue();
+ else
+ value = min->getFloatValue();
+ }
+ if (max && value > max->getFloatValue()) {
+ if (wrap && min)
+ value = min->getFloatValue();
+ else
+ value = max->getFloatValue();
+ }
+ return prop->setFloatValue(value);
+ }
case SGPropertyNode::DOUBLE:
case SGPropertyNode::UNSPECIFIED:
- return prop->setDoubleValue(prop->getDoubleValue()
- + step->getDoubleValue());
- default: // doesn't make sense with strings
+ case SGPropertyNode::NONE: {
+ double value;
+ if (hasStep)
+ value = prop->getDoubleValue() + step->getDoubleValue();
+ else
+ value = prop->getDoubleValue() + amount;
+ if (min && (value < min->getDoubleValue())) {
+ if (wrap && max)
+ value = max->getDoubleValue();
+ else
+ value = min->getDoubleValue();
+ }
+ if (max && value > max->getDoubleValue()) {
+ if (wrap && min)
+ value = min->getDoubleValue();
+ else
+ value = max->getDoubleValue();
+ }
+ return prop->setDoubleValue(value);
+ }
+ case SGPropertyNode::STRING: // doesn't make sense with strings
+ SG_LOG(SG_INPUT, SG_ALERT, "Cannot adjust a string value");
+ return false;
+ default:
+ SG_LOG(SG_INPUT, SG_ALERT, "Unknown value type");
return false;
}
}
* factor->getDoubleValue()));
case SGPropertyNode::DOUBLE:
case SGPropertyNode::UNSPECIFIED:
+ case SGPropertyNode::NONE:
return prop->setDoubleValue(prop->getDoubleValue()
* factor->getDoubleValue());
default: // doesn't make sense with strings
// FIXME: inefficient
const string & tmp = prop1->getStringValue();
return (prop1->setUnspecifiedValue(prop2->getStringValue()) &&
- prop2->setUnspecifiedValue(tmp));
+ prop2->setUnspecifiedValue(tmp.c_str()));
}
((PropertyCommandState *)(*state))->getOffset()->getDoubleValue();
double factor =
((PropertyCommandState *)(*state))->getFactor()->getDoubleValue();
+ bool squared =
+ ((PropertyCommandState *)(*state))->getSquared()->getBoolValue();
- return prop->setDoubleValue((setting + offset) * factor);
+ if (squared)
+ setting = (setting < 0 ? -1 : 1) * setting * setting;
+ double result = (setting + offset) * factor;
+
+ return prop->setDoubleValue(result);
}
{ "load", do_load },
{ "save", do_save },
{ "panel-load", do_panel_load },
+ { "panel-mouse-click", do_panel_mouse_click },
{ "preferences-load", do_preferences_load },
{ "view-cycle", do_view_cycle },
{ "screen-capture", do_screen_capture },
}
// end of fg_commands.hxx
+