]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/FGCocoaMenuBar.mm
Move viewer-related sources to separate folder.
[flightgear.git] / src / GUI / FGCocoaMenuBar.mm
index 7b44c7820b8ad3a850bb08d4c8c40baa09abfb23..916195f4a44ae1870bcaddd81d8d387c99ccfe2e 100644 (file)
@@ -8,6 +8,7 @@
 #include <simgear/props/props_io.hxx>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/structure/SGBinding.hxx>
+#include <simgear/misc/strutils.hxx>
 
 #include <Main/fg_props.hxx>
 
@@ -16,6 +17,7 @@
 using std::string;
 using std::map;
 using std::cout;
+using namespace simgear;
 
 typedef std::map<NSMenuItem*, SGBindingList> MenuItemBindings;
 
@@ -27,7 +29,6 @@ public:
   CocoaMenuBarPrivate();
   ~CocoaMenuBarPrivate();
   
-  bool labelIsSeparator(const std::string& s) const;  
   void menuFromProps(NSMenu* menu, SGPropertyNode* menuNode);
   
   void fireBindingsForItem(NSMenuItem* item);
@@ -63,25 +64,70 @@ static NSString* stdStringToCocoa(const string& s)
   return [NSString stringWithUTF8String:s.c_str()];
 }
 
-class EnabledListener : public SGPropertyChangeListener
+static void setFunctionKeyShortcut(NSMenuItem* item, unichar shortcut)
 {
-public:
-  EnabledListener(NSMenuItem* i) :
-    item(i)
-  {}
+  unichar ch[1];
+  ch[0] = shortcut;
+  [item setKeyEquivalentModifierMask:NSFunctionKeyMask];
+  [item setKeyEquivalent:[NSString stringWithCharacters:ch length:1]];
+  
+}
+
+static void setItemShortcutFromString(NSMenuItem* item, const string& s)
+{
+  const char* shortcut = "";
   
+  bool hasCtrl = strutils::starts_with(s, "Ctrl-"); 
+  bool hasShift = strutils::starts_with(s, "Shift-");
+  bool hasAlt = strutils::starts_with(s, "Alt-");
   
-  virtual void valueChanged(SGPropertyNode *node) 
-  {
-    BOOL b = node->getBoolValue();
-    [item setEnabled:b];
+  int offset = 0; // character offset from start of string
+  if (hasShift) offset += 6;
+  if (hasCtrl) offset += 5;
+  if (hasAlt) offset += 4;
+  
+  shortcut = s.c_str() + offset;
+  if (!strcmp(shortcut, "Esc"))
+    shortcut = "\e";    
+  
+  if (!strcmp(shortcut, "F11")) {
+    setFunctionKeyShortcut(item, NSF11FunctionKey);
+    return;
   }
   
-private:
-  NSMenuItem* item;
-};
-
+  if (!strcmp(shortcut, "F12")) {
+    setFunctionKeyShortcut(item, NSF12FunctionKey);
+    return;
+  }
+  
+  [item setKeyEquivalent:[NSString stringWithCString:shortcut encoding:NSUTF8StringEncoding]];
+  NSUInteger modifiers = 0;
+  if (hasCtrl) modifiers |= NSControlKeyMask;
+  if (hasShift) modifiers |= NSShiftKeyMask;
+  if (hasAlt) modifiers |= NSAlternateKeyMask;
+  
+  [item setKeyEquivalentModifierMask:modifiers];
+}
 
+namespace {
+  class CocoaEnabledListener : public SGPropertyChangeListener
+  {
+  public:
+    CocoaEnabledListener(NSMenuItem* i) :
+      item(i)
+    {}
+    
+    
+    virtual void valueChanged(SGPropertyNode *node) 
+    {
+      BOOL b = node->getBoolValue();
+      [item setEnabled:b];
+    }
+    
+  private:
+    NSMenuItem* item;
+  };
+} // of anonymous namespace
 
 FGCocoaMenuBar::CocoaMenuBarPrivate::CocoaMenuBarPrivate()
 {
@@ -94,15 +140,9 @@ FGCocoaMenuBar::CocoaMenuBarPrivate::~CocoaMenuBarPrivate()
   [delegate release];
 }
   
-bool FGCocoaMenuBar::CocoaMenuBarPrivate::labelIsSeparator(const std::string& s) const
+static bool labelIsSeparator(NSString* s)
 {
-  for (unsigned int i=0; i<s.size(); ++i) {
-    if (s[i] != '-') {
-      return false;
-    }
-  }
-  
-  return true;
+  return [s hasPrefix:@"---"];
 }
   
 void FGCocoaMenuBar::CocoaMenuBarPrivate::menuFromProps(NSMenu* menu, SGPropertyNode* menuNode)
@@ -113,22 +153,29 @@ void FGCocoaMenuBar::CocoaMenuBarPrivate::menuFromProps(NSMenu* menu, SGProperty
       n->setBoolValue("enabled", true);
     }
     
+    string shortcut;
     string l = n->getStringValue("label");
     string::size_type pos = l.find("(");
     if (pos != string::npos) {
-      l = l.substr(0, pos);
+      string full(l);
+      l = full.substr(0, pos);
+      shortcut = full.substr(pos + 1, full.size() - (pos + 2));
     }
     
-    NSString* label = stdStringToCocoa(l);
-    NSString* shortcut = @"";
+    NSString* label = stdStringToCocoa(strutils::simplify(l));
+    
     NSMenuItem* item;
     if (index >= [menu numberOfItems]) {
-      if (labelIsSeparator(l)) {
+      if (labelIsSeparator(label)) {
         item = [NSMenuItem separatorItem];
         [menu addItem:item];
       } else {        
-        item = [menu addItemWithTitle:label action:nil keyEquivalent:shortcut];
-        n->getNode("enabled")->addChangeListener(new EnabledListener(item));
+        item = [menu addItemWithTitle:label action:nil keyEquivalent:@""];
+        if (!shortcut.empty()) {
+          setItemShortcutFromString(item, shortcut);
+        }
+        
+        n->getNode("enabled")->addChangeListener(new CocoaEnabledListener(item));
         [item setTarget:delegate];
         [item setAction:@selector(itemAction:)];
       }
@@ -212,6 +259,13 @@ void FGCocoaMenuBar::init()
     p->menuFromProps(menu, n);
     ++index;
     previousMenu = item;
+    
+  // track menu enable/disable state
+    if (!n->hasValue("enabled")) {
+      n->setBoolValue("enabled", true);
+    }
+    
+    n->getNode("enabled")->addChangeListener(new CocoaEnabledListener(item));
   }
 }