* Melchior FRANZ -- Tuesday 06 December 2005 15:57: > This should better be hooked into the property tree, so that one can > directly set /sim/menubar/default/menu[2]/item[3]/enabled to false and > get the menu disabled.
Done. Attached is a better patch. No more fgCommand, and no Nasal-wrapper. Just set the "enabled" property. This can also be done in gui/menubar.xml. "Fuel & Payload" would be globally disabled there, and only FDMs which support this feature turn it on. (Or rather: gui.nas enables it for YASim.) m.
Index: menubar.cxx =================================================================== RCS file: /var/cvs/FlightGear-0.9/FlightGear/src/GUI/menubar.cxx,v retrieving revision 1.25 diff -u -p -r1.25 menubar.cxx --- menubar.cxx 9 Nov 2005 10:48:45 -0000 1.25 +++ menubar.cxx 6 Dec 2005 15:53:42 -0000 @@ -4,6 +4,7 @@ #include <string.h> #include <iostream> +#include <sstream> #include <plib/pu.h> #include <simgear/debug/logstream.hxx> @@ -302,6 +303,8 @@ FGMenuBar::make_menubar(const SGProperty make_menu(menu_nodes[i]); _menuBar->close(); + make_map(props); + if (_visible) _menuBar->reveal(); else @@ -349,6 +352,106 @@ FGMenuBar::destroy_menubar () SG_LOG(SG_GENERAL, SG_INFO, "Done."); } +struct MenuListener : SGPropertyChangeListener { + MenuListener() : menubar(0) { + NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); + if (gui) + menubar = gui->getMenuBar(); + } + FGMenuBar *menubar; + void valueChanged(SGPropertyNode* node) { + menubar->enable_item(node->getParent(), node->getBoolValue()); + } +}; + +void +FGMenuBar::make_map(const SGPropertyNode * node) +{ + string base = node->getPath(); + const char *legend; + + int menu_index = 0; + for (puObject *obj = ((puGroup *)_menuBar)->getFirstChild(); + obj; obj = obj->getNextObject()) { + + // skip puPopupMenus. They are also children of _menuBar, + // but we access them via getUserData() (see below) + if (!(obj->getType() & PUCLASS_ONESHOT)) + continue; + + legend = obj->getLegend(); + if (!legend) + continue; + + std::ostringstream menu; + menu << base << '/' << "menu[" << menu_index << "]"; + SGPropertyNode *prop = fgGetNode(menu.str().c_str()); + if (!prop) { + SG_LOG(SG_GENERAL, SG_WARN, "menu without node: " << menu.str()); + continue; + } + + // push "menu" entry + _entries[prop->getPath()] = obj; + if (!prop->hasValue("enabled")) + prop->setBoolValue("enabled", true); + + enable_item(prop, prop->getBoolValue("enabled")); + prop->getNode("enabled")->addChangeListener(new MenuListener()); + + // push "item" entries + puPopupMenu *popup = (puPopupMenu *)obj->getUserData(); + if (!popup) + continue; + + vector<puObject *> e; + + for (puObject *me = ((puGroup *)popup)->getFirstChild(); + me; me = me->getNextObject()) { + + legend = me->getLegend(); + if (!legend) + continue; + + e.push_back(me); + } + + for (unsigned int i = 0; i < e.size(); i++) { + + std::ostringstream item; + item << menu.str() << '/' << "item[" << (e.size() - i - 1) << "]"; + prop = fgGetNode(item.str().c_str()); + if (!prop) { + SG_LOG(SG_GENERAL, SG_WARN, "item without node: " << item.str()); + continue; + } + _entries[prop->getPath()] = e[i]; + if (!prop->hasValue("enabled")) + prop->setBoolValue("enabled", true); + + enable_item(prop, prop->getBoolValue("enabled")); + prop->getNode("enabled")->addChangeListener(new MenuListener()); + } + menu_index++; + } +} + +bool +FGMenuBar::enable_item(const SGPropertyNode * node, bool state) +{ + if (!node || _entries.find(node->getPath()) == _entries.end()) { + SG_LOG(SG_GENERAL, SG_WARN, "Trying to enable/disable " + "non-existent menu item"); + return false; + } + puObject *object = _entries[node->getPath()]; + if (state) + object->activate(); + else + object->greyOut(); + + return true; +} char ** FGMenuBar::make_char_array (int size) Index: menubar.hxx =================================================================== RCS file: /var/cvs/FlightGear-0.9/FlightGear/src/GUI/menubar.hxx,v retrieving revision 1.7 diff -u -p -r1.7 menubar.hxx --- menubar.hxx 22 Oct 2004 09:26:51 -0000 1.7 +++ menubar.hxx 6 Dec 2005 15:53:42 -0000 @@ -96,6 +96,12 @@ public: void destroy_menubar (); + /** + * disable/enable menu titles and entries + */ + bool enable_item (const SGPropertyNode * item, bool state); + + private: // Make a single menu. @@ -104,6 +110,9 @@ private: // Make the top-level menubar. void make_menubar (); + // Create a property-path -> puObject map for menu node + void make_map(const SGPropertyNode * node); + // Is the menu visible? bool _visible; @@ -121,6 +130,8 @@ private: puCallback * make_callback_array (int size); vector<char **> _char_arrays; vector<puCallback *> _callback_arrays; + + map<string, puObject *> _entries; }; #endif // __MENUBAR_HXX
_______________________________________________ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d