Esempio n. 1
0
/*
 * Changes the specified menu item in the current menu into a sub-menu trigger.
 */
void FGAPIENTRY glutChangeToSubMenu( int item, const char* label,
                                     int subMenuID )
{
    SFG_Menu*      subMenu;
    SFG_MenuEntry* menuEntry;

    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutChangeToSubMenu" );

    freeglut_return_if_fail( fgStructure.CurrentMenu );
    if (fgGetActiveMenu())
        fgError("Menu manipulation not allowed while menus in use.");

    /* Get handle to sub menu */
    subMenu = fgMenuByID( subMenuID );
    menuEntry = NULL;

    freeglut_return_if_fail( subMenu );

    /* Get n-th menu entry in the current menu, starting from one: */
    menuEntry = fghFindMenuEntry( fgStructure.CurrentMenu, item );

    freeglut_return_if_fail( menuEntry );

    /* We want it to become a sub menu entry, so: */
    if( menuEntry->Text )
        free( menuEntry->Text );

    menuEntry->Text    = strdup( label );
    menuEntry->SubMenu = subMenu;
    menuEntry->ID      = -1;
    fghCalculateMenuBoxSize( );
}
Esempio n. 2
0
/*
 * Creates a new menu object, adding it to the freeglut structure
 */
int FGAPIENTRY glutCreateMenu( void(* callback)( int ) )
{
    /* The menu object creation code resides in freeglut_structure.c */
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
    if (fgGetActiveMenu())
        fgError("Menu manipulation not allowed while menus in use.");
    return fgCreateMenu( callback )->ID;
}
Esempio n. 3
0
/*
 * Destroys a menu object, removing all references to it
 */
void FGAPIENTRY glutDestroyMenu( int menuID )
{
    SFG_Menu* menu;

    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDestroyMenu" );
    menu = fgMenuByID( menuID );

    freeglut_return_if_fail( menu );

    if (fgGetActiveMenu())
        fgError("Menu manipulation not allowed while menus in use.");

    /* The menu object destruction code resides in freeglut_structure.c */
    fgDestroyMenu( menu );
}
Esempio n. 4
0
/*
 * Detaches a menu from the current window
 */
void FGAPIENTRY glutDetachMenu( int button )
{
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDetachMenu" );

    freeglut_return_if_fail( fgStructure.CurrentWindow );

    freeglut_return_if_fail( fgStructure.CurrentMenu );
    if (fgGetActiveMenu())
        fgError("Menu manipulation not allowed while menus in use.");

    freeglut_return_if_fail( button >= 0 );
    freeglut_return_if_fail( button < FREEGLUT_MAX_MENUS );

    fgStructure.CurrentWindow->Menu[ button ] = NULL;
}
Esempio n. 5
0
/*
 * Adds a menu entry to the bottom of the current menu
 */
void FGAPIENTRY glutAddMenuEntry( const char* label, int value )
{
    SFG_MenuEntry* menuEntry;
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutAddMenuEntry" );
    menuEntry = (SFG_MenuEntry *)calloc( sizeof(SFG_MenuEntry), 1 );

    freeglut_return_if_fail( fgStructure.CurrentMenu );
    if (fgGetActiveMenu())
        fgError("Menu manipulation not allowed while menus in use.");

    menuEntry->Text = strdup( label );
    menuEntry->ID   = value;

    /* Have the new menu entry attached to the current menu */
    fgListAppend( &fgStructure.CurrentMenu->Entries, &menuEntry->Node );

    fghCalculateMenuBoxSize( );
}
Esempio n. 6
0
void fgPlatformCheckMenuDeactivate()
{
    /* If we have an open menu, see if the open menu should be closed
    * when focus was lost because user either switched
    * application or FreeGLUT window (if one is running multiple
    * windows). If so, close menu the active menu.
    */
    SFG_Menu* menu = NULL;

    if ( fgStructure.Menus.First )
        menu = fgGetActiveMenu();

    if ( menu )
    {
        SFG_Window* wnd = NULL;
        HWND hwnd = GetFocus();  /* Get window with current focus - NULL for non freeglut windows */
        if (hwnd)
            /* See which of our windows it is */
            wnd = fgWindowByHandle(hwnd);

        if (!hwnd || !wnd)
            /* User switched to another application*/
            fgDeactivateMenu(menu->ParentWindow);
        else if (!wnd->IsMenu)      /* Make sure we don't kill the menu when trying to enter a submenu */
        {
            if (wnd!=menu->ParentWindow)
                /* User switched to another FreeGLUT window */
                fgDeactivateMenu(menu->ParentWindow);
            else
            {
                /* Check if focus lost because non-client area of
                 * window was pressed (pressing on client area is
                 * handled in fgCheckActiveMenu)
                 */
                POINT mouse_pos;
                RECT clientArea;
                fghGetClientArea(&clientArea,menu->ParentWindow, GL_FALSE);
                GetCursorPos(&mouse_pos);
                if ( !PtInRect( &clientArea, mouse_pos ) )
                    fgDeactivateMenu(menu->ParentWindow);
            }
        }
    }
};
Esempio n. 7
0
/*
 * Add a sub menu to the bottom of the current menu
 */
void FGAPIENTRY glutAddSubMenu( const char *label, int subMenuID )
{
    SFG_MenuEntry *menuEntry;
    SFG_Menu *subMenu;

    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutAddSubMenu" );
    menuEntry = ( SFG_MenuEntry * )calloc( sizeof( SFG_MenuEntry ), 1 );
    subMenu = fgMenuByID( subMenuID );

    freeglut_return_if_fail( fgStructure.CurrentMenu );
    if (fgGetActiveMenu())
        fgError("Menu manipulation not allowed while menus in use.");

    freeglut_return_if_fail( subMenu );

    menuEntry->Text    = strdup( label );
    menuEntry->SubMenu = subMenu;
    menuEntry->ID      = -1;

    fgListAppend( &fgStructure.CurrentMenu->Entries, &menuEntry->Node );
    fghCalculateMenuBoxSize( );
}
Esempio n. 8
0
/*
 * Removes the specified menu item from the current menu
 */
void FGAPIENTRY glutRemoveMenuItem( int item )
{
    SFG_MenuEntry* menuEntry;

    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutRemoveMenuItem" );

    freeglut_return_if_fail( fgStructure.CurrentMenu );
    if (fgGetActiveMenu())
        fgError("Menu manipulation not allowed while menus in use.");

    /* Get n-th menu entry in the current menu, starting from one: */
    menuEntry = fghFindMenuEntry( fgStructure.CurrentMenu, item );

    freeglut_return_if_fail( menuEntry );

    fgListRemove( &fgStructure.CurrentMenu->Entries, &menuEntry->Node );
    if ( menuEntry->Text )
      free( menuEntry->Text );

    free( menuEntry );
    fghCalculateMenuBoxSize( );
}
Esempio n. 9
0
/*
 * Check whether an active menu absorbs a mouse click
 */
GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
                              int mouse_x, int mouse_y )
{
    GLboolean is_handled = GL_FALSE;
    GLboolean is_clicked = GL_FALSE;
    /*
     * 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, and potentially activate a new menu
     *    at the new mouse location. This includes clicks in
     *    different windows of course
     *  - 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
     * Since menus can have submenus, we need to check this recursively.
     */
    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, deactivate the menu and invoke the callback */
        if( fghCheckMenuStatus( 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.CurrentWindow;
            SFG_Menu *save_menu = fgStructure.CurrentMenu, *active_menu = window->ActiveMenu;   /* active menu is always the one with the mouse in it, due to fghCheckMenuStatus */
            SFG_MenuEntry *active_entry = active_menu->ActiveEntry;                             /* currently highlighted item -> must be the one that was just clicked */
            SFG_Window *parent_window = window->ActiveMenu->ParentWindow;

            /* ignore clicks on the submenu entry */
            if (!active_entry->SubMenu)
            {
                fgSetWindow( parent_window );
                fgStructure.CurrentMenu = active_menu;

                /* Deactivate menu and then call callback (we don't want menu to stay in view while callback is executing, and user should be able to change menus in callback) */
                fgDeactivateMenu( parent_window );
                active_menu->Callback( active_entry->ID );

                /* Restore the current window and menu */
                fgSetWindow( save_window );
                fgStructure.CurrentMenu = save_menu;
            }

            is_clicked = GL_TRUE;   /* Don't reopen... */
        }
        else if( pressed )
            /*
             * Outside the menu, deactivate if it's a downclick
             *
             * A downclick outside of the interior of our freeglut windows
             * is dealt with in the WM_KILLFOCUS handler of fgPlatformWindowProc
             */
        {
            fgDeactivateMenu( window->ActiveMenu->ParentWindow );
            /* Could reopen again in different location, as is_clicked remains false */
        }

        is_handled = GL_TRUE;
    }
    else if ( fgState.ActiveMenus ) /* Don't have to check whether this was a downpress or an uppress, there is no way to get an uppress in another window before a downpress... */
    {
        /* if another window than the one clicked in has an open menu, close it */
        SFG_Menu *menu = fgGetActiveMenu();
        if ( menu ) /* any open menu? */
            fgDeactivateMenu( menu->ParentWindow );

        /* Leave is_handled to false, we didn't do anything relevant from the perspective of the window that was clicked */
    }

    /* No active menu, let's check whether we need to activate one. */
    if( !is_clicked &&
            ( 0 <= button ) &&
            ( FREEGLUT_MAX_MENUS > button ) &&
            ( window->Menu[ button ] ) &&
            pressed )
    {
        /* If mouseclick was outside the parent window, ignore. This can
         * happen when another mouse button is already depressed and the
         * window thus has mouse capture
         */
        if (window->State.MouseX>0 && window->State.MouseY>0 &&
                window->State.MouseX<window->State.Width && window->State.MouseY<window->State.Height)
        {
            fghActivateMenu( window, button );
            is_handled = GL_TRUE;
        }
    }

    return is_handled;
}