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!
[Solved] Events with multiple possible sources
Moderators: CEGUI MVP, CEGUI Team
-
- Not too shy to talk
- Posts: 31
- Joined: Wed Feb 03, 2016 21:58
[Solved] Events with multiple possible sources
Last edited by TheWanderer on Wed Feb 22, 2017 20:55, edited 2 times in total.
Re: Events with multiple possible sources
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.
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"
-
- Not too shy to talk
- Posts: 31
- Joined: Wed Feb 03, 2016 21:58
Re: Events with multiple possible sources
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.
The other worthwhile piece of code would be:
Thanks for the fast response, BTW!
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!
Re: Events with multiple possible sources
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.
- 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"
-
- Not too shy to talk
- Posts: 31
- Joined: Wed Feb 03, 2016 21:58
Re: Events with multiple possible sources
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 * )
. I'll test this real quick, as its probably exactly what I want.
As always, thanks for the help![Smile :)](./images/smilies/icon_smile.gif)
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 * )
![Embarassed :oops:](./images/smilies/icon_redface.gif)
As always, thanks for the help
![Smile :)](./images/smilies/icon_smile.gif)
Re: Events with multiple possible sources
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"
-
- Not too shy to talk
- Posts: 31
- Joined: Wed Feb 03, 2016 21:58
Re: [Solved]Events with multiple possible sources
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!
Cheers!
Who is online
Users browsing this forum: No registered users and 20 guests