Changes remove duplicate menu code from "freeglut_window.c" and put it into one place in "freeglut_menu.c" where it belongs. - John Fay

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@543 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
puggles 2005-01-03 02:11:12 +00:00
parent 65980f45ac
commit cfef5bfb34
4 changed files with 113 additions and 186 deletions

View File

@ -777,8 +777,8 @@ SFG_Menu* fgMenuByID( int menuID );
* of the menu user interface handling code... * of the menu user interface handling code...
*/ */
void fgActivateMenu( SFG_Window* window, int button ); void fgActivateMenu( SFG_Window* window, int button );
void fgExecuteMenuCallback( SFG_Menu* menu ); GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ); int mouse_x, int mouse_y );
void fgDeactivateMenu( SFG_Window *window ); void fgDeactivateMenu( SFG_Window *window );
void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry ); void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry );

View File

@ -754,93 +754,13 @@ void FGAPIENTRY glutMainLoopEvent( void )
button = event.xbutton.button - 1; button = event.xbutton.button - 1;
/* /*
* XXX This comment is replicated in the WIN32 section and
* XXX maybe also in the menu code. Can we move the info
* XXX to one central place and *reference* it from here?
*
* Do not execute the application's mouse callback if a menu * Do not execute the application's mouse callback if a menu
* is hooked to this button. In that case an appropriate * is hooked to this button. In that case an appropriate
* private call should be generated. * private call should be generated.
* Near as I can tell, this is the menu behaviour:
* - Down-click the menu button, menu not active: activate
* the menu with its upper left-hand corner at the mouse
* location.
* - Down-click any button outside the menu, menu active:
* deactivate the menu
* - Down-click any button inside the menu, menu active:
* select the menu entry and deactivate the menu
* - Up-click the menu button, menu not active: nothing happens
* - Up-click the menu button outside the menu, menu active:
* nothing happens
* - Up-click the menu button inside the menu, menu active:
* select the menu entry and deactivate the menu
*/ */
/* Window has an active menu, it absorbs any mouse click */ if( fgCheckActiveMenu( window, button, pressed,
if( window->ActiveMenu ) event.xbutton.x_root, event.xbutton.y_root ) )
{
if( window == window->ActiveMenu->ParentWindow )
{
window->ActiveMenu->Window->State.MouseX =
event.xbutton.x_root - window->ActiveMenu->X;
window->ActiveMenu->Window->State.MouseY =
event.xbutton.y_root - window->ActiveMenu->Y;
}
/* In the menu, invoke the callback and deactivate the menu*/
if( fgCheckActiveMenu( window->ActiveMenu->Window,
window->ActiveMenu ) )
{
/*
* Save the current window and menu and set the current
* window to the window whose menu this is
*/
SFG_Window *save_window = fgStructure.Window;
SFG_Menu *save_menu = fgStructure.Menu;
SFG_Window *parent_window =
window->ActiveMenu->ParentWindow;
fgSetWindow( parent_window );
fgStructure.Menu = window->ActiveMenu;
/* Execute the menu callback */
fgExecuteMenuCallback( window->ActiveMenu );
fgDeactivateMenu( parent_window );
/* Restore the current window and menu */
fgSetWindow( save_window );
fgStructure.Menu = save_menu;
}
else if( pressed )
/*
* Outside the menu, deactivate if it's a downclick
*
* XXX This isn't enough. A downclick outside of
* XXX the interior of our freeglut windows should also
* XXX deactivate the menu. This is more complicated.
*/
fgDeactivateMenu( window->ActiveMenu->ParentWindow );
/*
* XXX Why does an active menu require a redisplay at
* XXX this point? If this can come out cleanly, then
* XXX it probably should do so; if not, a comment should
* XXX explain it.
*/
window->State.Redisplay = GL_TRUE;
break; break;
}
/* No active menu, let's check whether we need to activate one. */
if( ( 0 <= button ) &&
( FREEGLUT_MAX_MENUS > button ) &&
( window->Menu[ button ] ) &&
pressed )
{
/* XXX Posting a requisite Redisplay seems bogus. */
window->State.Redisplay = GL_TRUE;
fgSetWindow( window );
fgActivateMenu( window, button );
break;
}
/* /*
* Check if there is a mouse or mouse wheel callback hooked to the * Check if there is a mouse or mouse wheel callback hooked to the
@ -1329,6 +1249,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
SetCursor( NULL ); \ SetCursor( NULL ); \
break; break;
/* printf ( "Cursor event %x %x %x %x\n", window, window->State.Cursor, lParam, wParam ) ; */
if( LOWORD( lParam ) == HTCLIENT ) if( LOWORD( lParam ) == HTCLIENT )
switch( window->State.Cursor ) switch( window->State.Cursor )
{ {
@ -1483,64 +1404,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
return DefWindowProc( hWnd, uMsg, lParam, wParam ); return DefWindowProc( hWnd, uMsg, lParam, wParam );
/* /*
* XXX This comment is duplicated in two other spots. * Do not execute the application's mouse callback if a menu
* XXX Can we centralize it? * is hooked to this button. In that case an appropriate
* * private call should be generated.
* Do not execute the application's mouse callback if a
* menu is hooked to this button.
* In that case an appropriate private call should be generated.
* Near as I can tell, this is the menu behaviour:
* - Down-click the menu button, menu not active: activate
* the menu with its upper left-hand corner at the mouse location.
* - Down-click any button outside the menu, menu active:
* deactivate the menu
* - Down-click any button inside the menu, menu active:
* select the menu entry and deactivate the menu
* - Up-click the menu button, menu not active: nothing happens
* - Up-click the menu button outside the menu, menu active:
* nothing happens
* - Up-click the menu button inside the menu, menu active:
* select the menu entry and deactivate the menu
*/ */
/* Window has an active menu, it absorbs any mouse click */ if( fgCheckActiveMenu( window, button, pressed,
if( window->ActiveMenu ) window->State.MouseX, window->State.MouseY ) )
{
/* Outside the menu, deactivate the menu if it's a downclick */
if( ! fgCheckActiveMenu( window, window->ActiveMenu ) )
{
if( pressed )
fgDeactivateMenu( window->ActiveMenu->ParentWindow );
}
else /* In menu, invoke the callback and deactivate the menu*/
{
/*
* Save the current window and menu and set the current
* window to the window whose menu this is
*/
SFG_Window *save_window = fgStructure.Window;
SFG_Menu *save_menu = fgStructure.Menu;
SFG_Window *parent_window = window->ActiveMenu->ParentWindow;
fgSetWindow( parent_window );
fgStructure.Menu = window->ActiveMenu;
/* Execute the menu callback */
fgExecuteMenuCallback( window->ActiveMenu );
fgDeactivateMenu( parent_window );
/* Restore the current window and menu */
fgSetWindow( save_window );
fgStructure.Menu = save_menu;
}
/*
* Let's make the window redraw as a result of the mouse
* click and menu activity.
*/
if( ! window->IsMenu )
window->State.Redisplay = GL_TRUE;
break; break;
}
if( window->Menu[ button ] && pressed ) if( window->Menu[ button ] && pressed )
{ {

View File

@ -386,6 +386,30 @@ static void fghSetSubmenuParentWindow( SFG_Window *window, SFG_Menu *menu )
fghSetSubmenuParentWindow( window, menuEntry->SubMenu ); fghSetSubmenuParentWindow( window, menuEntry->SubMenu );
} }
/*
* Function to check for menu entry selection on menu deactivation
*/
static void fghExecuteMenuCallback( SFG_Menu* menu )
{
SFG_MenuEntry *menuEntry;
/* First of all check any of the active sub menus... */
for( menuEntry = (SFG_MenuEntry *)menu->Entries.First;
menuEntry;
menuEntry = (SFG_MenuEntry *)menuEntry->Node.Next)
{
if( menuEntry->IsActive )
{
if( menuEntry->SubMenu )
fghExecuteMenuCallback( menuEntry->SubMenu );
else
if( menu->Callback )
menu->Callback( menuEntry->ID );
return;
}
}
}
/* /*
* Displays the currently active menu for the current window * Displays the currently active menu for the current window
@ -474,45 +498,93 @@ void fgActivateMenu( SFG_Window* window, int button )
/* /*
* Check whether an active menu absorbs a mouse click * Check whether an active menu absorbs a mouse click
*/ */
GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ) GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
int mouse_x, int mouse_y )
{ {
/* /*
* Near as I can tell, this is the active menu behaviour: * Near as I can tell, this is the menu behaviour:
* - Down-click the menu button, menu not active: activate
* the menu with its upper left-hand corner at the mouse
* location.
* - Down-click any button outside the menu, menu active: * - Down-click any button outside the menu, menu active:
* deactivate the menu * deactivate the menu
* - Down-click any button inside the menu, menu active: * - Down-click any button inside the menu, menu active:
* select the menu entry and deactivate the menu * select the menu entry and deactivate the menu
* - Up-click the menu button, menu not active: nothing happens
* - Up-click the menu button outside the menu, menu active: * - Up-click the menu button outside the menu, menu active:
* nothing happens * nothing happens
* - Up-click the menu button inside the menu, menu active: * - Up-click the menu button inside the menu, menu active:
* select the menu entry and deactivate the menu * select the menu entry and deactivate the menu
* Since menus can have submenus, we need to check this recursively. * Since menus can have submenus, we need to check this recursively.
*/ */
return fghCheckMenuStatus( window, menu ); if( window->ActiveMenu )
{
if( window == window->ActiveMenu->ParentWindow )
{
window->ActiveMenu->Window->State.MouseX =
mouse_x - window->ActiveMenu->X;
window->ActiveMenu->Window->State.MouseY =
mouse_y - window->ActiveMenu->Y;
} }
/* In the menu, invoke the callback and deactivate the menu */
if( fghCheckMenuStatus( window->ActiveMenu->Window,
window->ActiveMenu ) )
{
/*
* Save the current window and menu and set the current
* window to the window whose menu this is
*/
SFG_Window *save_window = fgStructure.Window;
SFG_Menu *save_menu = fgStructure.Menu;
SFG_Window *parent_window = window->ActiveMenu->ParentWindow;
fgSetWindow( parent_window );
fgStructure.Menu = window->ActiveMenu;
/* Execute the menu callback */
fghExecuteMenuCallback( window->ActiveMenu );
fgDeactivateMenu( parent_window );
/* Restore the current window and menu */
fgSetWindow( save_window );
fgStructure.Menu = save_menu;
}
else if( pressed )
/*
* Outside the menu, deactivate if it's a downclick
*
* XXX This isn't enough. A downclick outside of
* XXX the interior of our freeglut windows should also
* XXX deactivate the menu. This is more complicated.
*/
fgDeactivateMenu( window->ActiveMenu->ParentWindow );
/* /*
* Function to check for menu entry selection on menu deactivation * XXX Why does an active menu require a redisplay at
* XXX this point? If this can come out cleanly, then
* XXX it probably should do so; if not, a comment should
* XXX explain it.
*/ */
void fgExecuteMenuCallback( SFG_Menu* menu ) if( ! window->IsMenu )
{ window->State.Redisplay = GL_TRUE;
SFG_MenuEntry *menuEntry;
/* First of all check any of the active sub menus... */ return GL_TRUE;
for( menuEntry = (SFG_MenuEntry *)menu->Entries.First;
menuEntry;
menuEntry = (SFG_MenuEntry *)menuEntry->Node.Next)
{
if( menuEntry->IsActive )
{
if( menuEntry->SubMenu )
fgExecuteMenuCallback( menuEntry->SubMenu );
else
if( menu->Callback )
menu->Callback( menuEntry->ID );
return;
} }
/* No active menu, let's check whether we need to activate one. */
if( ( 0 <= button ) &&
( FREEGLUT_MAX_MENUS > button ) &&
( window->Menu[ button ] ) &&
pressed )
{
/* XXX Posting a requisite Redisplay seems bogus. */
window->State.Redisplay = GL_TRUE;
fgSetWindow( window );
fgActivateMenu( window, button );
return GL_TRUE;
} }
return GL_FALSE;
} }
/* /*

View File

@ -274,24 +274,16 @@ void fgOpenWindow( SFG_Window* window, const char* title,
XSizeHints sizeHints; XSizeHints sizeHints;
XWMHints wmHints; XWMHints wmHints;
unsigned long mask; unsigned long mask;
/*
* XXX fgChooseVisual() is a common part of all three.
* XXX With a little thought, we should be able to greatly
* XXX simplify this.
*/
if( !window->IsMenu )
window->Window.VisualInfo = fgChooseVisual( );
else if( fgStructure.MenuContext )
window->Window.VisualInfo = fgChooseVisual( );
else
{
/* XXX Why are menus double- and depth-buffered? */
unsigned int current_DisplayMode = fgState.DisplayMode ; unsigned int current_DisplayMode = fgState.DisplayMode ;
fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ;
/* Save the display mode if we are creating a menu window */
if( window->IsMenu && ( ! fgStructure.MenuContext ) )
fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ;
window->Window.VisualInfo = fgChooseVisual( ); window->Window.VisualInfo = fgChooseVisual( );
if( window->IsMenu && ( ! fgStructure.MenuContext ) )
fgState.DisplayMode = current_DisplayMode ; fgState.DisplayMode = current_DisplayMode ;
}
if( ! window->Window.VisualInfo ) if( ! window->Window.VisualInfo )
{ {
@ -439,17 +431,10 @@ void fgOpenWindow( SFG_Window* window, const char* title,
* that they should replace a window manager that they like, and which * that they should replace a window manager that they like, and which
* works, just because *we* think that it's not "modern" enough. * works, just because *we* think that it's not "modern" enough.
*/ */
#if TARGET_HOST_WINCE /* Since this is in the X11 branch, it's pretty dumb */
sizeHints.x = 0;
sizeHints.y = 0;
sizeHints.width = 320;
sizeHints.height = 240;
#else
sizeHints.x = x; sizeHints.x = x;
sizeHints.y = y; sizeHints.y = y;
sizeHints.width = w; sizeHints.width = w;
sizeHints.height = h; sizeHints.height = h;
#endif /* TARGET_HOST_WINCE */
wmHints.flags = StateHint; wmHints.flags = StateHint;
wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState; wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState;