{-# LANGUAGE RecordWildCards, DeriveGeneric #-}
-- | Datastructures representing the CSS box model,
-- & utilities for operating on them.
module Graphics.Layout.Box(Border(..), mapX, mapY,
        Size(..), mapSizeX, mapSizeY,
        PaddedBox(..), zeroBox, lengthBox, mapX', mapY',
        width, height, minWidth, minHeight, maxWidth, maxHeight,
        leftSpace, rightSpace, topSpace, bottomSpace, hSpace, vSpace,
        Length(..), mapAuto, lowerLength, Zero(..), CastDouble(..)) where

import Control.DeepSeq (NFData)
import GHC.Generics (Generic)

-- | Amount of space surrounding the box.
data Border m n = Border {
    forall m n. Border m n -> m
top :: m, forall m n. Border m n -> m
bottom :: m, forall m n. Border m n -> n
left :: n, forall m n. Border m n -> n
right :: n
} deriving (Border m n -> Border m n -> Bool
(Border m n -> Border m n -> Bool)
-> (Border m n -> Border m n -> Bool) -> Eq (Border m n)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall m n. (Eq m, Eq n) => Border m n -> Border m n -> Bool
$c== :: forall m n. (Eq m, Eq n) => Border m n -> Border m n -> Bool
== :: Border m n -> Border m n -> Bool
$c/= :: forall m n. (Eq m, Eq n) => Border m n -> Border m n -> Bool
/= :: Border m n -> Border m n -> Bool
Eq, ReadPrec [Border m n]
ReadPrec (Border m n)
Int -> ReadS (Border m n)
ReadS [Border m n]
(Int -> ReadS (Border m n))
-> ReadS [Border m n]
-> ReadPrec (Border m n)
-> ReadPrec [Border m n]
-> Read (Border m n)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall m n. (Read m, Read n) => ReadPrec [Border m n]
forall m n. (Read m, Read n) => ReadPrec (Border m n)
forall m n. (Read m, Read n) => Int -> ReadS (Border m n)
forall m n. (Read m, Read n) => ReadS [Border m n]
$creadsPrec :: forall m n. (Read m, Read n) => Int -> ReadS (Border m n)
readsPrec :: Int -> ReadS (Border m n)
$creadList :: forall m n. (Read m, Read n) => ReadS [Border m n]
readList :: ReadS [Border m n]
$creadPrec :: forall m n. (Read m, Read n) => ReadPrec (Border m n)
readPrec :: ReadPrec (Border m n)
$creadListPrec :: forall m n. (Read m, Read n) => ReadPrec [Border m n]
readListPrec :: ReadPrec [Border m n]
Read, Int -> Border m n -> ShowS
[Border m n] -> ShowS
Border m n -> String
(Int -> Border m n -> ShowS)
-> (Border m n -> String)
-> ([Border m n] -> ShowS)
-> Show (Border m n)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall m n. (Show m, Show n) => Int -> Border m n -> ShowS
forall m n. (Show m, Show n) => [Border m n] -> ShowS
forall m n. (Show m, Show n) => Border m n -> String
$cshowsPrec :: forall m n. (Show m, Show n) => Int -> Border m n -> ShowS
showsPrec :: Int -> Border m n -> ShowS
$cshow :: forall m n. (Show m, Show n) => Border m n -> String
show :: Border m n -> String
$cshowList :: forall m n. (Show m, Show n) => [Border m n] -> ShowS
showList :: [Border m n] -> ShowS
Show, (forall x. Border m n -> Rep (Border m n) x)
-> (forall x. Rep (Border m n) x -> Border m n)
-> Generic (Border m n)
forall x. Rep (Border m n) x -> Border m n
forall x. Border m n -> Rep (Border m n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall m n x. Rep (Border m n) x -> Border m n
forall m n x. Border m n -> Rep (Border m n) x
$cfrom :: forall m n x. Border m n -> Rep (Border m n) x
from :: forall x. Border m n -> Rep (Border m n) x
$cto :: forall m n x. Rep (Border m n) x -> Border m n
to :: forall x. Rep (Border m n) x -> Border m n
Generic)
instance (NFData m, NFData n) => NFData (Border m n)
-- | Convert horizontal spacing via given callback.
mapX :: (n -> nn) -> Border m n -> Border m nn
-- | Convert vertical spacing via given callback.
mapY :: (m -> mm) -> Border m n -> Border mm n
mapX :: forall n nn m. (n -> nn) -> Border m n -> Border m nn
mapX n -> nn
cb Border m n
self = Border m n
self { left :: nn
left = n -> nn
cb (n -> nn) -> n -> nn
forall a b. (a -> b) -> a -> b
$ Border m n -> n
forall m n. Border m n -> n
left Border m n
self, right :: nn
right = n -> nn
cb (n -> nn) -> n -> nn
forall a b. (a -> b) -> a -> b
$ Border m n -> n
forall m n. Border m n -> n
right Border m n
self }
mapY :: forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY m -> mm
cb Border m n
self = Border m n
self { top :: mm
top = m -> mm
cb (m -> mm) -> m -> mm
forall a b. (a -> b) -> a -> b
$ Border m n -> m
forall m n. Border m n -> m
top Border m n
self, bottom :: mm
bottom = m -> mm
cb (m -> mm) -> m -> mm
forall a b. (a -> b) -> a -> b
$ Border m n -> m
forall m n. Border m n -> m
bottom Border m n
self }

-- | 2D size of a box. Typically inline is width & block is height.
-- This may change as support for vertical layout is added.
data Size m n = Size {forall m n. Size m n -> n
inline :: n, forall m n. Size m n -> m
block :: m} deriving (Size m n -> Size m n -> Bool
(Size m n -> Size m n -> Bool)
-> (Size m n -> Size m n -> Bool) -> Eq (Size m n)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall m n. (Eq n, Eq m) => Size m n -> Size m n -> Bool
$c== :: forall m n. (Eq n, Eq m) => Size m n -> Size m n -> Bool
== :: Size m n -> Size m n -> Bool
$c/= :: forall m n. (Eq n, Eq m) => Size m n -> Size m n -> Bool
/= :: Size m n -> Size m n -> Bool
Eq, Int -> Size m n -> ShowS
[Size m n] -> ShowS
Size m n -> String
(Int -> Size m n -> ShowS)
-> (Size m n -> String) -> ([Size m n] -> ShowS) -> Show (Size m n)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall m n. (Show n, Show m) => Int -> Size m n -> ShowS
forall m n. (Show n, Show m) => [Size m n] -> ShowS
forall m n. (Show n, Show m) => Size m n -> String
$cshowsPrec :: forall m n. (Show n, Show m) => Int -> Size m n -> ShowS
showsPrec :: Int -> Size m n -> ShowS
$cshow :: forall m n. (Show n, Show m) => Size m n -> String
show :: Size m n -> String
$cshowList :: forall m n. (Show n, Show m) => [Size m n] -> ShowS
showList :: [Size m n] -> ShowS
Show, ReadPrec [Size m n]
ReadPrec (Size m n)
Int -> ReadS (Size m n)
ReadS [Size m n]
(Int -> ReadS (Size m n))
-> ReadS [Size m n]
-> ReadPrec (Size m n)
-> ReadPrec [Size m n]
-> Read (Size m n)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall m n. (Read n, Read m) => ReadPrec [Size m n]
forall m n. (Read n, Read m) => ReadPrec (Size m n)
forall m n. (Read n, Read m) => Int -> ReadS (Size m n)
forall m n. (Read n, Read m) => ReadS [Size m n]
$creadsPrec :: forall m n. (Read n, Read m) => Int -> ReadS (Size m n)
readsPrec :: Int -> ReadS (Size m n)
$creadList :: forall m n. (Read n, Read m) => ReadS [Size m n]
readList :: ReadS [Size m n]
$creadPrec :: forall m n. (Read n, Read m) => ReadPrec (Size m n)
readPrec :: ReadPrec (Size m n)
$creadListPrec :: forall m n. (Read n, Read m) => ReadPrec [Size m n]
readListPrec :: ReadPrec [Size m n]
Read, (forall x. Size m n -> Rep (Size m n) x)
-> (forall x. Rep (Size m n) x -> Size m n) -> Generic (Size m n)
forall x. Rep (Size m n) x -> Size m n
forall x. Size m n -> Rep (Size m n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall m n x. Rep (Size m n) x -> Size m n
forall m n x. Size m n -> Rep (Size m n) x
$cfrom :: forall m n x. Size m n -> Rep (Size m n) x
from :: forall x. Size m n -> Rep (Size m n) x
$cto :: forall m n x. Rep (Size m n) x -> Size m n
to :: forall x. Rep (Size m n) x -> Size m n
Generic)
instance (NFData m, NFData n) => NFData (Size m n)
-- | Convert inline size via given callback
mapSizeY :: (m -> mm) -> Size m n -> Size mm n
mapSizeY :: forall m mm n. (m -> mm) -> Size m n -> Size mm n
mapSizeY m -> mm
cb Size m n
self = n -> mm -> Size mm n
forall m n. n -> m -> Size m n
Size (Size m n -> n
forall m n. Size m n -> n
inline Size m n
self) (m -> mm
cb (m -> mm) -> m -> mm
forall a b. (a -> b) -> a -> b
$ Size m n -> m
forall m n. Size m n -> m
block Size m n
self)
-- | Convert block size via given callback
mapSizeX :: (n -> nn) -> Size m n -> Size m nn
mapSizeX :: forall n nn m. (n -> nn) -> Size m n -> Size m nn
mapSizeX n -> nn
cb Size m n
self = nn -> m -> Size m nn
forall m n. n -> m -> Size m n
Size (n -> nn
cb (n -> nn) -> n -> nn
forall a b. (a -> b) -> a -> b
$ Size m n -> n
forall m n. Size m n -> n
inline Size m n
self) (Size m n -> m
forall m n. Size m n -> m
block Size m n
self)

-- | A box with min & max bounds & surrounding borders. The CSS Box Model.
data PaddedBox m n = PaddedBox {
    -- | The minimum amount of pixels this box should take.
    forall m n. PaddedBox m n -> Size m n
min :: Size m n,
    -- | The maximum amount of pixels this box should take.
    forall m n. PaddedBox m n -> Size m n
max :: Size m n,
    -- | The ideal number of pixels this box should take.
    forall m n. PaddedBox m n -> Size Double Double
nat :: Size Double Double,
    -- | The amount of pixels this box should take.
    forall m n. PaddedBox m n -> Size m n
size :: Size m n,
    -- | The amount of space between the box & the border.
    forall m n. PaddedBox m n -> Border m n
padding :: Border m n,
    -- | The amount of space for the border.
    forall m n. PaddedBox m n -> Border m n
border :: Border m n,
    -- | The amount of space between the border & anything else.
    forall m n. PaddedBox m n -> Border m n
margin :: Border m n
} deriving (PaddedBox m n -> PaddedBox m n -> Bool
(PaddedBox m n -> PaddedBox m n -> Bool)
-> (PaddedBox m n -> PaddedBox m n -> Bool) -> Eq (PaddedBox m n)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall m n. (Eq n, Eq m) => PaddedBox m n -> PaddedBox m n -> Bool
$c== :: forall m n. (Eq n, Eq m) => PaddedBox m n -> PaddedBox m n -> Bool
== :: PaddedBox m n -> PaddedBox m n -> Bool
$c/= :: forall m n. (Eq n, Eq m) => PaddedBox m n -> PaddedBox m n -> Bool
/= :: PaddedBox m n -> PaddedBox m n -> Bool
Eq, ReadPrec [PaddedBox m n]
ReadPrec (PaddedBox m n)
Int -> ReadS (PaddedBox m n)
ReadS [PaddedBox m n]
(Int -> ReadS (PaddedBox m n))
-> ReadS [PaddedBox m n]
-> ReadPrec (PaddedBox m n)
-> ReadPrec [PaddedBox m n]
-> Read (PaddedBox m n)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall m n. (Read n, Read m) => ReadPrec [PaddedBox m n]
forall m n. (Read n, Read m) => ReadPrec (PaddedBox m n)
forall m n. (Read n, Read m) => Int -> ReadS (PaddedBox m n)
forall m n. (Read n, Read m) => ReadS [PaddedBox m n]
$creadsPrec :: forall m n. (Read n, Read m) => Int -> ReadS (PaddedBox m n)
readsPrec :: Int -> ReadS (PaddedBox m n)
$creadList :: forall m n. (Read n, Read m) => ReadS [PaddedBox m n]
readList :: ReadS [PaddedBox m n]
$creadPrec :: forall m n. (Read n, Read m) => ReadPrec (PaddedBox m n)
readPrec :: ReadPrec (PaddedBox m n)
$creadListPrec :: forall m n. (Read n, Read m) => ReadPrec [PaddedBox m n]
readListPrec :: ReadPrec [PaddedBox m n]
Read, Int -> PaddedBox m n -> ShowS
[PaddedBox m n] -> ShowS
PaddedBox m n -> String
(Int -> PaddedBox m n -> ShowS)
-> (PaddedBox m n -> String)
-> ([PaddedBox m n] -> ShowS)
-> Show (PaddedBox m n)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall m n. (Show n, Show m) => Int -> PaddedBox m n -> ShowS
forall m n. (Show n, Show m) => [PaddedBox m n] -> ShowS
forall m n. (Show n, Show m) => PaddedBox m n -> String
$cshowsPrec :: forall m n. (Show n, Show m) => Int -> PaddedBox m n -> ShowS
showsPrec :: Int -> PaddedBox m n -> ShowS
$cshow :: forall m n. (Show n, Show m) => PaddedBox m n -> String
show :: PaddedBox m n -> String
$cshowList :: forall m n. (Show n, Show m) => [PaddedBox m n] -> ShowS
showList :: [PaddedBox m n] -> ShowS
Show, (forall x. PaddedBox m n -> Rep (PaddedBox m n) x)
-> (forall x. Rep (PaddedBox m n) x -> PaddedBox m n)
-> Generic (PaddedBox m n)
forall x. Rep (PaddedBox m n) x -> PaddedBox m n
forall x. PaddedBox m n -> Rep (PaddedBox m n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall m n x. Rep (PaddedBox m n) x -> PaddedBox m n
forall m n x. PaddedBox m n -> Rep (PaddedBox m n) x
$cfrom :: forall m n x. PaddedBox m n -> Rep (PaddedBox m n) x
from :: forall x. PaddedBox m n -> Rep (PaddedBox m n) x
$cto :: forall m n x. Rep (PaddedBox m n) x -> PaddedBox m n
to :: forall x. Rep (PaddedBox m n) x -> PaddedBox m n
Generic)
instance (NFData m, NFData n) => NFData (PaddedBox m n)
-- | An empty box, takes up nospace onscreen.
zeroBox :: PaddedBox Double Double
zeroBox :: PaddedBox Double Double
zeroBox = PaddedBox {
    min :: Size Double Double
min = Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
Size Double
0 Double
0,
    max :: Size Double Double
max = Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
Size Double
0 Double
0,
    nat :: Size Double Double
nat = Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
Size Double
0 Double
0,
    size :: Size Double Double
size = Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
Size Double
0 Double
0,
    padding :: Border Double Double
padding = Double -> Double -> Double -> Double -> Border Double Double
forall m n. m -> m -> n -> n -> Border m n
Border Double
0 Double
0 Double
0 Double
0,
    border :: Border Double Double
border = Double -> Double -> Double -> Double -> Border Double Double
forall m n. m -> m -> n -> n -> Border m n
Border Double
0 Double
0 Double
0 Double
0,
    margin :: Border Double Double
margin = Double -> Double -> Double -> Double -> Border Double Double
forall m n. m -> m -> n -> n -> Border m n
Border Double
0 Double
0 Double
0 Double
0
  }
-- | A box which takes up all available space with no borders.
lengthBox :: PaddedBox Length Length
lengthBox :: PaddedBox Length Length
lengthBox = PaddedBox {
    min :: Size Length Length
min = Length -> Length -> Size Length Length
forall m n. n -> m -> Size m n
Size Length
Auto Length
Auto,
    max :: Size Length Length
max = Length -> Length -> Size Length Length
forall m n. n -> m -> Size m n
Size Length
Auto Length
Auto,
    nat :: Size Double Double
nat = Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
Size Double
0 Double
0,
    size :: Size Length Length
size = Length -> Length -> Size Length Length
forall m n. n -> m -> Size m n
Size Length
Auto Length
Auto,
    padding :: Border Length Length
padding = Length -> Length -> Length -> Length -> Border Length Length
forall m n. m -> m -> n -> n -> Border m n
Border Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero,
    border :: Border Length Length
border = Length -> Length -> Length -> Length -> Border Length Length
forall m n. m -> m -> n -> n -> Border m n
Border Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero,
    margin :: Border Length Length
margin = Length -> Length -> Length -> Length -> Border Length Length
forall m n. m -> m -> n -> n -> Border m n
Border Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero Length
forall a. Zero a => a
zero
  }

-- | Convert all sizes along the inline axis via given callback.
mapX' :: (n -> nn) -> PaddedBox m n -> PaddedBox m nn
mapX' :: forall n nn m. (n -> nn) -> PaddedBox m n -> PaddedBox m nn
mapX' n -> nn
cb PaddedBox {Size m n
Size Double Double
Border m n
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size m n
max :: Size m n
nat :: Size Double Double
size :: Size m n
padding :: Border m n
border :: Border m n
margin :: Border m n
..} = PaddedBox {
    min :: Size m nn
min = nn -> m -> Size m nn
forall m n. n -> m -> Size m n
Size (n -> nn
cb (n -> nn) -> n -> nn
forall a b. (a -> b) -> a -> b
$ Size m n -> n
forall m n. Size m n -> n
inline Size m n
min) (Size m n -> m
forall m n. Size m n -> m
block Size m n
min),
    size :: Size m nn
size = nn -> m -> Size m nn
forall m n. n -> m -> Size m n
Size (n -> nn
cb (n -> nn) -> n -> nn
forall a b. (a -> b) -> a -> b
$ Size m n -> n
forall m n. Size m n -> n
inline Size m n
size) (Size m n -> m
forall m n. Size m n -> m
block Size m n
size),
    nat :: Size Double Double
nat = Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
Size Double
0 Double
0,
    max :: Size m nn
max = nn -> m -> Size m nn
forall m n. n -> m -> Size m n
Size (n -> nn
cb (n -> nn) -> n -> nn
forall a b. (a -> b) -> a -> b
$ Size m n -> n
forall m n. Size m n -> n
inline Size m n
max) (Size m n -> m
forall m n. Size m n -> m
block Size m n
max),
    padding :: Border m nn
padding = (n -> nn) -> Border m n -> Border m nn
forall n nn m. (n -> nn) -> Border m n -> Border m nn
mapX n -> nn
cb Border m n
padding,
    border :: Border m nn
border = (n -> nn) -> Border m n -> Border m nn
forall n nn m. (n -> nn) -> Border m n -> Border m nn
mapX n -> nn
cb Border m n
border,
    margin :: Border m nn
margin = (n -> nn) -> Border m n -> Border m nn
forall n nn m. (n -> nn) -> Border m n -> Border m nn
mapX n -> nn
cb Border m n
margin
  }
-- | Convert all sizes along the block axis via given callback.
mapY' :: (m -> mm) -> PaddedBox m n -> PaddedBox mm n
mapY' :: forall m mm n. (m -> mm) -> PaddedBox m n -> PaddedBox mm n
mapY' m -> mm
cb PaddedBox {Size m n
Size Double Double
Border m n
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size m n
max :: Size m n
nat :: Size Double Double
size :: Size m n
padding :: Border m n
border :: Border m n
margin :: Border m n
..} = PaddedBox {
    min :: Size mm n
min = n -> mm -> Size mm n
forall m n. n -> m -> Size m n
Size (Size m n -> n
forall m n. Size m n -> n
inline Size m n
min) (m -> mm
cb (m -> mm) -> m -> mm
forall a b. (a -> b) -> a -> b
$ Size m n -> m
forall m n. Size m n -> m
block Size m n
min),
    size :: Size mm n
size = n -> mm -> Size mm n
forall m n. n -> m -> Size m n
Size (Size m n -> n
forall m n. Size m n -> n
inline Size m n
size) (m -> mm
cb (m -> mm) -> m -> mm
forall a b. (a -> b) -> a -> b
$ Size m n -> m
forall m n. Size m n -> m
block Size m n
size),
    nat :: Size Double Double
nat = Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
Size Double
0 Double
0,
    max :: Size mm n
max = n -> mm -> Size mm n
forall m n. n -> m -> Size m n
Size (Size m n -> n
forall m n. Size m n -> n
inline Size m n
max) (m -> mm
cb (m -> mm) -> m -> mm
forall a b. (a -> b) -> a -> b
$ Size m n -> m
forall m n. Size m n -> m
block Size m n
max),
    padding :: Border mm n
padding = (m -> mm) -> Border m n -> Border mm n
forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY m -> mm
cb Border m n
padding,
    border :: Border mm n
border = (m -> mm) -> Border m n -> Border mm n
forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY m -> mm
cb Border m n
border,
    margin :: Border mm n
margin = (m -> mm) -> Border m n -> Border mm n
forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY m -> mm
cb Border m n
margin
  }

-- | The total size along the inline axis including borders, etc.
width :: PaddedBox m a -> a
width PaddedBox {Size m a
Size Double Double
Border m a
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size m a
max :: Size m a
nat :: Size Double Double
size :: Size m a
padding :: Border m a
border :: Border m a
margin :: Border m a
..} = Border m a -> a
forall m n. Border m n -> n
left Border m a
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
left Border m a
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
left Border m a
padding a -> a -> a
forall a. Num a => a -> a -> a
+
    Size m a -> a
forall m n. Size m n -> n
inline Size m a
size a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
padding a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
margin
-- | The total size along the block axis, including borders, etc.
height :: PaddedBox a n -> a
height PaddedBox {Size a n
Size Double Double
Border a n
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size a n
max :: Size a n
nat :: Size Double Double
size :: Size a n
padding :: Border a n
border :: Border a n
margin :: Border a n
..} = Border a n -> a
forall m n. Border m n -> m
top Border a n
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
top Border a n
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
top Border a n
padding a -> a -> a
forall a. Num a => a -> a -> a
+
    Size a n -> a
forall m n. Size m n -> m
block Size a n
size a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
padding a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
margin
-- | The total minimum size along the inline axis.
minWidth :: PaddedBox m a -> a
minWidth PaddedBox {Size m a
Size Double Double
Border m a
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size m a
max :: Size m a
nat :: Size Double Double
size :: Size m a
padding :: Border m a
border :: Border m a
margin :: Border m a
..} = Border m a -> a
forall m n. Border m n -> n
left Border m a
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
left Border m a
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
left Border m a
padding a -> a -> a
forall a. Num a => a -> a -> a
+
    Size m a -> a
forall m n. Size m n -> n
inline Size m a
min a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
padding a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
margin
-- | The total minimum size along the block axis.
minHeight :: PaddedBox a n -> a
minHeight PaddedBox {Size a n
Size Double Double
Border a n
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size a n
max :: Size a n
nat :: Size Double Double
size :: Size a n
padding :: Border a n
border :: Border a n
margin :: Border a n
..} = Border a n -> a
forall m n. Border m n -> m
top Border a n
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
top Border a n
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
top Border a n
padding a -> a -> a
forall a. Num a => a -> a -> a
+
    Size a n -> a
forall m n. Size m n -> m
block Size a n
min a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
padding a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
margin
-- | The total maximum size along the inline axis.
maxWidth :: PaddedBox m a -> a
maxWidth PaddedBox {Size m a
Size Double Double
Border m a
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size m a
max :: Size m a
nat :: Size Double Double
size :: Size m a
padding :: Border m a
border :: Border m a
margin :: Border m a
..} = Border m a -> a
forall m n. Border m n -> n
left Border m a
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
left Border m a
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
left Border m a
padding a -> a -> a
forall a. Num a => a -> a -> a
+
    Size m a -> a
forall m n. Size m n -> n
inline Size m a
max a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
padding a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
margin
-- | The total maximum size along the block axis.
maxHeight :: PaddedBox a n -> a
maxHeight PaddedBox {Size a n
Size Double Double
Border a n
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size a n
max :: Size a n
nat :: Size Double Double
size :: Size a n
padding :: Border a n
border :: Border a n
margin :: Border a n
..} = Border a n -> a
forall m n. Border m n -> m
top Border a n
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
top Border a n
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
top Border a n
padding a -> a -> a
forall a. Num a => a -> a -> a
+
    Size a n -> a
forall m n. Size m n -> m
block Size a n
max a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
padding a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
margin

-- | Amount of whitespace to the left, summing margins, borders, & padding.
leftSpace :: PaddedBox m a -> a
leftSpace PaddedBox {Size m a
Size Double Double
Border m a
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size m a
max :: Size m a
nat :: Size Double Double
size :: Size m a
padding :: Border m a
border :: Border m a
margin :: Border m a
..} = Border m a -> a
forall m n. Border m n -> n
left Border m a
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
left Border m a
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
left Border m a
padding
-- | Amount of whitespace to the right, summing margins, borders, & padding.
rightSpace :: PaddedBox m a -> a
rightSpace PaddedBox {Size m a
Size Double Double
Border m a
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size m a
max :: Size m a
nat :: Size Double Double
size :: Size m a
padding :: Border m a
border :: Border m a
margin :: Border m a
..} = Border m a -> a
forall m n. Border m n -> n
right Border m a
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border m a -> a
forall m n. Border m n -> n
right Border m a
padding
-- | Amount of whitespace to the top, summing margins, borders, & padding.
topSpace :: PaddedBox a n -> a
topSpace PaddedBox {Size a n
Size Double Double
Border a n
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size a n
max :: Size a n
nat :: Size Double Double
size :: Size a n
padding :: Border a n
border :: Border a n
margin :: Border a n
..} = Border a n -> a
forall m n. Border m n -> m
top Border a n
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
top Border a n
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
top Border a n
padding
-- | Amount of whitespace to the bottom, summing margins, borders, & padding.
bottomSpace :: PaddedBox a n -> a
bottomSpace PaddedBox {Size a n
Size Double Double
Border a n
min :: forall m n. PaddedBox m n -> Size m n
max :: forall m n. PaddedBox m n -> Size m n
nat :: forall m n. PaddedBox m n -> Size Double Double
size :: forall m n. PaddedBox m n -> Size m n
padding :: forall m n. PaddedBox m n -> Border m n
border :: forall m n. PaddedBox m n -> Border m n
margin :: forall m n. PaddedBox m n -> Border m n
min :: Size a n
max :: Size a n
nat :: Size Double Double
size :: Size a n
padding :: Border a n
border :: Border a n
margin :: Border a n
..} = Border a n -> a
forall m n. Border m n -> m
bottom Border a n
margin a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
border a -> a -> a
forall a. Num a => a -> a -> a
+ Border a n -> a
forall m n. Border m n -> m
bottom Border a n
padding
-- | Amount of whitespace along the x axis, summing margins, borders, & padding.
hSpace :: PaddedBox m a -> a
hSpace PaddedBox m a
self = PaddedBox m a -> a
forall {a} {m}. Num a => PaddedBox m a -> a
leftSpace PaddedBox m a
self a -> a -> a
forall a. Num a => a -> a -> a
+ PaddedBox m a -> a
forall {a} {m}. Num a => PaddedBox m a -> a
rightSpace PaddedBox m a
self
-- | Amount of whitespace along the y axis, summing margins, borders, & padding.
vSpace :: PaddedBox a n -> a
vSpace PaddedBox a n
self = PaddedBox a n -> a
forall {a} {n}. Num a => PaddedBox a n -> a
topSpace PaddedBox a n
self a -> a -> a
forall a. Num a => a -> a -> a
+ PaddedBox a n -> a
forall {a} {n}. Num a => PaddedBox a n -> a
bottomSpace PaddedBox a n
self

-- | A partially-computed length value.
data Length = Pixels Double -- ^ Absolute number of device pixels.
        | Percent Double -- ^ Multiplier by container width.
        | Auto -- ^ Use normal layout computations.
        | Preferred -- ^ Use computed preferred width.
        | Min -- ^ Use minimum legible width.
        deriving (Length -> Length -> Bool
(Length -> Length -> Bool)
-> (Length -> Length -> Bool) -> Eq Length
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Length -> Length -> Bool
== :: Length -> Length -> Bool
$c/= :: Length -> Length -> Bool
/= :: Length -> Length -> Bool
Eq, ReadPrec [Length]
ReadPrec Length
Int -> ReadS Length
ReadS [Length]
(Int -> ReadS Length)
-> ReadS [Length]
-> ReadPrec Length
-> ReadPrec [Length]
-> Read Length
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Length
readsPrec :: Int -> ReadS Length
$creadList :: ReadS [Length]
readList :: ReadS [Length]
$creadPrec :: ReadPrec Length
readPrec :: ReadPrec Length
$creadListPrec :: ReadPrec [Length]
readListPrec :: ReadPrec [Length]
Read, Int -> Length -> ShowS
[Length] -> ShowS
Length -> String
(Int -> Length -> ShowS)
-> (Length -> String) -> ([Length] -> ShowS) -> Show Length
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Length -> ShowS
showsPrec :: Int -> Length -> ShowS
$cshow :: Length -> String
show :: Length -> String
$cshowList :: [Length] -> ShowS
showList :: [Length] -> ShowS
Show, (forall x. Length -> Rep Length x)
-> (forall x. Rep Length x -> Length) -> Generic Length
forall x. Rep Length x -> Length
forall x. Length -> Rep Length x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Length -> Rep Length x
from :: forall x. Length -> Rep Length x
$cto :: forall x. Rep Length x -> Length
to :: forall x. Rep Length x -> Length
Generic)
instance NFData Length

-- | Convert a length given the container's width. Filling in 0 for keywords.
-- If you wish for keywords to be handled differently, callers need to compute
-- that themselves.
lowerLength :: Double -> Length -> Double
lowerLength :: Double -> Length -> Double
lowerLength Double
_ (Pixels Double
x) = Double
x
lowerLength Double
outerwidth (Percent Double
x) = Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
outerwidth
lowerLength Double
_ Length
_ = Double
0

-- | Replace keywords with a given number of pixels.
-- Useful for avoiding messing up percentage calculations in later processing.
mapAuto :: Double -> Length -> Length
mapAuto Double
x Length
Auto = Double -> Length
Pixels Double
x
mapAuto Double
x Length
Preferred = Double -> Length
Pixels Double
x
mapAuto Double
x Length
Min = Double -> Length
Pixels Double
x
mapAuto Double
_ Length
x = Length
x

-- | Typeclass for zeroing out fields, so layout primitives can be more reusable.
class Zero a where
    -- | Return the empty (or zero) value for a CatTrap geometric type.
    zero :: a

instance Zero Double where zero :: Double
zero = Double
0
instance Zero Length where zero :: Length
zero = Double -> Length
Pixels Double
0
instance (Zero m, Zero n) => Zero (PaddedBox m n) where
    zero :: PaddedBox m n
zero = PaddedBox {
        min :: Size m n
min = n -> m -> Size m n
forall m n. n -> m -> Size m n
Size n
forall a. Zero a => a
zero m
forall a. Zero a => a
zero,
        max :: Size m n
max = n -> m -> Size m n
forall m n. n -> m -> Size m n
Size n
forall a. Zero a => a
zero m
forall a. Zero a => a
zero,
        nat :: Size Double Double
nat = Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
Size Double
0 Double
0,
        size :: Size m n
size = n -> m -> Size m n
forall m n. n -> m -> Size m n
Size n
forall a. Zero a => a
zero m
forall a. Zero a => a
zero,
        padding :: Border m n
padding = m -> m -> n -> n -> Border m n
forall m n. m -> m -> n -> n -> Border m n
Border m
forall a. Zero a => a
zero m
forall a. Zero a => a
zero n
forall a. Zero a => a
zero n
forall a. Zero a => a
zero,
        border :: Border m n
border = m -> m -> n -> n -> Border m n
forall m n. m -> m -> n -> n -> Border m n
Border m
forall a. Zero a => a
zero m
forall a. Zero a => a
zero n
forall a. Zero a => a
zero n
forall a. Zero a => a
zero,
        margin :: Border m n
margin = m -> m -> n -> n -> Border m n
forall m n. m -> m -> n -> n -> Border m n
Border m
forall a. Zero a => a
zero m
forall a. Zero a => a
zero n
forall a. Zero a => a
zero n
forall a. Zero a => a
zero
    }
instance (Zero m, Zero n) => Zero (Border m n) where
    zero :: Border m n
zero = m -> m -> n -> n -> Border m n
forall m n. m -> m -> n -> n -> Border m n
Border m
forall a. Zero a => a
zero m
forall a. Zero a => a
zero n
forall a. Zero a => a
zero n
forall a. Zero a => a
zero

-- | Typeclass for converting between doubles & layout types, approximately if needs be.
-- So layout primitives can be more reusable.
class CastDouble a where
    -- | Convert a double to a double or length.
    fromDouble :: Double -> a
    -- | Convert a double or length to a double.
    toDouble :: a -> Double
    toDouble = Double -> a -> Double
forall a. CastDouble a => Double -> a -> Double
toDoubleWithin Double
0
    toDoubleWithin :: Double -> a -> Double
    toDoubleWithin Double
_ = a -> Double
forall a. CastDouble a => a -> Double
toDouble
    toDoubleWithinAuto :: Double -> Double -> a -> Double
    toDoubleWithinAuto Double
_ = Double -> a -> Double
forall a. CastDouble a => Double -> a -> Double
toDoubleWithin

instance CastDouble Double where
    fromDouble :: Double -> Double
fromDouble = Double -> Double
forall a. a -> a
id
    toDouble :: Double -> Double
toDouble = Double -> Double
forall a. a -> a
id
instance CastDouble Length where
    fromDouble :: Double -> Length
fromDouble = Double -> Length
Pixels
    toDoubleWithin :: Double -> Length -> Double
toDoubleWithin = Double -> Length -> Double
lowerLength
    toDoubleWithinAuto :: Double -> Double -> Length -> Double
toDoubleWithinAuto Double
x Double
_ Length
Auto = Double
x
    toDoubleWithinAuto Double
_ Double
x Length
y = Double -> Length -> Double
forall a. CastDouble a => Double -> a -> Double
toDoubleWithin Double
x Length
y