From a938b5b0df380a6ed7833aea2d84728cf9e92876 Mon Sep 17 00:00:00 2001 From: ehofman Date: Fri, 22 Oct 2004 09:26:51 +0000 Subject: [PATCH] Boris Koenig: This will modify menubar.cxx/hxx so that it exports the entire menubar (from menubar.xml) to the property tree, so that it can now be changed dynamically using Nasal's setprop() instruction and afterwards running a newly added fgcommand to update the menubar based on those changes using the appropriate menubar path within the property tree. By default the menubar from menubar.xml will be stored within: /sim/menubar/default Erik: I have moved the loading of menubar.xml into preferences.xml and made sure that the menubar is destroyed every time a new menubar is created. --- src/GUI/menubar.cxx | 116 ++++++++++++++++++++++++++++++-------------- src/GUI/menubar.hxx | 13 ++++- 2 files changed, 91 insertions(+), 38 deletions(-) diff --git a/src/GUI/menubar.cxx b/src/GUI/menubar.cxx index e2d888aa1..d1b6d2865 100644 --- a/src/GUI/menubar.cxx +++ b/src/GUI/menubar.cxx @@ -210,39 +210,7 @@ FGMenuBar::FGMenuBar () FGMenuBar::~FGMenuBar () { - 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 >::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."); + destroy_menubar(); } void @@ -323,11 +291,43 @@ FGMenuBar::make_menu (SGPropertyNode * node) void FGMenuBar::make_menubar () { - _menuBar = new puMenuBar; - SGPropertyNode props; + 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); +} - fgLoadProps("gui/menubar.xml", &props); - vector menu_nodes = props.getChildren("menu"); +/* 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 menu_nodes = props->getChildren("menu"); for (unsigned int i = 0; i < menu_nodes.size(); i++) make_menu(menu_nodes[i]); @@ -338,6 +338,48 @@ FGMenuBar::make_menubar () _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 >::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) { diff --git a/src/GUI/menubar.hxx b/src/GUI/menubar.hxx index 10aeaf7a6..6c7217786 100644 --- a/src/GUI/menubar.hxx +++ b/src/GUI/menubar.hxx @@ -54,7 +54,6 @@ public: * Initialize the menu bar from $FG_ROOT/gui/menubar.xml */ virtual void init (); - /** * Make the menu bar visible. @@ -85,6 +84,18 @@ public: virtual void fireItem (puObject * item); + /** + * create a menubar based on a PropertyList within the PropertyTree + */ + void make_menubar (const SGPropertyNode * props); + + + /** + * destroy a menubar based on a PropertyList within the PropertyTree + */ + void destroy_menubar (); + + private: // Make a single menu.