packages feed

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)