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
|
module analog_clock
import StdEnv, StdIO
:: TimerState :== Time
addSeconds :: Int Time -> Time
addSeconds 1 time=:{hours,minutes,seconds}
| seconds < 59 = {time & seconds=seconds+1}
| minutes < 59 = {time & minutes=minutes+1, seconds=0}
| hours < 11 = {hours=hours+1, minutes=0, seconds=0}
| otherwise = {hours=0, minutes=0, seconds=0}
addSeconds n time
| n < 0 = abort "Negative not allowed"
| n == 0 = time
| otherwise = addSeconds 1 (addSeconds (n-1) time)
Start :: *World -> *World
Start world
# (wid, world) = openId world
# (time, world) = getCurrentTime world
= clock time wid world
clock :: Time Id *World -> *World
clock time wid world = startIO SDI Void (snd o seqList [openWindow Void wdef, openTimer time tdef]) [ProcessClose closeProcess] world
where
windowEdge = 200
viewDomain = { corner1 = {x= ~windowEdge/2, y= ~windowEdge/2},
corner2 = {x= windowEdge/2, y= windowEdge/2} }
clockRadius = 90
wdef = Window "Clock" NilLS [ WindowId wid,
WindowInit (noLS (appPIO (appWindowPicture wid (drawClock time)))),
WindowViewSize (rectangleSize viewDomain),
WindowViewDomain viewDomain,
WindowClose (noLS closeProcess) ]
tdef = Timer ticksPerSecond NilLS [TimerFunction tick]
where
tick _ (time, pst)
# newTime = addSeconds 1 time
# pst = appPIO (appWindowPicture wid (drawClock newTime o unfill viewDomain)) pst
= (newTime, pst)
drawClock :: Time *Picture -> *Picture
drawClock time=:{hours,minutes,seconds} picture
# minutes` = toReal minutes + (toReal seconds / 60.0)
# hours` = toReal hours + minutes` / 60.0
= seq ([
setPenSize 2,
setPenColour (let scale=225 in RGB {r=scale,g=scale,b=scale}),
fill {oval_rx=clockRadius, oval_ry=clockRadius},
setPenColour Black,
draw {oval_rx=clockRadius, oval_ry=clockRadius}] ++
[drawAt {x=clock_x 0.88 12 h - 5,y=clock_y 0.88 12 h + 5} (toString h) \\ h <- [1..12]] ++ [
setPenSize 3,
drawLine zero {x=clock_x h_factor 12 hours`, y=clock_y h_factor 12 hours`},
setPenSize 2,
drawLine zero {x=clock_x m_factor 60 minutes`, y=clock_y m_factor 60 minutes`},
setPenSize 1,
setPenColour Red,
drawLine zero {x=clock_x s_factor 60 seconds, y=clock_y s_factor 60 seconds}]) picture
where
s_factor = 0.75
m_factor = 0.75
h_factor = 0.5
clock_x factor max n = toInt (sin (toReal n / (toReal max) * PI * 2.0) * (toReal clockRadius) * factor)
clock_y factor max n = 0 - toInt (cos (toReal n / (toReal max) * PI * 2.0) * (toReal clockRadius) * factor)
|