#include <string.h>
#include <iostream>
-#include <sstream>
#include <plib/pu.h>
#include <simgear/debug/logstream.hxx>
* contents, whether they are representing a 'legal' menubar structure.
*/
void
-FGMenuBar::make_menubar(const SGPropertyNode * props)
+FGMenuBar::make_menubar(SGPropertyNode * props)
{
// Just in case.
destroy_menubar();
make_menu(menu_nodes[i]);
_menuBar->close();
- make_map(props);
+ make_object_map(props);
if (_visible)
_menuBar->reveal();
SG_LOG(SG_GENERAL, SG_INFO, "Done.");
}
-struct EnabledListener : SGPropertyChangeListener {
- void valueChanged(SGPropertyNode* node) {
- NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
- if (!gui)
- return;
- FGMenuBar *menubar = gui->getMenuBar();
- if (menubar)
- menubar->enable_item(node->getParent(), node->getBoolValue());
- }
-};
-
-void
-FGMenuBar::add_enabled_listener(SGPropertyNode * node)
-{
- if (!node->hasValue("enabled"))
- node->setBoolValue("enabled", true);
-
- enable_item(node, node->getBoolValue("enabled"));
- node->getNode("enabled")->addChangeListener(new EnabledListener());
-}
-
void
-FGMenuBar::make_map(const SGPropertyNode * node)
+FGMenuBar::make_object_map(SGPropertyNode * node)
{
- string base = node->getPath();
-
- int menu_index = 0;
+ unsigned int menu_index = 0;
+ vector<SGPropertyNode_ptr> menus = node->getChildren("menu");
for (puObject *obj = ((puGroup *)_menuBar)->getFirstChild();
obj; obj = obj->getNextObject()) {
if (!(obj->getType() & PUCLASS_ONESHOT))
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;
+ if (menu_index >= menus.size()) {
+ SG_LOG(SG_GENERAL, SG_WARN, "'menu' object without node: "
+ << node->getPath() << "/menu[" << menu_index << ']');
+ return;
}
- // push "menu" entry
- _entries[prop->getPath()] = obj;
- add_enabled_listener(prop);
+ SGPropertyNode *menu = menus.at(menu_index);
+ _objects[menu->getPath()] = obj;
+ add_enabled_listener(menu);
- // push "item" entries
- puPopupMenu *popup = (puPopupMenu *)obj->getUserData();
+ puGroup *popup = (puGroup *)obj->getUserData();
if (!popup)
continue;
// the entries are for some reason reversed (last first), and we
- // don't know yet how many will be usable; so we collect first
+ // don't know yet how many there will be; so we collect first
vector<puObject *> e;
- for (puObject *me = ((puGroup *)popup)->getFirstChild();
- me; me = me->getNextObject())
+ for (puObject *me = popup->getFirstChild(); me; me = me->getNextObject())
e.push_back(me);
+ vector<SGPropertyNode_ptr> items = menu->getChildren("item");
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;
+ if (i >= items.size()) {
+ SG_LOG(SG_GENERAL, SG_WARN, "'item' object without node: "
+ << menu->getPath() << "/item[" << i << ']');
+ break;
}
- _entries[prop->getPath()] = e[i];
- add_enabled_listener(prop);
+ SGPropertyNode *item = items.at(e.size() - i - 1);
+ _objects[item->getPath()] = e[i];
+ add_enabled_listener(item);
}
menu_index++;
}
}
+struct EnabledListener : SGPropertyChangeListener {
+ void valueChanged(SGPropertyNode *node) {
+ NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
+ if (!gui)
+ return;
+ FGMenuBar *menubar = gui->getMenuBar();
+ if (menubar)
+ menubar->enable_item(node->getParent(), node->getBoolValue());
+ }
+};
+
+void
+FGMenuBar::add_enabled_listener(SGPropertyNode * node)
+{
+ if (!node->hasValue("enabled"))
+ node->setBoolValue("enabled", true);
+
+ enable_item(node, node->getBoolValue("enabled"));
+ node->getNode("enabled")->addChangeListener(new EnabledListener());
+}
+
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");
+ const char *path = node->getPath();
+ if (_objects.find(path) == _objects.end()) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Trying to enable/disable "
+ "non-existent menu item for node `" << path << '\'');
return false;
}
- puObject *object = _entries[node->getPath()];
+ puObject *object = _objects[path];
if (state)
object->activate();
else