aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamil Staps2015-08-20 00:06:01 +0200
committerCamil Staps2015-08-20 00:07:13 +0200
commite8a8b71b399a58ec041f1f607c51ec032b9c97ed (patch)
treef0607fedfa67617d9bcb9af9f4094506c0cbbeaa
parent9.1.2 internal clock (diff)
Analog clock
-rw-r--r--analog_clock.icl70
1 files changed, 70 insertions, 0 deletions
diff --git a/analog_clock.icl b/analog_clock.icl
new file mode 100644
index 0000000..affbb4c
--- /dev/null
+++ b/analog_clock.icl
@@ -0,0 +1,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)
+