Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   catch arrow keys (http://www.velocityreviews.com/forums/t897404-catch-arrow-keys.html)

Michael Goerz 04-10-2006 08:23 PM

catch arrow keys
 
Hi, how can I catch if someone presses the Arrow-Keys (Up, Down, Left,
Right) on the keyboard? I tried

use Term::ReadKey;
while (not defined ($pressedkey = ReadKey(-1))) {
# No key yet
}
printf(" Decimal: %d\tHex: %x\n", ord($pressedkey),
ord($pressedkey));

but that only return the escape-symbol (27) for each of the arrow-keys.
I need to react on which key was pressed.

Thanks,
Michael Goerz

xhoster@gmail.com 04-10-2006 08:26 PM

Re: catch arrow keys
 
Michael Goerz <news3@8439.e4ward.com> wrote:
> Hi, how can I catch if someone presses the Arrow-Keys (Up, Down, Left,
> Right) on the keyboard? I tried
>
> use Term::ReadKey;
> while (not defined ($pressedkey = ReadKey(-1))) {
> # No key yet
> }


Isn't that pretty silly? You go out of your way to do a nonblocking
read, only to put it into a busy-wait loop which emulates blocking in
a very inefficient way.

$pressedkey = ReadKey();


> printf(" Decimal: %d\tHex: %x\n", ord($pressedkey),
> ord($pressedkey));
>
> but that only return the escape-symbol (27) for each of the arrow-keys.
> I need to react on which key was pressed.


Control keys return multiple bytes per key-press. Once you see the 27, you
need to call ReadKey some more to get the rest of them.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB

jl_post@hotmail.com 04-10-2006 08:48 PM

Re: catch arrow keys
 
Michael Goerz wrote:
> Hi, how can I catch if someone presses the Arrow-Keys (Up, Down, Left,
> Right) on the keyboard? I tried
>
> use Term::ReadKey;
> while (not defined ($pressedkey = ReadKey(-1))) {
> # No key yet
> }
> printf(" Decimal: %d\tHex: %x\n", ord($pressedkey),
> ord($pressedkey));
>
> but that only return the escape-symbol (27) for each of the arrow-keys.
> I need to react on which key was pressed.



Dear Michael,

You might want to try reading the next two keys to see which
direction was pressed. If you get "[A", then that means UP was
pressed. "[B" means DOWN was pressed, "[C" means RIGHT was pressed,
and "[D" means LEFT was pressed.

Therefore, try this modification to your script:


use Term::ReadKey;
ReadMode 4; # Turn off controls keys
while (not defined ($key = ReadKey(-1))) {
# No key yet
}
if (ord($key) != 27) {
print "Got key $key\n";
} elsif ($key = ReadKey(-1) and $key ne '[') {
print "Not sure what I have...\n"
} else {
$key = ReadKey(-1);
if ($key eq 'A') { print "UP pressed.\n" }
elsif ($key eq 'B') { print "DOWN pressed.\n" }
elsif ($key eq 'C') { print "RIGHT pressed.\n" }
elsif ($key eq 'D') { print "LEFT pressed.\n" }
else { print "Not sure what I have...\n" }
}
ReadMode 0; # Reset tty mode before exiting


Just a warning: I don't know how portable this solution is, so
don't expect it to work on all platforms (like Win32).

I hope this helps, Michael.

-- Jean-Luc


jl_post@hotmail.com 04-10-2006 08:54 PM

Re: catch arrow keys
 
> Michael Goerz <news3@8439.e4ward.com> wrote:
> >
> > use Term::ReadKey;
> > while (not defined ($pressedkey = ReadKey(-1))) {
> > # No key yet
> > }



xhoster@gmail.com replied:
>
> Isn't that pretty silly? You go out of your way to do a nonblocking
> read, only to put it into a busy-wait loop which emulates blocking in
> a very inefficient way.



Actually, he got that code straight from "perldoc Term::ReadKey".
(But I don't disagree with you that that code could be written better.)

-- Jean-Luc


Michael Goerz 04-10-2006 08:57 PM

Re: catch arrow keys
 
xhoster@gmail.com wrote:
>> Hi, how can I catch if someone presses the Arrow-Keys (Up, Down, Left,
>> use Term::ReadKey;
>> while (not defined ($pressedkey = ReadKey(-1))) {
>> # No key yet
>> }

>
> Isn't that pretty silly? You go out of your way to do a nonblocking
> read, only to put it into a busy-wait loop which emulates blocking in
> a very inefficient way.
>
> $pressedkey = ReadKey();

Then I have to press Enter after each "keystroke". The code I used
before was actually taken from
http://search.cpan.org/~jstowe/TermR....30/ReadKey.pm

> Control keys return multiple bytes per key-press. Once you see the 27, you
> need to call ReadKey some more to get the rest of them.

Yes, that appears to work. Thanks a lot!

Michael

Michael Goerz 04-10-2006 09:08 PM

Re: catch arrow keys
 
jl_post@hotmail.com wrote:
> use Term::ReadKey;
> ReadMode 4; # Turn off controls keys
> while (not defined ($key = ReadKey(-1))) {
> # No key yet
> }
> if (ord($key) != 27) {
> print "Got key $key\n";
> } elsif ($key = ReadKey(-1) and $key ne '[') {
> print "Not sure what I have...\n"
> } else {
> $key = ReadKey(-1);
> if ($key eq 'A') { print "UP pressed.\n" }
> elsif ($key eq 'B') { print "DOWN pressed.\n" }
> elsif ($key eq 'C') { print "RIGHT pressed.\n" }
> elsif ($key eq 'D') { print "LEFT pressed.\n" }
> else { print "Not sure what I have...\n" }
> }
> ReadMode 0; # Reset tty mode before exiting
>
>
> Just a warning: I don't know how portable this solution is, so
> don't expect it to work on all platforms (like Win32).
>
> I hope this helps, Michael.
>
> -- Jean-Luc

That's perfect! Thank you!

Michael

Michael Goerz 04-10-2006 09:11 PM

Re: catch arrow keys
 
jl_post@hotmail.com wrote:
>> Michael Goerz <news3@8439.e4ward.com> wrote:
>>> use Term::ReadKey;
>>> while (not defined ($pressedkey = ReadKey(-1))) {
>>> # No key yet
>>> }

>
>
> xhoster@gmail.com replied:
>> Isn't that pretty silly? You go out of your way to do a nonblocking
>> read, only to put it into a busy-wait loop which emulates blocking in
>> a very inefficient way.

>
>
> Actually, he got that code straight from "perldoc Term::ReadKey".
> (But I don't disagree with you that that code could be written better.)
>
> -- Jean-Luc
>


What would be more efficient code, if I don't want to have to press
Enter after each keystroke? In fact, the tight loop bothers me somewhat.

Michael

jl_post@hotmail.com 04-10-2006 10:21 PM

Re: catch arrow keys
 
Michael Goerz wrote:
> >>> use Term::ReadKey;
> >>> while (not defined ($pressedkey = ReadKey(-1))) {
> >>> # No key yet
> >>> }

>
> What would be more efficient code, if I don't want to have to press
> Enter after each keystroke? In fact, the tight loop bothers me somewhat.



Basically, the purpose of the while-loop is to wait until a key has
been read in. If no key was read in, the while-block gets executed.
In the above example, the block does absolutely nothing. (Sometimes
you may want something to happen if no was pressed, which is why I
think the example was written like this.)

However, if all you want to do is wait until the first key is
pressed, you basically want to perform a "blocking" read (as opposed to
a "non-blocking" read). The "ReadKey(-1)" performs a "non-blocking"
read; to do a "blocking" read, you want to pass in a zero for
ReadKey()'s argument.

Therefore, I would recommend changing the above while-loop to the
following one line of code:

$pressedkey = ReadKey(0); # Note: no loop!

This will prevent the program from advancing any further until a key is
pressed.

By the way, did you know that you can get comprehensive
documentation for a module by using the perldocs? That is, you can
read the documentation for Term::ReadKey by typing the following at any
Unix prompt:

perldoc Term::ReadKey

The reason I ask this is because, in a previous post, you mentioned
that you found the Term::ReadKey documentation online. (I once knew a
programmer who'd been programming Perl for several years who wasn't
aware that he could look up the documentation for any module just by
typing "perldoc ModuleName" at a Unix prompt. Instead of using
documentation he already had, he had to scour the web to find it!)

(And sometimes the programmers who already know about the perldocs
don't realize that there are a lot of other programmers who don't know
about them, so the ones who don't know about the usefulness of the
perldocs continue to be left in the dark about them.)

Anyway, I hope this helps you, Michael.

-- Jean-Luc


Michael Goerz 04-10-2006 11:04 PM

Re: catch arrow keys
 
jl_post@hotmail.com wrote:
> Therefore, I would recommend changing the above while-loop to the
> following one line of code:
>
> $pressedkey = ReadKey(0); # Note: no loop!
>
> This will prevent the program from advancing any further until a key is
> pressed.

Wow, yes... that's exactly what I was looking for. Should have read the
docs more carefully.

> By the way, did you know that you can get comprehensive
> documentation for a module by using the perldocs? That is, you can
> read the documentation for Term::ReadKey by typing the following at any
> Unix prompt:
>
> perldoc Term::ReadKey

Yes, I know, but usually I prefer the online documentation, because of
its very readable formatting (syntax highlighting) and because it's
easier to browse around

> Anyway, I hope this helps you, Michael.

That did help a lot! Thanks again.

Michael

xhoster@gmail.com 04-11-2006 12:09 AM

Re: catch arrow keys
 
Michael Goerz <news3@8439.e4ward.com> wrote:
> xhoster@gmail.com wrote:
> >> Hi, how can I catch if someone presses the Arrow-Keys (Up, Down, Left,
> >> use Term::ReadKey;
> >> while (not defined ($pressedkey = ReadKey(-1))) {
> >> # No key yet
> >> }

> >
> > Isn't that pretty silly? You go out of your way to do a nonblocking
> > read, only to put it into a busy-wait loop which emulates blocking in
> > a very inefficient way.
> >
> > $pressedkey = ReadKey();


> Then I have to press Enter after each "keystroke".


In your original code, exactly as you posted it, you need to press Enter,
too. I suspect this is because the code you posted is not the real code
you are running, but rather your real code has "ReadMode 4;" in it.

If you don't include the "ReadMode 4;", then you have to press Enter
either way. If you do include the "ReadMode 4;", then you don't need
to press Enter, either way. It isn't about the ReadKey, it is about the
ReadMode


> The code I used before was actually taken from
> http://search.cpan.org/~jstowe/TermR....30/ReadKey.pm


Yep, but that example is expecting you to replace the "# No key yet" line
with something meaningful. If you leave it as is, then you are better
off using the blocking ReadKey.

Cheers,

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB


All times are GMT. The time now is 07:39 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.