{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module Main where
import Data.Default ( Default(..) )
import Data.Semigroup ( (<>) )
import Control.Monad ( liftM2 )
import Data.Boolean
import Language.Sunroof
import Language.Sunroof.Server
import Language.Sunroof.JS.Canvas
import Language.Sunroof.JS.Browser ( alert )
import Language.Sunroof.JS.JQuery
import Paths_sunroof_examples
main :: IO ()
main = do
dataDir <- getDataDir
sunroofServer (def { sunroofVerbose = 0
, cometResourceBaseDir = dataDir
, cometIndexFile = "examples/fib/index.html"
}) $ \ doc -> asyncJS doc prog
prog :: JSB ()
prog = do
ch <- newChan
jq "body" >>= on "click" ".click" (\ () -> do
the_id :: JSString <- jq (cast $ this) >>= invoke "attr" ("id" :: JSString)
o <- new "Object" ()
o # "id" := the_id
ch # writeChan o)
jq "body" >>= on "slide" ".slide" (\ (a :: JSObject, aux :: JSObject) -> do
the_id :: JSString <- jq (cast $ this) >>= invoke "attr" ("id" :: JSString)
o <- new "Object" ()
o # "id" := the_id
o # "value" := (aux ! "value" :: JSString)
ch # writeChan o)
obj <- new "Object" ()
obj # attr "model" := (0 :: JSNumber)
-- This is using the imperative update to enable the
let slider :: JSNumber -> JSObject -> JSB JSObject
slider nm = invoke "slider" ("value" :: JSString, nm)
update :: String -> JSNumber -> JSNumber -> JSNumber -> JSB ()
update nm val mn mx =
ifB ((val <=* mx) &&* (val >=* mn))
(obj # attr nm := val)
(return ())
switchB _ [] def = def
switchB tag ((a,b):xs) def = ifB (tag ==* a) b (switchB tag xs def)
fib <- fixJS $ \ fib -> function $ \ (n :: JSNumber) -> do
ifB (n <* 2)
(return (1 :: JSNumber))
(liftM2 (+) (apply fib (n - 1)) (apply fib (n - 2)))
loop () $ \() -> do
res <- ch # readChan
-- res <- wait "body" (slide <> click)
model <- evaluate (obj ! "model") :: JSB JSNumber
switchB (res ! "id" :: JSString)
[ ("slider", update "model" (res ! "value") 0 25)
, ("up" , update "model" (model + 1) 0 25)
, ("down" , update "model" (model - 1) 0 25)
, ("reset" , update "model" 0 0 25)
] $ return ()
model <- evaluate (obj ! "model") :: JSB JSNumber
jQuery "#slider" >>= slider (cast model)
liftJS $ do
jQuery "#fib-out" >>= setHtml ("fib " <> cast model <> "...")
res <- apply fib model
jQuery "#fib-out" >>= setHtml ("fib " <> cast model <> " = " <> cast res)
return ()
return ()
default(JSNumber, JSString, String)