Problem with GUI

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Coolkat88
Posts: 30
Joined: Tue Oct 03, 2006 3:14 pm

Problem with GUI

Post by Coolkat88 »

Hello all,

this is going to be kinda strange to explain so stay with me here.

I get no errors in my program, and im trying to build a game and at the moment im just working on the main menu but i was building it into a full program (i have state managers, etc.) So i built in the GUI and at first it worked.. i had a seg fault stopping the "restart" feature i was implementing.. so i closed the game for a bit.. came back a week later and when trying to load the game it didn't work AT ALL. where as a week ago it did.. so i went ahead and fixed the seg fault that i had there... now the GUI loads (4 buttons on the screen) but i can't click on them.. they don't do anything, or make an indented image when clicked on.. it's like they are just there...

now here is something alittle more sepecific to how the game itself is running behind the scenes to see what you all can make of it.

main.cpp:

Code: Select all

RPGDevice rpg;
IrrlichtDevice *device = 0;
EventHand *handle = new EventHand; // did this to fix a seg fault, it DOES inherit IEventReciever

.....

device = createDevice(...)

device->setEventReciever(handle);
handle->setDevice(device);
handle->setRPG(rpg);
how inside of the event handler i have it just like any other (more or less) with

eventhand.cpp

Code: Select all

class EventHand : IEventReciever
{

    virtual bool OnEvent(SEvent event);

    ....
}
now I made a special class to handle all the main menu events.. such as the render of different menu "lists" (such as which buttons and other objects to load depending on where they are in the menu section) this is the MainMenu class.. and in this class is where i have the buttons rendering.. it's called in RPGDevice


rpgdevice.cpp

Code: Select all

//pseudocode for length of post
// this is all done in OO, and it all compiles properly

void swichscene(int num)
{

   ...

       case 1:
       menu.loadMain();
    
       case 2:
       menu.loadSingle();


    ...
}
and i'll post the exact code from loadMain() (since that's the one in question here..)

mainmenu.cpp

Code: Select all

#define HEIGHT(num) scaleHeight( num , res.Y)
// this is actually in mainmenu.h but oh well..

......

void MainMenu::loadMain()
{
     // if this is the FIRST time that the menu will be loaded then
     // draw the background scene.. basically makes the background scene or not
     
     if(checkFlag(MENU_FIRST) == 1)
     {
                 //device->getSceneManager()->loadScene("./menu/menu.irr");
                // commented out since im not working with gfx at the moment
      
                 setFlag(MENU_FIRST, 0);
     }
     
     // height of the buttons
     s32 H = HEIGHT(75);
     
     // space between the buttons
     s32 S = HEIGHT(25);
     
     // Y values for all 8 Y coords
     s32 y1 = HEIGHT(700);
     s32 y2 = y1 - H;
     s32 y3 = y2 - S;
     s32 y4 = y3 - H;
     s32 y5 = y4 - S;
     s32 y6 = y5 - H;
     s32 y7 = y6 - (S + H);
     s32 y8 = y7 - H;
     
     IGUIButton *button1 = gui->addButton(rect<s32>(res.X1, res.Y - y1, res.X2, res.Y - y2), 0, 1, L"Campaign"); 
     IGUIButton *button2 = gui->addButton(rect<s32>(res.X1, res.Y - y3, res.X2, res.Y - y4), 0, 2, L"Multiplayer");
     IGUIButton *button3 = gui->addButton(rect<s32>(res.X1, res.Y - y5, res.X2, res.Y - y6), 0, 3, L"Cinematic");
        
     IGUIButton *button5 = gui->addButton(rect<s32>(res.X1, res.Y - y7, res.X2, res.Y - y8), 0, 5, L"Exit Game");
    
     
}
i thought that maybe it's the scaling function im using.. but that shouldn't really be a problem since all im doing is calculating the the 4 coords based on the screen resolution.. which by the way im running the device in windowed mode with resizing turned off.. if you need any other code i'll be happy to give it.. i didn't want to add too much information if it wasn't needed.

Thanks in advance, Coolkat.
CuteAlien
Admin
Posts: 9930
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Ok, first for the problem with "it worked a week ago and then suddenly it stopped working". This can happen if you are using uninitialized variables somewhere. They are not initialized - so they can have any value and your application might crash with some values and not crash with others. Or maybe you just changed something so small that you ignored it, thinking that it couldn't have been that small change (that happens often to me).

Now for the problem that the buttons don't do anything.
To me that sounds like you have an OnEvent function that returns true. In most cases you should return false.
Coolkat88
Posts: 30
Joined: Tue Oct 03, 2006 3:14 pm

Post by Coolkat88 »

ok i realized that for some reason there was no longer a return value at all from OnEvent, so i added that and the buttons click now... however they don't preform the action that is indented of them.. more detailed look at my event handler is:

Code: Select all

bool EventHand::OnEvent(SEvent event)
{
     if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
               handleKeyEvents(event, rpgc.getSceneNum());
     else if(event.EventType == EET_GUI_EVENT)
               handleGUIEvents(event, rpgc.getSceneNum());
     else if(event.EventType == EET_MOUSE_INPUT_EVENT)
               handleMouseEvents(event, rpgc.getSceneNum());
               
     return false;
} 
and for just the GUI events i have

Code: Select all

void EventHand::handleGUIEvents(SEvent event, int scenenum)
{
     
       /*********************************************************/
       /********************** SCENE ONE ************************/
       /*********************************************************/     
     
     
       if(scenenum == 1)
       {
             if(event.GUIEvent.EventType ==  gui::EGET_BUTTON_CLICKED)
             {
                   switch(event.GUIEvent.Caller->getID())
                   {
                            case 1: // testing
                                rpgc.Restart();
                                break;                            
                                                         
                            case 5: // exit game
                                rpgc.Shutdown();
                                break;
                                                         
                   }
             }
       }
}
ignore my funky comments ;)

now i know you are going to say that maybe it's to do with my Shutdown() function, and the reason im not posting that is because i tried it with handDevice->closeDevice() and still the buttons did not work.. but they DO have the clicking animation.. Thanks for your help and any more would be greatly appreciated!
CuteAlien
Admin
Posts: 9930
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Debug it. Either use a debugger and set breakpoints to see what happens, or if you don't want to do that you can also add some printf's. Find out how far the event does get.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Are you sure the scenenum is correct ???
Are you sure the button's IDs are correct ???

Now what really is missing is the return true; statements inside the event receiver !!!
Try it like this:

Code: Select all

bool EventHand::OnEvent(SEvent event){
  if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown){
    handleKeyEvents(event, rpgc.getSceneNum());
    return true;
  }else if(event.EventType == EET_GUI_EVENT){
    handleGUIEvents(event, rpgc.getSceneNum());
    return true;
  }else if(event.EventType == EET_MOUSE_INPUT_EVENT){
    handleMouseEvents(event, rpgc.getSceneNum());
    return true;
  }               
  return false;
}
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Coolkat88
Posts: 30
Joined: Tue Oct 03, 2006 3:14 pm

Post by Coolkat88 »

Acki, i tried the code you posted there and the buttons stopped being pressed at all..

and im sure of the scenenum value as it is the same variable that is used to draw the buttons.

also the button IDs im using is 1 and 5 which are both IDs from the buttons i have set when i drew the buttons in the first place.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Hmm, strange, it should work, at least it should not stop the buttons from action... :shock:

The return true; is necessary to tell Irrlicht that you handled the event and Irrlicht doesn't have to care about it anymore...

But I found another problem:

Code: Select all

void swichscene(int num){
   ...
       case 1:
       menu.loadMain();
   
       case 2:
       menu.loadSingle();
    ...
}
If num is 1 then first loadMain is called and right after this loadSingle is called...
You'll have to end a case with break:

Code: Select all

void swichscene(int num){
   ...
       case 1:
       menu.loadMain();
       break;

       case 2:
       menu.loadSingle();
       break;
    ...
}
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Hmm, strange, it should work, at least it should not stop the buttons from action...
Acki, you're screwing people up again... If you always return true from the event handler, then the gui/camera never get the events.

Your event receiver should return true if it fully handled the incoming event. If you don't do everything that needs to be done inside your event handler, then you need to return false so that the event can be handled by the other parts of the application, like your gui buttons.

I would propose that you update your handle*Events() functions to return a bool that indicates the event was handled or not. Then your OnEvent() would look like this.

Code: Select all

bool EventHand::OnEvent(SEvent event){ 
  if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown){ 
    return handleKeyEvents(event, rpgc.getSceneNum()); 
  }else if(event.EventType == EET_GUI_EVENT){ 
    return handleGUIEvents(event, rpgc.getSceneNum()); 
  }else if(event.EventType == EET_MOUSE_INPUT_EVENT){ 
    return handleMouseEvents(event, rpgc.getSceneNum()); 
  }                
  return false; 
}
If you are getting a crash, the best thing for you to do is get familiar with your debugger. It is a tool that will find to be invaluable when you write lots of code.

Travis
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

I never told something else... ;)
The return true; is necessary to tell Irrlicht that you handled the event and Irrlicht doesn't have to care about it anymore...
OK, you're right, the place I choose for the return true; was not the best, but it was just an example to show what I mean... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Coolkat88
Posts: 30
Joined: Tue Oct 03, 2006 3:14 pm

Post by Coolkat88 »

Acki: there actualyl are break statements there, i just typed that out fast and mentioned above that it wasn't complete. :)

and when i run the debugger, it doesn't say anything.. the game doesn't crash anymore.. it just doesn't do what i tell it to do.


let me implement this code really quick like..


*Please Hold while the party you are trying to reach is implementing code...*

ok i implemented just as you said vitek, and same thing happened.. it seems if return true is in there it doesn't like to work.. i double checked the scenenum variable to make sure all was well and it for some reason wasn't setting it properly.. so i'll have to check that.. in the RPGDevice constructor i set all the variables to 0 (well some.. not all).. and then i do a beginDevice() function that sets scenenum to 1... but it seems when i passed the RPGDevice again to another function (like mainmenu) it reset the value to 0... i think.. maybe.. i'll look into that more.. thanks all for your help it works now ;)
Post Reply