{-# LANGUAGE ExistentialQuantification #-}
{-----------------------------------------------------------------------------
reactive-banana-wx
Utility functions for interfacing with wxHaskell
------------------------------------------------------------------------------}
module Reactive.Banana.WX where
import Reactive.Banana
import qualified Graphics.UI.WX as WX
import Graphics.UI.WX (on, Prop(..))
{-----------------------------------------------------------------------------
Wx
Utilities for representing stuff from Wx as events and behaviors
------------------------------------------------------------------------------}
-- | Event with exactly one parameter.
event1 :: Typeable a => w -> WX.Event w (a -> IO ()) -> NetworkDescription (Event a)
event1 widget e = do
(addHandler, runHandlers) <- liftIO $ newAddHandler
liftIO $ WX.set widget [on e :~ \h x -> h x >> runHandlers x]
fromAddHandler addHandler
-- NOTE: Some events don't work, for instance leftKey and rightKey
-- "user error (WX.Events: the key event is write-only.)"
-- That's because they are actually just derived from the key event
-- Not sure what to do with this.
-- | Event without parameters.
event0 :: w -> WX.Event w (IO ()) -> NetworkDescription (Event ())
event0 widget e = event1 widget $ WX.mapEvent const (\_ e -> e ()) e
-- | Behavior form an attribute
behavior :: w -> WX.Attr w a -> NetworkDescription (Behavior a)
behavior widget attr = fromPoll . liftIO $ WX.get widget attr
data Prop' w = forall a. (WX.Attr w a) :== Discrete a
infixr 0 :==
-- | "Animate" a property with a stream of events
sink :: w -> [Prop' w] -> NetworkDescription ()
sink widget props = mapM_ sink1 props
where
sink1 (attr :== x) = do
liftIOLater $ WX.set widget [attr := initial x]
reactimate $ (\x -> WX.set widget [attr := x]) <$> changes x
-- Typeable instances, yikes!
-- Also, these instances are wrong, but I don't care.
instance Typeable WX.EventKey where
typeOf _ = mkTyConApp (mkTyCon "WX.EventKey") []
instance Typeable WX.EventMouse where
typeOf _ = mkTyConApp (mkTyCon "WX.EventMouse") []