events and interaction
In a modern interface like that of the Mac or Windows OS, the components of the interface respond to different sorts of events. When the mouse moves, that is an event. When a key is pressed, that is another kind of event. When a window is brought to the front, that is yet another kind of event. As programmers, we can make use of those events to interact with our applications.
We will look at how Processing handles mouse and keyboard events.
mouse events
The mouse is an object with properties and events. Its properties are:
- mouseX :: x position of the mouse
- mouseY :: y position of the mouse
- pmouseX :: previous x position of the mouse
- pmouseY :: previous y position of the mouse
- mousePressed :: true if the (left) mouse button is pressed, false otherwise
Its events are:
- mousePressed() :: triggered when the mouse button is pressed
- mouseReleased() :: triggered when the mouse button is released
- mouseMoved() :: triggered when the mouse is moved
- mouseDragged() :: triggered when the mouse is dragged
mouseX and mouseY
Let's write an extension of the checkerboard example. We'll use the mouseX and mouseY variables to highlight the cell under the mouse position. To do so, we will create a new function called showFocus(), and call it right after drawing the checkerboard.
// outlines the cell under the mouse in red
void showFocus() {
noFill();
// calculate the coordinates of the cell using integer division
int x = mouseX/cellSize;
x = x*cellSize;
int y = mouseY/cellSize;
y = y*cellSize;
stroke(255, 0, 0);
rect(x, y, cellSize, cellSize);
// clean up after yourself by resetting the stroke
noStroke();
}
mousePressed / mousePressed()
Like mouseX and mouseY, mousePressed is a property of the mouse (a variable), but it is of type boolean. Let's use it in this simple paint example:
int brushSize = 20;
void setup() {
size(400, 400);
smooth();
noStroke();
background(255);
}
void draw() {
if (mousePressed) {
brush(mouseX, mouseY);
}
}
void brush(int x, int y) {
fill(#CC3300);
arc(x, y, brushSize, brushSize, 0, PI);
fill(#003333);
arc(x, y, brushSize, brushSize, PI, TWO_PI);
}
We can try to get the same functionality by using the mousePressed() event instead of the mousePressed property. To use events, we need to write a function by the same name in our sketch, and it will be we called automatically every time the event occurs. In the following case, mousePressed() will be called every time the mouse is pressed.
int brushSize = 20;
void setup() {
size(400, 400);
smooth();
noStroke();
background(255);
}
void draw() {
// keep the motor running
}
void mousePressed() {
brush(mouseX, mouseY);
}
void brush(int x, int y) {
fill(#CC3300);
arc(x, y, brushSize, brushSize, 0, PI);
fill(#003333);
arc(x, y, brushSize, brushSize, PI, TWO_PI);
}
You'll notice that the application does not behave the same way. Although the mousePressed property and the mousePressed() event have the same name, they represent different things. mousePressed returns whether or not the mouse button is currently down, whereas mousePressed() gets called whenever the mouse becomes pressed, i.e. once per click.
To get a similar behaviour, we would need to use mouseDragged(), which gets called whenever the mouse is down and is moving.
void mouseDragged() {
brush(mouseX, mouseY);
}
keyboard events
The keyboard has properties and produces events as well. The properties are:
- keyPressed :: true if any key is pressed, false otherwise
- key :: the ASCII value of the last key that was pressed
- keyCode :: the value of the last special key that was pressed (UP, DOWN, ALT, SHIFT, ...)
The events are:
- keyPressed() :: triggered whenever a key is pressed
- keyReleased() :: triggered whenever a key is released
Keyboard events work just like mouse events. One thing to note is that the key and keyCode properties hold the value of the last key that was pressed, even after it is released. This is why they are usually used inside the keyPressed() or keyReleased() events.
We can update our brush by capturing a keyboard press to clear the display.
void keyPressed() {
if (key == 32) { // 32 is the ASCII decimal value representing the space bar
// clear the screen
background(255);
}
}