/* * Private static function to set the parent window of a submenu and all * of its submenus */ static void fghSetMenuParentWindow( SFG_Window *window, SFG_Menu *menu ) { SFG_MenuEntry *menuEntry; menu->ParentWindow = window; for( menuEntry = ( SFG_MenuEntry * )menu->Entries.First; menuEntry; menuEntry = ( SFG_MenuEntry * )menuEntry->Node.Next ) if( menuEntry->SubMenu ) fghSetMenuParentWindow( window, menuEntry->SubMenu ); }
/* * Activates a menu pointed by the function argument */ static void fghActivateMenu( SFG_Window* window, int button ) { int max_x, max_y; /* We'll be referencing this menu a lot, so remember its address: */ SFG_Menu* menu = window->Menu[ button ]; SFG_Window* current_window = fgStructure.CurrentWindow; /* If the menu is already active in another window, deactivate it there */ if ( menu->ParentWindow ) menu->ParentWindow->ActiveMenu = NULL ; /* Mark the menu as active, so that it gets displayed: */ window->ActiveMenu = menu; menu->IsActive = GL_TRUE; fghSetMenuParentWindow ( window, menu ); fgState.ActiveMenus++; /* Set up the initial menu position now: */ fghGetVMaxExtent(menu->ParentWindow, &max_x, &max_y); fgSetWindow( window ); menu->X = window->State.MouseX + glutGet( GLUT_WINDOW_X ); menu->Y = window->State.MouseY + glutGet( GLUT_WINDOW_Y ); if( menu->X + menu->Width > max_x ) menu->X -=menu->Width; if( menu->Y + menu->Height > max_y ) { menu->Y -=menu->Height; if( menu->Y < 0 ) menu->Y = 0; } menu->Window->State.MouseX = window->State.MouseX + glutGet( GLUT_WINDOW_X ) - menu->X; menu->Window->State.MouseY = window->State.MouseY + glutGet( GLUT_WINDOW_Y ) - menu->Y; fgSetWindow( menu->Window ); glutPositionWindow( menu->X, menu->Y ); glutReshapeWindow( menu->Width, menu->Height ); glutPopWindow( ); glutShowWindow( ); menu->Window->ActiveMenu = menu; fghCheckMenuStatus( menu ); fgSetWindow( current_window ); }
/* * Deactivates a menu pointed by the function argument. */ void fgDeactivateMenu( SFG_Window *window ) { SFG_Window *parent_window = NULL; /* Check if there is an active menu attached to this window... */ SFG_Menu* menu = window->ActiveMenu; SFG_MenuEntry *menuEntry; /* Did we find an active window? */ freeglut_return_if_fail( menu ); parent_window = menu->ParentWindow; /* Hide the present menu's window */ fgSetWindow( menu->Window ); glutHideWindow( ); /* Forget about having that menu active anymore, now: */ menu->Window->ActiveMenu = NULL; menu->ParentWindow->ActiveMenu = NULL; fghSetMenuParentWindow ( NULL, menu ); menu->IsActive = GL_FALSE; menu->ActiveEntry = NULL; fgState.ActiveMenus--; /* Hide all submenu windows, and the root menu's window. */ for ( menuEntry = ( SFG_MenuEntry * )menu->Entries.First; menuEntry; menuEntry = ( SFG_MenuEntry * )menuEntry->Node.Next ) { menuEntry->IsActive = GL_FALSE; /* Is that an active submenu by any case? */ if( menuEntry->SubMenu ) fghDeactivateSubMenu( menuEntry ); } fgSetWindow ( parent_window ) ; }
/* * Deactivates a menu pointed by the function argument. */ void fgDeactivateMenu( SFG_Window *window ) { SFG_Window *parent_window = NULL; SFG_Menu* menu; SFG_MenuEntry *menuEntry; /* Did we find an active window? */ freeglut_return_if_fail( window ); /* Check if there is an active menu attached to this window... */ menu = window->ActiveMenu; freeglut_return_if_fail( menu ); parent_window = menu->ParentWindow; /* Hide the present menu's window */ fgSetWindow( menu->Window ); glutHideWindow( ); /* Forget about having that menu active anymore, now: */ menu->Window->ActiveMenu = NULL; menu->ParentWindow->ActiveMenu = NULL; fghSetMenuParentWindow ( NULL, menu ); menu->IsActive = GL_FALSE; menu->ActiveEntry = NULL; fgState.ActiveMenus--; /* Hide all submenu windows, and the root menu's window. */ for ( menuEntry = ( SFG_MenuEntry * )menu->Entries.First; menuEntry; menuEntry = ( SFG_MenuEntry * )menuEntry->Node.Next ) { menuEntry->IsActive = GL_FALSE; /* Is that an active submenu by any chance? */ if( menuEntry->SubMenu ) fghDeactivateSubMenu( menuEntry ); } fgSetWindow ( parent_window ) ; /* Menu status callback */ if (fgState.MenuStateCallback || fgState.MenuStatusCallback) { fgStructure.CurrentMenu = menu; fgStructure.CurrentWindow = parent_window; if (fgState.MenuStateCallback) fgState.MenuStateCallback(GLUT_MENU_NOT_IN_USE); if (fgState.MenuStatusCallback) { /* Get cursor position on screen and convert to relative to parent_window's client area */ SFG_XYUse mouse_pos; fghGetCursorPos(&mouse_pos); mouse_pos.X -= glutGet( GLUT_WINDOW_X ); mouse_pos.Y -= glutGet( GLUT_WINDOW_Y ); fgState.MenuStatusCallback(GLUT_MENU_NOT_IN_USE, mouse_pos.X, mouse_pos.Y); } } }
/* * Activates a menu pointed by the function argument */ static void fghActivateMenu( SFG_Window* window, int button ) { int max_x, max_y; SFG_XYUse mouse_pos; /* We'll be referencing this menu a lot, so remember its address: */ SFG_Menu* menu = window->Menu[ button ]; SFG_Window* current_window = fgStructure.CurrentWindow; /* If the menu is already active in another window, deactivate it (and any submenus) there */ if ( menu->ParentWindow ) fgDeactivateMenu(menu->ParentWindow); /* Mark the menu as active, so that it gets displayed: */ window->ActiveMenu = menu; menu->IsActive = GL_TRUE; fghSetMenuParentWindow ( window, menu ); fgState.ActiveMenus++; /* Set up the initial menu position now: */ fghGetVMaxExtent(menu->ParentWindow, &max_x, &max_y); fgSetWindow( window ); /* get mouse position on screen (window->State.MouseX and window->State.MouseY * are relative to client area origin), and not easy to correct given that * glutGet( GLUT_WINDOW_X ) and glutGet( GLUT_WINDOW_Y ) return relative to parent * origin when looking at a child window * for parent windows: window->State.MouseX + glutGet( GLUT_WINDOW_X ) == mouse_pos.X */ fghGetCursorPos(&mouse_pos); menu->X = mouse_pos.X; menu->Y = mouse_pos.Y; /* Make sure the whole menu is on the screen */ if( menu->X + menu->Width > max_x ) menu->X -=menu->Width; if( menu->Y + menu->Height > max_y ) { menu->Y -=menu->Height; if( menu->Y < 0 ) menu->Y = 0; } /* Set position of mouse relative to top-left menu in menu's window state (could as well set 0 at creation time...) */ menu->Window->State.MouseX = mouse_pos.X - menu->X; menu->Window->State.MouseY = mouse_pos.Y - menu->Y; /* Menu status callback */ if (fgState.MenuStateCallback || fgState.MenuStatusCallback) { fgStructure.CurrentMenu = menu; fgStructure.CurrentWindow = window; if (fgState.MenuStateCallback) fgState.MenuStateCallback(GLUT_MENU_IN_USE); if (fgState.MenuStatusCallback) /* window->State.MouseX and window->State.MouseY are relative to client area origin, as needed */ fgState.MenuStatusCallback(GLUT_MENU_IN_USE, window->State.MouseX, window->State.MouseY); } fgSetWindow( menu->Window ); glutPositionWindow( menu->X, menu->Y ); glutReshapeWindow( menu->Width, menu->Height ); glutPopWindow( ); glutShowWindow( ); menu->Window->ActiveMenu = menu; fghCheckMenuStatus( menu ); fgSetWindow( current_window ); }
void fgDeactivateMenu( SFG_Window *window ) { SFG_Window *parent_window = NULL; SFG_Menu* menu; SFG_MenuEntry *menuEntry; /* Did we find an active window? */ freeglut_return_if_fail( window ); /* Check if there is an active menu attached to this window... */ menu = window->ActiveMenu; freeglut_return_if_fail( menu ); /* Check if we are already deactivating this menu, abort in that case (glutHideWindow below can cause this function to be called again on the same menu..) */ if (menu==menuDeactivating) return; menuDeactivating = menu; parent_window = menu->ParentWindow; /* Hide the present menu's window */ fgPlatformHideWindow( menu->Window ); /* Forget about having that menu active anymore, now: */ menu->Window->ActiveMenu = NULL; menu->ParentWindow->ActiveMenu = NULL; fghSetMenuParentWindow ( NULL, menu ); menu->IsActive = GL_FALSE; menu->ActiveEntry = NULL; fgState.ActiveMenus--; /* Hide all submenu windows, and the root menu's window. */ for ( menuEntry = ( SFG_MenuEntry * )menu->Entries.First; menuEntry; menuEntry = ( SFG_MenuEntry * )menuEntry->Node.Next ) { menuEntry->IsActive = GL_FALSE; /* Is that an active submenu by any chance? */ if( menuEntry->SubMenu ) fghDeactivateSubMenu( menuEntry ); } /* Done deactivating menu */ menuDeactivating = NULL; /* Menu status callback */ if (fgState.MenuStateCallback || fgState.MenuStatusCallback) { fgStructure.CurrentMenu = menu; fgStructure.CurrentWindow = parent_window; if (fgState.MenuStateCallback) fgState.MenuStateCallback(GLUT_MENU_NOT_IN_USE); if (fgState.MenuStatusCallback) { /* Get cursor position relative to parent_window's client area */ SFG_XYUse mouse_pos; fghPlatformGetCursorPos(parent_window, GL_TRUE, &mouse_pos); fgState.MenuStatusCallback(GLUT_MENU_NOT_IN_USE, mouse_pos.X, mouse_pos.Y); } } }