barrie-0.4.1: demos/CalcGadget.hs
module CalcGadget (CalcState, Operator(..),
digitButtonName, operatorButtonName,
startState, calcGUI) where
import Barrie
import CalcState
-- Names for various calculator gadgets
digitButtonName :: Int -> String
digitButtonName = show
operatorButtonName :: Operator -> String
operatorButtonName = show
-- CalcGadget puts the calculator operations into a gadget.
type CalcGadget = Gadget CalcState
data Operator = Plus | Minus | Multiply | Divide | Equals | Clear
deriving (Eq, Ord, Enum, Bounded, Read, Show)
opFn :: Operator -> CalcState -> CalcState
opFn Plus = op (+)
opFn Minus = op (-)
opFn Multiply = op (*)
opFn Divide = op div
opFn Equals = eval
opFn Clear = clear
calcGUI :: CalcGadget
calcGUI = sectionG "calculator" [display, buttons]
display :: CalcGadget
display = displayG "display" (\ st -> showBase (calcBase st) (calcValue st))
where showBase _ 0 = "0"
showBase b n = reverse $ sb n
where sb 0 = ""
sb x = toEnum (x `mod` b + 48) : sb (x `div` b)
buttons :: CalcGadget
buttons = sectionG "buttonArea" [sectionG "ops" (map mkCmd [minBound ..]),
sectionG "digits" (map mkDigit [0 .. 9]),
sectionG "base" [base8]]
where mkDigit d = enabled (\ st -> d < calcBase st) $
commandG (digitButtonName d) (addDigit d)
mkCmd op = commandG (operatorButtonName op) (opFn op)
base8 = editorG "base8" (\ st -> calcBase st == 8)
(\ v st -> if v then setBase 8 st else setBase 10 st)