module Examples.Grapefruit.Switching (
mainCircuit
) where
import Control.Applicative as Applicative
import Control.Arrow as Arrow (arr, returnA)
import Data.Record as Record
import FRP.Grapefruit.Signal as Signal
import FRP.Grapefruit.Signal.Discrete as DSignal
import FRP.Grapefruit.Signal.Segmented as SSignal
import Graphics.UI.Grapefruit.Comp as UIComp
import Graphics.UI.Grapefruit.Item as UIItem
import Graphics.UI.Grapefruit.Circuit as UICircuit
import Graphics.UI.Grapefruit.Backend.Basic as BasicUIBackend
mainCircuit :: (BasicUIBackend uiBackend) => UICircuit Window uiBackend era () (DSignal era ())
mainCircuit = proc _ -> do
X :& Closure := closure
`With` _ <- window `with` windowContent -< X :& Title := pure "Switching"
`With` ()
returnA -< closure
windowContent :: (BasicUIBackend uiBackend) => UIItem Widget uiBackend era () ()
windowContent = arr (const (X `With` ()))
|>> BasicUIBackend.box Horizontal `with` boxContent >>|
arr (\(X `With` _) -> ())
data Port = Port1 | Port2
boxContent :: (BasicUIBackend uiBackend) => UICircuit Widget uiBackend era () ()
boxContent = proc _ -> do
X :& Push := inc1 <- just pushButton -< X :& Text := pure "Inc 1"
X :& Push := inc2 <- just pushButton -< X :& Text := pure "Inc 2"
X :& Push := switchTo1 <- just pushButton -< X :& Text := pure "Switch to 1"
X :& Push := switchTo2 <- just pushButton -< X :& Text := pure "Switch to 2"
let
port = SSignal.fromInitAndUpdate Port1 (union (Port1 <$ switchTo1)
(Port2 <$ switchTo2))
localCounter = unOSF $
polySwitch ((\port -> withCounting port) <$> port) `sfApp` inc1
`sfApp` inc2
globalCounter = unOSF $
polySwitch ((\port -> withoutCounting port) <$> port) `sfApp` count inc1
`sfApp` count inc2
X <- just label -< X :& Text := localCounter
X <- just label -< X :& Text := globalCounter
returnA -< ()
withCounting :: Port -> PolySignalFun (DSignal `Of` () :->
DSignal `Of` () :->
SSignal `Of` String)
withCounting Port1 = PolySignalFun (SSF $ \inc1 ->
SSF $ \_ ->
OSF $ count inc1)
withCounting Port2 = PolySignalFun (SSF $ \_ ->
SSF $ \inc2 ->
OSF $ count inc2)
withoutCounting :: Port -> PolySignalFun (SSignal `Of` String :->
SSignal `Of` String :->
SSignal `Of` String)
withoutCounting Port1 = PolySignalFun (SSF $ \value1 ->
SSF $ \_ ->
OSF $ value1)
withoutCounting Port2 = PolySignalFun (SSF $ \_ ->
SSF $ \value2 ->
OSF $ value2)
count :: DSignal era dummy -> SSignal era String
count dSignal = show <$> SSignal.scan 0 (\num _ -> succ num) dSignal