Gui Event Handler Blocking Events

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
Dominicm99
Posts: 3
Joined: Sat May 27, 2017 4:59 am

Gui Event Handler Blocking Events

Post by Dominicm99 »

Hi, Been using Irrlicht for a couple months now for a Highschool software project, and have been having a weird issue with implementing a GUI.
I'm using a slightly modified version of the Mast Event receiver (taken from http://irrlicht.sourceforge.net/forum/v ... =9&t=21657 )to try and allow GUI events to be handled (using the GUI tutorial 5) This worked for a while, but in order to make the GUI more useable, i tried moving the GUI events to a separate class (GuiHandler.h) which just accepts the const irr::SEvent& eventType.

However, Now whenever there is ANY code within the confides of the if statement, The mouse events will not be handled, the gui will not refresh. The screen still refreshes and shows 1k+ fps, and the keyboard events seem to be working (im able to unlock the mouse from the fps controller using a keydown).

The full code of my event receiver is below:

Code: Select all

 
 
/// ==================================================================================================
/// MastEventReceiver code is © (Copyright) Robert E. Demarest, AKA Mastiff or Mastiff Odit
/// This file may be used in any non-commercial or commercial project as long as the following conditions are met:
/// You may not claim this code as being your own.
/// You may not use this code for any harmful, malicious or otherwise damaging programs.
///
/// This is version 1.2a of the class.
/// This class is designed for use with the Irrlicht Engine, it was written for version 1.3 of the engine.
/// ==================================================================================================
 
//taken from http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=21657
 
/// Modified on 12/3/17 by Dominic to enable event handling for GUI events
 
#include <irrlicht.h>
#include "GuiHandler.h"
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
/// ==============================
/// MastEventReceiver
/// ==============================
class MastEventReceiver : public IEventReceiver
{
 
protected:
 
    GuiHandler* GuiHND;
    // Enumeration for UP, DOWN, PRESSED and RELEASED key states. Also used for mouse button states.
    enum keyStatesENUM { UP, DOWN, PRESSED, RELEASED };
 
    // Enumeration for Event Handling State.
    enum processStateENUM { STARTED, ENDED };
 
    // Mouse button states.
    keyStatesENUM mouseButtonState[2]; //Left(0), Middle(1) and Right(2) Buttons.
 
                                       // Keyboard key states.
    keyStatesENUM keyState[KEY_KEY_CODES_COUNT];
 
    // Mouse X/Y coordinates and Wheel data.
    struct mouseData
    {
        int X;
        int Y;
        float wheel; //wheel is how far the wheel has moved
    };
    struct mouseData mouse;
 
    processStateENUM processState; // STARTED = handling events, ENDED = not handling events
 
 
    //Structs::SAppContext *Context;
 
    // Define some values that we'll use to identify individual GUI controls.
 
 
    virtual bool OnEvent(const SEvent& event)
    {
        bool eventprocessed = false;
 
        //////////////////////////////
        // Keyboard Input Event
        //////////////////////////////
        if (event.EventType == EET_KEY_INPUT_EVENT)
        {
            if (processState == STARTED)
            {
                // if key is Pressed Down
                if (event.KeyInput.PressedDown == true)
                {
                    // If key was not down before
                    if (keyState[event.KeyInput.Key] != DOWN)
                    {
                        keyState[event.KeyInput.Key] = PRESSED; // Set to Pressed
                    }
                    else
                    {
                        // if key was down before
                        keyState[event.KeyInput.Key] = DOWN; // Set to Down
                    }
                }
                else
                {
 
                    // if the key is down
                    if (keyState[event.KeyInput.Key] != UP)
                    {
                        keyState[event.KeyInput.Key] = RELEASED; // Set to Released
                    }
                }
            }
 
 
            eventprocessed = true;
        }
 
        //////////////////////////////
        // Mouse Input Event
        //////////////////////////////
 
        if (event.EventType == EET_MOUSE_INPUT_EVENT)
        {
            if (processState == STARTED)
            {
                //Mouse changed position
                if (event.MouseInput.Event == EMIE_MOUSE_MOVED)
                {
                    mouse.Y = event.MouseInput.Y;
                    mouse.X = event.MouseInput.X;
                }
 
                //Wheel moved.
                if (event.MouseInput.Event == EMIE_MOUSE_WHEEL)
                {
                    mouse.wheel += event.MouseInput.Wheel;
                }
 
                //Left Mouse Button Pressed
                if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
                {
                    //
                    if (mouseButtonState[0] == UP || mouseButtonState[0] == RELEASED)
                    {
                        mouseButtonState[0] = PRESSED;
                    }
                    else
                    {
                        mouseButtonState[0] = DOWN;
                    }
                }
 
                //Left Mouse Button Rleased
                if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
                {
                    //
                    if (mouseButtonState[0] != UP)
                    {
                        mouseButtonState[0] = RELEASED;
                    }
                }
 
                //Middle Mouse Button Pressed
                if (event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN)
                {
                    //
                    if (mouseButtonState[1] == UP || mouseButtonState[1] == RELEASED)
                    {
                        mouseButtonState[1] = PRESSED;
                    }
                    else
                    {
                        mouseButtonState[1] = DOWN;
                    }
                }
 
                //Middle Mouse Button Rleased
                if (event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP)
                {
                    //
                    if (mouseButtonState[1] != UP)
                    {
                        mouseButtonState[1] = RELEASED;
                    }
                }
 
                //Right Mouse Button Pressed
                if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
                {
                    //
                    if (mouseButtonState[2] == UP || mouseButtonState[2] == RELEASED)
                    {
                        mouseButtonState[2] = PRESSED;
                    }
                    else
                    {
                        mouseButtonState[2] = DOWN;
                    }
                }
 
                //Right Mouse Button Rleased
                if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)
                {
                    //
                    if (mouseButtonState[2] != UP)
                    {
                        mouseButtonState[2] = RELEASED;
                    }
                }
            }
 
            eventprocessed = true;
        }
 
        ////////////////////////////////
        // GUI Input Event
        //////////////////////////////
 
        if (event.EventType == EET_GUI_EVENT)
        {
            //if (processState == STARTED)
            //{
                //s32 id = event.GUIEvent.Caller->getID();
                //IGUIEnvironment* env = Context->device->getGUIEnvironment();
                //GuiHND->GuiEvent(event);
                //eventprocessed = true;
            //}
        }
 
        //return eventprocessed;
    }
 
 
    //////////////////////
    // Public functions
    //////////////////////
public:
    float mouseWheel()
    {
        return mouse.wheel;
    }
 
    int mouseX()
    {
        return mouse.X;
    }
 
    int mouseY()
    {
        return mouse.Y;
    }
 
    bool leftMouseReleased()
    {
        if (mouseButtonState[0] == RELEASED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool leftMouseUp()
    {
        if (mouseButtonState[0] == RELEASED || mouseButtonState[0] == UP)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool leftMousePressed()
    {
        if (mouseButtonState[0] == PRESSED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool leftMouseDown()
    {
        if (mouseButtonState[0] == PRESSED || mouseButtonState[0] == DOWN)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool middleMouseReleased()
    {
        if (mouseButtonState[1] == RELEASED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool middleMouseUp()
    {
        if (mouseButtonState[1] == RELEASED || mouseButtonState[1] == UP)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool middleMousePressed()
    {
        if (mouseButtonState[1] == PRESSED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool middleMouseDown()
    {
        if (mouseButtonState[1] == PRESSED || mouseButtonState[1] == DOWN)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool rightMouseReleased()
    {
        if (mouseButtonState[2] == RELEASED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool rightMouseUp()
    {
        if (mouseButtonState[2] == RELEASED || mouseButtonState[2] == UP)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool rightMousePressed()
    {
        if (mouseButtonState[2] == PRESSED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool rightMouseDown()
    {
        if (mouseButtonState[2] == PRESSED || mouseButtonState[2] == DOWN)
        {
            return true;
        }
        else
        {
            return false;
        }
    }//
 
    bool keyPressed(char keycode)
    {
        if (keyState[keycode] == PRESSED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool keyDown(char keycode)
    {
        if (keyState[keycode] == DOWN || keyState[keycode] == PRESSED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool keyUp(char keycode)
    {
        if (keyState[keycode] == UP || keyState[keycode] == RELEASED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    bool keyReleased(char keycode)
    {
        if (keyState[keycode] == RELEASED)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
 
    // This is used so that the Key States will not be changed during execution of your Main game loop.
    // Place this at the very START of your Main Loop
    void endEventProcess()
    {
        processState = ENDED;
    }
 
    // This is used so that the Key States will not be changed during execution of your Main game loop.
    // Place this function at the END of your Main Loop.
    void startEventProcess()
    {
 
        processState = STARTED;
        //Keyboard Key States
        for (int i = 0; i < KEY_KEY_CODES_COUNT; i++)
        {
            if (keyState[i] == RELEASED)
            {
                keyState[i] = UP;
            }
 
            if (keyState[i] == PRESSED)
            {
                keyState[i] = DOWN;
            }
        }
        //Mouse Button States
        for (int i = 0; i <= 2; i++)
        {
            if (mouseButtonState[i] == RELEASED)
            {
                mouseButtonState[i] = UP;
            }
 
            if (mouseButtonState[i] == PRESSED)
            {
                mouseButtonState[i] = DOWN;
            }
        }
        //Mouse Wheel state
        mouse.wheel = 0.0f;
 
    }
 
    void init(Structs::SAppContext *passContext)
    {
        //Context = passContext;
        //KeyBoard States.
        for (int i = 0; i <= KEY_KEY_CODES_COUNT; i++)
        {
            keyState[i] = UP;
        }
        //Mouse states
        for (int i = 0; i <= 2; i++)
        {
            mouseButtonState[i] = UP;
        }
        //Mouse X/Y coordenates.
        mouse.X = 0;
        mouse.Y = 0;
        mouse.wheel = 0.0f;
    }
    void getGuiHandler(GuiHandler* gHND)
    {
        GuiHND = gHND;
    }
 
};
/// ==========================================
/// END OF MastEventReceiver
/// ==========================================
 
The weirdest thing is that if there is any code whatsoever within the if (event.EventType == EET_GUI_EVENT) block, the mouse will not move the fps controller, and the gui will not respond.

The GUI is also created in the GuiHandler class and is shown below
GuiHandler.h:

Code: Select all

#pragma once
#include <irrlicht.h>
#include "Structs.h"
class GuiHandler
{
public:
    GuiHandler(Structs::SAppContext *contIN);
    void GuiEvent(const irr::SEvent& eventType);
    ~GuiHandler();
protected:
    void setSkinTransparency(s32 alpha, irr::gui::IGUISkin * skin);
    Structs::SAppContext *context;
};
 
GuiHandler.cpp:

Code: Select all

#include "GuiHandler.h"
 
GuiHandler::GuiHandler(Structs::SAppContext *contIN)
{
    context = contIN;
 
 
    IGUISkin* skin = context->env->getSkin();
    IGUIFont* font = context->env->getFont("media/fonthaettenschweiler.bmp");
    if (font)
        skin->setFont(font);
 
    skin->setFont(context->env->getBuiltInFont(), EGDF_TOOLTIP);
 
 
    context->env->addButton(rect<s32>(10, 240, 110, 240 + 32), 0, Structs::GUI_ID_QUIT_BUTTON,
        L"Quit", L"Exits Program");
    context->env->addButton(rect<s32>(10, 280, 110, 280 + 32), 0, Structs::GUI_ID_NEW_WINDOW_BUTTON,
        L"New Window", L"Launches a new Window");
    context->env->addButton(rect<s32>(10, 320, 110, 320 + 32), 0, Structs::GUI_ID_FILE_OPEN_BUTTON,
        L"File Open", L"Opens a file");
 
 
    context->env->addStaticText(L"Transparent Control:", rect<s32>(150, 20, 350, 40), true);
    IGUIScrollBar* scrollbar = context->env->addScrollBar(true,
        rect<s32>(150, 45, 350, 60), 0, Structs::GUI_ID_TRANSPARENCY_SCROLL_BAR);
    scrollbar->setMax(255);
    scrollbar->setPos(255);
    setSkinTransparency(scrollbar->getPos(), context->env->getSkin());
 
    // set scrollbar position to alpha value of an arbitrary element
    scrollbar->setPos(context->env->getSkin()->getColor(EGDC_WINDOW).getAlpha());
 
    context->env->addStaticText(L"Logging ListBox:", rect<s32>(50, 110, 250, 130), true);
    IGUIListBox * listbox = context->env->addListBox(rect<s32>(50, 140, 250, 210));
    context->listbox = listbox;
    context->env->addEditBox(L"Editable Text", rect<s32>(350, 80, 550, 100));
}
 
void GuiHandler::GuiEvent(const irr::SEvent& eventType)
{
    //s32 id = eventType.GUIEvent.Caller->getID();
 
    //IGUIEnvironment* env = context->device->getGUIEnvironment();
    /*
    switch (eventType.GUIEvent.EventType)
    {
        case EGET_SCROLL_BAR_CHANGED:
            if (id == Structs::GUI_ID_TRANSPARENCY_SCROLL_BAR)
            {
                s32 pos = ((IGUIScrollBar*)eventType.GUIEvent.Caller)->getPos();
                setSkinTransparency(pos, env->getSkin());
            }
            break;
 
        case EGET_BUTTON_CLICKED:
            switch (id)
            {
                case Structs::GUI_ID_QUIT_BUTTON:
                    context->device->closeDevice();
                    break;
 
                case Structs::GUI_ID_NEW_WINDOW_BUTTON:
                    {
                        //Context->listbox->addItem(L"Window created");
                        context->counter += 30;
                        if (context->counter > 200)
                            context->counter = 0;
 
                        IGUIWindow* window = env->addWindow(
                            rect<s32>(100 + context->counter, 100 + context->counter, 300 + context->counter, 200 + context->counter),
                            false, // modal?
                            L"Test window");
 
                        env->addStaticText(L"Please close me",
                            rect<s32>(35, 35, 140, 50),
                            true, // border?
                            false, // wordwrap?
                            window);
                    }
                    break;
 
                case Structs::GUI_ID_FILE_OPEN_BUTTON:
                    context->listbox->addItem(L"File open");
                    env->addFileOpenDialog(L"Please choose a file.", true, 0, -1, true);
                    break;
            }
            break;
 
        case EGET_FILE_SELECTED:
            // show the model filename, selected in the file dialog
            IGUIFileOpenDialog* dialog =
                (IGUIFileOpenDialog*)eventType.GUIEvent.Caller;
            context->listbox->addItem(dialog->getFileName());
            break;
 
    }*/
}
 
 
void GuiHandler::setSkinTransparency(s32 alpha, irr::gui::IGUISkin * skin)
{
    for (s32 i = 0; i<irr::gui::EGDC_COUNT; ++i)
    {
        video::SColor col = skin->getColor((EGUI_DEFAULT_COLOR)i);
        col.setAlpha(alpha);
        skin->setColor((EGUI_DEFAULT_COLOR)i, col);
    }
}
 
GuiHandler::~GuiHandler()
{
}
 
Note the removed code within the gui event receiver due to debugging
kornwaretm
Competition winner
Posts: 189
Joined: Tue Oct 16, 2007 3:53 am
Location: Indonesia
Contact:

Re: Gui Event Handler Blocking Events

Post by kornwaretm »

please confirm that the onEvent() are returning a boolean value. true if processed false if not yet. usually returning true is enough. if false returned make sure that the event chaining and at last return true.

[edit]
:oops: :oops: see CuteAlien's answer below
Last edited by kornwaretm on Mon May 29, 2017 3:04 am, edited 1 time in total.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Gui Event Handler Blocking Events

Post by CuteAlien »

Just the other way round as kornwaretm said ;-) You should nearly always return false - returning true means - this event has been completely handled and won't be passed on to Irrlicht anymore. So if you ever return true for mouse or keyboard events then the gui won't receive them.

Also you got a bug in your mouseButtonState declaration. It should be size 3 not 2 (as you use 0, 1 and 2 - which are 3 elements). Meaning you overwrite some random memory there (well, inn your case you overwrite keyState[0] which in most cases won't be horible, but still wrong).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Re: Gui Event Handler Blocking Events

Post by sudi »

For gui events you might wanna take a look at this snippet: http://irrlicht.sourceforge.net/forum/v ... =9&t=43344
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Post Reply