Problem with GUIElement OnEvent()

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Squarefox
Competition winner
Posts: 113
Joined: Tue Aug 19, 2008 6:46 pm
Location: Delta quadrant, Borg nexus 0001
Contact:

Problem with GUIElement OnEvent()

Post by Squarefox »

Hello,

I created a custom GUI element with a custom OnEvent() function, but it is never called.
Can anyone help me with that, please?

The code:

Code: Select all

#include "CGUITextBox.h"
 
namespace irr
{
namespace gui
{
CGUITextBox::CGUITextBox(irr::gui::IGUIFont * font, const wchar_t * text, 
                         IGUIEnvironment* environment, core::rect<s32> rectangle,
                         IGUIElement* parent, s32 id)
        : IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle)
{
    m_bScrollModeLines = true;
    m_bScrollbarRight = true;
 
    Text = text;
 
    m_pFont = font;
    
    m_pScrollbar = 0;
    m_pDummyText = 0;
    m_pStaticText = 0;
 
    reset();
}
 
CGUITextBox::~CGUITextBox()
{
}
 
//! Called if an event happened.
bool CGUITextBox::OnEvent(SEvent event)
{
    if (Parent)
        Parent->OnEvent(event);
 
    if(event.EventType == EET_MOUSE_INPUT_EVENT && event.MouseInput.Event == EMIE_MOUSE_WHEEL)
    {
        m_pScrollbar->setPos(m_pScrollbar->getPos() + (s32)event.MouseInput.Wheel*(-10));
        irr::s32 line = m_pScrollbar->getPos();
        setVisibleText(line);
    }
 
    if(event.EventType == EET_GUI_EVENT && event.GUIEvent.EventType == EGET_SCROLL_BAR_CHANGED)
    {
        IGUIScrollBar * bar = static_cast <irr::gui::IGUIScrollBar *>
            (event.GUIEvent.Caller);
        if(bar == m_pScrollbar)
        {
            irr::s32 line = m_pScrollbar->getPos();
            setVisibleText(line);
        }
    }
 
    return true;
}
 
void CGUITextBox::setScrollModeLines(bool bLines){
    m_bScrollModeLines = bLines;
    calculateScrollbarSize();
}
bool CGUITextBox::isScrollModeLines(void){
    return m_bScrollModeLines;
}
 
void CGUITextBox::setScrollbarRight(bool bRight)
{
    if(!m_pStaticText || !m_pScrollbar || !m_pDummyText)
        return;
 
    irr::s32 right, down;
    right = RelativeRect.getWidth();    
    down = RelativeRect.getHeight();
    if(bRight)
    {
        m_pScrollbar->setRelativePosition(core::rect<s32>
            (right - 10, 0, right, down));
        m_pDummyText->setRelativePosition(core::rect<s32>
            (0, 0, right - 10, down));
        m_pStaticText->setRelativePosition(core::rect<s32>
            (0, 0, right - 10, down));
    }
    else
    {
        m_pScrollbar->setRelativePosition(core::rect<s32>
            (0, 0, 10, down));
        m_pDummyText->setRelativePosition(core::rect<s32>
            (10, 0, right, down));
        m_pStaticText->setRelativePosition(core::rect<s32>
            (10, 0, right, down));
    }
    m_bScrollbarRight = bRight;
}
bool CGUITextBox::isScrollbarRight(void){
    return m_bScrollbarRight;
}
 
void CGUITextBox::setText(const wchar_t* text)
{
    Text = text;
    m_pStaticText->setText(text);
    calculateScrollbarSize();
    m_pScrollbar->setPos(0);
    setVisibleText(0);  
}
 
void CGUITextBox::setRelativePosition(const core::rect<s32> r)
{
    RelativeRect = r;
    updateAbsolutePosition();
    reset();
}
 
/////////////////////////////////
// Private
 
void CGUITextBox::setVisibleText(irr::s32 startLine)
{
    if(!m_pStaticText)
    {
        return;
    }
 
    // Calculate Current Position
    irr::s32 fontHeight = m_pFont->getDimension(L"A").Height;
    irr::s32 deltaX = 0;
    deltaX = (m_bScrollModeLines ? startLine * fontHeight : startLine);
 
    // Set the Position of the text
    irr::core::rect<irr::s32> dim = getRelativePosition();
    s32 left = (m_bScrollbarRight ? 0 : 10);
    s32 right = (m_bScrollbarRight ? -10 : 0);
    dim = irr::core::rect<irr::s32> (left, -deltaX, dim.getWidth()+right,dim.getHeight());
    m_pStaticText->setRelativePosition(dim);
}
 
irr::s32 CGUITextBox::calculateScrollbarSize(void)
{
    if(!m_pScrollbar)
    {
        return -1;
    }
    
    irr::core::rect<irr::s32> origRect = m_pStaticText->getRelativePosition();
    m_pStaticText->setRelativePosition(m_pDummyText->getRelativePosition());
 
    irr::s32 fontHeight = m_pFont->getDimension(L"A").Height;   // Height depending on font     
    // Irrlicht serves us with giving the correct Text Height
    irr::s32 textHeight = m_pStaticText->getTextHeight();
    irr::s32 scrollbarSize = 0;
    if(m_bScrollModeLines)
    {
        irr::s32 iLineViewableCount = (origRect.getHeight() / fontHeight);
        scrollbarSize = textHeight / fontHeight - iLineViewableCount;
    }
    else
    {
        scrollbarSize = textHeight - origRect.getHeight();
    }
 
    // Revert to original Size and set the Max. Value of the Scrollbar
    m_pStaticText->setRelativePosition(origRect);
    m_pScrollbar->setMax(scrollbarSize);
    return scrollbarSize;
}
 
void CGUITextBox::reset(void)
{
    if(m_pScrollbar)
    {
        m_pScrollbar->remove();
        m_pScrollbar = 0;
    }
    if(m_pStaticText)
    {
        m_pStaticText->remove();
        m_pStaticText = 0;
    }
    if(m_pDummyText)
    {
        m_pDummyText->remove();
        m_pDummyText = 0;
    }
 
    irr::s32 right, down;
    right = RelativeRect.getWidth();
    down = RelativeRect.getHeight();
 
    // Default Scrollbar Position is on the right   
    m_pScrollbar = Environment->addScrollBar(false,
        irr::core::rect<irr::s32>(right - 10, 0, right, down), this);
        
    m_pDummyText = Environment->addStaticText(L"",
        irr::core::rect<irr::s32>(0, 0, right - 10, down), true,
        true, this);
    m_pStaticText = Environment->addStaticText(L"",
        irr::core::rect<irr::s32>(0, 0, right - 10, down), false,
        true, this);
    m_pStaticText->setOverrideFont(m_pFont);
    m_pStaticText->setOverrideColor(irr::video::SColor(255,255,255,255));
    m_pStaticText->enableOverrideColor(true);
 
    setText(Text.c_str());
    setScrollbarRight(m_bScrollbarRight);
}
 
 
}   // end namespace gui
}   // end namespace irr 
Regards,
Squarefox
Squarefox
Competition winner
Posts: 113
Joined: Tue Aug 19, 2008 6:46 pm
Location: Delta quadrant, Borg nexus 0001
Contact:

Re: Problem with GUIElement OnEvent()

Post by Squarefox »

I did some tests and noticed the following:

When the underlying scrollbar is changed, then the event EGET_SCROLL_BAR_CHANGED is send to the scrollbars parent.
This would be the CGUITextBox.
But instead of calling CGUITextBox::OnEvent, IGUIElement::OnEvent is called, even if this is a virtual function.
The debugger recognizes the parent correctly as CGUITextBox.

Does anyone have a explanation for this behaviour?
Squarefox
Competition winner
Posts: 113
Joined: Tue Aug 19, 2008 6:46 pm
Location: Delta quadrant, Borg nexus 0001
Contact:

Re: Problem with GUIElement OnEvent()

Post by Squarefox »

I found the error:

OnEvent was overloaded wrongly.

OnEvent(SEvent event) was used instead of OnEvent(const SEvent& event).
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Problem with GUIElement OnEvent()

Post by hendu »

Add the override keyword if your compiler is new enough. Would catch that.
ibax
Posts: 193
Joined: Thu Jun 21, 2007 8:56 am
Location: hungary
Contact:

Re: Problem with GUIElement OnEvent()

Post by ibax »

The same is happening with me... But only now...

Until I used the official 1.8 release of Irrlicht, this worked. 2-3 weeks ago I had to change my irrlicht version to rev5800 because of a correction, but now the scrollbar events are not recognized as CGUITextbox events... Basically nothing is happening when I'm using my mouse wheel in a CGUITextbox gui element...

Code: Select all

 
#include "CGUITextBox.h"
 
namespace irr
{
namespace gui
{
CGUITextBox::CGUITextBox(irr::gui::IGUIFont * font, const wchar_t * text, 
                         IGUIEnvironment* environment, core::rect<s32> rectangle,
                         IGUIElement* parent, s32 id)
        : IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle)
{
    m_bScrollModeLines = true;
    m_bScrollbarRight = true;
 
    Text = text;
 
    m_pFont = font;
    
    m_pScrollbar = 0;
    m_pDummyText = 0;
    m_pStaticText = 0;
 
    reset();
}
 
CGUITextBox::~CGUITextBox()
{
} 
 
//! Called if an event happened.
bool CGUITextBox::OnEvent(const SEvent& event)
{
    if (Parent)
        Parent->OnEvent(event);
 
    if(event.EventType == EET_MOUSE_INPUT_EVENT && event.MouseInput.Event == EMIE_MOUSE_WHEEL)
    {
        m_pScrollbar->setPos(m_pScrollbar->getPos() + (s32)event.MouseInput.Wheel*(-10));
        irr::s32 line = m_pScrollbar->getPos();
        setVisibleText(line);
    }
 
    else if(event.EventType == EET_GUI_EVENT && event.GUIEvent.EventType == EGET_SCROLL_BAR_CHANGED)
    {
        IGUIScrollBar * bar = static_cast <irr::gui::IGUIScrollBar *>
            (event.GUIEvent.Caller);
        if(bar == m_pScrollbar)
        {
            irr::s32 line = m_pScrollbar->getPos();
            setVisibleText(line);
        }
    }
 
    return true;
}
 
 

This is how I create my CGUITextbox...

Code: Select all

 
 
    CGUITextBox* DescriptionBox = new CGUITextBox(  environment->getFont ( Ex1_determineFont( screenResX , screenResY , -1 ) ) ,
                                                    L"" , 
                                                    environment , 
                                                    rect<s32>( (int)x1 , (int)y1 , (int)x2 , (int)y2 ) , 
                                                    parentElement , -1 ) ;
    
    DescriptionBox->setScrollbarRight(true);
    DescriptionBox->setScrollModeLines(true);                           // Scroll the text per pixel, not per line.
    DescriptionBox->setVisible(true);
    
 
CuteAlien
Admin
Posts: 9651
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Problem with GUIElement OnEvent()

Post by CuteAlien »

Sorry, I can't help unless I have complete code to compile and reproduce problems.

On first view I only see that you return "true" in OnEvent which is a very bad default. It means you mark all events as handled - even mouse and keyboard events and the engine won't pass them on anymore. Always return false as default in event-handlers and only return true if an event really should no longer be processed.

Beside that - you can set a conditional breakpoint and then step through the code to see what's going on.

This is not related to the problems mentioned in this thread. Your OnEvent already uses the const ref version and that hasn't changed again since 1.8.
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
Post Reply