{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
module GI.Gtk.Declarative.Attributes.Internal.EventHandler
( Purity(..)
, EventHandlerReturn(..)
, EventHandler(..)
, UserEventHandler
, ToEventHandler(..)
)
where
import Data.Functor.Identity
data Purity = Pure | Impure
data EventHandlerReturn m gtkReturn event where
OnlyEvent ::m e -> EventHandlerReturn m () e
ReturnAndEvent ::m (Bool, e) -> EventHandlerReturn m Bool e
instance Functor m => Functor (EventHandlerReturn m gtkEventHandler) where
fmap f = \case
OnlyEvent e -> OnlyEvent (fmap f e)
ReturnAndEvent mr -> ReturnAndEvent (fmap (fmap f) mr)
data EventHandler gtkEventHandler widget (purity :: Purity) event where
PureEventHandler ::EventHandlerReturn Identity ret e -> EventHandler (IO ret) w Pure e
ImpureEventHandler ::(w -> EventHandlerReturn IO ret e) -> EventHandler (IO ret) w Impure e
EventHandlerFunction ::(a -> EventHandler b w p e) -> EventHandler (a -> b) w p e
instance Functor (EventHandler gtkEventHandler widget purity) where
fmap f = \case
PureEventHandler r -> PureEventHandler (fmap f r)
ImpureEventHandler r -> ImpureEventHandler (fmap (fmap f) r)
EventHandlerFunction eh -> EventHandlerFunction (\a -> fmap f (eh a))
type family UserEventHandler gtkCallback widget (purity :: Purity) event where
UserEventHandler (IO ()) widget Pure event = event
UserEventHandler (IO Bool) widget Pure event = (Bool, event)
UserEventHandler (IO ()) widget Impure event = widget -> IO event
UserEventHandler (IO Bool) widget Impure event = widget -> IO (Bool, event)
UserEventHandler (a -> b) widget purity event = a -> UserEventHandler b widget purity event
class ToEventHandler gtkEventHandler widget purity where
toEventHandler
:: UserEventHandler gtkEventHandler widget purity event
-> EventHandler gtkEventHandler widget purity event
instance ToEventHandler (IO ()) widget Pure where
toEventHandler = PureEventHandler . OnlyEvent . pure
instance ToEventHandler (IO Bool) widget Pure where
toEventHandler = PureEventHandler . ReturnAndEvent . pure
instance ToEventHandler (IO ()) widget Impure where
toEventHandler eh = ImpureEventHandler (OnlyEvent . eh)
instance ToEventHandler (IO Bool) widget Impure where
toEventHandler eh = ImpureEventHandler (ReturnAndEvent . eh)
instance (ToEventHandler b widget purity) => ToEventHandler (a -> b) widget purity where
toEventHandler f = EventHandlerFunction (toEventHandler . f)