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.
Let mouse be the name of our mouse callback function. The following code must be added to the main function:
mouseFunc (Just mouse)
The 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 field: LeftButton, MiddleButton or RightButton. The button_Status, that indicates if the button was pressed or released, has Up or Down as possble values. Finally, the window_Position must be in the format, where x and 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
[Coming Soon!]
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.