-- No elements inside.

placePrim :: MonadWriter [Placement] m => Alignment -> Bounds -> LayoutPrim -> m ()
placePrim screenAlign parentBounds prim =
  case prim of
    Anchor{..} -> do
      let thisBounds = connect (lyParentAlign, parentBounds) (lyThisAlign, lyElement)
          plac = Placement { placAlign   = screenAlign
                           , placPos     = boundsAnchor screenAlign thisBounds
                           , placBounds  = thisBounds
                           , placElement = lyElement
                           }
      tell [plac]
      traverse_ (placePrim screenAlign thisBounds) lyChildren

    Box{..} -> do
      (_, placements) <- listen $ traverse_ (placePrim screenAlign parentBounds) lyInside
      let bounds = case placements of
                     [] -> parentBounds  -- If nothing inside, use the parent bounds.
                     _  -> (foldl1' unionBounds . map placBounds) placements
      traverse_ (placePrim screenAlign bounds) lyChildren
placePrim :: MonadWriter [Placement] m => Alignment -> Bounds -> LayoutPrim -> m ()
placePrim screenAlign parentBounds prim =
  case prim of
    Anchor{..} -> do
      let thisBounds = connect (lyParentAlign, parentBounds) (lyThisAlign, lyElement)
          plac = Placement { placAlign   = screenAlign
                           , placPos     = boundsAnchor screenAlign thisBounds
                           , placBounds  = thisBounds
                           , placElement = lyElement
                           }
      tell [plac]
      traverse_ (placePrim screenAlign thisBounds) lyChildren

    Box{..} -> do
      (_, placements) <- listen $ traverse_ (placePrim screenAlign parentBounds) lyInside
      let bounds = case placements of
                     [] -> parentBounds  -- If nothing inside, use the parent bounds.
                     _  -> (foldl1' unionBounds . map placBounds) placements
      traverse_ (placePrim screenAlign bounds) lyChildren
placePrim screenAlign parentBounds prim =
  case prim of
    Anchor{..} -> do
      let thisBounds = connect (lyParentAlign, parentBounds) (lyThisAlign, lyElement)
          plac = Placement { placAlign   = screenAlign
                           , placPos     = boundsAnchor screenAlign thisBounds
                           , placBounds  = thisBounds
                           , placElement = lyElement
                           }
      tell [plac]
      traverse_ (placePrim screenAlign thisBounds) lyChildren

    Box{..} -> do
      (_, placements) <- listen $ traverse_ (placePrim screenAlign parentBounds) lyInside
      let bounds = case placements of
                     [] -> parentBounds  -- If nothing inside, use the parent bounds.
                     _  -> (foldl1' unionBounds . map placBounds) placements
      traverse_ (placePrim screenAlign bounds) lyChildren