Introduction
Mouse objects are obtained from the mouse attribute of a
display object such as scene. For example,
to obtain mouse input from the default window created by Visual, refer to
scene.mouse. For basic 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. It also has functions getevent()
and getclick(), which return an object with
similar attributes corresponding to the state of the mouse when the user last
did something with the mouse buttons. If the user has not already done something
with the mouse buttons, getevent() and getclick()
will stop program execution until this happens.
Different kinds of mouse
The mouse routines can handle a three-button mouse, with "left",
"right", and "middle" buttons. For systems with a two-button
mouse, the "middle" button consists of the left and right buttons
pressed together. For systems with a one button mouse, the right button is
invoked by holding down the SHIFT key, and the middle button is invoked by
holding down the CTRL key.
Current state of mouse
pos The current 3D position
of the mouse cursor; scene.mouse.pos. Visual
always chooses a point in the plane parallel to the screen and passing through
display.center. (See Projecting
mouse information onto a given plane for other options.)
button = None (no buttons
pressed), 'left', 'right', 'middle', or 'wheel' (scroll wheel pressed on some
Windows mouses). Example: scene.mouse.button == 'left'
is true if the left button is currently down.
pick The nearest object
in the scene which falls under the cursor, or None. At present only spheres,
boxes, cylinders, and convex can be picked. The picked object is scene.mouse.pick.
pickpos The 3D point on
the surface of the picked object which falls under the cursor, or None; scene.mouse.pickpos.
camera The read-only current
position of the camera as positioned by the user, scene.mouse.camera.
For example, mag(scene.mouse.camera-scene.center)
is the distance from the center of the scene to the current position of the
camera. If you want to set the camera position and direction by program, use
scene.forward and scene.center,
described in Controlling Windows.
ray A unit vector pointing
from camera in the direction of the mouse cursor. The points under the mouse
cursor are exactly { camera + t*ray for t>0}.
The camera
and ray attributes together define all of the
3D points under the mouse cursor.
project() Projects position
onto a plane. See Projecting mouse position onto a given
plane.
alt = 1 if the ALT key
is down, otherwise 0
ctrl = 1 if the CTRL key
is down, otherwise 0 (for a one-button mouse, meaningful only if mouse buttons
up)
shift = 1 if the SHIFT
key is down, otherwise 0 (for a one-button mouse, meaningful only if mouse
buttons up)
Note that programs that depend on modifying a mouse event
with CTRL or SHIFT will not work properly with a one-button mouse (e.g. most
Macintosh systems), since CTRL invokes "middle" button, and SHIFT
invokes "right" button.
Getting events
There are four kinds of mouse events: press, click, drag,
and drop:
A press event occurs when a mouse button
is depressed.
A click event occurs when all mouse buttons
are released with no or very slight movement of the mouse.
Note that a click event happens when the mouse button is
released. See Click example.
A drag event occurs when the mouse is moved
slightly after a press event, with mouse buttons still down.
This can be used to signal the beginning of dragging an
object. See Drag example.
A drop event occurs when the mouse buttons
are released after a drag event.
Between a drag event (start of dragging) and a drop event
(end of dragging), there are no mouse events but you can examine the continuously
updated position of the mouse indicated by scene.mouse.pos.
Here is how to tell that an event has happened, and to get information about
that event:
events The number of events
(press, click, drag, or drop) which have been queued; e.g.
scene.mouse.events.
scene.mouse.events = 0 may be used to discard
all input. No value other than zero can be assigned.
getevent() Obtains the
earliest mouse event and removes it from the input queue. If no events are
waiting in the queue (that is, if scene.mouse.events
is zero), getevent() waits until the user enters
a mouse event (press, click, drag, or drop). getevent()
returns an object with attributes similar to a mouse object: pos,
button, pick, pickpos,
camera, ray,
project(), alt,
ctrl, and shift.
These attributes correspond to the state of the mouse when the event took
place. For example, after executing mm = scene.mouse.getevent()
you can look at the various properties of this event, such as mm.pos,
mm.pick, mm.drag
(see below), etc.
If you are interested in every type of event (press, click,
drag, and drop), you must use events and getevent().
If you are only interested in left click events (left button down and up without
significant mouse movement), you can use clicked
and getclick():
clicked The number of left
clicks which have been queued; e.g. scene.mouse.clicked.
This does not include a count of nonclick events (press, drag, or drop).
getclick() Obtains the
earliest mouse left click event (pressing the left button and releasing it
in nearly the same position) and removes it from the input queue, discarding
any earlier press, drag, or drop events. If no clicks are waiting in the queue
(that is, if scene.mouse.clicked is zero),
getclick() waits until the user clicks. Otherwise
getclick() is just like getevent().
It is a useful debugging technique to insert scene.mouse.getclick()
into your program at a point where you would like to stop temporarily to examine
the scene. Then just click to proceed.
Additional information obtained with
getevent() or getclick()
In addition to the information available with scene.mouse,
getevent() and getclick()
furnish this additional information:
press = 'left' or 'right'
or 'middle' for a press event, or None
click = 'left' or 'right'
or 'middle' for a click event, or None; in this case pos
and other attributes correspond to the state
of the mouse at the time of the original press event, so as not to lose initial
position information. See Click example.
drag = 'left' or 'right'
or 'middle' for a drag event, or None; in this case pos
and other attributes correspond to the state
of the mouse at the time of the original press event, so as not to lose initial
position information. See Drag example.
drop = 'left' or 'right'
or 'middle' for a drop event, or None
release = 'left' or 'right'
or 'middle' following click and drop events, indicating which button was released,
or None
Normally, dragging with right or middle button represents
spin or zoom, and is handled automatically by Visual, so you can check for
left-button drag or drop events simply by checking whether drag
or drop is true (in Python, a nonempty string
such as 'left' is true, None is false). Unless you disable user zoom (scene.userzoom
= 0), click, drag,
and drop with the middle button are invisible
to your program. Unless you disable user spin (scene.userspin
= 0), click, drag,
and drop with the right button are invisible
to your program.
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=(0,1,0), point=(0,3,0))
if temp: # temp is None if no intersection with plane
ball.pos = temp
This projects the mouse cursor onto a plane that is perpendicular
to the specified normal. If point is not
specified, the plane passes through the origin. It returns a 3D position,
or None if the projection of the mouse misses 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 d
from the origin to the plane that is perpendicular to the specified normal.
The example above is equivalent to
temp = scene.mouse.project(normal=(0,1,0), d=3)