module tut10_4_3 // ******************************************************************************** // Clean tutorial example program. // // This program defines a Controls component that implements a manually settable // counter. // A bi-directional receiver is added to give external access to the counter value. // ******************************************************************************** import StdEnv, StdIO Start :: *World -> *World Start world = startIO NDI Void initialise [] world where initialise pst # (displayId, pst) = accPIO openId pst # (resetId, pst) = accPIO openRId pst # (readId, pst) = accPIO openR2Id pst # (error, pst) = openDialog Void (dialog displayId resetId readId) pst | error <> NoError = abort "Counter could not open counter dialog." # (displayId, pst) = accPIO openId pst # (error, pst) = openDialog Void (display displayId readId) pst | error <> NoError = abort "Counter could not open display dialog." | otherwise = pst dialog displayId resetId readId = Dialog "Counter" (counter :+: resetButton) [WindowClose (noLS closeProcess)] where counter = { newLS = initcount, newDef = LayoutControl (EditControl (toString initcount) (PixelWidth (hmm 50.0)) 1 [ControlId displayId, ControlSelectState Unable] :+: ButtonControl "-" [ControlFunction (count(-1)), ControlWidth (PixelWidth (hmm 25.0)), ControlPos (BelowPrev, zero)] :+: ButtonControl "+" [ControlFunction (count 1 ), ControlWidth (PixelWidth (hmm 25.0))] :+: Receiver resetId reset [] :+: Receiver2 readId read []) [ControlPos (Center, zero), ControlHMargin 0 0, ControlVMargin 0 0, ControlItemSpace 0 0] } where initcount = 0 count :: Int (Int, PSt .l) -> (Int, PSt .l) count dx (count, pst) = (count + dx, appPIO (setControlText displayId (toString (count+dx))) pst) reset :: m (Int, PSt .l) -> (Int, PSt .l) reset _ (_, pst) = (initcount, appPIO (setControlText displayId (toString initcount)) pst) read :: m (Int, PSt .l) -> (Int, (Int, PSt .l)) read _ (count, pst) = (count, (count, pst)) resetButton = ButtonControl "Reset" [ControlFunction (noLS (snd o syncSend resetId undef)), ControlPos (Center, zero)] display displayId readId = Dialog "Read" (EditControl "" (PixelWidth (hmm 50.0)) 1 [ControlId displayId, ControlSelectState Unable] :+: ButtonControl "Read" [ControlFunction (noLS read), ControlPos (Center, zero)]) [WindowClose (noLS closeProcess)] where read pst # ((error, value), pst) = syncSend2 readId undef pst | error <> SendOk = abort "Could not read counter value" | otherwise = appPIO (setControlText displayId (toString (fromJust value))) pst