Author: manolo
Date: 2012-01-11 09:54:51 -0800 (Wed, 11 Jan 2012)
New Revision: 9219
Log:
Fixed the use of fltk3::SUBMENU_POINTER in fltk3::SysMenuBar objects (Mac 
OS-specific).
Modified the menubar demo program to exercise the fltk3::SysMenuBar class.

Modified:
   branches/branch-3.0/src/fltk3/SysMenuBar.cxx
   branches/branch-3.0/src/fltk3/cocoa.mm
   branches/branch-3.0/test/menubar.cxx

Modified: branches/branch-3.0/src/fltk3/SysMenuBar.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/SysMenuBar.cxx        2012-01-11 16:16:31 UTC 
(rev 9218)
+++ branches/branch-3.0/src/fltk3/SysMenuBar.cxx        2012-01-11 17:54:51 UTC 
(rev 9219)
@@ -109,46 +109,46 @@
 /*
  * create a sub menu for a specific menu handle
  */
-static void createSubMenu( void * mh, pFl_Menu_Item &mm )
+static void createSubMenu( void * mh, pFl_Menu_Item &mm,  const 
fltk3::MenuItem *mitem )
 {
   void *submenu;
   int miCnt, flags;
   
   void *menuItem;
-  submenu = 
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::initWithTitle, 
mm->text);
+  submenu = 
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::initWithTitle, 
mitem->text);
   int cnt;
   fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::numberOfItems, 
mh, &cnt);
   cnt--;
   menuItem = 
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::itemAtIndex, mh, 
cnt);
   fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::setSubmenu, 
menuItem, submenu);
-  if ( mm->flags & fltk3::MENU_INACTIVE ) {
-    fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::setEnabled, 
menuItem, 0);
-  }
-  mm++;
   
   while ( mm->text )
   {
-    int flRank = mm - fltk3::sys_menu_bar->fltk3::Menu_::menu();
-    fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addNewItem, 
submenu, flRank, &miCnt);
+    char visible = mm->visible() ? 1 : 0;
+    fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addNewItem, 
submenu, mm, &miCnt);
     setMenuFlags( submenu, miCnt, mm );
     setMenuShortcut( submenu, miCnt, mm );
-    if ( mm->flags & fltk3::MENU_INACTIVE ) {
+    if ( mm->flags & fltk3::MENU_INACTIVE || mitem->flags & 
fltk3::MENU_INACTIVE) {
       void *item = 
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::itemAtIndex, 
submenu, miCnt);
       fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::setEnabled, 
item, 0);
     }
     flags = mm->flags;
     if ( mm->flags & fltk3::SUBMENU )
     {
-      createSubMenu( submenu, mm );
+      mm++;
+      createSubMenu( submenu, mm, mm - 1 );
     }
     else if ( mm->flags & fltk3::SUBMENU_POINTER )
     {
       const fltk3::MenuItem *smm = (fltk3::MenuItem*)mm->user_data_;
-      createSubMenu( submenu, smm );
+      createSubMenu( submenu, smm, mm );
     }
     if ( flags & fltk3::MENU_DIVIDER ) {
       
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addSeparatorItem, 
submenu);
       }
+    if ( !visible ) {
+      fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::removeItem, 
submenu, miCnt);
+    }
     mm++;
   }
 }
@@ -156,10 +156,11 @@
 
 /*
  * convert a complete fltk3::MenuItem array into a series of menus in the top 
menu bar
- * ALL PREVIOUS SYSTEM MENUS, EXCEPT APPLICATION MENU, ARE REPLACED BY THE NEW 
DATA
+ * ALL PREVIOUS SYSTEM MENUS, EXCEPT THE APPLICATION MENU, ARE REPLACED BY THE 
NEW DATA
  */
 static void convertToMenuBar(const fltk3::MenuItem *mm)
 {
+  int rank;
   int count;//first, delete all existing system menus
   fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::numberOfItems, 
fl_system_menu, &count);
   for(int i = count - 1; i > 0; i--) {
@@ -171,17 +172,18 @@
     if ( !mm || !mm->text )
       break;
     char visible = mm->visible() ? 1 : 0;
-    int flRank = mm - fltk3::sys_menu_bar->fltk3::Menu_::menu();
-    fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addNewItem, 
fl_system_menu, flRank, NULL);
-               
-    if ( mm->flags & fltk3::SUBMENU )
-      createSubMenu( fl_system_menu, mm );
+    fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::addNewItem, 
fl_system_menu, mm, &rank);
+    
+    if ( mm->flags & fltk3::SUBMENU ) {
+      mm++;
+      createSubMenu( fl_system_menu, mm, mm - 1);
+    }
     else if ( mm->flags & fltk3::SUBMENU_POINTER ) {
       const fltk3::MenuItem *smm = (fltk3::MenuItem*)mm->user_data_;
-      createSubMenu( fl_system_menu, smm );
+      createSubMenu( fl_system_menu, smm, mm);
     }
-    if ( visible ) {
-      //      InsertMenu( mh, 0 );
+    if ( !visible ) {
+      fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::removeItem, 
fl_system_menu, rank);
     }
     mm++;
   }

Modified: branches/branch-3.0/src/fltk3/cocoa.mm
===================================================================
--- branches/branch-3.0/src/fltk3/cocoa.mm      2012-01-11 16:16:31 UTC (rev 
9218)
+++ branches/branch-3.0/src/fltk3/cocoa.mm      2012-01-11 17:54:51 UTC (rev 
9219)
@@ -2946,29 +2946,40 @@
 @interface FLMenuItem : NSMenuItem 
 - (void) doCallback:(id)unused;
 - (void) directCallback:(id)unused;
+- (const fltk3::MenuItem*) getFlItem;
 @end
 @implementation FLMenuItem
+- (const fltk3::MenuItem*) getFlItem
+{
+  return *(const fltk3::MenuItem **)[(NSData*)[self representedObject] bytes];
+}
 - (void) doCallback:(id)unused
 {
   fl_lock_function();
-  int flRank = [self tag];
-  const fltk3::MenuItem *items = fltk3::sys_menu_bar->fltk3::Menu_::menu();
-  const fltk3::MenuItem *item = items + flRank;
+  const fltk3::MenuItem *item = [self getFlItem];
+  NSMenu* menu = [self menu];
+  NSInteger flRank = [menu indexOfItem:self];
+  NSInteger last = [menu numberOfItems];
   if (item) {
     fltk3::sys_menu_bar->picked(item);
     if ( item->flags & fltk3::MENU_TOGGLE ) {  // update the menu toggle symbol
       [self setState:(item->value() ? NSOnState : NSOffState)];
     }
     else if ( item->flags & fltk3::MENU_RADIO ) {      // update the menu 
radio symbols
+      const fltk3::MenuItem *item2;
       int from = flRank;
-      while( from > 0 && items[from - 1].label() && (items[from - 1].flags & 
fltk3::MENU_RADIO) &&
-            !(items[from - 1].flags & fltk3::MENU_DIVIDER) ) {
-        from--;
+      while(from > 0) {
+       if ([[menu itemAtIndex:from-1] isSeparatorItem]) break;
+       item2 = [(FLMenuItem*)[menu itemAtIndex:from-1] getFlItem];
+       if ( !(item2->flags & fltk3::MENU_RADIO) ) break;
+       from--;
       }
       int to = flRank;
-      while( !(items[to].flags & fltk3::MENU_DIVIDER) && items[to + 1].label() 
&& 
-            (items[to + 1].flags & fltk3::MENU_RADIO) ) {
-        to++;
+      while (to+1 < last) {
+       if ([[menu itemAtIndex:to+1] isSeparatorItem]) break;
+       item2 = [(FLMenuItem*)[menu itemAtIndex:to+1] getFlItem];
+       if (!(item2->flags & fltk3::MENU_RADIO)) break;
+       to++;
       }
       NSMenu *nsmenu = [self menu];
       int nsrank = (int)[nsmenu indexOfItem:self];
@@ -3122,20 +3133,21 @@
     value = va_arg(ap, int);
     [menu removeItem:[menu itemAtIndex:value]];
   }
-  else if (operation == fltk3::SysMenuBar::addNewItem) {               // 
arguments: NSMenu *menu, int flrank, int *prank
+  else if (operation == fltk3::SysMenuBar::addNewItem) {               // 
arguments: NSMenu *menu, flk3::MenuItem flrank, int *prank
     // creates a new menu item at the end of 'menu'
-    // attaches the item of rank flrank (counted in fltk3::Menu_) of 
fltk3::sys_menu_bar to it
+    // attaches the item of fltk3::sys_menu_bar to it
     // upon return, puts the rank (counted in NSMenu) of the new item in 
*prank unless prank is NULL
     menu = va_arg(ap, NSMenu*);
-    int flRank = va_arg(ap, int);
-    char *name = remove_ampersand( (fltk3::sys_menu_bar->fltk3::Menu_::menu() 
+ flRank)->label());
+    fltk3::MenuItem *mitem = va_arg(ap, fltk3::MenuItem *);
     int *prank = va_arg(ap, int*);
+    char *name = remove_ampersand(mitem->label());
     CFStringRef cfname = CFStringCreateWithCString(NULL, name, 
kCFStringEncodingUTF8);
     free(name);
     FLMenuItem *item = [[FLMenuItem alloc] initWithTitle:(NSString*)cfname 
                                                  action:@selector(doCallback:) 
                                           keyEquivalent:@""];
-    [item setTag:flRank];
+    NSData *pointer = [NSData dataWithBytes:&mitem 
length:sizeof(fltk3::MenuItem*)];
+    [item setRepresentedObject:pointer];
     [menu addItem:item];
     CFRelease(cfname);
     [item setTarget:item];

Modified: branches/branch-3.0/test/menubar.cxx
===================================================================
--- branches/branch-3.0/test/menubar.cxx        2012-01-11 16:16:31 UTC (rev 
9218)
+++ branches/branch-3.0/test/menubar.cxx        2012-01-11 17:54:51 UTC (rev 
9219)
@@ -28,7 +28,7 @@
 #include <fltk3/run.h>
 #include <fltk3/Box.h>
 #include <fltk3/DoubleWindow.h>
-#include <fltk3/MenuBar.h>
+#include <fltk3/SysMenuBar.h>
 #include <fltk3/ToggleButton.h>
 #include <fltk3/MenuButton.h>
 #include <fltk3/Choice.h>
@@ -179,6 +179,33 @@
   {0}
 };
 
+#ifdef __APPLE__
+fltk3::MenuItem menu_location[] = {
+  {"Window menu bar",  0, 0, 0, fltk3::MENU_VALUE},
+  {"System menu bar",  },
+  {0}
+};
+
+fltk3::SysMenuBar* smenubar;
+
+void menu_location_cb(fltk3::Widget* w, void* data) 
+{
+  fltk3::MenuBar *menubar = (fltk3::MenuBar*)data;
+  if (((fltk3::Choice*)w)->value() == 1) { // switch to system menu bar
+    menubar->hide();
+    const fltk3::MenuItem *menu = menubar->menu();
+    smenubar = new  fltk3::SysMenuBar(0,0,0,30); 
+    smenubar->menu(menu);
+    smenubar->callback(test_cb);
+  }
+  else { // switch to window menu bar
+    smenubar->clear();
+    delete smenubar;
+    menubar->show();
+  }
+}
+#endif // __APPLE__
+
 #define WIDTH 700
 
 fltk3::Menu_* menus[4];
@@ -213,6 +240,11 @@
   fltk3::Box b(200,200,200,100,"Press right button\nfor a pop-up menu");
   window.resizable(&mb);
   window.size_range(300,400,0,400);
+#ifdef __APPLE__
+  fltk3::Choice ch2(500,100,150,25,"Use:"); 
+  ch2.menu(menu_location);
+  ch2.callback(menu_location_cb, &menubar);
+#endif
   window.end();
   window.show(argc, argv);
   return fltk3::run();

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to