{-# LANGUAGE CPP #-}
{-|
A module aimed at making working with GtkBuilder easier.
It's meant to be used like this (requires OverloadedStrings):

> buildUI :: BuildFn ()
> buildUI = do
>     mainWin <- buildMainWin
>     buildAboutDialog
>
>     widgetShowAll mainWin
>
> buildMainWin :: BuildFn ApplicationWindow
> buildMainWin = do
>     buildHeaderBar
>     buildMenuBar
>     buildMainArea
>
>     mainWin <- getObject' ApplicationWindow "mainWin"
>     on mainWin Destroy mainQuit
>     return mainWin
>
> buildAboutDialog :: BuildFn AboutDialog
> ...
>
> buildHeaderBar :: BuildFn HeaderBar
> ...
>
> buildMenuBar :: BuildFn MenuBar
> ...
>
> buildMainArea :: BuildFn Grid
> ...
-}
module Data.GI.Gtk.BuildFn
    ( BuildFn
    , buildWithBuilder
    , getObject
    ) where

import           Prelude ()
import           Prelude.Compat
import           Control.Monad.Reader (ReaderT, runReaderT, ask, MonadIO, liftIO)
import           Data.GI.Base (GObject, castTo)
#if !MIN_VERSION_haskell_gi_base(0,20,1)
import           Data.GI.Base.BasicTypes (nullToNothing)
#endif
import           Data.Maybe (fromJust)
import qualified Data.Text as T
import           Foreign.ForeignPtr (ForeignPtr)

import           GI.Gtk hiding (main)

type BuildFn a = ReaderT Builder IO a

buildWithBuilder :: MonadIO m => BuildFn a -> Builder -> m a
buildWithBuilder :: BuildFn a -> Builder -> m a
buildWithBuilder fn :: BuildFn a
fn builder :: Builder
builder = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ BuildFn a -> Builder -> IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT BuildFn a
fn Builder
builder

getObject :: GObject a => (ManagedPtr a -> a) -> T.Text -> BuildFn a
getObject :: (ManagedPtr a -> a) -> Text -> BuildFn a
getObject ctor :: ManagedPtr a -> a
ctor name :: Text
name = do
    Builder
builder <- ReaderT Builder IO Builder
forall r (m :: * -> *). MonadReader r m => m r
ask
#if MIN_VERSION_haskell_gi_base(0,20,1)
    Just obj :: Object
obj <- Builder -> Text -> ReaderT Builder IO (Maybe Object)
forall (m :: * -> *) a.
(HasCallStack, MonadIO m, IsBuilder a) =>
a -> Text -> m (Maybe Object)
builderGetObject Builder
builder Text
name
#else
    Just obj <- nullToNothing $ builderGetObject builder name
#endif
    IO a -> BuildFn a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> BuildFn a) -> IO a -> BuildFn a
forall a b. (a -> b) -> a -> b
$ Maybe a -> a
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe a -> a) -> IO (Maybe a) -> IO a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ManagedPtr a -> a) -> Object -> IO (Maybe a)
forall o o'.
(GObject o, GObject o') =>
(ManagedPtr o' -> o') -> o -> IO (Maybe o')
castTo ManagedPtr a -> a
ctor Object
obj