📄 glutmenu.cpp
字号:
/*********************************************************** * Copyright (C) 1997, Be Inc. Copyright (C) 1999, Jake Hamby. * * 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. * * FILE: glutMenu.cpp * * DESCRIPTION: code for popup menu handling ***********************************************************//*********************************************************** * Headers ***********************************************************/#include <GL/glut.h>#include <stdlib.h>#include <string.h>#include "glutint.h"#include "glutState.h"/*********************************************************** * Private variables ***********************************************************/static GlutMenu **menuList = 0;static int menuListSize = 0;/*********************************************************** * FUNCTION: getUnusedMenuSlot * * DESCRIPTION: helper function to get a new menu slot ***********************************************************/GlutMenu *__glutGetMenuByNum(int menunum){ if (menunum < 1 || menunum > menuListSize) { return NULL; } return menuList[menunum - 1];}/*********************************************************** * FUNCTION: getUnusedMenuSlot * * DESCRIPTION: helper function to get a new menu slot ***********************************************************/static intgetUnusedMenuSlot(void){ int i; /* Look for allocated, unused slot. */ for (i = 0; i < menuListSize; i++) { if (!menuList[i]) { return i; } } /* Allocate a new slot. */ menuListSize++; menuList = (GlutMenu **) realloc(menuList, menuListSize * sizeof(GlutMenu *)); if (!menuList) __glutFatalError("out of memory."); menuList[menuListSize - 1] = NULL; return menuListSize - 1;}/*********************************************************** * FUNCTION: glutCreateMenu (6.1) * * DESCRIPTION: create a new menu ***********************************************************/int APIENTRY glutCreateMenu(GLUTselectCB selectFunc){ GlutMenu *menu; int menuid; menuid = getUnusedMenuSlot(); menu = new GlutMenu(menuid, selectFunc); // constructor sets up members menuList[menuid] = menu; gState.currentMenu = menu; return menuid + 1;}/*********************************************************** * FUNCTION: glutSetMenu (6.2) * glutGetMenu * * DESCRIPTION: set and get the current menu ***********************************************************/int APIENTRY glutGetMenu(void){ if (gState.currentMenu) { return gState.currentMenu->id + 1; } else { return 0; }}void APIENTRY glutSetMenu(int menuid){ GlutMenu *menu; if (menuid < 1 || menuid > menuListSize) { __glutWarning("glutSetMenu attempted on bogus menu."); return; } menu = menuList[menuid - 1]; if (!menu) { __glutWarning("glutSetMenu attempted on bogus menu."); return; } gState.currentMenu = menu;}/*********************************************************** * FUNCTION: glutDestroyMenu (6.3) * * DESCRIPTION: destroy the specified menu ***********************************************************/void APIENTRY glutDestroyMenu(int menunum){ GlutMenu *menu = __glutGetMenuByNum(menunum); menuList[menunum - 1] = 0; if (gState.currentMenu == menu) { gState.currentMenu = 0; } delete menu;}/*********************************************************** * FUNCTION: glutAddMenuEntry (6.4) * * DESCRIPTION: add a new menu item ***********************************************************/voidglutAddMenuEntry(const char *label, int value){ new GlutMenuItem(gState.currentMenu, false, value, label);}/*********************************************************** * FUNCTION: glutAddSubMenu (6.5) * * DESCRIPTION: add a new submenu ***********************************************************/voidglutAddSubMenu(const char *label, int menu){ new GlutMenuItem(gState.currentMenu, true, menu-1, label);}/*********************************************************** * FUNCTION: glutChangeToMenuEntry (6.6) * * DESCRIPTION: change menuitem into a menu entry ***********************************************************/voidglutChangeToMenuEntry(int num, const char *label, int value){ GlutMenuItem *item; int i; i = gState.currentMenu->num; item = gState.currentMenu->list; while (item) { if (i == num) { free(item->label); item->label = strdup(label); item->isTrigger = false; item->value = value; return; } i--; item = item->next; } __glutWarning("Current menu has no %d item.", num);}/*********************************************************** * FUNCTION: glutChangeToSubMenu (6.7) * * DESCRIPTION: change menuitem into a submenu ***********************************************************/voidglutChangeToSubMenu(int num, const char *label, int menu){ GlutMenuItem *item; int i; i = gState.currentMenu->num; item = gState.currentMenu->list; while (item) { if (i == num) { free(item->label); item->label = strdup(label); item->isTrigger = true; item->value = menu-1; return; } i--; item = item->next; } __glutWarning("Current menu has no %d item.", num);}/*********************************************************** * FUNCTION: glutRemoveMenuItem (6.8) * * DESCRIPTION: remove a menu item ***********************************************************/voidglutRemoveMenuItem(int num){ GlutMenuItem *item, **prev; int i; i = gState.currentMenu->num; prev = &gState.currentMenu->list; item = gState.currentMenu->list; while (item) { if (i == num) { gState.currentMenu->num--; /* Patch up menu's item list. */ *prev = item->next; free(item->label); delete item; return; } i--; prev = &item->next; item = item->next; } __glutWarning("Current menu has no %d item.", num);}/*********************************************************** * FUNCTION: glutAttachMenu (6.9) * glutDetachMenu * * DESCRIPTION: attach and detach menu from view ***********************************************************/voidglutAttachMenu(int button){ gState.currentWindow->menu[button] = gState.currentMenu->id + 1;}voidglutDetachMenu(int button){ gState.currentWindow->menu[button] = 0;}/*********************************************************** * CLASS: GlutMenu * * FUNCTION: CreateBMenu * * DESCRIPTION: construct a BPopupMenu for this menu ***********************************************************/BMenu *GlutMenu::CreateBMenu(bool toplevel) { BMenu *bpopup; if(toplevel) { bpopup = new GlutPopUp(id+1); } else { bpopup = new BMenu(""); } GlutMenuItem *item = list; while (item) { GlutBMenuItem *bitem; if(item->isTrigger) { // recursively call CreateBMenu bitem = new GlutBMenuItem(menuList[item->value]->CreateBMenu(false)); bitem->SetLabel(item->label); bitem->menu = 0; // real menu items start at 1 bitem->value = 0; } else { bitem = new GlutBMenuItem(item->label); bitem->menu = id + 1; bitem->value = item->value; } bpopup->AddItem(bitem, 0); item = item->next; } return bpopup;}/*********************************************************** * CLASS: GlutMenu * * FUNCTION: (destructor) * * DESCRIPTION: destroy the menu and its items (but not submenus!) ***********************************************************/GlutMenu::~GlutMenu() { while (list) { GlutMenuItem *next = list->next; delete list; list = next; }}/*********************************************************** * CLASS: GlutMenuItem * * FUNCTION: (constructor) * * DESCRIPTION: construct the new menu item and add to parent ***********************************************************/GlutMenuItem::GlutMenuItem(GlutMenu *n_menu, bool n_trig, int n_value, const char *n_label){ menu = n_menu; isTrigger = n_trig; value = n_value; label = strdup(n_label); next = menu->list; menu->list = this; menu->num++;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -