Page 1 of 1

Some GUI Events not being consumed

Posted: Thu Feb 16, 2006 16:58
by davesh
I have keyPressed and keyReleased methods defined.
Within keyPressed I execute:

bool rtn1 = CEGUI::System::getSingleton().injectKeyDown(e->getKey());
bool rtn2 =CEGUI::System::getSingleton().injectChar(e->getKeyChar());

Within keyReleased I execute

bool rtn = CEGUI::System::getSingleton().injectKeyUp(e->getKey());


Though I'm typing into a text widget (and the text is appearing correctly within it) neither rtn1 (in pressed) nor rtn (in released) return a true indicating that CEGUI has consumed the event.

Only rtn2 is true as one would expect. Currently this means that I'm unable to detect a release and the end result is that the "release event" leaks through to the background (non-CEGUI) event handler.

Can someone please help me to understand this?

Thanks.

Posted: Thu Feb 16, 2006 19:49
by CrazyEddie
Only a handful of keys are handled by the Editbox / text widget via the key down event (the arrow movement keys for example), everything else is handled via the 'char' based event. The key up events are not used at all in this widget. Anyway, that's the reason they're not marked as consumed.

For your issue, one possible solution would be to check if the text box widget is actively accepting input. You might do this using the member:

Code: Select all

bool Editbox::hasInputFocus(void);


if the editbox has focus, make sure that you do not pass your key inputs beyond CEGUI.

HTH

CE.

Posted: Fri Feb 17, 2006 02:44
by davesh
Thanks for the clarification... sounds like the "focus check" should do it for me.

I'll try it in the morn!!
:)

Posted: Thu Mar 02, 2006 21:19
by davesh
Ok.

Its been a week or so... but I'm back to this. Your suggestion that I use hasInputFocus() worked just fine.

This question is more of a software architectural question. In my original test application I had one window with a couple of text widgets. For this case it was a relatively simple matter to capture the keyboard event and then to test a couple of CEGUI::Editbox's to see if they had input focus and then to process the event accordingly. Now in a real application I will have several windows and many widgets within each. I want to ensure that I handle events in such a fashion that I am only performing the hasInputFocus check for those widgets that are in the window that is currently active.


If I have dozens of windows and hundreds of Editboxes in my application but only one editbox on the currently exposed (active) window then I should be able to test only the editbox for the window that is currently active. How does this work in CEGUI can I define an event callback at the window level? If not can I loop through each base window and determine which window is "active" and then for that window check those editboxes within it to see if they have inputFocus? Ideally I can register a unique callback (using subscribeEvent) for each window within my application and test only those widgets that are part of that window.



Thanks in advance.

Posted: Fri Mar 03, 2006 12:07
by davesh
This question is more of a software architectural question. In my original test application I had one window with a couple of text widgets. For this case it was a relatively simple matter to capture the keyboard event and then to test a couple of CEGUI::Editbox's to see if they had input focus and then to process the event accordingly. Now in a real application I will have several windows and many widgets within each. I want to ensure that I handle events in such a fashion that I am only performing the hasInputFocus check for those widgets that are in the window that is currently active.

If I have dozens of windows and hundreds of Editboxes in my application but only one editbox on the currently exposed (active) window then I should be able to test only the editbox for the window that is currently active. How does this work in CEGUI can I define an event callback at the window level? If not can I loop through each base window and determine which window is "active" and then for that window check those editboxes within it to see if they have inputFocus? Ideally I can register a unique callback (using subscribeEvent) for each window within my application and test only those widgets that are part of that window.


I'm not actually suggesting that my application will have hundreds of Editboxes. :D

I'm just highlighting the fact that I don't want to have to check all of them if there is a simple way to determine that the keyboard event can be reduced to one of several editboxes (those on the "active window").

To the extent that you can post a code snippet that illustrates a recommended mechanism to handle events from multiple windows then I'd appreciate this. I have, btw, looked at each of the demos, none of these seem to do what I am referring to... perhaps I missed something. If so please just point me to the demo that might "properly" handle events occuring on multiple widgets in multiple windows.

Thanks again. :shock:

Posted: Sun Mar 05, 2006 16:17
by CrazyEddie
Hi,

the Window::getActiveChild member will return the window that generally has input focus. The Editbox is a 'special case' widget in that it can be the active child but not actually be actively accepting keyboard input (which is why it has the test member for this).

So, you might do something like this:

Code: Select all

CEGUI::Editbox* getActiveEditbox()
{
   using namespace CEGUI;

   Window* root = System::getSingleton().getGUISheet();
   
   if (root)
   {
      Window* activeChild = root->getActiveChild();
      
      if ((activeChild != 0) &&
         activeChild->testClassName("Editbox") &&
         static_cast<Editbox*>(activeChild)->hasInputFocus())
      {
         return static_cast<Editbox*>(activeChild);
      }
   }

   return 0;
}

This should return a ptr to an Editbox widget that's active and accepting key input, or 0 otherwise.

HTH

CE.