threepenny-gui-0.3.0.0: src/MissingDollars.hs
{-# LANGUAGE CPP, PackageImports #-}
import Control.Monad
import Safe
#ifdef CABAL
import qualified "threepenny-gui" Graphics.UI.Threepenny as UI
import "threepenny-gui" Graphics.UI.Threepenny.Core
#else
import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core
#endif
import Paths
{-----------------------------------------------------------------------------
Missing Dollars
------------------------------------------------------------------------------}
main :: IO ()
main = do
static <- getStaticDir
startGUI defaultConfig
{ tpPort = 10000
, tpStatic = Just static
} setup
setup :: Window -> IO ()
setup w = void $ do
return w # set title "Missing Dollars"
UI.addStyleSheet w "missing-dollars.css"
(headerView,headerMe) <- mkHeader
riddle <- mkMissingDollarRiddle headerMe
let layout = [element headerView] ++ riddle ++ attributionSource
getBody w #+ [UI.div #. "wrap" #+ layout]
mkHeader :: IO (Element, Element)
mkHeader = do
headerMe <- string "..."
view <- UI.h1 #+ [string "The ", element headerMe, string " Dollars"]
return (view, headerMe)
attributionSource :: [IO Element]
attributionSource =
[ UI.p #+
[ UI.anchor #. "view-source" # set UI.href urlSource
#+ [string "View source code"]
]
, UI.p #+
[ string "Originally by "
, UI.anchor # set UI.href urlAttribution #+ [string "Albert Lai"]
]
]
where
urlSource = "https://github.com/HeinrichApfelmus/threepenny-gui/blob/master/src/MissingDollars.hs"
urlAttribution = "http://www.vex.net/~trebla/humour/missing_dollar.html"
mkMissingDollarRiddle :: Element -> IO [IO Element]
mkMissingDollarRiddle headerMe = do
-- declare input and display values
(hotelOut : hotelCost : hotelHold : _)
<- sequence . replicate 3 $
UI.input # set (attr "size") "3" # set (attr "type") "text"
(hotelChange : hotelRet : hotelBal : hotelPocket :
hotelBal2 : hotelPocket2 : hotelSum : hotelMe : _)
<- sequence . replicate 8 $ UI.span
-- update procedure
let updateDisplay out cost hold = do
let change = out - cost
ret = change - hold
bal = out - ret
sum = bal + hold
diff = sum - out
element hotelOut # set value (show out)
element hotelCost # set value (show cost)
element hotelHold # set value (show hold)
element hotelChange # set text (show change)
element hotelRet # set text (show ret)
element hotelBal # set text (show bal)
element hotelPocket # set text (show hold)
element hotelBal2 # set text (show bal)
element hotelPocket2 # set text (show hold)
element hotelSum # set text (show sum)
if diff >= 0
then do element hotelMe # set text ("extra $" ++ show diff ++ " come from")
element headerMe # set text "Extra"
else do element hotelMe # set text ("missing $" ++ show (-diff) ++ " go")
element headerMe # set text "Missing"
return ()
-- initialize values
updateDisplay 30 25 2
-- calculate button
calculate <- UI.button #+ [string "Calculate"]
on UI.click calculate $ \_ -> do
result <- mapM readMay `liftM` getValuesList [hotelOut,hotelCost,hotelHold]
case result of
Just [getout,getcost,gethold] -> updateDisplay getout getcost gethold
_ -> return ()
return $
[ UI.h2 #+ [string "The Guests, The Bellhop, And The Pizza"]
, UI.p #+
[ string "Three guests went to a hotel and gave $"
, element hotelOut
, string " to the bellhop to buy pizza. The pizza cost only $"
, element hotelCost
, string ". Of the $"
, element hotelChange
, string " change, the bellhop kept $"
, element hotelHold
, string " to himself and returned $"
, element hotelRet
, string " to the guests."
]
, UI.p #+
[ string "So the guests spent $"
, element hotelBal
, string ", and the bellhop pocketed $"
, element hotelPocket
, string ". Now "
, string "$"
, element hotelBal2
, string "+$"
, element hotelPocket2
, string "=$"
, element hotelSum
, string ". Where did the "
, element hotelMe
, string "?"
]
, element calculate
]