-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFGLUT.hs
85 lines (74 loc) · 2.38 KB
/
FGLUT.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
{-
- FGLUT = Framework of GLUT
- GLUT = OpenGL utility toolkit
{- Oh, nested comment is allowed! -}
Unlike C/C++ :
/* /* there is */ error here!! */
-}
module FGLUT
( Event
( EventDisplay
, EventIdle
, EventReshape
, EventKeyDown
, EventKeyUp
, EventMouseDown
, EventMouseUp
, EventMouseMove
, EventTimer
)
, startGlut
) where
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
import Data.IORef
import System.Time
-- import System.Clock : Can't compile this in MacOS!!
data Event
= EventDisplay
| EventIdle
| EventReshape Size
| EventKeyDown Char Position
| EventKeyUp Char Position
| EventMouseDown MouseButton Position
| EventMouseUp MouseButton Position
| EventMouseMove Position
| EventTimer Integer
| EventVoid
startGlut :: String -- Window Title
-> Int -- Timer Interval
-> state -- Init State
-> (state -> Event -> IO state) -- Event Handler
-> IO ()
startGlut title timerIntv initState onEvent = do
mainWin <- createWindow title
world <- newIORef initState
let evt = eventHandler world
displayCallback $= ( evt (EventDisplay) )
reshapeCallback $= Just (\ s -> evt (EventReshape s) )
motionCallback $= Just (\ p -> evt (EventMouseMove p) )
passiveMotionCallback $= Just (\ p -> evt (EventMouseMove p) )
keyboardMouseCallback $= Just
(\ key kstate modifiers pos -> evt
( case (key, kstate) of
(MouseButton k, Down) -> EventMouseDown k pos
(MouseButton k, Up ) -> EventMouseUp k pos
(Char k , Down) -> EventKeyDown k pos
(Char k , Up ) -> EventKeyUp k pos
)
)
addTimerCallback timerIntv (onTimerEvent world)
mainLoop
where
onTimerEvent world = do
clk <- getClock
eventHandler world (EventTimer clk)
postRedisplay Nothing
addTimerCallback timerIntv (onTimerEvent world)
eventHandler world event = do
curState <- readIORef world
nxtState <- onEvent curState event
writeIORef world nxtState
getClock = do
TOD a b <- getClockTime
return (a * 1000 + (b `div` 1000000000))