Mouse and Keyboard Events
Introduction to events
You can wait for a mouse click, or for a key to be pressed or released (once the keyboard event problem is solved), with these statements:
scene.waitfor('click') Wait for a mouse click.
scene.waitfor('keydown') Wait for a key to be pressed.
scene.waitfor('keyup') Wait for a key to be released.
scene.waitfor('keydown keyup') Wait for a key press or release.
You can also set up a function to be called when a mouse or keyboard event occurs. The following will display the type of event (mouse click or keydown) and, in the case of a keydown event, which key is involved:
def process(event):
print(event.event, event.which)
scene.bind('click keydown', process)
The quantity event.event will be 'keydown' if a key was pressed or 'mousedown' if the left mouse button was pressed. The quantity event.which is the numerical key code or mouse button indicator (mouse button is always 1 for now). For example, event.which is 65 for the 'a' key. The quantity event.key is the corresponding character string, such as 'a' or 'delete'.
The quantity event.canvas is the canvas associated with the event. You can bind events on different canvases to the same function and be able to tell in which canvas the event occurred.
Note that scene.mouse.shift is true if the shift key is down at the time of the keyboard event; similarly for scene.mouse.ctrl and scene.mouse.alt.
In RapydScript it is possible to use "anonymous" (unnamed) functions in this situation. For examples, see the mouse drag discussion.
JavaScript version::
var process = function(event) {
print(event.type, event.which)
}
scene.bind('click keydown', process)
More on mouse events
Mouse objects are obtained from the mouse attribute of a
canvas object such as scene. For example,
to obtain mouse input from the default window created by GlowScript, refer to the object scene.mouse. For specific examples of mouse handling,
see Click example and Drag
example. A mouse object has a group of attributes corresponding to
the current state of the mouse.
The simplest mouse interaction is to wait for a mouse click:
scene.pause() An icon is displayed in the canvas to indicate a pause, waiting for a mouse click.
scene.pause("Click to proceed") The specified text is displayed in the canvas to indicate a pause, waiting for a mouse click.
You can also wait for mouse interactions without displaying a prompt:
scene.waitfor("click") Wait for the mouse button to be depressed and then released
scene.waitfor("mousedown") Wait for the mouse button to be depressed
scene.waitfor("mousemove") Wait for the mouse to move, whether or not the mouse button is depressed
scene.waitfor("mouseup") Wait for the mouse button to be released
scene.waitfor("mouseenter") Wait for the mouse to move, whether or not the mouse button is depressed
scene.waitfor("mouseleave") Wait for the mouse button to be released
Here are waitfor options to wait for canvas updates:
scene.waitfor("redraw") Wait for the start of the next update of the canvas by the web browser
scene.waitfor("draw_complete") Wait for the end of the next update of the canvas by the web browser
It is a useful debugging technique to insert scene.pause() into your program at a point where you would like to stop temporarily to examine
the scene. Then just click to proceed.
Multiple event types: You can wait for more than one type of event. The following statement will wait for either the mouse entering the canvas or leaving the canvas:
scene.waitfor("mouseenter mouseleave")
In the Drag
example you will see how to use event-handling functions to process mouse events continuously.
Current state of mouse and control keys
pos The current 3D position
of the mouse cursor; scene.mouse.pos. GlowScript
always chooses a point in the plane parallel to the screen and passing through canvas.center. (See Projecting
mouse information onto a given plane for other options.)
ray A unit vector pointing
from camera in the direction of the mouse cursor. The points under the mouse
cursor are exactly { scene.camera.pos + t*scene.mouse.ray for t>0}.
project() Projects position
onto a plane. See Projecting mouse position onto a given
plane.
pick() Execute var obj = scene.mouse.pick() to obtain the object pointed to by the mouse. If you have a box named B, you can determine whether the picked object is that box by asking if (B == obj). If there is no object pointed to by the mouse, obj is null. Also, obj will be null if the object has the pickable attribute set to false. For example, the curves, spheres, and arrows created by attach_trail and attach_arrow are not pickable, and you may wish to specify that some of your own objects are not pickable. Label objects are never pickable. For curve objects, obj.segment is the number of the picked segment along the curve, starting with 1 (representing the segment from point number 0 to point number 1). You can test for a curve object with if (obj.constructor == curve). See the GlowScript example MousePicking.
alt The quantity scene.mouse.alt is true if the ALT key
is currently down (Mac Options key), otherwise false
ctrl The quantity scene.mouse.ctrl is true if the CTRL key
is currently down, otherwise false
shift The quantity scene.mouse.shift is true if the SHIFT
key is currently down, otherwise false
Note that if scene.userzoom = true you won't see mouse events with the ALT key down, and if scene.userspin = true you won't see mouse events with the CTRL key down.
Projecting
mouse position onto a given plane
Here is a way to get the mouse position relative to a particular
plane in space:
temp = scene.mouse.project(
normal=vec(0,1,0),
point=vec(0,3,0) )
# null if no intersection with plane:
if temp != null) ball.pos = temp
This projects the mouse cursor onto a plane that is perpendicular
to the specified normal. If the second parameter is not
specified, the plane passes through the origin. It returns a 3D position,
or null if the projection of the mouse misses the plane (scene.mouse.ray is parallel to the plane).
In the example shown above, the user of your program will
be able to use the mouse to place balls in a plane parallel to the xy plane,
a height of 3 above the xy plane, no matter how the user has rotated the point
of view.
You can instead specify a perpendicular distance from the origin to the plane that is perpendicular to the specified normal.
The example above is equivalent to
temp=scene.mouse.project(
normal=vec(0,1,0),
d=3 )
|