on_key_press not called when there's a textbox active

Started by thezombiecow, Sun 10/05/2009 18:10:30

Previous topic - Next topic

thezombiecow

I'd like a sound effect to play whenever the player pressed a key into a textbox.

It seems on_key_press doesn't get called if there's a textbox active, so that's out. What I need is the equivalent to:

if (IsKeyPressed(eKeyANY))
{
PlaySound(42);
}

...except eKeyANY doesn't exist... Is there a sensible way of doing that??

cheers,

d

Trent R

What happens when you set the Enabled or Clickable properties of the textbox? Granted, those deal with mouse clicks....


~Trent
To give back to the AGS community, I can get you free, full versions of commercial software. Recently, Paint Shop Pro X, and eXPert PDF Pro 6. Please PM me for details.


Current Project: The Wanderer
On Hold: Hero of the Rune

Akatosh

I'm not sure if this is the most effective way of doing it, but a while loop should at least work. As in,

Code: ags

int i=0;
while (i<=90) {
if (IsKeyPressed(i)) {PlaySound(42); i=90;}
i++;}


/EDIT: If you're using some sort of custom GUI for this, though, you can always just set "Visibility" to "Normal, initially off" instead of "Pause game when shown".

Sephiroth

#3
on_key_press will be called whenever a key is pressed so you could just use this:

Code: ags

function on_key_press()
{

 if( MyTextBoxGUI.Visible == true )
 {
   PlaySound(2);
 }

}
 


I think if you put it outside of the IsGamePaused() check it *should* work. You could check if the gui is visible and if the focus is on the textbox but I don't know the function, I can edit later if you need. Would that solve the problem?

Edit: I checked and as long as you didn't use "Pause game when shown" option in the Gui properties it should be ok.

thezombiecow

#4
Quoteon_key_press will be called whenever a key is pressed

on_key_press doesn't get called if there's a text box active, so that code won't work. You can pop whatever you like in there, and if the text box is active it won't get called. :(

Quote from: Akatosh on Sun 10/05/2009 18:20:38
I'm not sure if this is the most effective way of doing it, but a while loop should at least work. As in,

Code: ags

int i=0;
while (i<=90) {
if (IsKeyPressed(i)) {PlaySound(42); i=90;}
i++;}


Yeah, my current work-around is similar to that:

Code: ags

function repeatedly_execute_always()
{
	int i = 0;
	while (i < 200) // 200 is temp... will work it to whatever this eventually needs to be ;)
	{
		if (IsKeyPressed(i)) {InputBox01.Enabled = false;}
		i++;
	}
}

function on_key_press(int keycode)
{
	PlaySound(105);
        InputBox01.Enabled = true;
}


Unfortunately InputBox01.Enabled doens't get reset in time to read in the key press, so the sound plays perfectly, but the box won't update with the added char.

EDIT: I'm still looking into this, but it seems on_key_press is being picky. If I use this as a tester:

Code: ags

function repeatedly_execute_always()
{
	int i = 0;
	while (i < 200)
	{
		if (IsKeyPressed(i)) { InputBox01.X++;}
		i++;
	}
}

function on_key_press(int keycode)
{
	PlaySound(105);
	InputBox01.X = 0;
}


... the InputBox moves off to the right as expected, but doens't ever get reset to 0... hang on, still looking into it ;)

Akatosh

Well, the key press is already processed by the time the box is re-enabled. Does the code I posted work (if you put it into repeatedly_execute_always)?

Sephiroth

#6
Strange, I can get a GUI with a textbox, type some text into it and when I press the "a" key it prints "a" in the textbox and plays a sound (same goes for every letter with the example code I tried). A basic example I just made could confirm this. Unless I misread something :p

thezombiecow

Quote from: Akatosh on Sun 10/05/2009 18:43:57
Well, the key press is already processed by the time the box is re-enabled. Does the code I posted work (if you put it into repeatedly_execute_always)?

Aaah, I see. Yes, but it lacks the elgance of an on_key_press. I'd still need an IsKeyPressed(null) equivalent to reset a 'play a sound' bool...

QuoteStrange, I can get a GUI with a textbox, type some text into it and when I press the "a" key it prints "a" in the textbox and plays a sound.

Weird. Maybe it is something I've set this end, then...

Akatosh

Quote from: thezombiecow on Sun 10/05/2009 18:51:56
I'd still need an IsKeyPressed(null) equivalent to reset a 'play a sound' bool...

Code: ags

bool any_key_pressed=true;
int i=0;
while ((i<=90)&&(any_key_pressed==true)) {
if (IsKeyPressed(i)) any_key_pressed=false;
i++;}


Again, untested, but should work. About the other thing: are you using a custom GUI for this, or Game.InputBox?


Sephiroth

Last advice if I can be useful for once ;)

Create a new script, you'll get two files, copy the following code to the .asc file:

Code: ags

function on_key_press(int keycode)
{

 if( Gui1.Visible == true )
 {
  PlaySound(1);
 }

}


Just replace Gui1 with the real name of your gui and please tell me if it works, because it does with me.

thezombiecow

Quote from: Sephiroth on Sun 10/05/2009 19:07:25
Last advice if I can be useful for once ;)

Create a new script, you'll get two files, copy the following code to the .asc file:

Code: ags

function on_key_press(int keycode)
{

 if( Gui1.Visible == true )
 {
  PlaySound(1);
 }

}


Just replace Gui1 with the real name of your gui and please tell me if it works, because it does with me.

Nope, sorry, not a peep. :)

Sephiroth

#12
Alright I just realised what was wrong and found a workaround:

1- Create a Global String called OldText.

2- Add this in the GlobalScript (just replace YourGui with the gui name, textbox_id with the ID property of the textbox, and the sound number) :

Code: ags

function repeatedly_execute()
{

  if(YourGui.Visible == true && YourGui.Controls[textbox_id].AsTextBox.Text != OldText)
  {
   PlaySound(2);
   OldText = YourGui.Controls[textbox_id].AsTextBox.Text;
  }

}


This is like a OnTextBoxChange custom event.
I give you a cookie if it doesn't work this time :D

thezombiecow

What a frightfully clever workaround!

Big chocolate cookie for you, it works a treat! Thanks muchly ;)

Sephiroth

#14
You're most welcome, I'm glad I could help :)

I guess AGS textboxes are using their own custom on_key_press event, it seems logical because you'd have to print the letters inside the box and filter them by yourself otherwise. What's strange is that it will disable all other on_key_press hooks. I wonder if we can get access to this hidden textbox "keyboard hook" function, maybe in later versions of the Editor, anyways I wish you luck on your project.

Ahhh cookiiie! *crunch*  :D

Edit: Ah well, it could be optimised if you used a global INT called OldLength, change YourTextBox to the ScriptName property of the textbox and then:

Code: ags

function repeatedly_execute()
{

  if(YourGui.Visible == true && YourTextBox.Text.Length != OldLength)
  {
   PlaySound(2);
   OldLength = YourTextBox.Text.Length;
  }

}


Since comparing long strings in the repeatedly execute might waste some resources for no purpose. (edited the syntax)

Pumaman

Quote from: Sephiroth on Mon 11/05/2009 12:08:04
I guess AGS textboxes are using their own custom on_key_press event, it seems logical because you'd have to print the letters inside the box and filter them by yourself otherwise. What's strange is that it will disable all other on_key_press hooks.

Yes, if there is an enabled text box on a visible GUI, it will intercept key presses and handle them itself. Any key presses that the text box does not handle (eg. the Up Arrow Key) should still be passed on to on_key_press.

Quote
function repeatedly_execute()
  if(YourGui.Visible == true && YourGui.Controls[textbox_id].AsTextBox.Text.Length != OldLength)
  {
   PlaySound(2);
   OldLength = YourGui.Controls[textbox_id].AsTextBox.Text.Length;
  }

Please, set a script name on the text box, it vastly simplifies the code!

  if(YourGui.Visible == true && txtMyTextBox.Text.Length != OldLength)
  {
   PlaySound(2);
   OldLength = txtMyTextBox.Text.Length;
  }

SMF spam blocked by CleanTalk