/*
 * 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 );
}
Example #2
0
/*
 * 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 );
}
Example #3
0
/*
 * 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 );
}
Example #6
0
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);
        }
    }
}