If you understood how the keyboard and special keys callback functions work (previous lesson), you won't have any problems to get in touch with the mouse and joystick callback functions.
mouse be the name of our mouse callback function. The following code must be added to the
mouseFunc (Just mouse)
mouse function has the following structure:
mouse :: MouseAction mouse button button_Status window_Position = procedure mouse button button_Status window_Position = procedure ...
You can use the following parameters for the
button_Status, that indicates if the button was pressed or released, has
Down as possble values. Finally, the
window_Position must be in the
y indicates where the mouse pointer was, in pixels, when the event happened. Observe:
mouse :: MouseAction mouse LeftButton Up _ = procedure_1 mouse RightButton Down (WindowPosition x y) = procedure_2 (x,y) mouse _ _ _ = return ()
The program above calls
procedure_1 when the left mouse button is released, calls
procedure_2 when the right mouse button is pressed (using the "click position" as a parameter) or doesn't do anything at all if none of these events happen.
Let's take a look at a more elaborated program, in which a white square is drawn when the left mouse button is pressed (notice that the bottom left corner of the square is exactly the same point as the "click point").
import GL import GLUT winX, winY :: Int winX = 500 winY = 500 myInit :: IO () myInit = do clearColor (Color4 0.0 0.0 0.0 0.0) clear [ColorBufferBit] matrixMode Projection loadIdentity ortho 0.0 1.0 0.0 1.0 (-1.0) 1.0 mouse :: MouseAction mouse LeftButton Down (WindowPosition x y) = drawSquare ((fromIntegral x),(fromIntegral y)) mouse _ _ _ = return () drawSquare :: (GLfloat,GLfloat) -> IO () drawSquare (x,y) = do clear [ColorBufferBit] color (Color3 1.0 1.0 1.0 :: Color3 GLfloat) beginEnd Quads $ mapM_ vertex [ Vertex3 px py 0.0, Vertex3 (px + 0.2) py 0.0, Vertex3 (px + 0.2) (py + 0.2) 0.0, Vertex3 px (py + 0.2) (0.0 :: GLfloat)] flush where px = x/(fromIntegral winX) py = 1.0 - y/(fromIntegral winY) display :: DisplayAction display = do clear [ColorBufferBit] flush main :: IO () main = do GLUT.init Nothing createWindow "Mouse" (return ()) [ Single, GLUT.Rgba ] (Just (WindowPosition 100 100)) (Just (WindowSize winX winY)) myInit mouseFunc (Just mouse) displayFunc display mainLoop
The callback functions you've learned in this lesson are defined in module GLUT_CBWindow, which is automatically imported if your program already imports module GLUT.