diff options
| author | Manolo Gouy <Manolo> | 2012-01-11 16:16:31 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2012-01-11 16:16:31 +0000 |
| commit | 4be97ea19c9a8a83e2831eedd1829da4ac381ba7 (patch) | |
| tree | a52c2f3f9c2e75ce7eded54604dbeae2cb316cb9 | |
| parent | aa0e4bb823949946ad4153b8d7eecbff0662553d (diff) | |
Fixed the use of FL_SUBMENU_POINTER in Fl_Sys_Menu_Bar objects (Mac OS-specific).
Modified the menubar demo program to exercise the Fl_Sys_Menu_Bar class.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9218 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | src/Fl_Sys_Menu_Bar.cxx | 44 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 44 | ||||
| -rw-r--r-- | test/menubar.cxx | 34 |
3 files changed, 85 insertions, 37 deletions
diff --git a/src/Fl_Sys_Menu_Bar.cxx b/src/Fl_Sys_Menu_Bar.cxx index 3bff75e42..2ec0ec20c 100644 --- a/src/Fl_Sys_Menu_Bar.cxx +++ b/src/Fl_Sys_Menu_Bar.cxx @@ -100,46 +100,46 @@ static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) /* * 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 Fl_Menu_Item *mitem) { void *submenu; int miCnt, flags; void *menuItem; - submenu = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::initWithTitle, mm->text); + submenu = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::initWithTitle, mitem->text); int cnt; Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, mh, &cnt); cnt--; menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, cnt); Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setSubmenu, menuItem, submenu); - if ( mm->flags & FL_MENU_INACTIVE ) { - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, menuItem, 0); - } - mm++; while ( mm->text ) { - int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, submenu, flRank, &miCnt); + char visible = mm->visible() ? 1 : 0; + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, submenu, mm, &miCnt); setMenuFlags( submenu, miCnt, mm ); setMenuShortcut( submenu, miCnt, mm ); - if ( mm->flags & FL_MENU_INACTIVE ) { + if ( mm->flags & FL_MENU_INACTIVE || mitem->flags & FL_MENU_INACTIVE) { void *item = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, submenu, miCnt); Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, item, 0); } flags = mm->flags; if ( mm->flags & FL_SUBMENU ) { - createSubMenu( submenu, mm ); + mm++; + createSubMenu( submenu, mm, mm - 1 ); } else if ( mm->flags & FL_SUBMENU_POINTER ) { const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; - createSubMenu( submenu, smm ); + createSubMenu( submenu, smm, mm ); } if ( flags & FL_MENU_DIVIDER ) { Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addSeparatorItem, submenu); } + if ( !visible ) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, submenu, miCnt); + } mm++; } } @@ -147,10 +147,11 @@ static void createSubMenu( void * mh, pFl_Menu_Item &mm ) /* * convert a complete Fl_Menu_Item 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 Fl_Menu_Item *mm) { + int rank; int count;//first, delete all existing system menus Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, fl_system_menu, &count); for(int i = count - 1; i > 0; i--) { @@ -162,17 +163,18 @@ static void convertToMenuBar(const Fl_Menu_Item *mm) if ( !mm || !mm->text ) break; char visible = mm->visible() ? 1 : 0; - int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, fl_system_menu, flRank, NULL); - - if ( mm->flags & FL_SUBMENU ) - createSubMenu( fl_system_menu, mm ); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, fl_system_menu, mm, &rank); + + if ( mm->flags & FL_SUBMENU ) { + mm++; + createSubMenu( fl_system_menu, mm, mm - 1); + } else if ( mm->flags & FL_SUBMENU_POINTER ) { const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; - createSubMenu( fl_system_menu, smm ); + createSubMenu( fl_system_menu, smm, mm); } - if ( visible ) { - // InsertMenu( mh, 0 ); + if ( !visible ) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, fl_system_menu, rank); } mm++; } @@ -271,6 +273,8 @@ void Fl_Sys_Menu_Bar::replace(int rank, const char *name) void Fl_Sys_Menu_Bar::draw() { } +extern class Fl_Sys_Menu_Bar *fl_sys_menu_bar; + #endif /* __APPLE__ */ diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 4299374b9..ed8d47577 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -2949,30 +2949,41 @@ static void createAppleMenu(void) } - (void) doCallback:(id)unused; - (void) directCallback:(id)unused; +- (const Fl_Menu_Item*) getFlItem; @end @implementation FLMenuItem +- (const Fl_Menu_Item*) getFlItem +{ + return *(const Fl_Menu_Item **)[(NSData*)[self representedObject] bytes]; +} - (void) doCallback:(id)unused { fl_lock_function(); - int flRank = [self tag]; - const Fl_Menu_Item *items = fl_sys_menu_bar->Fl_Menu_::menu(); - const Fl_Menu_Item *item = items + flRank; + const Fl_Menu_Item *item = [self getFlItem]; + NSMenu* menu = [self menu]; + NSInteger flRank = [menu indexOfItem:self]; + NSInteger last = [menu numberOfItems]; if (item) { fl_sys_menu_bar->picked(item); if ( item->flags & FL_MENU_TOGGLE ) { // update the menu toggle symbol [self setState:(item->value() ? NSOnState : NSOffState)]; } else if ( item->flags & FL_MENU_RADIO ) { // update the menu radio symbols + const Fl_Menu_Item *item2; int from = flRank; - while( from > 0 && items[from - 1].label() && (items[from - 1].flags & FL_MENU_RADIO) && - !(items[from - 1].flags & FL_MENU_DIVIDER) ) { - from--; - } + while(from > 0) { + if ([[menu itemAtIndex:from-1] isSeparatorItem]) break; + item2 = [(FLMenuItem*)[menu itemAtIndex:from-1] getFlItem]; + if ( !(item2->flags & FL_MENU_RADIO) ) break; + from--; + } int to = flRank; - while( !(items[to].flags & FL_MENU_DIVIDER) && items[to + 1].label() && - (items[to + 1].flags & FL_MENU_RADIO) ) { - to++; - } + while (to+1 < last) { + if ([[menu itemAtIndex:to+1] isSeparatorItem]) break; + item2 = [(FLMenuItem*)[menu itemAtIndex:to+1] getFlItem]; + if (!(item2->flags & FL_MENU_RADIO)) break; + to++; + } NSMenu *nsmenu = [self menu]; int nsrank = (int)[nsmenu indexOfItem:self]; for(int i = from - flRank + nsrank ; i <= to - flRank + nsrank; i++) { @@ -3125,20 +3136,21 @@ void *Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::menuOrItemOperatio value = va_arg(ap, int); [menu removeItem:[menu itemAtIndex:value]]; } - else if (operation == Fl_Sys_Menu_Bar::addNewItem) { // arguments: NSMenu *menu, int flrank, int *prank + else if (operation == Fl_Sys_Menu_Bar::addNewItem) { // arguments: NSMenu *menu, Fl_Menu_Item* mitem, int *prank // creates a new menu item at the end of 'menu' - // attaches the item of rank flrank (counted in Fl_Menu_) of fl_sys_menu_bar to it + // attaches the item of fl_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( (fl_sys_menu_bar->Fl_Menu_::menu() + flRank)->label()); + Fl_Menu_Item *mitem = va_arg(ap, Fl_Menu_Item *); 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(Fl_Menu_Item*)]; + [item setRepresentedObject:pointer]; [menu addItem:item]; CFRelease(cfname); [item setTarget:item]; diff --git a/test/menubar.cxx b/test/menubar.cxx index d9139ec33..dadb80770 100644 --- a/test/menubar.cxx +++ b/test/menubar.cxx @@ -19,7 +19,7 @@ #include <FL/Fl.H> #include <FL/Fl_Box.H> #include <FL/Fl_Double_Window.H> -#include <FL/Fl_Menu_Bar.H> +#include <FL/Fl_Sys_Menu_Bar.H> #include <FL/Fl_Toggle_Button.H> #include <FL/Fl_Menu_Button.H> #include <FL/Fl_Choice.H> @@ -170,6 +170,33 @@ Fl_Menu_Item pulldown[] = { {0} }; +#ifdef __APPLE__ +Fl_Menu_Item menu_location[] = { + {"Window menu bar", 0, 0, 0, FL_MENU_VALUE}, + {"System menu bar", }, + {0} +}; + +Fl_Sys_Menu_Bar* smenubar; + +void menu_location_cb(Fl_Widget* w, void* data) +{ + Fl_Menu_Bar *menubar = (Fl_Menu_Bar*)data; + if (((Fl_Choice*)w)->value() == 1) { // switch to system menu bar + menubar->hide(); + const Fl_Menu_Item *menu = menubar->menu(); + smenubar = new Fl_Sys_Menu_Bar(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 Fl_Menu_* menus[4]; @@ -204,6 +231,11 @@ int main(int argc, char **argv) { Fl_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__ + Fl_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 Fl::run(); |
