@class CocoaMenuDelegate;
+namespace {
+
+ class CocoaEnabledListener : public SGPropertyChangeListener
+ {
+ public:
+ CocoaEnabledListener(SGPropertyNode_ptr prop, NSMenuItem* i) :
+ property(prop->getNode("enabled")),
+ item(i)
+ {
+ if (property.get()) {
+ property->addChangeListener(this);
+ }
+ }
+
+ ~CocoaEnabledListener()
+ {
+ if (property.get()) {
+ property->removeChangeListener(this);
+ }
+ }
+
+
+ virtual void valueChanged(SGPropertyNode *node)
+ {
+ CocoaAutoreleasePool pool;
+ BOOL b = node->getBoolValue();
+ [item setEnabled:b];
+ }
+
+ private:
+ SGPropertyNode_ptr property;
+ NSMenuItem* item;
+ };
+} // of anonymous namespace
+
class FGCocoaMenuBar::CocoaMenuBarPrivate
{
public:
CocoaMenuDelegate* delegate;
MenuItemBindings itemBindings;
- std::vector<SGPropertyChangeListener*> listeners;
+ std::vector<CocoaEnabledListener*> listeners;
};
// prior to the 10.6 SDK, NSMenuDelegate was an informal protocol
[item setKeyEquivalentModifierMask:modifiers];
}
-namespace {
-
- class CocoaEnabledListener : public SGPropertyChangeListener
- {
- public:
- CocoaEnabledListener(NSMenuItem* i) :
- item(i)
- {
-
- }
-
- ~CocoaEnabledListener()
- {
-
- }
-
-
- virtual void valueChanged(SGPropertyNode *node)
- {
- CocoaAutoreleasePool pool;
- BOOL b = node->getBoolValue();
- [item setEnabled:b];
- }
-
- private:
- NSMenuItem* item;
- };
-} // of anonymous namespace
-
FGCocoaMenuBar::CocoaMenuBarPrivate::CocoaMenuBarPrivate()
{
delegate = [[CocoaMenuDelegate alloc] init];
setItemShortcutFromString(item, shortcut);
}
- SGPropertyChangeListener* enableListener = new CocoaEnabledListener(item);
- listeners.push_back(enableListener);
- n->getNode("enabled")->addChangeListener(enableListener);
+ CocoaEnabledListener* cl = new CocoaEnabledListener(n, item);
+ listeners.push_back(cl);
+
[item setTarget:delegate];
[item setAction:@selector(itemAction:)];
}
[topLevelItem.submenu removeAllItems];
}
- std::vector<SGPropertyChangeListener*>::iterator it;
+ std::vector<CocoaEnabledListener*>::iterator it;
for (it = p->listeners.begin(); it != p->listeners.end(); ++it) {
delete *it;
- }
+ }
+
+ // owing to the bizarre destructor behaviour of SGBinding, we need
+ // to explicitly clear these bindings. (PUIMenuBar takes a different
+ // approach, and copies each binding into /sim/bindings)
+ MenuItemBindings::iterator j;
+ for (j = p->itemBindings.begin(); j != p->itemBindings.end(); ++j) {
+ clearBindingList(j->second);
+ }
}
void FGCocoaMenuBar::init()
n->setBoolValue("enabled", true);
}
- SGPropertyChangeListener* l = new CocoaEnabledListener(item);
+ CocoaEnabledListener* l = new CocoaEnabledListener( n, item);
p->listeners.push_back(l);
- n->getNode("enabled")->addChangeListener(l);
}
}
void
NewGUI::init ()
{
-#if defined(SG_MAC)
- if (fgGetBool("/sim/menubar/native", true)) {
- _menubar.reset(new FGCocoaMenuBar);
- }
-#endif
- if (!_menubar.get()) {
- _menubar.reset(new FGPUIMenuBar);
- }
-
+ createMenuBarImplementation();
fgTie("/sim/menubar/visibility", this,
&NewGUI::getMenuBarVisible, &NewGUI::setMenuBarVisible);
setStyle();
SGPath p(globals->get_fg_root(), "gui/dialogs");
readDir(p);
- const std::string aircraft_dir(fgGetString("/sim/aircraft-dir"));
- readDir( SGPath(aircraft_dir, "gui/dialogs") );
+
+ SGPath aircraftDialogDir(string(fgGetString("/sim/aircraft-dir")), "gui/dialogs");
+ if (aircraftDialogDir.exists()) {
+ readDir(aircraftDialogDir);
+ }
// Fix for http://code.google.com/p/flightgear-bugs/issues/detail?id=947
fgGetNode("sim/menubar")->setAttribute(SGPropertyNode::PRESERVE, true);
reset(false);
}
+void
+NewGUI::createMenuBarImplementation()
+{
+#if defined(SG_MAC)
+ if (fgGetBool("/sim/menubar/native", true)) {
+ _menubar.reset(new FGCocoaMenuBar);
+ }
+#endif
+ if (!_menubar.get()) {
+ _menubar.reset(new FGPUIMenuBar);
+ }
+}
+
void
NewGUI::reset (bool reload)
{
setStyle();
unbind();
-#if !defined(SG_MAC)
- _menubar.reset(new FGPUIMenuBar);
-#endif
if (reload) {
_dialog_props.clear();
_dialog_names.clear();
init();
} else {
+ createMenuBarImplementation();
_menubar->init();
}