Page 1 of 1

[Solved] Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 04:10
by Alundra
Hi,
I'm creating the root window on the init of the GUI like that :

Code: Select all

// Create the root window and set it as root window.
CEGUI::Window* RootWindow = CEGUI::WindowManager::getSingleton().createWindow( "DefaultWindow", "Root" );
CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow( RootWindow );
RootWindow->setMousePassThroughEnabled( true );

When I load layout I set the root of the loaded layout as child.
I have to set setMousePassThroughEnabled to true to not have the input issue because I bypass my events based on the return of the events of CEGUI.
Is it the correct method to use CEGUI ?
Thanks

Re: Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 08:58
by Ident
Alundra wrote:I have to set setMousePassThroughEnabled to true to not have the input issue because I bypass my events based on the return of the events of CEGUI.


What do you mean by that?

Re: Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 14:13
by Alundra
Apparently if I don't set that the event of CEGUI always returns TRUE and then my custom event is bypassed because I stop the event processing if CEGUI returns TRUE on one event injection to not have any event if one GUI event is processed.

Re: Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 16:12
by Ident
Show me an example of an event handler you use that doesn't work as expected. I am not sure I fully get it so far, that sentence was quite convoluted :D

Re: Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 19:16
by Alundra
Here the process event function :

Code: Select all

bool CGUISystem::ProcessEvent( const SDL_Event& Event )
{
   // Process the event.
   switch( Event.type )
   {
      case SDL_WINDOWEVENT :
      {
         // Check if the size of the window has changed.
         if( Event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED )
         {
            // Get the width and the height of the window.
            const float Width = static_cast< float >( Event.window.data1 );
            const float Height = static_cast< float >( Event.window.data2 );

            // Notify the display size changed.
            CEGUI::System::getSingleton().notifyDisplaySizeChanged( CEGUI::Sizef( Width, Height ) );
         }

         // Return false to not stop the event processing.
         return false;
      }

      case SDL_KEYDOWN :
      {
         return CEGUI::System::getSingleton().getDefaultGUIContext().injectKeyDown( ToCEGUIKey( Event.key.keysym.sym ) );
      }

      case SDL_KEYUP :
      {
         return CEGUI::System::getSingleton().getDefaultGUIContext().injectKeyUp( ToCEGUIKey( Event.key.keysym.sym ) );
      }

      case SDL_MOUSEBUTTONDOWN :
      {
         return CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseButtonDown( ToCEGUIMouseButton( Event.button.button ) );
      }

      case SDL_MOUSEBUTTONUP :
      {
         return CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseButtonUp( ToCEGUIMouseButton( Event.button.button ) );
      }

      case SDL_MOUSEMOTION :
      {
         const float x = static_cast< float >( Event.motion.x );
         const float y = static_cast< float >( Event.motion.y );
         return CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition( x, y );
      }

      case SDL_MOUSEWHEEL :
      {
         const float Delta = static_cast< float >( Event.wheel.y );
         return CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseWheelChange( Delta );
      }

      case SDL_TEXTINPUT :
      {
         const UInt32 CodePointUTF32 = UTF8ToUTF32( reinterpret_cast< const UInt8* >( Event.text.text ) );
         return CEGUI::System::getSingleton().getDefaultGUIContext().injectChar( CodePointUTF32 );
      }
   }

   // Return false to not stop the event processing.
   return false;
}

The main loop calls PollEvent of SDL to process each event, if the GUI process event function returns TRUE, the processing of the event for the game actions is bypassed.
If I don't bypass the input on the root (and same for the layout root), I never have the mouse motion and mouse buttons processed for the game actions.

Re: Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 19:23
by Ident
You probably got an invisible extra window attached to the root that eats all input. Did you check?

Although, on second thought, that makes no sense..

Re: Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 20:50
by Alundra
The root here is a DefaultWindow :

Code: Select all

CEGUI::Window* RootWindow = CEGUI::WindowManager::getSingleton().createWindow( "DefaultWindow", "Root" );
CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow( RootWindow );

And in the layout it's like that :

Code: Select all

Root (DefaultWindow)
  -> Item1 (Image)
  -> Item2 (Button)

When I load the layout I do :

Code: Select all

MainMenuRoot = CEGUI::WindowManager::getSingleton().loadLayoutFromFile( "MainMenu.layout" );
CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->addChild( MainMenuRoot );

So, basically internally in CEGUI the hierarchy is like that :

Code: Select all

Root (DefaultWindow)
  -> Root (DefaultWindow)
    -> Item1 (Image)
    -> Item2 (Button)

I tried again to be sure, without setMousePassThroughEnabled set to TRUE on the two root, I got the issue.
The first root is used to attach all other layout loaded, and the root on the layout is apparently required so you must have it.
But even if it was not required, it was needed to have it to have the management easy to not enter in chaos.

EDIT :
Apparently only on the first root it's needed.

Re: Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 21:17
by Ident
You can directly attach the root. You can swap them out when swapping out layouts. Did you try that? Did it help?

Re: Correct method to use CEGUI ?

Posted: Sun Mar 26, 2017 23:06
by Alundra
But doing this method, if I want to show a layout on a layout, like a window on the game interface, it's not possible right ?
Using the method I actually use I can simply add a child layout, but maybe another way exists already ?
Example : In-Game menu layout on the In-Game interface layout.

Re: Correct method to use CEGUI ?

Posted: Mon Mar 27, 2017 18:32
by Ident
I think this should be correct usage:

Root
- Background (MousePassThrough = true)
- GameInterface
-- Inventory
-- Hud (MousePassThrough = true)
- Fps Counter (MousePassThrough = true)

This should enable that a click on the counter or background will propagate to GameInterface and a click on the Hud will propagate to the Inventory, in case those windows would be hit instead, underneath.

Does that work like this?

Re: Correct method to use CEGUI ?

Posted: Tue Mar 28, 2017 01:17
by Alundra
All in one layout ?
Basically I don't need a big GUI :
- MainMenu with different windows for the settings
- InGame interface (life, weapon used + bullets, minimap)
- InGame menu to go back to the main menu + settings in game
So what I thought was to have a created root always there and manage the add child of loaded layout.
I didn't look yet but I guess CEGUI manage the Z-Order to sort the layout so I don't see an issue like that.
The goal is to have something easy to manage and can spawn the window without issue.
Is it better to do all in two layouts : "MainMenu.layout" and "InGame.layout", or it's better to have different window by layout ?
I didn't look yet for that too but if CEED doesn't allow to hide things it can be the chaos in CEED to work on the layout.

Re: Correct method to use CEGUI ?

Posted: Tue Mar 28, 2017 17:33
by Ident
Alundra wrote:Is it better to do all in two layouts : "MainMenu.layout" and "InGame.layout", or it's better to have different window by layout ?
I didn't look yet for that too but if CEED doesn't allow to hide things it can be the chaos in CEED to work on the layout.

A layout is just a Window in the end so it is really up to you. I would put it into different layouts in CEED and then put it together in the application as described above.