fixes for menus being attached to multiple buttons/windows (John Fay)
authorBrian Paul <brianp@vmware.com>
Wed, 16 Feb 2005 00:52:23 +0000 (00:52 +0000)
committerBrian Paul <brianp@vmware.com>
Wed, 16 Feb 2005 00:52:23 +0000 (00:52 +0000)
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
src/freeglut_main.c
src/freeglut_menu.c
src/freeglut_structure.c
src/freeglut_window.c

index 96326c7..a3804ba 100644 (file)
@@ -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 );
 
index d464ca4..d2f4d45 100644 (file)
@@ -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
index 5733262..25b98a3 100644 (file)
@@ -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 );
 }
 
 /*
index 07bf892..482740e 100644 (file)
@@ -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 )
index e2e7f3b..043b8f3 100644 (file)
@@ -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