/*
 * Deactivates a menu pointed by the function argument.
 */
static void fghDeactivateSubMenu( SFG_MenuEntry *menuEntry )
{
    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;
    menuEntry->SubMenu->ActiveEntry = NULL;

    /* 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 )
    {
        subMenuIter->IsActive = GL_FALSE;

        /* Is that an active submenu by any case? */
        if( subMenuIter->SubMenu )
            fghDeactivateSubMenu( subMenuIter );
    }

    fgSetWindow ( menuEntry->SubMenu->ParentWindow ) ;
}
Beispiel #2
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);
        }
    }
}
/*
 * Private function to check for the current menu/sub menu activity state
 */
static GLboolean fghCheckMenuStatus( SFG_Menu* menu )
{
    SFG_MenuEntry* menuEntry;
    int x, y;

    /* 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->SubMenu && menuEntry->IsActive )
        {
            /*
             * OK, have the sub-menu checked, too. If it returns GL_TRUE, it
             * will mean that it caught the mouse cursor and we do not need
             * to regenerate the activity list, and so our parents do...
             */
            GLboolean return_status;

            menuEntry->SubMenu->Window->State.MouseX =
                menu->Window->State.MouseX + menu->X - menuEntry->SubMenu->X;
            menuEntry->SubMenu->Window->State.MouseY =
                menu->Window->State.MouseY + menu->Y - menuEntry->SubMenu->Y;
            return_status = fghCheckMenuStatus( menuEntry->SubMenu );

            if ( return_status )
                return GL_TRUE;
        }
    }

    /* That much about our sub menus, let's get to checking the current menu: */
    x = menu->Window->State.MouseX;
    y = menu->Window->State.MouseY;

    /* Check if the mouse cursor is contained within the current menu box */
    if( ( x >= FREEGLUT_MENU_BORDER ) &&
        ( x < menu->Width  - FREEGLUT_MENU_BORDER ) &&
        ( y >= FREEGLUT_MENU_BORDER ) &&
        ( y < menu->Height - FREEGLUT_MENU_BORDER )  )
    {
        int menuID = ( y - FREEGLUT_MENU_BORDER ) / FREEGLUT_MENU_HEIGHT;

        /* The mouse cursor is somewhere over our box, check it out. */
        menuEntry = fghFindMenuEntry( menu, menuID + 1 );
        FREEGLUT_INTERNAL_ERROR_EXIT( menuEntry, "Cannot find menu entry",
                                      "fghCheckMenuStatus" );

        menuEntry->IsActive = GL_TRUE;
        menuEntry->Ordinal = menuID;

        /*
         * If this is not the same as the last active menu entry, deactivate
         * the previous entry.  Specifically, if the previous active entry
         * was a submenu then deactivate it.
         */
        if( menu->ActiveEntry && ( menuEntry != menu->ActiveEntry ) )
            if( menu->ActiveEntry->SubMenu )
                fghDeactivateSubMenu( menu->ActiveEntry );

        if( menuEntry != menu->ActiveEntry )
        {
            menu->Window->State.Redisplay = GL_TRUE;
            if( menu->ActiveEntry )
                menu->ActiveEntry->IsActive = GL_FALSE;
        }

        menu->ActiveEntry = menuEntry;
        menu->IsActive = GL_TRUE;  /* XXX Do we need this? */

        /*
         * OKi, we have marked that entry as active, but it would be also
         * nice to have its contents updated, in case it's a sub menu.
         * Also, ignore the return value of the check function:
         */
        if( menuEntry->SubMenu )
        {
            if ( ! menuEntry->SubMenu->IsActive )
            {
                int max_x, max_y;
                SFG_Window *current_window = fgStructure.CurrentWindow;

                /* Set up the initial menu position now... */
                menuEntry->SubMenu->IsActive = GL_TRUE;

                /* Set up the initial submenu position now: */
                fghGetVMaxExtent(menu->ParentWindow, &max_x, &max_y);
                menuEntry->SubMenu->X = menu->X + menu->Width;
                menuEntry->SubMenu->Y = menu->Y +
                    menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT;

                if( menuEntry->SubMenu->X + menuEntry->SubMenu->Width > max_x )
                    menuEntry->SubMenu->X = menu->X - menuEntry->SubMenu->Width;

                if( menuEntry->SubMenu->Y + menuEntry->SubMenu->Height > max_y )
                {
                    menuEntry->SubMenu->Y -= ( menuEntry->SubMenu->Height -
                                               FREEGLUT_MENU_HEIGHT -
                                               2 * FREEGLUT_MENU_BORDER );
                    if( menuEntry->SubMenu->Y < 0 )
                        menuEntry->SubMenu->Y = 0;
                }

                fgSetWindow( menuEntry->SubMenu->Window );
                glutPositionWindow( menuEntry->SubMenu->X,
                                    menuEntry->SubMenu->Y );
                glutReshapeWindow( menuEntry->SubMenu->Width,
                                   menuEntry->SubMenu->Height );
                glutPopWindow( );
                glutShowWindow( );
                menuEntry->SubMenu->Window->ActiveMenu = menuEntry->SubMenu;
                fgSetWindow( current_window );
                menuEntry->SubMenu->Window->State.MouseX =
                    x + menu->X - menuEntry->SubMenu->X;
                menuEntry->SubMenu->Window->State.MouseY =
                    y + menu->Y - menuEntry->SubMenu->Y;
                fghCheckMenuStatus( menuEntry->SubMenu );
            }

            /* Activate it because its parent entry is active */
            menuEntry->SubMenu->IsActive = GL_TRUE;  /* XXX Do we need this? */
        }

        /* Report back that we have caught the menu cursor */
        return GL_TRUE;
    }

    /* Looks like the menu cursor is somewhere else... */
    if( menu->ActiveEntry && menu->ActiveEntry->IsActive &&
        ( !menu->ActiveEntry->SubMenu ||
          !menu->ActiveEntry->SubMenu->IsActive ) )
    {
        menu->Window->State.Redisplay = GL_TRUE;
        menu->ActiveEntry->IsActive = GL_FALSE;
        menu->ActiveEntry = NULL;
    }

    return GL_FALSE;
}
Beispiel #5
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);
        }
    }
}