module Barrie.Gadgets.Connections (connectChooser, connectCommand, connectDisplay, connectUpdater, connectEditor, connectChild) where import Control.Monad import Data.Dynamic import Barrie.Gadgets connectCommand :: (IO () -> IO ()) -- ^ connection creator -> IO a -- ^ state retriever -> Gadget a -- ^ gadget representing the command -> (a -> IO ()) -- ^ state updater -> IO () connectCommand onCommand getState gadget setState = do onCommand (getState >>= setState . gadgetCommand gadget) connectDisplay :: (Dynamic -> IO ()) -- ^ GUI element updater -> Gadget a -- ^ gadget representing the display -> a -- ^ new state -> IO () connectDisplay update gadget = update . gadgetDisplay gadget connectEditor :: (IO () -> IO ()) -- ^ connection creator -> IO a -- ^ gui state retriever -> (Dynamic -> IO Bool) -- ^ true if update should happen -> IO Dynamic -- ^ current value of GUI element -> Gadget a -- ^ gadget representing the editor -> (a -> IO ()) -- ^ state change applier -> IO () connectEditor onAction getState doUpdate getValue gadget apply = do let connect get set = onAction (do st <- getState go <- doUpdate (get st) when go (do curr <- getValue apply $ set curr st)) connect (gadgetDisplay gadget) (gadgetUpdate gadget) connectUpdater :: (IO () -> IO ()) -- ^ connection creator -> IO a -- ^ gui state retriever -> IO Dynamic -- ^ current value of GUI element -> Gadget a -- ^ gadget representing the editor -> (a -> IO ()) -- ^ state change applier -> IO () connectUpdater onAction getState getValue gadget apply = onAction (do st <- getState curr <- getValue apply $ gadgetUpdate gadget curr st) -- |Connect a chooser to the GUI. Elements of the chooser are stored -- |in a tuple; as (renderable value, state value). connectChooser :: ([Dynamic] -> IO ()) -- ^ Set list of options -> (Int -> IO ()) -- ^ choose value -> Gadget a -- ^ gadget representing the chooser -> a -> IO () connectChooser setChoices setValue gadget = do let update getChoices get st = (setChoices (getChoices st) >> setValue (snd $ fromDyn (get st) ([get st],-12))) update (gadgetChooser gadget) (gadgetDisplay gadget) connectChild :: (IO () -> IO ()) -- ^ show child -> (Gadget a -> a -> IO a) -- ^ child runner -> IO a -- ^ parent state retriever -> Gadget a -- ^ parent -> (a -> IO ()) -- ^ parent state updater -> IO () connectChild onLaunch inner getState gadget setState = do onLaunch (do st <- getState st' <- inner (gadgetChild gadget) st setState st')