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
This commit is contained in:
parent
aa0e4bb823
commit
4be97ea19c
@ -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__ */
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user