-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.

{-# LANGUAGE FlexibleContexts, LambdaCase, TupleSections #-}

{-|
Description : Reactive helpers for 'Box'es
Copyright   : Sven Bartscher 2020
License     : MPL-2.0
Maintainer  : sven.bartscher@weltraumschlangen.de
Stability   : experimental

This module provides helpers for dealing with 'Box'es in reactive
contexts.
-}
module Reflex.GI.Gtk.Widget.Box
  ( sinkBox
  , sinkBoxUniform
  ) where

import Control.Monad (when)
import Control.Monad.IO.Class (MonadIO)
import Data.Align ( Semialign
                  , align
                  )
import Data.Foldable (foldl')
import Data.GI.Base (GObject)
import Data.GI.Base.Overloading (IsDescendantOf)
import qualified Data.Map as M
import Data.These ( These( This
                         , That
                         , These
                         )
                  )
import Data.Word (Word32)
import GI.Gtk ( Box
              , Container
              , PackType( PackTypeStart
                        , PackTypeEnd
                        )
              , Widget
              , boxPackEnd
              , boxPackStart
              , boxReorderChild
              , boxSetChildPacking
              , containerRemove
              )
import Reflex ( MonadHold
              , PerformEvent
              , Performable
              , PostBuild
              , (<@>)
              , performEvent_
              , hold
              )
import Reflex.GI.Gtk.Output ( Sinkable
                            , toSinkEvent
                            )
import Reflex.GI.Gtk.Run.Class ( MonadRunGtk
                               , runGtk
                               )
import Reflex.GI.Gtk.Widget.Ord (OrdWidget(OrdWidget))

pack :: ( MonadIO m
        , GObject box
        , IsDescendantOf Box box
        , GObject child
        , IsDescendantOf Widget child
        )
       => box -> child -> Bool -> Bool -> Word32 -> PackType -> m ()
pack :: forall (m :: * -> *) box child.
(MonadIO m, GObject box, IsDescendantOf Box box, GObject child,
 IsDescendantOf Widget child) =>
box -> child -> Bool -> Bool -> Word32 -> PackType -> m ()
pack box
box child
child Bool
expand Bool
fill Word32
padding PackType
PackTypeStart = box -> child -> Bool -> Bool -> Word32 -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsBox a, IsWidget b) =>
a -> b -> Bool -> Bool -> Word32 -> m ()
boxPackStart box
box child
child Bool
expand Bool
fill Word32
padding
pack box
box child
child Bool
expand Bool
fill Word32
padding PackType
PackTypeEnd = box -> child -> Bool -> Bool -> Word32 -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsBox a, IsWidget b) =>
a -> b -> Bool -> Bool -> Word32 -> m ()
boxPackEnd box
box child
child Bool
expand Bool
fill Word32
padding
pack box
box child
child Bool
expand Bool
fill Word32
padding PackType
unknownPackType = do
  -- We don't know this packing, but boxSetChildPacking may know it,
  -- so we pack at start and then set the correct packing.
  box -> child -> Bool -> Bool -> Word32 -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsBox a, IsWidget b) =>
a -> b -> Bool -> Bool -> Word32 -> m ()
boxPackStart box
box child
child Bool
expand Bool
fill Word32
padding
  box -> child -> Bool -> Bool -> Word32 -> PackType -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsBox a, IsWidget b) =>
a -> b -> Bool -> Bool -> Word32 -> PackType -> m ()
boxSetChildPacking box
box child
child Bool
expand Bool
fill Word32
padding PackType
unknownPackType

-- | Pack a dynamically changing sequence of widgets into a box. Each
-- widget has individual dynamic packing parameters.
--
-- The widgets will be packed into the 'Box' in left-fold order.
sinkBox :: ( GObject box
           , IsDescendantOf Container box
           , IsDescendantOf Box box
           , Foldable f
           , Semialign f
           , GObject w
           , IsDescendantOf Widget w
           , Eq w
           , PerformEvent t m
           , PostBuild t m
           , MonadHold t m
           , MonadRunGtk m
           , MonadRunGtk (Performable m)
           , Sinkable t s
           )
        => box
        -- ^ The 'Box' to pack into
        -> s (f (w, Bool, Bool, Word32, PackType))
        -- ^ The dynamic sequence of 'Widget's. The arguments are the
        -- same as those for 'boxSetChildPacking'.
        -> m ()
sinkBox :: forall box (f :: * -> *) w t (m :: * -> *) (s :: * -> *).
(GObject box, IsDescendantOf Container box, IsDescendantOf Box box,
 Foldable f, Semialign f, GObject w, IsDescendantOf Widget w, Eq w,
 PerformEvent t m, PostBuild t m, MonadHold t m, MonadRunGtk m,
 MonadRunGtk (Performable m), Sinkable t s) =>
box -> s (f (w, Bool, Bool, Word32, PackType)) -> m ()
sinkBox box
box s (f (w, Bool, Bool, Word32, PackType))
widgetSinkable = do
  Event t (f (w, Bool, Bool, Word32, PackType))
widgetUpdates <- s (f (w, Bool, Bool, Word32, PackType))
-> m (Event t (f (w, Bool, Bool, Word32, PackType)))
forall t (s :: * -> *) (m :: * -> *) a.
(Sinkable t s, PostBuild t m) =>
s a -> m (Event t a)
forall (m :: * -> *) a. PostBuild t m => s a -> m (Event t a)
toSinkEvent s (f (w, Bool, Bool, Word32, PackType))
widgetSinkable
  Behavior t (Maybe (f (w, Bool, Bool, Word32, PackType)))
currentWidgets <- Maybe (f (w, Bool, Bool, Word32, PackType))
-> Event t (Maybe (f (w, Bool, Bool, Word32, PackType)))
-> m (Behavior t (Maybe (f (w, Bool, Bool, Word32, PackType))))
forall a. a -> Event t a -> m (Behavior t a)
forall {k} (t :: k) (m :: * -> *) a.
MonadHold t m =>
a -> Event t a -> m (Behavior t a)
hold Maybe (f (w, Bool, Bool, Word32, PackType))
forall a. Maybe a
Nothing (Event t (Maybe (f (w, Bool, Bool, Word32, PackType)))
 -> m (Behavior t (Maybe (f (w, Bool, Bool, Word32, PackType)))))
-> Event t (Maybe (f (w, Bool, Bool, Word32, PackType)))
-> m (Behavior t (Maybe (f (w, Bool, Bool, Word32, PackType))))
forall a b. (a -> b) -> a -> b
$ f (w, Bool, Bool, Word32, PackType)
-> Maybe (f (w, Bool, Bool, Word32, PackType))
forall a. a -> Maybe a
Just (f (w, Bool, Bool, Word32, PackType)
 -> Maybe (f (w, Bool, Bool, Word32, PackType)))
-> Event t (f (w, Bool, Bool, Word32, PackType))
-> Event t (Maybe (f (w, Bool, Bool, Word32, PackType)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event t (f (w, Bool, Bool, Word32, PackType))
widgetUpdates
  Event t (Performable m ()) -> m ()
forall t (m :: * -> *).
PerformEvent t m =>
Event t (Performable m ()) -> m ()
performEvent_ (Event t (Performable m ()) -> m ())
-> Event t (Performable m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ Maybe (f (w, Bool, Bool, Word32, PackType))
-> f (w, Bool, Bool, Word32, PackType) -> Performable m ()
forall {b} {m :: * -> *} {t :: * -> *}.
(IsDescendantOf Widget b, MonadRunGtk m, Foldable t, GObject b,
 Eq b, Semialign t) =>
Maybe (t (b, Bool, Bool, Word32, PackType))
-> t (b, Bool, Bool, Word32, PackType) -> m ()
update (Maybe (f (w, Bool, Bool, Word32, PackType))
 -> f (w, Bool, Bool, Word32, PackType) -> Performable m ())
-> Behavior t (Maybe (f (w, Bool, Bool, Word32, PackType)))
-> Behavior
     t (f (w, Bool, Bool, Word32, PackType) -> Performable m ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Behavior t (Maybe (f (w, Bool, Bool, Word32, PackType)))
currentWidgets Behavior
  t (f (w, Bool, Bool, Word32, PackType) -> Performable m ())
-> Event t (f (w, Bool, Bool, Word32, PackType))
-> Event t (Performable m ())
forall {k} (t :: k) a b.
Reflex t =>
Behavior t (a -> b) -> Event t a -> Event t b
<@> Event t (f (w, Bool, Bool, Word32, PackType))
widgetUpdates
  where update :: Maybe (t (b, Bool, Bool, Word32, PackType))
-> t (b, Bool, Bool, Word32, PackType) -> m ()
update Maybe (t (b, Bool, Bool, Word32, PackType))
Nothing t (b, Bool, Bool, Word32, PackType)
widgets =
          IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadRunGtk m => IO a -> m a
runGtk (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ (IO () -> (b, Bool, Bool, Word32, PackType) -> IO ())
-> IO () -> t (b, Bool, Bool, Word32, PackType) -> IO ()
forall b a. (b -> a -> b) -> b -> t a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\IO ()
acc (b
w, Bool
expand, Bool
fill, Word32
padding, PackType
packType) ->
                              IO ()
acc
                              IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> box -> b -> Bool -> Bool -> Word32 -> PackType -> IO ()
forall (m :: * -> *) box child.
(MonadIO m, GObject box, IsDescendantOf Box box, GObject child,
 IsDescendantOf Widget child) =>
box -> child -> Bool -> Bool -> Word32 -> PackType -> m ()
pack box
box b
w Bool
expand Bool
fill Word32
padding PackType
packType
                          ) (() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) t (b, Bool, Bool, Word32, PackType)
widgets
        update (Just t (b, Bool, Bool, Word32, PackType)
olds) t (b, Bool, Bool, Word32, PackType)
neww =
          let (IO ()
reorder, Int32
_, Map (OrdWidget b) (Bool, Bool, Word32, PackType)
removed) =
                ((IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
 -> These
      (b, Bool, Bool, Word32, PackType) (b, Bool, Bool, Word32, PackType)
 -> (IO (), Int32,
     Map (OrdWidget b) (Bool, Bool, Word32, PackType)))
-> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> t (These
        (b, Bool, Bool, Word32, PackType)
        (b, Bool, Bool, Word32, PackType))
-> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall b a. (b -> a -> b) -> b -> t a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\(IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc -> \case
                           This (b, Bool, Bool, Word32, PackType)
old -> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall {w} {a} {b} {a} {b} {c} {d}.
(GObject w, Eq w) =>
(a, b, Map (OrdWidget w) (a, b, c, d))
-> (w, a, b, c, d) -> (a, b, Map (OrdWidget w) (a, b, c, d))
markOld (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc (b, Bool, Bool, Word32, PackType)
old
                           That (b, Bool, Bool, Word32, PackType)
new -> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall {b} {m :: * -> *} {a}.
(IsDescendantOf Widget b, GObject b, Eq b, MonadIO m) =>
(m a, Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (m (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
otherWidget (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc (b, Bool, Bool, Word32, PackType)
new
                           These
                             wold :: (b, Bool, Bool, Word32, PackType)
wold@(b
old, Bool
oldExpand, Bool
oldFill, Word32
oldPadding, PackType
oldPackType)
                             wnew :: (b, Bool, Bool, Word32, PackType)
wnew@(b
new, Bool
newExpand, Bool
newFill, Word32
newPadding, PackType
newPackType)
                             | b
old b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
new ->
                                 (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> b
-> (Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType)
-> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall {b} {m :: * -> *} {b} {a} {c}.
(IsDescendantOf Widget b, MonadIO m, GObject b, Enum b) =>
(m a, b, c)
-> b
-> (Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType)
-> (m (), b, c)
repackWidget (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc b
new
                                 (Bool
oldExpand, Bool
oldFill, Word32
oldPadding, PackType
oldPackType)
                                 (Bool
newExpand, Bool
newFill, Word32
newPadding, PackType
newPackType)
                             | Bool
otherwise ->
                                 (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall {b} {m :: * -> *} {a}.
(IsDescendantOf Widget b, GObject b, Eq b, MonadIO m) =>
(m a, Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (m (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
otherWidget ((IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall {w} {a} {b} {a} {b} {c} {d}.
(GObject w, Eq w) =>
(a, b, Map (OrdWidget w) (a, b, c, d))
-> (w, a, b, c, d) -> (a, b, Map (OrdWidget w) (a, b, c, d))
markOld (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc (b, Bool, Bool, Word32, PackType)
wold) (b, Bool, Bool, Word32, PackType)
wnew
                       ) (() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (), Int32
0, Map (OrdWidget b) (Bool, Bool, Word32, PackType)
forall k a. Map k a
M.empty) (t (These
      (b, Bool, Bool, Word32, PackType)
      (b, Bool, Bool, Word32, PackType))
 -> (IO (), Int32,
     Map (OrdWidget b) (Bool, Bool, Word32, PackType)))
-> t (These
        (b, Bool, Bool, Word32, PackType)
        (b, Bool, Bool, Word32, PackType))
-> (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall a b. (a -> b) -> a -> b
$ t (b, Bool, Bool, Word32, PackType)
-> t (b, Bool, Bool, Word32, PackType)
-> t (These
        (b, Bool, Bool, Word32, PackType)
        (b, Bool, Bool, Word32, PackType))
forall a b. t a -> t b -> t (These a b)
forall (f :: * -> *) a b.
Semialign f =>
f a -> f b -> f (These a b)
align t (b, Bool, Bool, Word32, PackType)
olds t (b, Bool, Bool, Word32, PackType)
neww
          in IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadRunGtk m => IO a -> m a
runGtk (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$
             (IO () -> OrdWidget b -> (Bool, Bool, Word32, PackType) -> IO ())
-> IO ()
-> Map (OrdWidget b) (Bool, Bool, Word32, PackType)
-> IO ()
forall a k b. (a -> k -> b -> a) -> a -> Map k b -> a
M.foldlWithKey' (\IO ()
acc (OrdWidget b
w) (Bool, Bool, Word32, PackType)
_ ->
                                IO ()
acc IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> box -> b -> IO ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsContainer a, IsWidget b) =>
a -> b -> m ()
containerRemove box
box b
w
                             ) (() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) Map (OrdWidget b) (Bool, Bool, Word32, PackType)
removed
             IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
reorder
        markOld :: (a, b, Map (OrdWidget w) (a, b, c, d))
-> (w, a, b, c, d) -> (a, b, Map (OrdWidget w) (a, b, c, d))
markOld (a
acc, b
i, Map (OrdWidget w) (a, b, c, d)
oldWidgets) (w
w, a
expand, b
fill, c
padding, d
packType) =
          ( a
acc
          , b
i
          , OrdWidget w
-> (a, b, c, d)
-> Map (OrdWidget w) (a, b, c, d)
-> Map (OrdWidget w) (a, b, c, d)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (w -> OrdWidget w
forall w. w -> OrdWidget w
OrdWidget w
w) (a
expand, b
fill, c
padding, d
packType) Map (OrdWidget w) (a, b, c, d)
oldWidgets
          )
        otherWidget :: (m a, Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (m (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
otherWidget wacc :: (m a, Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc@(m a
_, Int32
_, Map (OrdWidget b) (Bool, Bool, Word32, PackType)
oldWidgets) ww :: (b, Bool, Bool, Word32, PackType)
ww@(b
w, Bool
_, Bool
_, Word32
_, PackType
_) =
          case Map (OrdWidget b) (Bool, Bool, Word32, PackType)
oldWidgets Map (OrdWidget b) (Bool, Bool, Word32, PackType)
-> OrdWidget b -> Maybe (Bool, Bool, Word32, PackType)
forall k a. Ord k => Map k a -> k -> Maybe a
M.!? b -> OrdWidget b
forall w. w -> OrdWidget w
OrdWidget b
w of
            Maybe (Bool, Bool, Word32, PackType)
Nothing -> (m a, Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (m (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall {b} {m :: * -> *} {a} {c}.
(IsDescendantOf Widget b, MonadIO m, GObject b) =>
(m a, Int32, c)
-> (b, Bool, Bool, Word32, PackType) -> (m (), Int32, c)
newWidget (m a, Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc (b, Bool, Bool, Word32, PackType)
ww
            Just (Bool, Bool, Word32, PackType)
oldPacking -> (m a, Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
-> (b, Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType)
-> (m (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
forall {b} {m :: * -> *} {a} {a}.
(IsDescendantOf Widget b, MonadIO m, GObject b, Eq b) =>
(m a, Int32, Map (OrdWidget b) a)
-> (b, Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType)
-> (m (), Int32, Map (OrdWidget b) a)
reuseWidget (m a, Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc (b, Bool, Bool, Word32, PackType)
ww (Bool, Bool, Word32, PackType)
oldPacking
        newWidget :: (m a, Int32, c)
-> (b, Bool, Bool, Word32, PackType) -> (m (), Int32, c)
newWidget (m a
acc, Int32
i, c
oldWidgets) (b
w, Bool
expand, Bool
fill, Word32
padding, PackType
packType) =
          ( do
              a
_ <- m a
acc
              box -> b -> Bool -> Bool -> Word32 -> PackType -> m ()
forall (m :: * -> *) box child.
(MonadIO m, GObject box, IsDescendantOf Box box, GObject child,
 IsDescendantOf Widget child) =>
box -> child -> Bool -> Bool -> Word32 -> PackType -> m ()
pack box
box b
w Bool
expand Bool
fill Word32
padding PackType
packType
              box -> b -> Int32 -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsBox a, IsWidget b) =>
a -> b -> Int32 -> m ()
boxReorderChild box
box b
w Int32
i
          , Int32 -> Int32
forall a. Enum a => a -> a
succ Int32
i
          , c
oldWidgets
          )
        repackWidget :: (m a, b, c)
-> b
-> (Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType)
-> (m (), b, c)
repackWidget (m a
acc, b
i, c
oldWidgets) b
w (Bool, Bool, Word32, PackType)
oldPacking
          newPacking :: (Bool, Bool, Word32, PackType)
newPacking@(Bool
expand, Bool
fill, Word32
padding, PackType
packType) =
          ( do
              a
_ <- m a
acc
              Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ((Bool, Bool, Word32, PackType)
oldPacking (Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType) -> Bool
forall a. Eq a => a -> a -> Bool
/= (Bool, Bool, Word32, PackType)
newPacking)
                (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ box -> b -> Bool -> Bool -> Word32 -> PackType -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsBox a, IsWidget b) =>
a -> b -> Bool -> Bool -> Word32 -> PackType -> m ()
boxSetChildPacking box
box b
w Bool
expand Bool
fill Word32
padding PackType
packType
          , b -> b
forall a. Enum a => a -> a
succ b
i
          , c
oldWidgets
          )
        reuseWidget :: (m a, Int32, Map (OrdWidget b) a)
-> (b, Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType)
-> (m (), Int32, Map (OrdWidget b) a)
reuseWidget (m a
acc, Int32
i, Map (OrdWidget b) a
oldWidgets) (b
w, Bool
expand, Bool
fill, Word32
padding, PackType
packType) (Bool, Bool, Word32, PackType)
oldPacking =
          (m (), Int32, Map (OrdWidget b) a)
-> b
-> (Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType)
-> (m (), Int32, Map (OrdWidget b) a)
forall {b} {m :: * -> *} {b} {a} {c}.
(IsDescendantOf Widget b, MonadIO m, GObject b, Enum b) =>
(m a, b, c)
-> b
-> (Bool, Bool, Word32, PackType)
-> (Bool, Bool, Word32, PackType)
-> (m (), b, c)
repackWidget ( do
                           a
_ <- m a
acc
                           box -> b -> Int32 -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadIO m, IsBox a, IsWidget b) =>
a -> b -> Int32 -> m ()
boxReorderChild box
box b
w Int32
i
                       , Int32
i -- repack widget already increases this
                       , OrdWidget b -> Map (OrdWidget b) a -> Map (OrdWidget b) a
forall k a. Ord k => k -> Map k a -> Map k a
M.delete (b -> OrdWidget b
forall w. w -> OrdWidget w
OrdWidget b
w) Map (OrdWidget b) a
oldWidgets
                       ) b
w (Bool, Bool, Word32, PackType)
oldPacking (Bool
expand, Bool
fill, Word32
padding, PackType
packType)

-- | Like 'sinkBox', but the packing parameters are statically
-- specified for all widgets.
sinkBoxUniform :: ( GObject box
                  , IsDescendantOf Container box
                  , IsDescendantOf Box box
                  , Foldable f
                  , Semialign f
                  , GObject w
                  , IsDescendantOf Widget w
                  , Eq w
                  , PerformEvent t m
                  , PostBuild t m
                  , MonadRunGtk m
                  , MonadRunGtk (Performable m)
                  , MonadHold t m
                  , Sinkable t s
                  )
               => box
               -- ^ The 'Box' to pack into
               -> s (f w)
               -- ^ The dynamic sequence of 'Widget's
               -> Bool
               -> Bool
               -> Word32
               -> PackType
               -> m ()
sinkBoxUniform :: forall box (f :: * -> *) w t (m :: * -> *) (s :: * -> *).
(GObject box, IsDescendantOf Container box, IsDescendantOf Box box,
 Foldable f, Semialign f, GObject w, IsDescendantOf Widget w, Eq w,
 PerformEvent t m, PostBuild t m, MonadRunGtk m,
 MonadRunGtk (Performable m), MonadHold t m, Sinkable t s) =>
box -> s (f w) -> Bool -> Bool -> Word32 -> PackType -> m ()
sinkBoxUniform box
box s (f w)
widgets Bool
expand Bool
fill Word32
padding PackType
packType =
  box -> s (f (w, Bool, Bool, Word32, PackType)) -> m ()
forall box (f :: * -> *) w t (m :: * -> *) (s :: * -> *).
(GObject box, IsDescendantOf Container box, IsDescendantOf Box box,
 Foldable f, Semialign f, GObject w, IsDescendantOf Widget w, Eq w,
 PerformEvent t m, PostBuild t m, MonadHold t m, MonadRunGtk m,
 MonadRunGtk (Performable m), Sinkable t s) =>
box -> s (f (w, Bool, Bool, Word32, PackType)) -> m ()
sinkBox box
box (s (f (w, Bool, Bool, Word32, PackType)) -> m ())
-> s (f (w, Bool, Bool, Word32, PackType)) -> m ()
forall a b. (a -> b) -> a -> b
$ (w -> (w, Bool, Bool, Word32, PackType))
-> f w -> f (w, Bool, Bool, Word32, PackType)
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (, Bool
expand, Bool
fill, Word32
padding, PackType
packType) (f w -> f (w, Bool, Bool, Word32, PackType))
-> s (f w) -> s (f (w, Bool, Bool, Word32, PackType))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s (f w)
widgets