From 4634982c39857ee13ad0c5fa67b3ad197a37daf1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Feb 2005 00:52:23 +0000 Subject: [PATCH] fixes for menus being attached to multiple buttons/windows (John Fay) git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@570 7f0cb862-5218-0410-a997-914c9d46530a --- src/freeglut_internal.h | 13 +++----- src/freeglut_main.c | 23 ++----------- src/freeglut_menu.c | 80 +++++++++++++++++++++++----------------------- src/freeglut_structure.c | 16 ++++------ src/freeglut_window.c | 2 +- 5 files changed, 55 insertions(+), 79 deletions(-) diff --git a/src/freeglut_internal.h b/src/freeglut_internal.h index 96326c7..a3804ba 100644 --- a/src/freeglut_internal.h +++ b/src/freeglut_internal.h @@ -514,7 +514,7 @@ struct tagSFG_Menu SFG_MenuEntry *ActiveEntry; /* Currently active entry in the menu */ SFG_Window *Window; /* Window for menu */ - SFG_Window *ParentWindow; /* Window in which the menu is defined */ + SFG_Window *ParentWindow; /* Window in which the menu is invoked */ }; /* This is a menu entry */ @@ -759,6 +759,9 @@ int glutJoystickGetNumAxes( int ident ); int glutJoystickGetNumButtons( int ident ); int glutJoystickNotWorking( int ident ); +/* Setting the cursor for a given window */ +void fgSetCursor ( SFG_Window *window, int cursorID ); + /* * Helper function to enumerate through all registered windows * and one to enumerate all of a window's subwindows... @@ -799,11 +802,9 @@ SFG_Menu* fgMenuByID( int menuID ); * The menu activation and deactivation the code. This is the meat * of the menu user interface handling code... */ -void fgActivateMenu( SFG_Window* window, int button ); GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed, int mouse_x, int mouse_y ); void fgDeactivateMenu( SFG_Window *window ); -void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry ); /* * This function gets called just before the buffers swap, so that @@ -812,12 +813,6 @@ void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry ); */ void fgDisplayMenu( void ); -/* - * Display the mouse cursor using OpenGL calls. The function - * is defined in freeglut_cursor.c file. - */ -void fgDisplayCursor( void ); - /* Elapsed time as per glutGet(GLUT_ELAPSED_TIME). */ long fgElapsedTime( void ); diff --git a/src/freeglut_main.c b/src/freeglut_main.c index d464ca4..d2f4d45 100644 --- a/src/freeglut_main.c +++ b/src/freeglut_main.c @@ -1223,27 +1223,19 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, case WM_ACTIVATE: if (LOWORD(wParam) != WA_INACTIVE) { -/* printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window, +/* printf("WM_ACTIVATE: fgSetCursor( %p, %d)\n", window, window->State.Cursor ); */ - glutSetCursor( window->State.Cursor ); + fgSetCursor( window, window->State.Cursor ); } lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); break; #endif - /* - * XXX Why not re-use some common code with the glutSetCursor() - * XXX function (or perhaps invoke glutSetCursor())? - * XXX That is, why are we duplicating code, here, from - * XXX glutSetCursor()? The WIN32 code should be able to just - * XXX call glutSetCursor() instead of defining two macros - * XXX and implementing a nested case in-line. - */ case WM_SETCURSOR: /* printf ( "Cursor event %x %x %x %x\n", window, window->State.Cursor, lParam, wParam ) ; */ if( LOWORD( lParam ) == HTCLIENT ) - glutSetCursor ( window->State.Cursor ) ; + fgSetCursor ( window, window->State.Cursor ) ; else lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); break; @@ -1387,15 +1379,6 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, window->State.MouseX, window->State.MouseY ) ) break; - if( window->Menu[ button ] && pressed ) - { - window->State.Redisplay = GL_TRUE; - fgSetWindow( window ); - fgActivateMenu( window, button ); - - break; - } - /* Set capture so that the window captures all the mouse messages */ /* * XXX - Multiple button support: Under X11, the mouse is not released diff --git a/src/freeglut_menu.c b/src/freeglut_menu.c index 5733262..25b98a3 100644 --- a/src/freeglut_menu.c +++ b/src/freeglut_menu.c @@ -106,6 +106,34 @@ static SFG_MenuEntry *fghFindMenuEntry( SFG_Menu* menu, int index ) } /* + * Deactivates a menu pointed by the function argument. + */ +static void fghDeactivateSubMenu( SFG_MenuEntry *menuEntry ) +{ + SFG_Window *current_window = fgStructure.Window; + SFG_MenuEntry *subMenuIter; + /* Hide the present menu's window */ + fgSetWindow( menuEntry->SubMenu->Window ); + glutHideWindow( ); + + /* Forget about having that menu active anymore, now: */ + menuEntry->SubMenu->Window->ActiveMenu = NULL; + menuEntry->SubMenu->IsActive = GL_FALSE; + + /* Hide all submenu windows, and the root menu's window. */ + for ( subMenuIter = (SFG_MenuEntry *)menuEntry->SubMenu->Entries.First; + subMenuIter; + subMenuIter = (SFG_MenuEntry *)subMenuIter->Node.Next ) + { + /* Is that an active submenu by any case? */ + if( subMenuIter->SubMenu ) + fghDeactivateSubMenu( subMenuIter ); + } + + fgSetWindow( current_window ); +} + +/* * Private function to check for the current menu/sub menu activity state */ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu ) @@ -173,7 +201,7 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu ) */ if( menu->ActiveEntry && ( menuEntry != menu->ActiveEntry ) ) if( menu->ActiveEntry->SubMenu ) - fgDeactivateSubMenu( menu->ActiveEntry ); + fghDeactivateSubMenu( menu->ActiveEntry ); menu->ActiveEntry = menuEntry; menu->IsActive = GL_TRUE; @@ -369,7 +397,7 @@ static void fghDisplayMenuBox( SFG_Menu* menu ) * Private static function to set the parent window of a submenu and all * of its submenus */ -static void fghSetSubmenuParentWindow( SFG_Window *window, SFG_Menu *menu ) +static void fghSetMenuParentWindow( SFG_Window *window, SFG_Menu *menu ) { SFG_MenuEntry *menuEntry; @@ -379,7 +407,7 @@ static void fghSetSubmenuParentWindow( SFG_Window *window, SFG_Menu *menu ) menuEntry; menuEntry = ( SFG_MenuEntry * )menuEntry->Node.Next ) if( menuEntry->SubMenu ) - fghSetSubmenuParentWindow( window, menuEntry->SubMenu ); + fghSetMenuParentWindow( window, menuEntry->SubMenu ); } /* @@ -463,14 +491,19 @@ void fgDisplayMenu( void ) /* * Activates a menu pointed by the function argument */ -void fgActivateMenu( SFG_Window* window, int button ) +static void fghActivateMenu( SFG_Window* window, int button ) { /* We'll be referencing this menu a lot, so remember its address: */ SFG_Menu* menu = window->Menu[ button ]; + /* 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: */ @@ -576,7 +609,7 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed, /* XXX Posting a requisite Redisplay seems bogus. */ window->State.Redisplay = GL_TRUE; fgSetWindow( window ); - fgActivateMenu( window, button ); + fghActivateMenu( window, button ); return GL_TRUE; } @@ -604,6 +637,7 @@ void fgDeactivateMenu( SFG_Window *window ) /* Forget about having that menu active anymore, now: */ menu->Window->ActiveMenu = NULL; menu->ParentWindow->ActiveMenu = NULL; + fghSetMenuParentWindow ( NULL, menu ); menu->IsActive = GL_FALSE; fgState.ActiveMenus--; @@ -615,35 +649,7 @@ void fgDeactivateMenu( SFG_Window *window ) { /* Is that an active submenu by any case? */ if( menuEntry->SubMenu ) - fgDeactivateSubMenu( menuEntry ); - } - - fgSetWindow( current_window ); -} - -/* - * Deactivates a menu pointed by the function argument. - */ -void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry ) -{ - SFG_Window *current_window = fgStructure.Window; - SFG_MenuEntry *subMenuIter; - /* Hide the present menu's window */ - fgSetWindow( menuEntry->SubMenu->Window ); - glutHideWindow( ); - - /* Forget about having that menu active anymore, now: */ - menuEntry->SubMenu->Window->ActiveMenu = NULL; - menuEntry->SubMenu->IsActive = GL_FALSE; - - /* Hide all submenu windows, and the root menu's window. */ - for ( subMenuIter = (SFG_MenuEntry *)menuEntry->SubMenu->Entries.First; - subMenuIter; - subMenuIter = (SFG_MenuEntry *)subMenuIter->Node.Next ) - { - /* Is that an active submenu by any case? */ - if( subMenuIter->SubMenu ) - fgDeactivateSubMenu( subMenuIter ); + fghDeactivateSubMenu( menuEntry ); } fgSetWindow( current_window ); @@ -788,9 +794,6 @@ void FGAPIENTRY glutAddSubMenu( const char *label, int subMenuID ) menuEntry->SubMenu = subMenu; menuEntry->ID = -1; - /* Make the submenu's parent window be the menu's parent window */ - fghSetSubmenuParentWindow( fgStructure.Menu->ParentWindow, subMenu ); - fgListAppend( &fgStructure.Menu->Entries, &menuEntry->Node ); fghCalculateMenuBoxSize( ); } @@ -888,9 +891,6 @@ void FGAPIENTRY glutAttachMenu( int button ) freeglut_return_if_fail( button < FREEGLUT_MAX_MENUS ); fgStructure.Window->Menu[ button ] = fgStructure.Menu; - - /* Make the parent window of the menu (and all submenus) the current window */ - fghSetSubmenuParentWindow( fgStructure.Window, fgStructure.Menu ); } /* diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c index 07bf892..482740e 100644 --- a/src/freeglut_structure.c +++ b/src/freeglut_structure.c @@ -99,7 +99,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, * dependant, and resides in freeglut_window.c. Uses fgState. */ fgOpenWindow( window, title, x, y, w, h, gameMode, - parent ? GL_TRUE : GL_FALSE ); + (GLboolean)(parent ? GL_TRUE : GL_FALSE) ); return window; } @@ -115,7 +115,7 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ) /* Have the menu object created */ SFG_Menu* menu = (SFG_Menu *)calloc( sizeof(SFG_Menu), 1 ); - menu->ParentWindow = fgStructure.Window; + menu->ParentWindow = NULL; /* Create a window for the menu to reside in. */ @@ -192,8 +192,6 @@ void fgCloseWindows( ) */ void fgDestroyWindow( SFG_Window* window ) { - int menu_index; - FREEGLUT_INTERNAL_ERROR_EXIT ( window, "Window destroy function called with null window", "fgDestroyWindow" ); @@ -214,10 +212,6 @@ void fgDestroyWindow( SFG_Window* window ) if( window->ActiveMenu ) fgDeactivateMenu( window ); - for( menu_index = 0; menu_index < 3; menu_index ++ ) - if( window->Menu[ menu_index ] ) - window->Menu[ menu_index ]->ParentWindow = NULL; - fghClearCallBacks( window ); fgCloseWindow( window ); free( window ); @@ -234,6 +228,10 @@ static void fghRemoveMenuFromWindow( SFG_Window* window, SFG_Menu* menu ) SFG_Window *subWindow; int i; + /* Check whether this is the active menu in the window */ + if ( menu == window->ActiveMenu ) + window->ActiveMenu = NULL ; + /* * Check if the menu is attached to the current window, * if so, have it detached (by overwriting with a NULL): @@ -318,7 +316,7 @@ void fgDestroyMenu( SFG_Menu* menu ) } if( fgStructure.Window == menu->Window ) - fgSetWindow( menu->ParentWindow ); + fgSetWindow( NULL ); fgDestroyWindow( menu->Window ); fgListRemove( &fgStructure.Menus, &menu->Node ); if( fgStructure.Menu == menu ) diff --git a/src/freeglut_window.c b/src/freeglut_window.c index e2e7f3b..043b8f3 100644 --- a/src/freeglut_window.c +++ b/src/freeglut_window.c @@ -593,7 +593,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, #endif /* TARGET_HOST_WINCE */ UpdateWindow( window->Window.Handle ); - ShowCursor( TRUE ); /* XXX Old comments say "hide cusror"! */ + ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */ #endif -- 1.7.10.4