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)