injecting character input

For help with anything that CEGUI doesn't offer straight out-of-the-box, e.g.:
- Implementation of new features, such as new Core classes, widgets, WindowRenderers, etc. ...
- Modification of any existing features for specific purposes
- Integration of CEGUI in new engines or frameworks and writing of new plugins (Renderer, Parser, ...) or modules

Moderators: CEGUI MVP, CEGUI Team

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

injecting character input

Postby granx » Tue Jul 05, 2005 19:54

Hi,
I have a full featured application using CEGUI and Producer. I have the mouse input handled properly, finally, and now I am focusing on correctly implementing the character input. Here is a snapshot of my code, which does work:

Code: Select all

void Injector::keyPress(Producer::KeyCharacter key)
{
   //CEGUI::System::getSingleton().injectKeyDown( static_cast<CEGUI::uint>(key) );
   CEGUI::System::getSingleton().injectChar( static_cast<CEGUI::utf32>( key ) );
}

void Injector::keyRelease(Producer::KeyCharacter key)
{
   //CEGUI::System::getSingleton().injectKeyUp( static_cast<CEGUI::uint>(key) );
   CEGUI::System::getSingleton().injectChar( static_cast<CEGUI::utf32>( key ) );
}


I would prefer to use the commented code. It will compile, but it produces no results. The uncommented code is currently being used and it allows me to edit text fields. Why doesn't the commented one work? BTW, a Producer::KeyCharacter is just a typedef for some ascii code, defined like this excerpt shows:

Code: Select all

enum KeyCharacter
{
    ...
    KeyChar_X                   = 0x058,
    KeyChar_Y                   = 0x059,
    KeyChar_Z                   = 0x05a,
    KeyChar_bracketleft         = 0x05b,
    KeyChar_backslash           = 0x05c,
    KeyChar_bracketright        = 0x05d,
    KeyChar_asciicircum         = 0x05e,
    KeyChar_underscore          = 0x05f,
    KeyChar_grave               = 0x060,
    KeyChar_quoteleft           = 0x060,
    KeyChar_a                   = 0x061,
    KeyChar_b                   = 0x062,
    KeyChar_c                   = 0x063,
    ....
};


Thanks, -granx

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: injecting character input

Postby lindquist » Tue Jul 05, 2005 20:31

key press events should call both injectKeyDown and injectChar.
key release events on the other hand should only call injectKeyUp.

with injectKeyDown/Up you should pass the scancode of the key.
with injectChar you should pass the actual character code.

HTH

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: injecting character input

Postby granx » Thu Jul 07, 2005 23:04

lindquist,
Yeah, that helped, thanks. I understand the intent behind those injections now. However, I am still having some problems. A big problem is that I don't even know what you mean by 'scan code'. Also, I can't get some keys recognized by CEGUI when I press them. For instance, I can highlight some text in a text field, and then I will hit the 'backspace' key, expecting them to erase. This does not work :( . Any ideas? Here is my slightly improved code:

Code: Select all

void Injector::keyPress(Producer::KeyCharacter key)
{
   // try to support some KeyCharacters that are not translating well
   if( key == Producer::Key_BackSpace )
   {
      ///\todo FIX THIS - nothing is making 'backspace' be recognized.
      //CEGUI::System::getSingleton().injectChar( CEGUI::Key::Backspace );   // not a fix :-(
      CEGUI::System::getSingleton().injectKeyDown( 0xFF08 );                 // also, not a fix :-(
   }

   ///\todo use the "scan code" here instead of the KeyCharacter, which unfortunately is the actual character code
   //CEGUI::System::getSingleton().injectKeyDown( static_cast<CEGUI::uint>(key) );
   CEGUI::System::getSingleton().injectChar( static_cast<CEGUI::utf32>( key ) );
}

void Injector::keyRelease(Producer::KeyCharacter key)
{
   ///\todo use the "scan code" here instead of the KeyCharacter, which is the actual character code
   //CEGUI::System::getSingleton().injectKeyUp( static_cast<CEGUI::uint>(key) );
}

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: injecting character input

Postby lindquist » Fri Jul 08, 2005 00:28

Try taking a look at CEGUIInputEvent.h
It lists the key scancodes.

AFAIK the scancode is a hardware identifier for the keys.
Thus fx regular number buttons have different codes than the ones on the numpad.

Unfortunately I don't know Producer, so I really can't say whether it even has the feature.

If all fails, I guess you could set up a map or a switch statement to do the work...

so fx something like this:

Code: Select all

CEGUI::Key::Scan k;
switch(incoming_key)
{
    case Producer::Backspace:
        k = CEGUI::Key::Backspace;
    ...
}
CEGUI::System::getSingleton().injectKeyDown(k);
CEGUI::System::getSingleton().injectChar(incoming_key);


as you can see the CEGUI::Key::Scan enum is scancodes to be passed to injectKeyDown - not injectChar

User avatar
POLSKASH
Not too shy to talk
Not too shy to talk
Posts: 44
Joined: Mon Jun 20, 2005 14:45

Re: injecting character input

Postby POLSKASH » Sat Jul 09, 2005 19:30

I'm working on the key input for the GUI, and I don't think sample code compiles lindquist. Here's what I'm doing, I'm using DirectInput to get my input:

Code: Select all

...
//KEYBOARD INPUT//
char KeyStateBuffer[256];

ReadData(keyboard, (void*)KeyStateBuffer, 256);
   
if(KeyState(DIK_ESCAPE) == TRUE)
{
   CEGUI::Key k;
   k = CEGUI::Key::Escape;
   man->injectKeyPress(k);
}

void cGUIManager::injectKeyPress(const CEGUI::Key key)
{
        CEGUI::System::getSingleton().injectKeyDown(key);
   //CEGUI::System::getSingleton().injectChar(???); Dunno how to get the char code
}


I'm trying to figure out how to set this up. I need a scan code, and if it's a character key, and char code. I'm not sure how get these. The above code produces this error:

c:\Documents and Settings\Owner\Desktop\GUI Manager\main.cpp(224) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'CEGUI::Key::Scan' (or there is no acceptable conversion)
cGUIManager.cpp
c:\Documents and Settings\Owner\Desktop\GUI Manager\cGUIManager.cpp(129) : error C2664: 'CEGUI::System::injectKeyDown' : cannot convert parameter 1 from 'const CEGUI::Key' to 'CEGUI::uint'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: injecting character input

Postby lindquist » Sun Jul 10, 2005 00:11

I updated my post.

Code: Select all

CEGUI::Key
should have been

Code: Select all

CEGUI::Key::Scan


also remember to inject key-release events...

User avatar
POLSKASH
Not too shy to talk
Not too shy to talk
Posts: 44
Joined: Mon Jun 20, 2005 14:45

Re: injecting character input

Postby POLSKASH » Sun Jul 10, 2005 04:03

Here's what I've put together for character input, but I'm not getting results. The problem is somewhere in my use of CEGUI; I already checked the DirectInput and it's working fine.

I'm doing something like this in my input function:

Code: Select all

if(KeyState(DIK_A) == TRUE)//Check directinput buffer
{

   CEGUI::Key::Scan k;
   k = CEGUI::Key::A;
   man->injectKeyPress(k);
}


I have these inject functions:

Code: Select all

void cGUIManager::injectKeyPress(const CEGUI::Key::Scan key)
{
   CEGUI::System::getSingleton().injectKeyDown(key);
   injectChar(static_cast<CEGUI::utf32>(key));
   injectKeyUp(key);
}

void cGUIManager::injectChar(const CEGUI::utf32 charCode)
{
   CEGUI::System::getSingleton().injectChar(charCode);
}

void cGUIManager::injectKeyUp(const CEGUI::Key::Scan key)
{
   CEGUI::System::getSingleton().injectKeyUp(key);
}


Is what I'm doing in the injectKeyPress() function valid? The static_cast<>()? Also, I'm thinking a subsequent call to inject key up would be ok, even if the key is pressed down. Because really, the program will loop back around and detect the key to be pressed down again if the user is holding it down anyway, so it will inject a key press and inject a key up again. If this is flawed thinking, let me know.

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: injecting character input

Postby lindquist » Sun Jul 10, 2005 12:02

injectKeyDown is to be called when the user presses the key down.
injectKeyUp is to be called when the user releases it again.

User avatar
POLSKASH
Not too shy to talk
Not too shy to talk
Posts: 44
Joined: Mon Jun 20, 2005 14:45

Re: injecting character input

Postby POLSKASH » Sun Jul 10, 2005 16:52

Alright, so here's what I'm doing now:

I do this for every key in my input function:

Code: Select all

//Checks a boolean array to see if we have to worry about
//injecting a key up
if(man->alreadyDown(DIK_A)){//the key was pressed on that last iteration
   if(KeyState(DIK_A) == TRUE)//if it's pressed again
   {
      CEGUI::Key::Scan k;
      k = CEGUI::Key::A;
      man->injectKeyPress(k);
   }
   else//not pressed, need to send key up
   {
      CEGUI::Key::Scan k;
      k = CEGUI::Key::A;
      man->injectKeyUp(k);
   }
}
else  //not pressed during last iteration
{
        if(KeyState(DIK_A) == TRUE)//Pressed during this one
   {
      CEGUI::Key::Scan k;
      k = CEGUI::Key::A;
      man->injectKeyPress(k);
      man->setDown(DIK_A);
   }
}


My inject function

Code: Select all

void cGUIManager::injectKeyPress(const CEGUI::Key::Scan key)
{
   CEGUI::System::getSingleton().injectKeyDown(key);
        //I don't think this next line works
   injectChar(static_cast<CEGUI::utf32>(key));
}


I don't think that static_cast is working for me. I'm not even sure if I can do that. I don't know how else to get the character code.

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: injecting character input

Postby lindquist » Sun Jul 10, 2005 17:38

You cannot just cast the scancode to make it a charactercode.

I suggest that you take a look at the sample sources once more. In the directory Samples/common/src check out Win32AppHelper.cpp and CEGuiD3D9BaseApplication.cpp

the character injection is done like this in Win32AppHelper.cpp:

Code: Select all

LRESULT CALLBACK Win32AppHelper::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_CHAR:
        CEGUI::System::getSingleton().injectChar((CEGUI::utf32)wParam);
        break;
    ...
    ...
    ...


as to your keydown injections, there must be an easier way than the one you're useing. As the the value you need to inject exactly matches the keycodes you're getting from DirectInput having hundreds of those if else... statements is not something I would like to do...

User avatar
POLSKASH
Not too shy to talk
Not too shy to talk
Posts: 44
Joined: Mon Jun 20, 2005 14:45

Re: injecting character input

Postby POLSKASH » Sun Jul 10, 2005 20:25

What do you mean the value I need to inject matches the key codes I get from DirectInput? All I get from DirectInput is a 256 char array. I just check the high bit on those to see if the key is pressed. DIK_A is just an enumerated value.

As for the character input, I'm not using Windows Messages to get input, so I don't have a WPARAM to typecast as in that example. There's no samples using DirectInput, so I have no idea of how to get a character code.

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: injecting character input

Postby lindquist » Sun Jul 10, 2005 22:50

The samples uses DirectInput for keyDown injections. Take a look at that. As to the character - this is a forum of CEGUI discussion - not how to use DirectInput. I _don't_ use DirectInput and as such I'm only providing pointers that I hope might give you ideas.

My suggestion is that you get the hang of your tools before you start using them together with other tools.

If the samples and all this talk is'nt enough, well, it's all there is at the moment...

I feel that I'm not able to help you!

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: injecting character input

Postby CrazyEddie » Mon Jul 11, 2005 08:18

The Win32 sample helper class is a good thing to look at if you want to see at least one successful way of injecting inputs to CEGUI.

Generally speaking, for GUI use, you want to be using buffered input from DirectInput for your key up / kwy down injections, otherwise you may end up testing a whole load of buttons in your state array (like 100, or something). Having said that, you only really need to inject scan codes for keys you care about; usually this is the arrow keys, shift, alt, control, backspace, delete, and return.

For character input, you can either use the WM_CHAR message (using DirectInput does not mean you can't use windows messages also). If for some unknown reason this is unacceptable, then you'll need to create your own key translation table and also correctly deal with shift/caps-lock states etc (so you'll be doing your own key-mapping).

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: injecting character input

Postby granx » Thu Jul 14, 2005 19:18

[url=cyrf.com/content/apps/producer_cegui.zip]Producer & CEGUI example[/url]
I fixed my problem - Producer offered a 'specialKeyPress' function that I was not using. Apparently, some keys are "special" :) Anyway, I would be flattered if these files were hosted on the Wiki. I would be happy to document the code there at some point soon. It is pretty straight forward, so it really serves as a good example for CEGUI users that want to learn the basics for rendering in a pretty generic windowing API, Producer. I know there is an example using SDL, but somehow it wasn't enough. Maybe this will help others. OpenGL users will probably like it a lot. :pint:

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: injecting character input

Postby CrazyEddie » Fri Jul 15, 2005 13:29

Yeah, glut thinks certain keys are special too :)

I don't know about hosting files, usually people host these themselves and link to that within the wiki articles. I think if we started hosting files the costs would start to rack up.

Though please do put up any documentation or tutorials you write - we need as much of this kind of thing as we can get :hammer:


Return to “Modifications / Integrations / Customisations”

Who is online

Users browsing this forum: No registered users and 8 guests