summaryrefslogtreecommitdiff
path: root/src/glut/beos/glutMenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/glut/beos/glutMenu.cpp')
-rw-r--r--src/glut/beos/glutMenu.cpp322
1 files changed, 322 insertions, 0 deletions
diff --git a/src/glut/beos/glutMenu.cpp b/src/glut/beos/glutMenu.cpp
new file mode 100644
index 0000000000..1dad5970c9
--- /dev/null
+++ b/src/glut/beos/glutMenu.cpp
@@ -0,0 +1,322 @@
+/***********************************************************
+ * Copyright (C) 1997, Be Inc. All rights reserved.
+ *
+ * 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 int
+getUnusedMenuSlot(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
+ ***********************************************************/
+void
+glutAddMenuEntry(const char *label, int value)
+{
+ new GlutMenuItem(gState.currentMenu, false, value, label);
+}
+
+/***********************************************************
+ * FUNCTION: glutAddSubMenu (6.5)
+ *
+ * DESCRIPTION: add a new submenu
+ ***********************************************************/
+void
+glutAddSubMenu(const char *label, int menu)
+{
+ new GlutMenuItem(gState.currentMenu, true, menu-1, label);
+}
+
+/***********************************************************
+ * FUNCTION: glutChangeToMenuEntry (6.6)
+ *
+ * DESCRIPTION: change menuitem into a menu entry
+ ***********************************************************/
+void
+glutChangeToMenuEntry(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
+ ***********************************************************/
+void
+glutChangeToSubMenu(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
+ ***********************************************************/
+void
+glutRemoveMenuItem(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
+ ***********************************************************/
+void
+glutAttachMenu(int button)
+{
+ gState.currentWindow->menu[button] = gState.currentMenu->id + 1;
+}
+
+void
+glutDetachMenu(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++;
+}