From d2e9a9aa23fe843257ac6826d38d9fbb8b9f6e5f Mon Sep 17 00:00:00 2001 From: Diederick Niehorster Date: Sat, 17 Nov 2012 01:02:30 +0000 Subject: [PATCH] menus attached to child windows did not appear in the right place. Fixed in fghActivateMenu, whose logic is now simpler and commented as well git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1398 7f0cb862-5218-0410-a997-914c9d46530a --- progs/demos/One/one.c | 16 +++++++++++++--- src/fg_menu.c | 21 +++++++++++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/progs/demos/One/one.c b/progs/demos/One/one.c index b5d9732..464c2bf 100644 --- a/progs/demos/One/one.c +++ b/progs/demos/One/one.c @@ -277,13 +277,18 @@ void SampleSpecial( int nSpecial, int nMouseX, int nMouseY ) */ void SampleMenu( int menuID ) { - /* - * Just print something funny - */ printf( "SampleMenu() callback executed, menuID is %i\n", menuID ); } /* + * A sample menu status callback + */ +void SampleMenuStatus( int status, int x, int y ) +{ + printf ( "SampleMenu() callback executed, MenuStatus is %i at (%i,%i)\n", status, x, y ); +} + +/* * The sample's entry point */ int main( int argc, char** argv ) @@ -325,6 +330,7 @@ int main( int argc, char** argv ) glutSpecialFunc( SampleSpecial ); glutIdleFunc( SampleIdle ); glutEntryFunc( SampleEntry ); + glutMenuStatusFunc( SampleMenuStatus ); glutAttachMenu( GLUT_LEFT_BUTTON ); glutInitWindowPosition( 200, 200 ); @@ -334,6 +340,8 @@ int main( int argc, char** argv ) glutKeyboardFunc( SampleKeyboard ); glutSpecialFunc( SampleSpecial ); glutIdleFunc( SampleIdle ); + glutEntryFunc( SampleEntry ); + glutMenuStatusFunc( SampleMenuStatus ); glutAttachMenu( GLUT_LEFT_BUTTON ); glutSetMenu(subMenuA); glutAttachMenu( GLUT_RIGHT_BUTTON ); @@ -367,6 +375,8 @@ int main( int argc, char** argv ) glutReshapeFunc( SampleReshape ); glutKeyboardFunc( SampleGameModeKeyboard ); glutIdleFunc( SampleIdle ); + glutEntryFunc( SampleEntry ); + glutMenuStatusFunc( SampleMenuStatus ); glutSetMenu(menuID); glutAttachMenu( GLUT_LEFT_BUTTON ); diff --git a/src/fg_menu.c b/src/fg_menu.c index 6a7d96d..9b40bfe 100644 --- a/src/fg_menu.c +++ b/src/fg_menu.c @@ -509,6 +509,7 @@ void fgDisplayMenu( void ) 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 ]; @@ -527,9 +528,17 @@ static void fghActivateMenu( SFG_Window* window, int button ) /* 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 ); + /* 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 + */ + fghPlatformGetCursorPos(&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; @@ -540,10 +549,9 @@ static void fghActivateMenu( SFG_Window* window, int button ) 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; + /* 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) @@ -553,6 +561,7 @@ static void fghActivateMenu( SFG_Window* window, int button ) 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); } -- 1.7.10.4