[Solved] Events with multiple possible sources

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 31
Joined: Wed Feb 03, 2016 21:58

[Solved] Events with multiple possible sources

Postby TheWanderer » Mon Feb 20, 2017 20:27

Hi all,

I had another quick question, this time having to do with events. In this case, I'm working on a game where there are multiple objects on the screen which the user can click on. Doing so open up a "Item Information" window which, among other things, allows the user to tweak that particular item's behavior or properties (e.g. rename it, turn it on, etc). This window is shared across all items and is populated with the information for the particular item that was clicked.

The question is, once a button in the window is pressed, the callback goes to a static function which is not tied to any one item (since the window is really a global construct not tied to any one item), so I would like to pass some metadata to the callback in order to identify the object which the window is representing. Is there such a mechanism?

So far, I've considered using Properties, having an invisible window and set the text to parse in the callback (hacktastic), or some global variable on my side. I just wanted to see whether there were any alternatives before I started going down those routes (which, TBH, I'm not particularly fond of).

Thank you for any help!
Last edited by TheWanderer on Wed Feb 22, 2017 20:55, edited 2 times in total.

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Events with multiple possible sources

Postby Ident » Mon Feb 20, 2017 20:37

Not quite sure I understand you correctly.

Can you show us a stub of the event handler, which would be the static function in your case I think?

Just remove all code you dont want to share for whatever reason. I mostly care about the signature and what data you want there.
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 31
Joined: Wed Feb 03, 2016 21:58

Re: Events with multiple possible sources

Postby TheWanderer » Mon Feb 20, 2017 21:12

Hey, Ident,

A more concrete example. I have two NPC's on the screen, I click one, and a window comes up which allows me to rename it. The callback function for the "Apply" button is part of a Singleton system called the NPCmanager. So I need to determine which NPC was clicked during the callback on in order to rename them. I have this information when the NPC is clicked on.

Code: Select all

bool8_t NPCManager::RenameNPCUICallback( const CEGUI::EventArgs& )
{
    CEGUI::Editbox *nameEditBox = static_cast<CEGUI::Editbox*>( m_uiSheet->getChildRecursive("NPCName_EditBox") );
    std::string newNPCName( nameEditBox->getText().c_str() );

    uint32_t npcId = 0;
    /* Somehow determine which NPC this is supposed to apply to */

    NPCObject *object = GetNPCById( npcId );
    object->setName( newNPCName );

    return true;
}


The other worthwhile piece of code would be:

Code: Select all

bool Game::mouseReleased( const OIS::MouseEvent &arg,
                                     OIS::MouseButtonID buttonId )
{
    if( buttonId == OIS::MB_Left )
    {
        // Determine what was clicked
        NPCObject *clickedNPC = DetermineClickedNPC( arg );
        if( clickedNPC != nullptr)
        {
            CEGUI::Window *renameWindow = m_uiSheet->getChildRecursive("NPCName_Window")
            renameWindow->enable();
            renameWindow->setVisible(true);
      
       /* At this point, I would add some metadata to the window as to identify clickedNPC on the callback */
       clieckedNPC->getObjId();
   }
    }   
   return true;
}


Thanks for the fast response, BTW!

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Events with multiple possible sources

Postby Ident » Tue Feb 21, 2017 08:09

You could always make a custom widget for that:
- derive from the Editbox
- setup your own WidgetLook based on the new editbox
- use that as widget where you now use some editbox widgetlook
- then override the event type and event handler
- add member variables to the new editbox class to store the info you want (and feed it in with setters in your code after you create this for your NPC)
- in the event handler then cast the event to the new derived type and retrieve the info (such as ID) that you need

or, much simpler and imo preferrable to the above lengthy approach:
- make a user-property to the editbox and just set the ID into there

or, this is what i would do (because imo nothing of this has to do with the UI directly so the UI should be unchanged):
- maintain a static container (e.g. map) of Editbox* to SomeDataStruct mappings
- Everytime you add the editbox for an NPC (in that case you should know what NPC ID it is, right?) you add the editbox to that map and setup the data with it
- later in the handler you know what editbox was clicked and you access the map to retrieve your data

or, in case you only ever can have one editbox at a time:
- make a simple cache of the last NPC ID that had an editbox created. If one is clicked it must be that one.
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 31
Joined: Wed Feb 03, 2016 21:58

Re: Events with multiple possible sources

Postby TheWanderer » Tue Feb 21, 2017 20:13

Hey, Ident,

Thanks for all the answers. One follow up:

What's the proper way of programmatically (as opposed to in XML) defining a new Property, one that can be added with addProperty()? Would it be using the TplProperty class? I ask because that class requires getters / setters which are usually defined in the class defining the element itself. I can certainly make global ones, but then I might as well just use those directly. I also ran across the PropertyDefinition class, bu wasn't sure whether I needed to use it.

One thing that I would add to the conversation is that it would be useful if the EventArgs struct (or maybe WindowEventArgs) had a void ptr member to which you could attach some metadata (maybe when setting the callback) which is then delivered to the callback when an event is triggered. I've used this in transactional systems (Databases, WebServices, etc) and it's a pretty handy feature to have. Which already exists in Window::SetUserData( void * ) :oops:. I'll test this real quick, as its probably exactly what I want.

As always, thanks for the help :)

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Events with multiple possible sources

Postby Ident » Wed Feb 22, 2017 20:27

Yea, user-data is what i meant by user-property earlier, I wasnt clear about it. Afaik it is a property in the end.
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 31
Joined: Wed Feb 03, 2016 21:58

Re: [Solved]Events with multiple possible sources

Postby TheWanderer » Wed Feb 22, 2017 20:55

I tested it and it worked like a charm. I appreciate the help, Ident. This has been a most edifying discussion, as knowing this feature will make a lot of other things easier for me to do.

Cheers!


Return to “Help”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 29 guests