Hello everyone,
I am trying to make a simple navigation menu for my application. Simple buttons really. I managed to work out the mouse input events, but I am having a hard time to bind different key events to the buttons. I want to have Arrow Up and Arrow Down button navigation/selection and Enter to confirm, ESC to cancel. I read that there is no keyboard support in CEGUI, or any easy way to have it done, but the posts that i read were from 2 years back. How is it now, what is a suggested way of doing this? I could not find it in any tutorials (they concentrate on mouse input). If it helps, i use CEGUI + OGRE.
Keyboard events
Moderators: CEGUI MVP, CEGUI Team
Keyboard events
Last edited by bogas on Thu Jun 19, 2008 21:42, edited 1 time in total.
it's exactly the same as mouse input, so to speak. You inject your own keyboard events into cegui (http://www.cegui.org.uk/wiki/index.php/The_Beginner_Guide_to_Injecting_Inputs); cegui processes that input, and then sends out the appropriate events to the appropriate window/widget. If you subscribed to those events (http://www.cegui.org.uk/wiki/index.php/FAQ#What_is_the_correct_way_to_subscribe_for_an_event.3F) then cegui will call the function/method you subscribed with. The reason you can't find keyboard specific code is because all input/events are essentially handled the same way. You might also try looking at the API docs, as it provides information regarding the EventArgs object passed to your subscriber (http://www.cegui.org.uk/api_reference/classCEGUI_1_1KeyEventArgs.html).
Ok. I managed to get keyboard input into CEGUI, however my function that subscribes to the EventKeyUp does not allow me to check which key was released/pressed. When I change the function to
instead of
I get an error:
It seems like it cannot have KeyEventArgs as an paramter. I am confused.
This is how I inject the event to CEGUI:
And this is how i subscribe to it:
Code: Select all
bool MainMenuDlg::Window_OnKeyUp(const CEGUI::KeyEventArgs &args)
instead of
Code: Select all
bool MainMenuDlg::Window_OnKeyUp(const CEGUI::EventArgs &args)
I get an error:
Code: Select all
error C2661: 'CEGUI::SubscriberSlot::SubscriberSlot' : no overloaded function takes 2 arguments
It seems like it cannot have KeyEventArgs as an paramter. I am confused.
This is how I inject the event to CEGUI:
Code: Select all
bool InputHandler::keyReleased(const OIS::KeyEvent &evt) {
if (evt.key == OIS::KC_ESCAPE)
m_simulation->requestStateChange(SHUTDOWN);
CEGUI::KeyEventArgs* keyEvent = new CEGUI::KeyEventArgs(CEGUI::WindowManager::getSingleton().getWindow("Main"));
return m_pSystem->injectKeyUp(keyEvent->scancode);
}
And this is how i subscribe to it:
Code: Select all
CEGUI::PushButton* pMainWindow = (CEGUI::PushButton *)CEGUI::WindowManager::getSingleton().getWindow("Main");
pMainWindow->subscribeEvent(CEGUI::PushButton::EventKeyUp, CEGUI::Event::Subscriber(&MainMenuDlg::Window_OnKeyUp, this));
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Hi,
you can cast the CEGUI::EventArgs structure to the 'real' type that the specific handler knows that it will be getting.
For example:
CE
you can cast the CEGUI::EventArgs structure to the 'real' type that the specific handler knows that it will be getting.
For example:
Code: Select all
bool MainMenuDlg::Window_OnKeyUp(const CEGUI::EventArgs &args)
{
const CEGUI::KeyEventArgs& key_args = static_cast<const CEGUI::KeyEventArgs&>{args);
// TODO: Your code here!
}
CE
CE is correct, you just need to cast the EventArg parameter to real type.
As far as your code to inject the keyboard input, it doesn't look like it's actually injecting the input. I can see you are taking a keyboard event from your input handler (OIS::KeyEvent), but you are handling that event inside the cegui->injector function; I suppose this is fine if you want some global-keybinds, but if you are trying to handle window/widget-specific events you should be handling this event in the callback function you defined when you subscribed to the event (in your case, Window_OnKeyUp).
Also, it doesn't appear that you are actually injecting anything into cegui. It looks like you are simply creating a fake keyboard event and injecting that into cegui. Generally you should be injecting the actual keyboard event (evt.key) into cegui; this way you can take advantage of any builtin functionality that cegui has for the different widgets. However, note that you may need to remap some of your keys to cegui keys before injecting them (I believe the Guild to Injecting Inputs describes this). For example:
As far as your code to inject the keyboard input, it doesn't look like it's actually injecting the input. I can see you are taking a keyboard event from your input handler (OIS::KeyEvent), but you are handling that event inside the cegui->injector function; I suppose this is fine if you want some global-keybinds, but if you are trying to handle window/widget-specific events you should be handling this event in the callback function you defined when you subscribed to the event (in your case, Window_OnKeyUp).
Also, it doesn't appear that you are actually injecting anything into cegui. It looks like you are simply creating a fake keyboard event and injecting that into cegui. Generally you should be injecting the actual keyboard event (evt.key) into cegui; this way you can take advantage of any builtin functionality that cegui has for the different widgets. However, note that you may need to remap some of your keys to cegui keys before injecting them (I believe the Guild to Injecting Inputs describes this). For example:
Code: Select all
bool InputHandler::keyReleased(const OIS::KeyEvent &evt) {
return m_pSystem->injectKeyUp(MyKeyToCeKey(evt.key));
}
bool MainMenuDlg::Window_OnKeyUp(const CEGUI::EventArgs &args)
{
const CEGUI::KeyEventArgs& keyEvent = static_cast<const CEGUI::KeyEventArgs&>(args);
if (CEGUI::Key::Escape == keyEvent.scancode)
m_simulation->requestStateChange(SHUTDOWN);
}
Thanks for the help. It did work after changing the code according to your suggestion guys. That is how I do the conversion from OIS to CEGUI:
Is that what you meant Jamarr?
Even though it works now, I am still a little confused. I experimented more and found out that the following code also works fine:
It is basically the same code as for keyPressed() function. This saves the conversion code, but according to the injectChar() description is not correct because it injects characters pressed rather than released. Any comment on that, that would help me better understand this?
Code: Select all
bool InputHandler::keyReleased(const OIS::KeyEvent &evt) {
if (evt.key == OIS::KC_ESCAPE)
{
m_simulation->requestStateChange(SHUTDOWN);
return true;
}
// L stands for nothing, just an experiment
if (evt.key == OIS::KC_L)
return m_pSystem->injectKeyUp(CEGUI::Key::L);
return m_pSystem->injectKeyUp(evt.key);
}
Is that what you meant Jamarr?
Even though it works now, I am still a little confused. I experimented more and found out that the following code also works fine:
Code: Select all
bool InputHandler::keyReleased(const OIS::KeyEvent &evt) {
unsigned int ch = evt.text;
if (evt.key == OIS::KC_ESCAPE)
{
m_simulation->requestStateChange(SHUTDOWN);
return true;
}
//if (evt.key == OIS::KC_L)
// return m_pSystem->injectKeyUp(CEGUI::Key::L);
m_pSystem->injectKeyUp(evt.key);
return m_pSystem->injectChar(ch);
}
It is basically the same code as for keyPressed() function. This saves the conversion code, but according to the injectChar() description is not correct because it injects characters pressed rather than released. Any comment on that, that would help me better understand this?
Is there a particular reason why you decided to use a KeyUp event instead of KeyDown? You can't replicate key holding (key repeat) using the KeyUp events; using KeyDown events seem to be the general standard (at least in my experience).
Anyway, the way I use it is that I only use injectKeyDown()+injectKeyUp() for system-related keybinds (ex: esc, return, F1-F12, tab, backspace, delete, arrow keys, etc. etc.), and for all ascii/character related events I just use injectChar(). It works very well for my setup.
Anyway, the way I use it is that I only use injectKeyDown()+injectKeyUp() for system-related keybinds (ex: esc, return, F1-F12, tab, backspace, delete, arrow keys, etc. etc.), and for all ascii/character related events I just use injectChar(). It works very well for my setup.
Who is online
Users browsing this forum: No registered users and 5 guests