{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}

-- |
-- Module      : FULE.Container.Positioned
-- Description : The @Positioned@ Container.
-- Copyright   : (c) Paul Schnapp, 2023
-- License     : BSD3
-- Maintainer  : Paul Schnapp <paul.schnapp@gmail.com>
--
-- A 'FULE.Container.Container' to position content relative to its parent
-- container, including in the center.
module FULE.Container.Positioned
 ( Positioned
 , topLeft
 , topMiddle
 , topRight
 , middleLeft
 , centered
 , middleRight
 , bottomLeft
 , bottomMiddle
 , bottomRight
 ) where

import Control.Monad.Trans.Class
import Data.Proxy

import FULE.Component
import FULE.Container
import FULE.Layout
import FULE.LayoutOp


data Position
  = TopLeft
  | TopMiddle
  | TopRight
  | MiddleLeft
  | MiddleMiddle
  | MiddleRight
  | BottomLeft
  | BottomMiddle
  | BottomRight

-- | A container for positioning content within a larger container in one of
--   nine positions relative to the parent. Relative positioning will adjust
--   to keep up with changes to the size of the parent container.
data Positioned c = Positioned Position c

instance (Container c k m) => Container (Positioned c) k m where
  minWidth :: Positioned c -> Proxy k -> m (Maybe Int)
minWidth (Positioned Position
_ c
c) = c -> Proxy k -> m (Maybe Int)
forall c k (m :: * -> *).
Container c k m =>
c -> Proxy k -> m (Maybe Int)
minWidth c
c
  minHeight :: Positioned c -> Proxy k -> m (Maybe Int)
minHeight (Positioned Position
_ c
c) = c -> Proxy k -> m (Maybe Int)
forall c k (m :: * -> *).
Container c k m =>
c -> Proxy k -> m (Maybe Int)
minHeight c
c
  addToLayout :: Positioned c -> Proxy k -> Bounds -> Maybe Int -> LayoutOp k m ()
addToLayout (Positioned Position
position c
c) Proxy k
proxy Bounds
bounds Maybe Int
renderGroup = do
    Maybe Int
reqWidth <- WriterT [ComponentInfo k] m (Maybe Int)
-> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int)
forall (m :: * -> *) a. Monad m => m a -> StateT LayoutOpState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (WriterT [ComponentInfo k] m (Maybe Int)
 -> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int))
-> (m (Maybe Int) -> WriterT [ComponentInfo k] m (Maybe Int))
-> m (Maybe Int)
-> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (Maybe Int) -> WriterT [ComponentInfo k] m (Maybe Int)
forall (m :: * -> *) a.
Monad m =>
m a -> WriterT [ComponentInfo k] m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe Int)
 -> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int))
-> m (Maybe Int)
-> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int)
forall a b. (a -> b) -> a -> b
$ c -> Proxy k -> m (Maybe Int)
forall c k (m :: * -> *).
Container c k m =>
c -> Proxy k -> m (Maybe Int)
minWidth c
c Proxy k
proxy
    Maybe Int
reqHeight <- WriterT [ComponentInfo k] m (Maybe Int)
-> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int)
forall (m :: * -> *) a. Monad m => m a -> StateT LayoutOpState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (WriterT [ComponentInfo k] m (Maybe Int)
 -> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int))
-> (m (Maybe Int) -> WriterT [ComponentInfo k] m (Maybe Int))
-> m (Maybe Int)
-> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (Maybe Int) -> WriterT [ComponentInfo k] m (Maybe Int)
forall (m :: * -> *) a.
Monad m =>
m a -> WriterT [ComponentInfo k] m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe Int)
 -> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int))
-> m (Maybe Int)
-> StateT LayoutOpState (WriterT [ComponentInfo k] m) (Maybe Int)
forall a b. (a -> b) -> a -> b
$ c -> Proxy k -> m (Maybe Int)
forall c k (m :: * -> *).
Container c k m =>
c -> Proxy k -> m (Maybe Int)
minHeight c
c Proxy k
proxy
    let clipping :: Maybe Bounds
clipping = Bounds -> Maybe Bounds
clippingOf Bounds
bounds
    Bounds
bounds' <- case Position
position of
      Position
TopLeft -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereTop Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereLeft Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
      Position
TopMiddle -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereTop Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleHoriz Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
      Position
TopRight -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereTop Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereRight Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
      Position
MiddleLeft -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleVert Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereLeft Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
      Position
MiddleMiddle -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleVert Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleHoriz Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
      Position
MiddleRight -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleVert Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereRight Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
      Position
BottomLeft -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereBottom Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereLeft Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
      Position
BottomMiddle -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereBottom Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleHoriz Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
      Position
BottomRight -> do
        (GuideID, GuideID)
vert <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereBottom Bounds
bounds Maybe Int
reqHeight
        (GuideID, GuideID)
horiz <- Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereRight Bounds
bounds Maybe Int
reqWidth
        Bounds -> StateT LayoutOpState (WriterT [ComponentInfo k] m) Bounds
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID, GuideID)
vert (GuideID, GuideID)
horiz Maybe Bounds
clipping)
    c -> Proxy k -> Bounds -> Maybe Int -> LayoutOp k m ()
forall c k (m :: * -> *).
Container c k m =>
c -> Proxy k -> Bounds -> Maybe Int -> LayoutOp k m ()
addToLayout c
c Proxy k
proxy Bounds
bounds' Maybe Int
renderGroup

adhereTop :: (Monad m) => Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereTop :: forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereTop Bounds
bounds Maybe Int
Nothing = (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bounds -> GuideID
topOf Bounds
bounds, Bounds -> GuideID
bottomOf Bounds
bounds)
adhereTop (Bounds { topOf :: Bounds -> GuideID
topOf = GuideID
top }) (Just Int
h) = do
  GuideID
bottom <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ Int -> GuideID -> PlasticDependencyType -> GuideSpecification
Relative Int
h GuideID
top PlasticDependencyType
Asymmetric
  (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (GuideID
top, GuideID
bottom)

adhereMiddleVert :: (Monad m) => Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleVert :: forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleVert Bounds
bounds Maybe Int
Nothing = (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bounds -> GuideID
topOf Bounds
bounds, Bounds -> GuideID
bottomOf Bounds
bounds)
adhereMiddleVert Bounds
bounds (Just Int
h) = do
  GuideID
horiz <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ (GuideID, Double) -> (GuideID, Double) -> GuideSpecification
Between (Bounds -> GuideID
topOf Bounds
bounds, Double
0.5) (Bounds -> GuideID
bottomOf Bounds
bounds, Double
0.5)
  GuideID
top <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ Int -> GuideID -> PlasticDependencyType -> GuideSpecification
Relative (-Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (Int
h Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2)) GuideID
horiz PlasticDependencyType
Asymmetric
  GuideID
bottom <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ Int -> GuideID -> PlasticDependencyType -> GuideSpecification
Relative Int
h GuideID
top PlasticDependencyType
Symmetric
  (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (GuideID
top, GuideID
bottom)

adhereBottom :: (Monad m) => Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereBottom :: forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereBottom Bounds
bounds Maybe Int
Nothing = (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bounds -> GuideID
topOf Bounds
bounds, Bounds -> GuideID
bottomOf Bounds
bounds)
adhereBototm :: Bounds
-> Maybe Int
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
adhereBototm (Bounds { bottomOf :: Bounds -> GuideID
bottomOf = GuideID
bottom }) (Just Int
h) = do
  GuideID
top <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ Int -> GuideID -> PlasticDependencyType -> GuideSpecification
Relative (-Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
h) GuideID
bottom PlasticDependencyType
Asymmetric
  (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (GuideID
top, GuideID
bottom)

adhereLeft :: (Monad m) => Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereLeft :: forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereLeft Bounds
bounds Maybe Int
Nothing = (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bounds -> GuideID
leftOf Bounds
bounds, Bounds -> GuideID
rightOf Bounds
bounds)
adhereLeft (Bounds { leftOf :: Bounds -> GuideID
leftOf = GuideID
left }) (Just Int
w) = do
  GuideID
right <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ Int -> GuideID -> PlasticDependencyType -> GuideSpecification
Relative Int
w GuideID
left PlasticDependencyType
Asymmetric
  (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (GuideID
left, GuideID
right)

adhereMiddleHoriz :: (Monad m) => Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleHoriz :: forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereMiddleHoriz Bounds
bounds Maybe Int
Nothing = (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bounds -> GuideID
leftOf Bounds
bounds, Bounds -> GuideID
rightOf Bounds
bounds)
adhereMiddleHoriz Bounds
bounds (Just Int
w) = do
  GuideID
vert <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ (GuideID, Double) -> (GuideID, Double) -> GuideSpecification
Between (Bounds -> GuideID
leftOf Bounds
bounds, Double
0.5) (Bounds -> GuideID
rightOf Bounds
bounds, Double
0.5)
  GuideID
left <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ Int -> GuideID -> PlasticDependencyType -> GuideSpecification
Relative (-Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (Int
w Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2)) GuideID
vert PlasticDependencyType
Asymmetric
  GuideID
right <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ Int -> GuideID -> PlasticDependencyType -> GuideSpecification
Relative Int
w GuideID
left PlasticDependencyType
Symmetric
  (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (GuideID
left, GuideID
right)

adhereRight :: (Monad m) => Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereRight :: forall (m :: * -> *) k.
Monad m =>
Bounds -> Maybe Int -> LayoutOp k m (GuideID, GuideID)
adhereRight Bounds
bounds Maybe Int
Nothing = (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bounds -> GuideID
leftOf Bounds
bounds, Bounds -> GuideID
rightOf Bounds
bounds)
adhereRight (Bounds { rightOf :: Bounds -> GuideID
rightOf = GuideID
right }) (Just Int
w) = do
  GuideID
left <- GuideSpecification -> LayoutOp k m GuideID
forall (m :: * -> *) k.
Monad m =>
GuideSpecification -> LayoutOp k m GuideID
addGuideToLayout (GuideSpecification -> LayoutOp k m GuideID)
-> GuideSpecification -> LayoutOp k m GuideID
forall a b. (a -> b) -> a -> b
$ Int -> GuideID -> PlasticDependencyType -> GuideSpecification
Relative (-Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
w) GuideID
right PlasticDependencyType
Asymmetric
  (GuideID, GuideID)
-> StateT
     LayoutOpState (WriterT [ComponentInfo k] m) (GuideID, GuideID)
forall a. a -> StateT LayoutOpState (WriterT [ComponentInfo k] m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (GuideID
left, GuideID
right)

makeBounds :: (GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds :: (GuideID, GuideID) -> (GuideID, GuideID) -> Maybe Bounds -> Bounds
makeBounds (GuideID
top, GuideID
bottom) (GuideID
left, GuideID
right) Maybe Bounds
clipping =
  Bounds
  { topOf :: GuideID
topOf = GuideID
top
  , leftOf :: GuideID
leftOf = GuideID
left
  , rightOf :: GuideID
rightOf = GuideID
right
  , bottomOf :: GuideID
bottomOf = GuideID
bottom
  , clippingOf :: Maybe Bounds
clippingOf = Maybe Bounds
clipping
  }

-- | Position content in the /top-left/ corner of its parent container.
topLeft :: c -> Positioned c
topLeft :: forall c. c -> Positioned c
topLeft = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
TopLeft

-- | Position content in the middle of the /top/ side of its parent container.
topMiddle :: c -> Positioned c
topMiddle :: forall c. c -> Positioned c
topMiddle = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
TopMiddle

-- | Position content in the /top-right/ corner of its parent container.
topRight :: c -> Positioned c
topRight :: forall c. c -> Positioned c
topRight = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
TopRight

-- | Position content in the middle of the /left/ side of its parent container.
middleLeft :: c -> Positioned c
middleLeft :: forall c. c -> Positioned c
middleLeft = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
MiddleLeft

-- | Position content in the very center of its parent container.
centered :: c -> Positioned c
centered :: forall c. c -> Positioned c
centered = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
MiddleMiddle

-- | Position content in the middle of the /right/ side of its parent container.
middleRight :: c -> Positioned c
middleRight :: forall c. c -> Positioned c
middleRight = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
MiddleRight

-- | Position content in the /bottom-left/ corner of its parent container.
bottomLeft :: c -> Positioned c
bottomLeft :: forall c. c -> Positioned c
bottomLeft = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
BottomLeft

-- | Position content in the middle of the /bottom/ side of its parent container.
bottomMiddle :: c -> Positioned c
bottomMiddle :: forall c. c -> Positioned c
bottomMiddle = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
BottomMiddle

-- | Position content in the /bottom-right/ corner of its parent container.
bottomRight :: c -> Positioned c
bottomRight :: forall c. c -> Positioned c
bottomRight = Position -> c -> Positioned c
forall c. Position -> c -> Positioned c
Positioned Position
BottomRight