1869b30b58
I have traced that reset on carrier problem down to several problems. One of them is the fact that on reset the carrier is updated while the aircraft is not. That made the aircraft drop down an elevator sometimes. Depending on the passed realtime while loading some parts of the scenery.
382 lines
9.7 KiB
C++
382 lines
9.7 KiB
C++
#ifdef HAVE_CONFIG_H
|
||
# include <config.h>
|
||
#endif
|
||
|
||
#include <string.h>
|
||
#include <iostream>
|
||
#include <plib/pu.h>
|
||
#include <simgear/debug/logstream.hxx>
|
||
|
||
#include <Autopilot/auto_gui.hxx>
|
||
#include <Input/input.hxx>
|
||
#include <Main/globals.hxx>
|
||
#include <Main/fg_props.hxx>
|
||
|
||
#include "new_gui.hxx"
|
||
#include "menubar.hxx"
|
||
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
// FIXME!!
|
||
//
|
||
// Deprecated wrappers for old menu commands.
|
||
//
|
||
// DO NOT ADD TO THESE. THEY WILL BE DELETED SOON!
|
||
//
|
||
// These are defined in gui_funcs.cxx. They should be replaced with
|
||
// user-configured dialogs and new commands where necessary.
|
||
////////////////////////////////////////////////////////////////////////
|
||
|
||
extern void reInit (puObject *);
|
||
static bool
|
||
do_reinit_dialog (const SGPropertyNode * arg)
|
||
{
|
||
reInit(0);
|
||
return true;
|
||
}
|
||
|
||
#if defined(TR_HIRES_SNAP)
|
||
extern void dumpHiResSnapShot (puObject *);
|
||
static bool
|
||
do_hires_snapshot_dialog (const SGPropertyNode * arg)
|
||
{
|
||
dumpHiResSnapShot(0);
|
||
return true;
|
||
}
|
||
#endif // TR_HIRES_SNAP
|
||
|
||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
|
||
extern void printScreen (puObject *);
|
||
static bool
|
||
do_print_dialog (const SGPropertyNode * arg)
|
||
{
|
||
printScreen(0);
|
||
return true;
|
||
}
|
||
#endif
|
||
|
||
extern void fgHUDalphaAdjust (puObject *);
|
||
static bool
|
||
do_hud_alpha_dialog (const SGPropertyNode * arg)
|
||
{
|
||
fgHUDalphaAdjust(0);
|
||
return true;
|
||
}
|
||
|
||
extern void prop_pickerView (puObject *);
|
||
static bool
|
||
do_properties_dialog (const SGPropertyNode * arg)
|
||
{
|
||
prop_pickerView(0);
|
||
return true;
|
||
}
|
||
|
||
extern void AddWayPoint (puObject *);
|
||
static bool
|
||
do_ap_add_waypoint_dialog (const SGPropertyNode * arg)
|
||
{
|
||
AddWayPoint(0);
|
||
return true;
|
||
}
|
||
|
||
extern void PopWayPoint (puObject *);
|
||
static bool
|
||
do_ap_pop_waypoint_dialog (const SGPropertyNode * arg)
|
||
{
|
||
PopWayPoint(0);
|
||
return true;
|
||
}
|
||
|
||
extern void ClearRoute (puObject *);
|
||
static bool
|
||
do_ap_clear_route_dialog (const SGPropertyNode * arg)
|
||
{
|
||
ClearRoute(0);
|
||
return true;
|
||
}
|
||
|
||
#if 0
|
||
extern void fgAPAdjust (puObject *);
|
||
static bool
|
||
do_ap_adjust_dialog (const SGPropertyNode * arg)
|
||
{
|
||
fgAPAdjust(0);
|
||
return true;
|
||
}
|
||
#endif
|
||
|
||
extern void fgLatLonFormatToggle (puObject *);
|
||
static bool
|
||
do_lat_lon_format_dialog (const SGPropertyNode * arg)
|
||
{
|
||
fgLatLonFormatToggle(0);
|
||
return true;
|
||
}
|
||
|
||
extern void helpCb (puObject *);
|
||
static bool
|
||
do_help_dialog (const SGPropertyNode * arg)
|
||
{
|
||
helpCb(0);
|
||
return true;
|
||
}
|
||
|
||
static struct {
|
||
const char * name;
|
||
SGCommandMgr::command_t command;
|
||
} deprecated_dialogs [] = {
|
||
{ "old-reinit-dialog", do_reinit_dialog },
|
||
#if defined(TR_HIRES_SNAP)
|
||
{ "old-hires-snapshot-dialog", do_hires_snapshot_dialog },
|
||
#endif
|
||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
|
||
{ "old-print-dialog", do_print_dialog },
|
||
#endif
|
||
{ "old-hud-alpha-dialog", do_hud_alpha_dialog },
|
||
{ "old-properties-dialog", do_properties_dialog },
|
||
{ "old-ap-add-waypoint-dialog", do_ap_add_waypoint_dialog },
|
||
{ "old-ap-pop-waypoint-dialog", do_ap_pop_waypoint_dialog },
|
||
{ "old-ap-clear-route-dialog", do_ap_clear_route_dialog },
|
||
{ "old-lat-lon-format-dialog", do_lat_lon_format_dialog },
|
||
{ "old-help-dialog", do_help_dialog },
|
||
{ 0, 0 }
|
||
};
|
||
|
||
static void
|
||
add_deprecated_dialogs ()
|
||
{
|
||
SG_LOG(SG_GENERAL, SG_INFO, "Initializing old dialog commands:");
|
||
for (int i = 0; deprecated_dialogs[i].name != 0; i++) {
|
||
SG_LOG(SG_GENERAL, SG_INFO, " " << deprecated_dialogs[i].name);
|
||
globals->get_commands()->addCommand(deprecated_dialogs[i].name,
|
||
deprecated_dialogs[i].command);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
// Static functions.
|
||
////////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
static void
|
||
menu_callback (puObject * object)
|
||
{
|
||
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
|
||
gui->getMenuBar()->fireItem(object);
|
||
}
|
||
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
// Implementation of FGMenuBar.
|
||
////////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
FGMenuBar::FGMenuBar ()
|
||
: _visible(false),
|
||
_menuBar(0)
|
||
{
|
||
}
|
||
|
||
FGMenuBar::~FGMenuBar ()
|
||
{
|
||
destroy_menubar();
|
||
}
|
||
|
||
void
|
||
FGMenuBar::init ()
|
||
{
|
||
delete _menuBar; // FIXME: check if PUI owns the pointer
|
||
make_menubar();
|
||
// FIXME: temporary commands to get at
|
||
// old, hard-coded dialogs.
|
||
add_deprecated_dialogs();
|
||
}
|
||
|
||
void
|
||
FGMenuBar::show ()
|
||
{
|
||
if (_menuBar != 0)
|
||
_menuBar->reveal();
|
||
_visible = true;
|
||
}
|
||
|
||
void
|
||
FGMenuBar::hide ()
|
||
{
|
||
if (_menuBar != 0)
|
||
_menuBar->hide();
|
||
_visible = false;
|
||
}
|
||
|
||
bool
|
||
FGMenuBar::isVisible () const
|
||
{
|
||
return _visible;
|
||
}
|
||
|
||
void
|
||
FGMenuBar::fireItem (puObject * item)
|
||
{
|
||
const char * name = item->getLegend();
|
||
vector<FGBinding *> &bindings = _bindings[name];
|
||
int nBindings = bindings.size();
|
||
|
||
for (int i = 0; i < nBindings; i++)
|
||
bindings[i]->fire();
|
||
}
|
||
|
||
void
|
||
FGMenuBar::make_menu (SGPropertyNode * node)
|
||
{
|
||
const char * name = strdup(node->getStringValue("label"));
|
||
vector<SGPropertyNode_ptr> item_nodes = node->getChildren("item");
|
||
|
||
int array_size = item_nodes.size();
|
||
|
||
char ** items = make_char_array(array_size);
|
||
puCallback * callbacks = make_callback_array(array_size);
|
||
|
||
for (unsigned int i = 0, j = item_nodes.size() - 1;
|
||
i < item_nodes.size();
|
||
i++, j--) {
|
||
|
||
// Set up the PUI entries for this item
|
||
items[j] = strdup((char *)item_nodes[i]->getStringValue("label"));
|
||
callbacks[j] = menu_callback;
|
||
|
||
// Load all the bindings for this item
|
||
vector<SGPropertyNode_ptr> bindings = item_nodes[i]->getChildren("binding");
|
||
SGPropertyNode * dest = fgGetNode("/sim/bindings/menu", true);
|
||
|
||
for (unsigned int k = 0; k < bindings.size(); k++) {
|
||
unsigned int m = 0;
|
||
SGPropertyNode *binding;
|
||
while (dest->getChild("binding", m))
|
||
m++;
|
||
|
||
binding = dest->getChild("binding", m, true);
|
||
copyProperties(bindings[k], binding);
|
||
_bindings[items[j]].push_back(new FGBinding(binding));
|
||
}
|
||
}
|
||
|
||
_menuBar->add_submenu(name, items, callbacks);
|
||
}
|
||
|
||
void
|
||
FGMenuBar::make_menubar ()
|
||
{
|
||
SGPropertyNode *targetpath;
|
||
|
||
targetpath = fgGetNode("/sim/menubar/default",true);
|
||
// fgLoadProps("gui/menubar.xml", targetpath);
|
||
|
||
/* NOTE: there is no check to see whether there's any usable data at all
|
||
*
|
||
* This would also have the advantage of being able to create some kind of
|
||
* 'fallback' menu - just in case that either menubar.xml is empty OR that
|
||
* its XML data is not valid, that way we would avoid displaying an
|
||
* unusable menubar without any functionality - if we decided to add another
|
||
* char * element to the commands structure in
|
||
* $FG_SRC/src/Main/fgcommands.cxx
|
||
* we could additionally save each function's (short) description and use
|
||
* this as label for the fallback PUI menubar item labels - as a workaround
|
||
* one might simply use the internal fgcommands and put them into the
|
||
* fallback menu, so that the user is at least able to re-init the menu
|
||
* loading - just in case there was some malformed XML in it
|
||
* (it happend to me ...)
|
||
*/
|
||
|
||
make_menubar(targetpath);
|
||
}
|
||
|
||
/* WARNING: We aren't yet doing any validation of what's found - but since
|
||
* this isn't done with menubar.xml either, it should not really matter
|
||
* right now. Although one should later on consider to validate the
|
||
* contents, whether they are representing a 'legal' menubar structure.
|
||
*/
|
||
void
|
||
FGMenuBar::make_menubar(const SGPropertyNode * props)
|
||
{
|
||
// Just in case.
|
||
destroy_menubar();
|
||
_menuBar = new puMenuBar;
|
||
|
||
vector<SGPropertyNode_ptr> menu_nodes = props->getChildren("menu");
|
||
for (unsigned int i = 0; i < menu_nodes.size(); i++)
|
||
make_menu(menu_nodes[i]);
|
||
|
||
_menuBar->close();
|
||
if (_visible)
|
||
_menuBar->reveal();
|
||
else
|
||
_menuBar->hide();
|
||
}
|
||
|
||
void
|
||
FGMenuBar::destroy_menubar ()
|
||
{
|
||
if ( _menuBar == 0 )
|
||
return;
|
||
|
||
hide();
|
||
puDeleteObject(_menuBar);
|
||
|
||
unsigned int i;
|
||
|
||
// Delete all the character arrays
|
||
// we were forced to keep around for
|
||
// plib.
|
||
SG_LOG(SG_GENERAL, SG_INFO, "Deleting char arrays");
|
||
for (i = 0; i < _char_arrays.size(); i++) {
|
||
for (int j = 0; _char_arrays[i][j] != 0; j++)
|
||
free(_char_arrays[i][j]); // added with strdup
|
||
delete[] _char_arrays[i];
|
||
}
|
||
|
||
// Delete all the callback arrays
|
||
// we were forced to keep around for
|
||
// plib.
|
||
SG_LOG(SG_GENERAL, SG_INFO, "Deleting callback arrays");
|
||
for (i = 0; i < _callback_arrays.size(); i++)
|
||
delete[] _callback_arrays[i];
|
||
|
||
// Delete all those bindings
|
||
SG_LOG(SG_GENERAL, SG_INFO, "Deleting bindings");
|
||
map<string,vector<FGBinding *> >::iterator it;
|
||
it = _bindings.begin();
|
||
for (it = _bindings.begin(); it != _bindings.end(); it++) {
|
||
SG_LOG(SG_GENERAL, SG_INFO, "Deleting bindings for " << it->first);
|
||
for ( i = 0; i < it->second.size(); i++ )
|
||
delete it->second[i];
|
||
}
|
||
|
||
SG_LOG(SG_GENERAL, SG_INFO, "Done.");
|
||
}
|
||
|
||
|
||
char **
|
||
FGMenuBar::make_char_array (int size)
|
||
{
|
||
char ** list = new char*[size+1];
|
||
for (int i = 0; i <= size; i++)
|
||
list[i] = 0;
|
||
_char_arrays.push_back(list);
|
||
return list;
|
||
}
|
||
|
||
puCallback *
|
||
FGMenuBar::make_callback_array (int size)
|
||
{
|
||
puCallback * list = new puCallback[size+1];
|
||
for (int i = 0; i <= size; i++)
|
||
list[i] = 0;
|
||
_callback_arrays.push_back(list);
|
||
return list;
|
||
}
|
||
|
||
// end of menubar.cxx
|