Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
macx_menu.m
/* Copyright (c) Dietmar Planitzer, 1998, 2002 */ |
/* This program is freely distributable without licensing fees |
and is provided without guarantee or warrantee expressed or |
implied. This program is -not- in the public domain. */ |
#import "macx_glut.h" |
#import "GLUTMenu.h" |
#import "GLUTApplication.h" |
#import "GLUTView.h" |
#import "GLUTWindow.h" |
GLUTView * __glutMenuWindow = nil; // Window while menu is active |
GLUTMenu * __glutMappedMenu = nil; |
GLUTmenuStatusCB __glutMenuStatusFunc = NULL; |
GLUTmenuStatusFCB __fglutMenuStatusFunc = NULL; /* fortran callback */ |
GLUTMenu * __glutCurrentMenu = nil; |
static GLUTMenu ** __glutMenuList = NULL; |
static int __glutMenuListSize = 0; |
void __glutSetMenu(GLUTMenu *menu) |
{ |
__glutCurrentMenu = menu; |
} |
GLUTMenu *__glutGetMenu(void) |
{ |
return __glutCurrentMenu; |
} |
void __glutStartMenu(GLUTMenu *menu, GLUTView *window, NSPoint wMouseLoc) |
{ |
/* User is about to start a menu tracking session. We install a special |
timer which will execute the idle function while menu tracking is |
going on because menu tracking happens in its own modal event loop. */ |
__glutStartIdleFuncTimer(); |
__glutMappedMenu = menu; |
__glutMenuWindow = window; |
if(__glutMenuStatusFunc) { |
__glutSetMenu(menu); |
__glutSetWindow(window); |
wMouseLoc = [window convertPoint: wMouseLoc fromView: nil]; |
__glutMenuStatusFunc(GLUT_MENU_IN_USE, rint(wMouseLoc.x), rint(wMouseLoc.y)); |
} |
} |
void __glutFinishMenu(NSPoint sMouseLoc) |
{ |
/* Setting __glutMappedMenu to NULL permits operations that |
change menus or destroy the menu window again. */ |
__glutMappedMenu = nil; |
if(__glutMenuStatusFunc) { |
__glutSetWindow(__glutMenuWindow); |
__glutSetMenu(__glutMappedMenu); |
sMouseLoc = [[__glutMenuWindow window] convertScreenToBase: sMouseLoc]; |
sMouseLoc = [__glutMenuWindow convertPoint: sMouseLoc fromView: nil]; |
__glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, rint(sMouseLoc.x), rint(sMouseLoc.y)); |
} |
} |
static int __glutGetUnusedMenuSlot(void) |
{ |
int i; |
/* Look for allocated, unused slot. */ |
for(i = 0; i < __glutMenuListSize; i++) { |
if(!__glutMenuList[i]) { |
return i; |
} |
} |
/* Allocate a new slot. */ |
__glutMenuListSize++; |
__glutMenuList = (GLUTMenu **) realloc(__glutMenuList, __glutMenuListSize * sizeof(GLUTMenu *)); |
if(!__glutMenuList) { |
__glutFatalError("out of memory."); |
} |
__glutMenuList[__glutMenuListSize - 1] = NULL; |
return __glutMenuListSize - 1; |
} |
static GLUTMenu *__glutGetMenuByNum(int menunum) |
{ |
if(menunum < 1 || menunum > __glutMenuListSize) { |
return nil; |
} |
return __glutMenuList[menunum - 1]; |
} |
static void __glutMenuModificationError(void) |
{ |
/* XXX Remove the warning after GLUT 3.0. */ |
__glutWarning("The following is a new check for GLUT 3.0; update your code."); |
__glutFatalError("menu manipulation not allowed while menus in use."); |
} |
/* CENTRY */ |
int APIENTRY glutCreateMenu(void (*func) (int value)) |
{ |
GLUTMenu * menu; |
int menuid = 0; |
GLUTAPI_DECLARATIONS |
GLUTAPI_BEGIN |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
menuid = __glutGetUnusedMenuSlot(); |
menu = [[GLUTMenu alloc] initWithCallback: func menuID: menuid + 1]; |
if(menu == nil) { |
__glutFatalError("out of memory."); // will exit |
} |
__glutMenuList[menuid] = menu; |
__glutSetMenu(menu); |
GLUTAPI_END |
return menuid + 1; |
} |
int APIENTRY glutGetMenu(void) |
{ |
if(__glutCurrentMenu) { |
return [__glutCurrentMenu menuID]; |
} else { |
return 0; |
} |
} |
void APIENTRY glutSetMenu(int menuid) |
{ |
GLUTMenu * menu = __glutGetMenuByNum(menuid); |
if(!menu) { |
__glutWarning("glutSetMenu attempted on bogus menu."); |
return; |
} |
__glutSetMenu(menu); |
} |
void APIENTRY glutAddMenuEntry(const char *name, int value) |
{ |
NSString * title; |
GLUTAPI_DECLARATIONS |
GLUTAPI_BEGIN |
if(name == NULL) { |
__glutFatalError("glutAddMenuEntry called with NULL name."); |
} |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
title = [NSString stringWithUTF8String: name]; |
if(!title) { |
__glutFatalError("out of memory"); |
} |
[__glutCurrentMenu addMenuItemWithTitle: title tag: value]; |
GLUTAPI_END |
} |
void APIENTRY glutAddSubMenu(const char *name, int menu) |
{ |
GLUTMenu * submenu; |
NSString * title; |
GLUTAPI_DECLARATIONS |
GLUTAPI_BEGIN |
if(name == NULL) { |
__glutFatalError("glutAddSubMenu called with NULL name."); |
} |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
title = [NSString stringWithUTF8String: name]; |
if(!title) { |
__glutFatalError("out of memory"); |
} |
submenu = __glutGetMenuByNum(menu); |
if(!submenu) { |
__glutWarning("glutAddSubMenu attempted on bogus menu."); |
GLUTAPI_VOIDRETURN; |
} |
[__glutCurrentMenu addSubMenuWithTitle: title menu: submenu]; |
GLUTAPI_END |
} |
void APIENTRY glutAttachMenu(int button) |
{ |
GLUTAPI_DECLARATIONS |
GLUTAPI_BEGIN |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
[__glutCurrentView attachMenu: __glutCurrentMenu toButton: button]; |
GLUTAPI_END |
} |
void APIENTRY glutDetachMenu(int button) |
{ |
GLUTAPI_DECLARATIONS |
GLUTAPI_BEGIN |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
[__glutCurrentView detachMenuFromButton: button]; |
GLUTAPI_END |
} |
void APIENTRY glutDestroyMenu(int menu) |
{ |
GLUTMenu * menuObj; |
menuObj = __glutGetMenuByNum(menu); |
if(!menuObj) { |
__glutWarning("glutDestroyMenu attempted on bogus menu %d.", menu); |
return; |
} |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
if(menuObj == __glutCurrentMenu) { |
__glutCurrentMenu = nil; |
} |
[menuObj release]; |
__glutMenuList[menu - 1] = NULL; |
} |
void APIENTRY glutChangeToMenuEntry(int entry, const char *name, int value) |
{ |
NSString * title; |
GLUTAPI_DECLARATIONS |
GLUTAPI_BEGIN |
if(name == NULL) { |
__glutFatalError("glutChangeToMenuEntry called with NULL name."); |
} |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
title = [NSString stringWithUTF8String: name]; |
if(!title) { |
__glutFatalError("out of memory"); |
} |
[__glutCurrentMenu setMenuItemAtIndex: entry - 1 toTitle: title tag: value]; |
GLUTAPI_END |
} |
void APIENTRY glutChangeToSubMenu(int entry, const char *name, int menu) |
{ |
GLUTMenu * submenu; |
NSString * title; |
GLUTAPI_DECLARATIONS |
GLUTAPI_BEGIN |
if(name == NULL) { |
__glutFatalError("glutChangeToSubMenu called with NULL name."); |
} |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
submenu = __glutGetMenuByNum(menu); |
if(!submenu) { |
__glutWarning("glutChangeToSubMenu attempted on bogus menu."); |
GLUTAPI_VOIDRETURN; |
} |
title = [NSString stringWithUTF8String: name]; |
if(!title) { |
__glutFatalError("out of memory"); |
} |
[__glutCurrentMenu setMenuItemAtIndex: entry - 1 toTitle: title menu: submenu]; |
GLUTAPI_END |
} |
void APIENTRY glutRemoveMenuItem(int entry) |
{ |
GLUTAPI_DECLARATIONS |
GLUTAPI_BEGIN |
if(__glutMappedMenu) { |
__glutMenuModificationError(); |
} |
[__glutCurrentMenu removeMenuItemAtIndex: entry - 1]; |
GLUTAPI_END |
} |
void APIENTRY glutMenuStatusFunc(void (*func)(int status, int x, int y)) |
{ |
__glutMenuStatusFunc = func; |
} |
void APIENTRY glutMenuStateFunc(void (*func)(int status)) |
{ |
__glutMenuStatusFunc = (GLUTmenuStatusCB) func; |
} |
/* ENDCENTRY */ |
Copyright © 2008 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2008-02-08