GUI bugs after deserialization

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

GUI bugs after deserialization

Post by chronologicaldot »

I've been loading GUI elements using deserializeAttributes() in both irrlicht 1.7 and 1.8. Everything works fine except for the following:

1) Textures do not load for buttons. I've loaded the textures using CAttributes, and I know the path is correct because it is used to display the image elsewhere (and the path for displaying it elsewhere has been taken directly from the CAttribute instance). For some reason, no matter what the given parameters, they don't load for buttons.
For one image (.jpg) irrlicht returns a message that the textures have been re-sized (106x82 -> 64x64,3), but it says it loaded it. I also created a 64x64 image (.bmp) that I've used to test it.
So far, .bmp and .jpg files have been tested.

I'm loading the textures using:

Code: Select all

 
tag->setAttribute( name, irrDev->getVideoDriver()->getTexture( word ) );
 
where "tag" is the CAttributes instance, name is a string, word is a string, and irrDev is obviously the irrlicht device. For every other attribute, the code is identical (with the obvious exception that they don't load textures), so I'm assuming this may be an engine problem.


2) GUI context menus act funny in a way that's hard to pinpoint what the problem is. They load, however, allow me to describe their activity:
Example uses a two-option context menu, the second option being another context menu. The first menu I will call "outer menu" and the second menu I will call "inner menu" for the sake of simplicity. The outer menu is open at all times.

I use the following code to test for highlighting:

Code: Select all

 
using namespace irr;
class SER : public IEventReceiver
{
// constructor... (nothing in there)
//...
// on event:
bool OnEvent( const SEvent& event )
{
if ( event.EventType == EET_GUI_EVENT )
{
gui::IGUIElement* elem = event.GUIEvent.Caller;
 
/* The outer menu has been assigned the ID of 20 and the inner menu has been assigned the ID of 15 */
if ( elem->getID() = 20 || elem->getID() == 15 )
{
cout << "\nMenu(" << elem->getID() << ")";
s32 i = ((gui::IGUIContextMenu*)elem)->getSelectedItem();
cout << "\nButton(" << i << ")";
}
}
}
};
 
Program start:

When the outer menu is scrolled over, nothing happens. It simply recognizes the outer menu has been scrolled over.
Upon clicking the first option, it highlights.
Scrolling over the second option does nothing. The first is still highlighted.
Clicking on the first option allows me to turn the check mark on and off, if I have it on there.
Clicking and dragging from the first option to the second option highlights the second option and de-highlights the first option. The innter menu is now open.
Output:

Code: Select all

 
Menu(20)
Button(0)
 
Releasing the mouse button and scrolling into the inner menu highlights the first option of the inner menu.
Output:

Code: Select all

 
Menu(15)
Button(0)
 
Scrolling down to the inner menu's second option highlights the second option but does not add to the output.
Clicking on the second option gives the output:

Code: Select all

 
Menu(20)
Button(1)
 
Not sure I understand what it's doing.

Scrolling back up to the first option of the inner menu does nothing.
Clicking the first option of the inner menu at this point does nothing.
Clicking and dragging from the inner menu second option to the inner menu first option does nothing.
Clicking on the second option of the outer menu produces the output:

Code: Select all

 
Menu(15)
Button(1)
Menu(15)
Button(1)
Menu(20)
Button(1)
 
And those outputs continue to pop up as I hover the mouse around.

Now: the most peculiar activity:
>> In only the OUTER open context menu does the check-mark ever change, and that's only when the option is selected, which has to be done by clicking and dragging the highlighting from one option to the other. Auto-checking is set to true.
>> Furthermore, regardless of the settings on context menus, the inner context menu doesn't close after you select and option. Yet it does when it's part of a bar menu.
>> In the bar menu, clicking on an item in a sub menu will close the sub menu but not change the check mark (to on or off).
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: GUI bugs after deserialization

Post by CuteAlien »

Please always use examples that are complete, reproduce the bug and which I others can just use and compile. I tried reproducing the first given your description, but image serialization works for me:

Code: Select all

 
#include <irrlicht.h>
#include <iostream>
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
 
 
int main()
{
    video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
    IrrlichtDevice * device = createDevice(driverType, core::dimension2d<u32>(640, 480));
    if (device == 0)
        return 1; // could not create selected driver.
 
    video::IVideoDriver* driver = device->getVideoDriver();
    IGUIEnvironment* env = device->getGUIEnvironment();
    
    s32 top = 50;
    s32 default_height = 100;
    s32 default_width = 180;
    core::rect<s32> rect(10, top, 10 + default_width, top + default_height);
 
    
    IGUIButton * btn = env->addButton (rect, NULL, -1, L"text", L"tooltip");
    btn->setImage( driver->getTexture("../../media/open.png") );
    btn->setScaleImage(true);
    
    env->saveGUI ("wnd_gui.xml");
    env->clear();
    env->loadGUI ("wnd_gui.xml");
 
    while(device->run() && driver)
    {
        if (device->isWindowActive())
        {
            driver->beginScene(true, true, SColor(0,200,200,200));
    
            env->drawAll();
        
            driver->endScene();
        }
    }
 
    device->drop();
 
    return 0;
}
 
I did not try coding the second now. This so much easier for you to create an example than it is for others based on a report. You already have the problem, you notice if it no longer happens when you reduce it to a testcase, you know exactly which lines are needed to reproduce it. For us it means first investing lots of time trying around and in the end we usually can't reproduce it (this happens far more often than being succesful when trying to reproduce bugreports which are incomplete).
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
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: GUI bugs after deserialization

Post by chronologicaldot »

Okay, for the button, I figured out the problem. I didn't realize that you guys have CAttributes return a valid rectangle (albeit one of zero width and height), which was passed to the button via "ImageRect", making the image there... but not there. To fix that, I just added an attribute for ImageRect in my file to be deserialized. ... So there was nothing wrong with anyone's code to begin with, just with the file being used for deserializing attributes.

Sorry about that.

However, I'm still left with the problem of the menus.
I tried writing up an example for you, using the same code you used above but by replacing the line:

Code: Select all

 
IGUIButton * btn = env->addButton (rect, NULL, -1, L"text", L"tooltip");
btn->setImage( driver->getTexture("../../media/open.png") );
btn->setScaleImage(true);
 
with

Code: Select all

 
IGUIContextMenu* menu1 = env->addContextMenu(rect,NULL,-1);
IGUIContextMenu* menu2 = env->addContextMenu(rect,NULL,-1); // second menu (note the name)
 
menu1->addChild(menu2);
 
and it compiles without error, but now it says access violation when it reaches that last line there. I change that line to menu1->setNotClipped(true) but it didn't matter. It's still complaining.

All that to say, when I can get a straightforward, simple example put together for you, hopefully my compiler will stop complaining so I can share the example.
Post Reply