Squeak
  links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
Keyboard support in Etoys
Last updated at 11:41 am UTC on 28 August 2010
This page applies to versions 3.8g and 3.9.

Stefan Matthias Aust asked in December 2004 on the squeak-dev list:

Q: On the german list the question came up about etoys and keyboard support.
Is it possible to e.g. control the car with the keyboard?
I searched the list, and in 2002 Karl Ramberg posted an enhancement (etoy keystroke.5.cs).
Has this (or something similar) been added to etoys in the meantime?


How to save a part bin replied: that he jsut made a project that shows just that. You can get
it at: http://bike-nomad.com/squeak/DriveUsingKeyboard.002.pr

Before loading it make sure you have the keystroke fix loaded first. If you use a Squeakland version of Squeak than just load it from the update stream ("get updates"). It is the update 0377enableKeystrokeEvent.
( http://squeakland.org/updates/0377enableKeystrokeEvent-nk.cs )

If you are using the developer version you can also get it at: http://squeakalpha.org/updates/0377enableKeystrokeEvent-nk.cs.

Ned mentioned in additon that he has added a simple (keystroke based) support for keys to the current Squeakland image, and has posted a fix CS to the Squeak-dev list that makes
the (existing) support work with the current version work with Squeak 3.8.

Here is an excerpt from a message that he posted to the Squeakland list on 13 December 2004.
http://lists.squeakfoundation.org/pipermail/squeak-dev/2004-December/086791.html
(He also posted a similar one to Squeak-dev on the 14th).



There are two parts to the keyboard support:

The World has a String-valued property called lastKeystroke


This is a string that holds the keystroke, in a form that can be used in string comparisons, like:
'a'
'<left>'
'<Ctrl-left>'
'A'
'<Shift-left>'

So you can have a ticking script (for instance) testing the lastKeystroke property.
But you may very well miss one, unless you use the other part:

You can trigger a script that is owned by the World on a 'keyStroke' event.


You do this by clicking on the 'when this script should run' button, and choosing 'more...' and then 'keyStroke'.

Note that this does not do keyUp/keyDown events, just keystrokes.
So if you want to, say, have the rocket thrusting while a key is down, that's not currently supported.

What I had intended to do is to provide a KeyMorph and perhaps also a KeyboardMorph that could provide this kind of support.
The keystroke support that I added recently is much more modest, and doesn't suffer from the problems of different keyboard maps.

The problem is that the keyDown/keyUp events are not associated with any meaning when they come in.
So depending on what keyboard you have, several different physical keys (and hence keycodes) may generate, say, the "1" keystroke.
And this will differ by physical keyboard, operating system, etc.

When we get a keyUp event, we also ask the operating system how to interpret that key code number as a keystroke.
But until that time we just know the number.

I couldn't think of an easy way to deal with this problem in a cross-platform way, and I didn't want to make it so that people could make projects that couldn't easily be shared between different computers.

I am open to suggestions as to how to fix this. One idea I had was to learn the relationship: upon loading a project that uses particular keys, the KeyMorphs wouldn't know what numeric keycodes they needed to respond to. But they would know the keyStroke (like <left>).
By watching all the keyUp/keyDown/keyStroke events (assuming the user is just pressing one key at once, and there are no combining or modifier keys also being used), we can see the correspondence between the keyUp events and the keyStroke events that follow.

Perhaps the KeyMorphs, upon being loaded or created, would prompt the user to press the given key so they could learn.
Perhaps they could just not respond until the second press of their given key.

As I noted above, this is complicated by: