{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module GI.Gtk.Declarative.Attributes
( Attribute(..)
, classes
, on
, onM
, ToGtkCallback(..)
)
where
import Control.Monad (void)
import qualified Data.GI.Base.Attributes as GI
import qualified Data.GI.Base.Signals as GI
import qualified Data.HashSet as HashSet
import Data.Text (Text)
import Data.Typeable
import GHC.TypeLits (KnownSymbol, Symbol)
import qualified GI.Gtk as Gtk
import GI.Gtk.Declarative.CSS
data Attribute widget event where
(:=)
:: (GI.AttrOpAllowed 'GI.AttrConstruct info widget
, GI.AttrOpAllowed 'GI.AttrSet info widget
, GI.AttrGetC info widget attr getValue
, GI.AttrSetTypeConstraint info setValue
, KnownSymbol attr
, Typeable attr
)
=> GI.AttrLabelProxy (attr :: Symbol) -> setValue -> Attribute widget event
Classes
:: Gtk.IsWidget widget
=> ClassSet
-> Attribute widget event
OnSignalPure
:: ( Gtk.GObject widget
, GI.SignalInfo info
, callback ~ GI.HaskellCallbackType info
, Functor (PureCallback callback)
, ToGtkCallback (PureCallback callback)
, callback ~ CustomGtkCallback (PureCallback callback)
)
=> Gtk.SignalProxy widget info
-> PureCallback callback event
-> Attribute widget event
OnSignalImpure
:: ( Gtk.GObject widget
, GI.SignalInfo info
, callback ~ GI.HaskellCallbackType info
, Functor (ImpureCallback callback widget)
, ToGtkCallback (ImpureCallback callback widget)
, (widget -> callback) ~ CustomGtkCallback (ImpureCallback callback widget)
)
=> Gtk.SignalProxy widget info
-> ImpureCallback callback widget event
-> Attribute widget event
instance Functor (Attribute widget) where
fmap f = \case
attr := value -> attr := value
Classes cs -> Classes cs
OnSignalPure signal cb -> OnSignalPure signal (fmap f cb)
OnSignalImpure signal cb -> OnSignalImpure signal (fmap f cb)
classes :: Gtk.IsWidget widget => [Text] -> Attribute widget event
classes = Classes . HashSet.fromList
on
:: ( Gtk.GObject widget
, GI.SignalInfo info
, callback ~ GI.HaskellCallbackType info
, pure ~ ToPureCallback callback event
, Functor (PureCallback callback)
, ToGtkCallback (PureCallback callback)
, callback ~ CustomGtkCallback (PureCallback callback)
)
=> Gtk.SignalProxy widget info
-> pure
-> Attribute widget event
on signal = OnSignalPure signal . PureCallback
onM
:: ( Gtk.GObject widget
, GI.SignalInfo info
, callback ~ GI.HaskellCallbackType info
, impure ~ ToImpureCallback callback event
, withWidget ~ (widget -> impure)
, Functor (ImpureCallback callback widget)
, ToGtkCallback (ImpureCallback callback widget)
, (widget -> callback) ~ CustomGtkCallback (ImpureCallback callback widget)
)
=> Gtk.SignalProxy widget info
-> withWidget
-> Attribute widget event
onM signal = OnSignalImpure signal . ImpureCallback
type family ToPureCallback gtkCallback event where
ToPureCallback (IO ()) event = event
ToPureCallback (a -> b) event = a -> ToPureCallback b event
data PureCallback callback event where
PureCallback
:: (pure ~ ToPureCallback callback event)
=> pure
-> PureCallback callback event
instance Functor (PureCallback (IO ())) where
fmap f (PureCallback e) = PureCallback (f e)
instance Functor (PureCallback (x -> IO ())) where
fmap f (PureCallback g) = PureCallback (f . g)
instance Functor (PureCallback (x -> y -> IO ())) where
fmap f (PureCallback g) = PureCallback (\x -> f . g x)
type family ToImpureCallback t e where
ToImpureCallback (IO ()) e = IO e
ToImpureCallback (a -> b) e = a -> ToImpureCallback b e
data ImpureCallback callback widget event where
ImpureCallback
:: (impure ~ ToImpureCallback callback event)
=> (widget -> impure)
-> ImpureCallback callback widget event
instance Functor (ImpureCallback (IO ()) widget) where
fmap f (ImpureCallback g) = ImpureCallback (\w -> f <$> g w)
instance Functor (ImpureCallback (x -> IO ()) widget) where
fmap f (ImpureCallback g) = ImpureCallback (\w -> fmap f . g w)
instance Functor (ImpureCallback (x -> y -> IO ()) widget) where
fmap f (ImpureCallback g) = ImpureCallback (\w x -> fmap f . g w x)
class ToGtkCallback userCallback where
type CustomGtkCallback userCallback :: *
toGtkCallback :: userCallback event -> (event -> IO ()) -> CustomGtkCallback userCallback
instance ToGtkCallback (PureCallback (IO ())) where
type CustomGtkCallback (PureCallback (IO ())) = IO ()
toGtkCallback (PureCallback cb) f = void (f cb)
instance ToGtkCallback (PureCallback (x -> IO ())) where
type CustomGtkCallback (PureCallback (x -> IO ())) = x -> IO ()
toGtkCallback (PureCallback cb) f x = void (f (cb x))
instance ToGtkCallback (PureCallback (x -> y -> IO ())) where
type CustomGtkCallback (PureCallback (x -> y -> IO ())) = x -> y -> IO ()
toGtkCallback (PureCallback cb) f x y = void (f (cb x y))
instance ToGtkCallback (ImpureCallback (IO ()) widget) where
type CustomGtkCallback (ImpureCallback (IO ()) widget) = widget -> IO ()
toGtkCallback (ImpureCallback cb) f w = void (cb w >>= f)