-- 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 :: box -> child -> Bool -> Bool -> Word32 -> PackType -> m ()
pack box :: box
box child :: child
child expand :: Bool
expand fill :: Bool
fill padding :: Word32
padding 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
box child :: child
child expand :: Bool
expand fill :: Bool
fill padding :: Word32
padding 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
box child :: child
child expand :: Bool
expand fill :: Bool
fill padding :: Word32
padding unknownPackType :: 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 :: box -> s (f (w, Bool, Bool, Word32, PackType)) -> m ()
sinkBox box :: box
box widgetSinkable :: 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)
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 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 :: * -> *).
(MonadRunGtk m, IsDescendantOf Widget b, 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 Nothing widgets :: t (b, Bool, Bool, Word32, PackType)
widgets =
          IO () -> m ()
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 (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\acc :: IO ()
acc (w :: b
w, expand :: Bool
expand, fill :: Bool
fill, padding :: Word32
padding, packType :: PackType
packType) ->
                              IO ()
acc
                              IO () -> IO () -> IO ()
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 (f :: * -> *) a. Applicative f => a -> f a
pure ()) t (b, Bool, Bool, Word32, PackType)
widgets
        update (Just olds :: t (b, Bool, Bool, Word32, PackType)
olds) neww :: t (b, Bool, Bool, Word32, PackType)
neww =
          let (reorder :: IO ()
reorder, _, removed :: 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 (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\wacc :: (IO (), Int32, Map (OrdWidget b) (Bool, Bool, Word32, PackType))
wacc -> \case
                           This old :: (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 new :: (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@(old :: b
old, oldExpand :: Bool
oldExpand, oldFill :: Bool
oldFill, oldPadding :: Word32
oldPadding, oldPackType :: PackType
oldPackType)
                             wnew :: (b, Bool, Bool, Word32, PackType)
wnew@(new :: b
new, newExpand :: Bool
newExpand, newFill :: Bool
newFill, newPadding :: Word32
newPadding, newPackType :: 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 (f :: * -> *) a. Applicative f => a -> f a
pure (), 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 (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 (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' (\acc :: IO ()
acc (OrdWidget w :: b
w) _ ->
                                IO ()
acc IO () -> IO () -> IO ()
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 (f :: * -> *) a. Applicative f => a -> f a
pure ()) Map (OrdWidget b) (Bool, Bool, Word32, PackType)
removed
             IO () -> IO () -> IO ()
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 (acc :: a
acc, i :: b
i, oldWidgets :: Map (OrdWidget w) (a, b, c, d)
oldWidgets) (w :: w
w, expand :: a
expand, fill :: b
fill, padding :: c
padding, packType :: 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@(_, _, oldWidgets :: Map (OrdWidget b) (Bool, Bool, Word32, PackType)
oldWidgets) ww :: (b, Bool, Bool, Word32, PackType)
ww@(w :: b
w, _, _, _, _) =
          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
            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 oldPacking :: (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 (acc :: m a
acc, i :: Int32
i, oldWidgets :: c
oldWidgets) (w :: b
w, expand :: Bool
expand, fill :: Bool
fill, padding :: Word32
padding, packType :: 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 (acc :: m a
acc, i :: b
i, oldWidgets :: c
oldWidgets) w :: b
w oldPacking :: (Bool, Bool, Word32, PackType)
oldPacking
          newPacking :: (Bool, Bool, Word32, PackType)
newPacking@(expand :: Bool
expand, fill :: Bool
fill, padding :: Word32
padding, packType :: 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 (acc :: m a
acc, i :: Int32
i, oldWidgets :: Map (OrdWidget b) a
oldWidgets) (w :: b
w, expand :: Bool
expand, fill :: Bool
fill, padding :: Word32
padding, packType :: PackType
packType) oldPacking :: (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 :: box -> s (f w) -> Bool -> Bool -> Word32 -> PackType -> m ()
sinkBoxUniform box :: box
box widgets :: s (f w)
widgets expand :: Bool
expand fill :: Bool
fill padding :: Word32
padding packType :: 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 (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