{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MonoLocalBinds #-}
module Data.GI.Gtk.ModelView.CellLayout (
module GI.Gtk.Interfaces.CellLayout
, cellLayoutSetAttributes
, cellLayoutSetDataFunction
, cellLayoutSetDataFunc'
, convertIterFromParentToChildModel
) where
import Control.Monad.IO.Class (MonadIO(..))
import Foreign.Ptr (castPtr)
import Foreign.Storable (peek)
import Data.GI.Base.Attributes (AttrOp, AttrOpTag(..), set)
import Data.GI.Base.ManagedPtr (castTo, withManagedPtr)
import GI.Gtk.Interfaces.CellLayout
import GI.Gtk.Objects.TreeModelFilter (TreeModelFilter(..), getTreeModelFilterChildModel, treeModelFilterConvertIterToChildIter)
import GI.Gtk.Objects.TreeModelSort (TreeModelSort(..), getTreeModelSortModel, treeModelSortConvertIterToChildIter)
import GI.Gtk.Structs.TreeIter
(getTreeIterStamp, getTreeIterUserData3, getTreeIterUserData2,
getTreeIterUserData, TreeIter(..))
import GI.Gtk.Objects.CellRenderer (IsCellRenderer, CellRenderer(..), toCellRenderer)
import Data.GI.Gtk.ModelView.Types
import Data.GI.Gtk.ModelView.TreeModel
import Data.GI.Gtk.ModelView.CustomStore (customStoreGetRow)
import Data.GI.Base (get)
import Data.GI.Base.BasicTypes (ManagedPtr(..))
cellLayoutSetAttributes :: (MonadIO m,
IsCellLayout self,
IsCellRenderer cell,
IsTreeModel (model row),
IsTypedTreeModel model)
=> self
-> cell
-> model row
-> (row -> [AttrOp cell 'AttrSet])
-> m ()
cellLayoutSetAttributes :: forall (m :: * -> *) self cell (model :: * -> *) row.
(MonadIO m, IsCellLayout self, IsCellRenderer cell,
IsTreeModel (model row), IsTypedTreeModel model) =>
self
-> cell -> model row -> (row -> [AttrOp cell 'AttrSet]) -> m ()
cellLayoutSetAttributes self
self cell
cell model row
model row -> [AttrOp cell 'AttrSet]
attributes =
self -> cell -> model row -> (TreeIter -> IO ()) -> m ()
forall (m :: * -> *) self cell model.
(MonadIO m, IsCellLayout self, IsCellRenderer cell,
IsTreeModel model) =>
self -> cell -> model -> (TreeIter -> IO ()) -> m ()
cellLayoutSetDataFunc' self
self cell
cell model row
model ((TreeIter -> IO ()) -> m ()) -> (TreeIter -> IO ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \TreeIter
iter -> do
row <- model row -> TreeIter -> IO row
forall (m :: * -> *) (model :: * -> *) row.
(MonadIO m, IsTypedTreeModel model) =>
model row -> TreeIter -> m row
customStoreGetRow model row
model TreeIter
iter
set cell (attributes row)
cellLayoutSetDataFunction :: (MonadIO m,
IsCellLayout self,
IsCellRenderer cell,
IsTreeModel (model row),
IsTypedTreeModel model)
=> self
-> cell
-> model row
-> (row -> IO ())
-> m ()
cellLayoutSetDataFunction :: forall (m :: * -> *) self cell (model :: * -> *) row.
(MonadIO m, IsCellLayout self, IsCellRenderer cell,
IsTreeModel (model row), IsTypedTreeModel model) =>
self -> cell -> model row -> (row -> IO ()) -> m ()
cellLayoutSetDataFunction self
self cell
cell model row
model row -> IO ()
callback =
self -> cell -> model row -> (TreeIter -> IO ()) -> m ()
forall (m :: * -> *) self cell model.
(MonadIO m, IsCellLayout self, IsCellRenderer cell,
IsTreeModel model) =>
self -> cell -> model -> (TreeIter -> IO ()) -> m ()
cellLayoutSetDataFunc' self
self cell
cell model row
model ((TreeIter -> IO ()) -> m ()) -> (TreeIter -> IO ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \TreeIter
iter -> do
row <- model row -> TreeIter -> IO row
forall (m :: * -> *) (model :: * -> *) row.
(MonadIO m, IsTypedTreeModel model) =>
model row -> TreeIter -> m row
customStoreGetRow model row
model TreeIter
iter
callback row
cellLayoutSetDataFunc' :: (MonadIO m,
IsCellLayout self,
IsCellRenderer cell,
IsTreeModel model)
=> self
-> cell
-> model
-> (TreeIter -> IO ())
-> m ()
cellLayoutSetDataFunc' :: forall (m :: * -> *) self cell model.
(MonadIO m, IsCellLayout self, IsCellRenderer cell,
IsTreeModel model) =>
self -> cell -> model -> (TreeIter -> IO ()) -> m ()
cellLayoutSetDataFunc' self
self cell
cell model
model TreeIter -> IO ()
func = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
self -> cell -> Maybe CellLayoutDataFunc -> IO ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsCellLayout a, IsCellRenderer b) =>
a -> b -> Maybe CellLayoutDataFunc -> m ()
cellLayoutSetCellDataFunc self
self cell
cell (Maybe CellLayoutDataFunc -> IO ())
-> (CellLayoutDataFunc -> Maybe CellLayoutDataFunc)
-> CellLayoutDataFunc
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CellLayoutDataFunc -> Maybe CellLayoutDataFunc
forall a. a -> Maybe a
Just (CellLayoutDataFunc -> IO ()) -> CellLayoutDataFunc -> IO ()
forall a b. (a -> b) -> a -> b
$ \CellLayout
_ (CellRenderer ManagedPtr CellRenderer
cellPtr') TreeModel
model' TreeIter
iter -> do
castModel <- model -> IO TreeModel
forall (m :: * -> *) o.
(MonadIO m, IsTreeModel o) =>
o -> m TreeModel
toTreeModel model
model
iter <- convertIterFromParentToChildModel iter model' castModel
CellRenderer cellPtr <- toCellRenderer cell
if managedForeignPtr cellPtr /= managedForeignPtr cellPtr' then
error ("cellLayoutSetAttributeFunc: attempt to set attributes of "++
"a different CellRenderer.")
else func iter
convertIterFromParentToChildModel ::
TreeIter
-> TreeModel
-> TreeModel
-> IO TreeIter
convertIterFromParentToChildModel :: TreeIter -> TreeModel -> TreeModel -> IO TreeIter
convertIterFromParentToChildModel TreeIter
iter parentModel :: TreeModel
parentModel@(TreeModel ManagedPtr TreeModel
parentModelPtr) TreeModel
childModel =
let (TreeModel ManagedPtr TreeModel
modelPtr) = TreeModel
childModel in
if ManagedPtr TreeModel -> ForeignPtr TreeModel
forall a. ManagedPtr a -> ForeignPtr a
managedForeignPtr ManagedPtr TreeModel
modelPtr ForeignPtr TreeModel -> ForeignPtr TreeModel -> Bool
forall a. Eq a => a -> a -> Bool
== ManagedPtr TreeModel -> ForeignPtr TreeModel
forall a. ManagedPtr a -> ForeignPtr a
managedForeignPtr ManagedPtr TreeModel
parentModelPtr
then TreeIter -> IO TreeIter
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return TreeIter
iter
else
(ManagedPtr TreeModelFilter -> TreeModelFilter)
-> TreeModel -> IO (Maybe TreeModelFilter)
forall o o'.
(HasCallStack, ManagedPtrNewtype o, TypedObject o,
ManagedPtrNewtype o', TypedObject o', GObject o') =>
(ManagedPtr o' -> o') -> o -> IO (Maybe o')
castTo ManagedPtr TreeModelFilter -> TreeModelFilter
TreeModelFilter TreeModel
parentModel IO (Maybe TreeModelFilter)
-> (Maybe TreeModelFilter -> IO TreeIter) -> IO TreeIter
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just TreeModelFilter
tmFilter -> do
childIter <- TreeModelFilter -> TreeIter -> IO TreeIter
forall (m :: * -> *) a.
(HasCallStack, MonadIO m, IsTreeModelFilter a) =>
a -> TreeIter -> m TreeIter
treeModelFilterConvertIterToChildIter TreeModelFilter
tmFilter TreeIter
iter
Just child@(TreeModel childPtr) <- getTreeModelFilterChildModel tmFilter
if managedForeignPtr childPtr == managedForeignPtr modelPtr
then return childIter
else convertIterFromParentToChildModel childIter child childModel
Maybe TreeModelFilter
Nothing -> do
(ManagedPtr TreeModelSort -> TreeModelSort)
-> TreeModel -> IO (Maybe TreeModelSort)
forall o o'.
(HasCallStack, ManagedPtrNewtype o, TypedObject o,
ManagedPtrNewtype o', TypedObject o', GObject o') =>
(ManagedPtr o' -> o') -> o -> IO (Maybe o')
castTo ManagedPtr TreeModelSort -> TreeModelSort
TreeModelSort TreeModel
parentModel IO (Maybe TreeModelSort)
-> (Maybe TreeModelSort -> IO TreeIter) -> IO TreeIter
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just TreeModelSort
tmSort -> do
childIter <- TreeModelSort -> TreeIter -> IO TreeIter
forall (m :: * -> *) a.
(HasCallStack, MonadIO m, IsTreeModelSort a) =>
a -> TreeIter -> m TreeIter
treeModelSortConvertIterToChildIter TreeModelSort
tmSort TreeIter
iter
child@(TreeModel childPtr) <- getTreeModelSortModel tmSort
if managedForeignPtr childPtr == managedForeignPtr modelPtr
then return childIter
else convertIterFromParentToChildModel childIter child childModel
Maybe TreeModelSort
Nothing -> do
stamp <- TreeIter -> IO Int32
forall (m :: * -> *). MonadIO m => TreeIter -> m Int32
getTreeIterStamp TreeIter
iter
ud1 <- getTreeIterUserData iter
ud2 <- getTreeIterUserData2 iter
ud3 <- getTreeIterUserData3 iter
error ("CellLayout: don't know how to convert iter "++show (stamp, ud1, ud2, ud3)++
" from model "++show (managedForeignPtr parentModelPtr)++" to model "++
show (managedForeignPtr modelPtr)++". Is it possible that you are setting the "++
"attributes of a CellRenderer using a different model than "++
"that which was set in the view?")