{-# LANGUAGE RecordWildCards, OverloadedStrings, DeriveGeneric #-}
-- | Sizes grid cells & positions elements to them.
module Graphics.Layout.Grid(Grid(..), Track(..), GridItem(..), GridItem'(..), Alignment(..),
        buildTrack, buildGrid, setCellBox, enumerate, gridItemBox, cellSize,
        trackMin, trackNat, gridEstWidth, sizeTrackMins, sizeTrackNats, sizeTrackMaxs,
        trackPosition, gridPosition, trackLayout, gridLayout) where

import Data.Either (fromRight)
import Data.Text (Text)
import Data.List (intersperse)
import Graphics.Layout.Box as B

import Debug.Trace (trace)
import GHC.Generics (Generic)
import Control.DeepSeq (NFData)

-- | An element which positions it's children within a grid.
type Grid m n = Size (Track m) (Track n)
-- | The sizes to which children are alonged on a single axis.
data Track x = Track {
    -- | The desired size of each cell.
    -- If Left specifies ratio of excess space to use.
    forall x. Track x -> [Either x Double]
cells :: [Either x Double],
    -- | The minimum amount of space each cell should take.
    forall x. Track x -> [Double]
trackMins :: [Double],
    -- | The ideal amount of space each cell should take.
    forall x. Track x -> [Double]
trackNats :: [Double],
    -- | How much space to add between cells.
    forall x. Track x -> x
gap :: x
} deriving (Int -> Track x -> ShowS
[Track x] -> ShowS
Track x -> String
(Int -> Track x -> ShowS)
-> (Track x -> String) -> ([Track x] -> ShowS) -> Show (Track x)
forall x. Show x => Int -> Track x -> ShowS
forall x. Show x => [Track x] -> ShowS
forall x. Show x => Track x -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall x. Show x => Int -> Track x -> ShowS
showsPrec :: Int -> Track x -> ShowS
$cshow :: forall x. Show x => Track x -> String
show :: Track x -> String
$cshowList :: forall x. Show x => [Track x] -> ShowS
showList :: [Track x] -> ShowS
Show, ReadPrec [Track x]
ReadPrec (Track x)
Int -> ReadS (Track x)
ReadS [Track x]
(Int -> ReadS (Track x))
-> ReadS [Track x]
-> ReadPrec (Track x)
-> ReadPrec [Track x]
-> Read (Track x)
forall x. Read x => ReadPrec [Track x]
forall x. Read x => ReadPrec (Track x)
forall x. Read x => Int -> ReadS (Track x)
forall x. Read x => ReadS [Track x]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall x. Read x => Int -> ReadS (Track x)
readsPrec :: Int -> ReadS (Track x)
$creadList :: forall x. Read x => ReadS [Track x]
readList :: ReadS [Track x]
$creadPrec :: forall x. Read x => ReadPrec (Track x)
readPrec :: ReadPrec (Track x)
$creadListPrec :: forall x. Read x => ReadPrec [Track x]
readListPrec :: ReadPrec [Track x]
Read, Track x -> Track x -> Bool
(Track x -> Track x -> Bool)
-> (Track x -> Track x -> Bool) -> Eq (Track x)
forall x. Eq x => Track x -> Track x -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall x. Eq x => Track x -> Track x -> Bool
== :: Track x -> Track x -> Bool
$c/= :: forall x. Eq x => Track x -> Track x -> Bool
/= :: Track x -> Track x -> Bool
Eq, Eq (Track x)
Eq (Track x)
-> (Track x -> Track x -> Ordering)
-> (Track x -> Track x -> Bool)
-> (Track x -> Track x -> Bool)
-> (Track x -> Track x -> Bool)
-> (Track x -> Track x -> Bool)
-> (Track x -> Track x -> Track x)
-> (Track x -> Track x -> Track x)
-> Ord (Track x)
Track x -> Track x -> Bool
Track x -> Track x -> Ordering
Track x -> Track x -> Track x
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {x}. Ord x => Eq (Track x)
forall x. Ord x => Track x -> Track x -> Bool
forall x. Ord x => Track x -> Track x -> Ordering
forall x. Ord x => Track x -> Track x -> Track x
$ccompare :: forall x. Ord x => Track x -> Track x -> Ordering
compare :: Track x -> Track x -> Ordering
$c< :: forall x. Ord x => Track x -> Track x -> Bool
< :: Track x -> Track x -> Bool
$c<= :: forall x. Ord x => Track x -> Track x -> Bool
<= :: Track x -> Track x -> Bool
$c> :: forall x. Ord x => Track x -> Track x -> Bool
> :: Track x -> Track x -> Bool
$c>= :: forall x. Ord x => Track x -> Track x -> Bool
>= :: Track x -> Track x -> Bool
$cmax :: forall x. Ord x => Track x -> Track x -> Track x
max :: Track x -> Track x -> Track x
$cmin :: forall x. Ord x => Track x -> Track x -> Track x
min :: Track x -> Track x -> Track x
Ord)
-- | Which cells a child should be aligned to.
type GridItem = Size GridItem' GridItem'
-- | How a grid child should be aligned per-axis.
data GridItem' = GridItem {
    -- | On which cell should this child start.
    GridItem' -> Int
cellStart :: Int,
    -- | Before which cell should this child end.
    GridItem' -> Int
cellEnd :: Int,
    -- | How to redistribute excess space.
    GridItem' -> Alignment
alignment :: Alignment,
    -- | The minimum amount of space to allocate to this child.
    GridItem' -> Double
minSize :: Double,
    -- | The maximum aount of space to allocate to this child.
    GridItem' -> Double
natSize :: Double
} deriving (ReadPrec [GridItem']
ReadPrec GridItem'
Int -> ReadS GridItem'
ReadS [GridItem']
(Int -> ReadS GridItem')
-> ReadS [GridItem']
-> ReadPrec GridItem'
-> ReadPrec [GridItem']
-> Read GridItem'
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS GridItem'
readsPrec :: Int -> ReadS GridItem'
$creadList :: ReadS [GridItem']
readList :: ReadS [GridItem']
$creadPrec :: ReadPrec GridItem'
readPrec :: ReadPrec GridItem'
$creadListPrec :: ReadPrec [GridItem']
readListPrec :: ReadPrec [GridItem']
Read, Int -> GridItem' -> ShowS
[GridItem'] -> ShowS
GridItem' -> String
(Int -> GridItem' -> ShowS)
-> (GridItem' -> String)
-> ([GridItem'] -> ShowS)
-> Show GridItem'
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GridItem' -> ShowS
showsPrec :: Int -> GridItem' -> ShowS
$cshow :: GridItem' -> String
show :: GridItem' -> String
$cshowList :: [GridItem'] -> ShowS
showList :: [GridItem'] -> ShowS
Show, Eq GridItem'
Eq GridItem'
-> (GridItem' -> GridItem' -> Ordering)
-> (GridItem' -> GridItem' -> Bool)
-> (GridItem' -> GridItem' -> Bool)
-> (GridItem' -> GridItem' -> Bool)
-> (GridItem' -> GridItem' -> Bool)
-> (GridItem' -> GridItem' -> GridItem')
-> (GridItem' -> GridItem' -> GridItem')
-> Ord GridItem'
GridItem' -> GridItem' -> Bool
GridItem' -> GridItem' -> Ordering
GridItem' -> GridItem' -> GridItem'
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: GridItem' -> GridItem' -> Ordering
compare :: GridItem' -> GridItem' -> Ordering
$c< :: GridItem' -> GridItem' -> Bool
< :: GridItem' -> GridItem' -> Bool
$c<= :: GridItem' -> GridItem' -> Bool
<= :: GridItem' -> GridItem' -> Bool
$c> :: GridItem' -> GridItem' -> Bool
> :: GridItem' -> GridItem' -> Bool
$c>= :: GridItem' -> GridItem' -> Bool
>= :: GridItem' -> GridItem' -> Bool
$cmax :: GridItem' -> GridItem' -> GridItem'
max :: GridItem' -> GridItem' -> GridItem'
$cmin :: GridItem' -> GridItem' -> GridItem'
min :: GridItem' -> GridItem' -> GridItem'
Ord, GridItem' -> GridItem' -> Bool
(GridItem' -> GridItem' -> Bool)
-> (GridItem' -> GridItem' -> Bool) -> Eq GridItem'
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GridItem' -> GridItem' -> Bool
== :: GridItem' -> GridItem' -> Bool
$c/= :: GridItem' -> GridItem' -> Bool
/= :: GridItem' -> GridItem' -> Bool
Eq, (forall x. GridItem' -> Rep GridItem' x)
-> (forall x. Rep GridItem' x -> GridItem') -> Generic GridItem'
forall x. Rep GridItem' x -> GridItem'
forall x. GridItem' -> Rep GridItem' x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. GridItem' -> Rep GridItem' x
from :: forall x. GridItem' -> Rep GridItem' x
$cto :: forall x. Rep GridItem' x -> GridItem'
to :: forall x. Rep GridItem' x -> GridItem'
Generic)
instance NFData GridItem'
-- | How to redistribute excess space.
data Alignment = Start | Mid | End deriving (ReadPrec [Alignment]
ReadPrec Alignment
Int -> ReadS Alignment
ReadS [Alignment]
(Int -> ReadS Alignment)
-> ReadS [Alignment]
-> ReadPrec Alignment
-> ReadPrec [Alignment]
-> Read Alignment
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Alignment
readsPrec :: Int -> ReadS Alignment
$creadList :: ReadS [Alignment]
readList :: ReadS [Alignment]
$creadPrec :: ReadPrec Alignment
readPrec :: ReadPrec Alignment
$creadListPrec :: ReadPrec [Alignment]
readListPrec :: ReadPrec [Alignment]
Read, Int -> Alignment -> ShowS
[Alignment] -> ShowS
Alignment -> String
(Int -> Alignment -> ShowS)
-> (Alignment -> String)
-> ([Alignment] -> ShowS)
-> Show Alignment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Alignment -> ShowS
showsPrec :: Int -> Alignment -> ShowS
$cshow :: Alignment -> String
show :: Alignment -> String
$cshowList :: [Alignment] -> ShowS
showList :: [Alignment] -> ShowS
Show, Int -> Alignment
Alignment -> Int
Alignment -> [Alignment]
Alignment -> Alignment
Alignment -> Alignment -> [Alignment]
Alignment -> Alignment -> Alignment -> [Alignment]
(Alignment -> Alignment)
-> (Alignment -> Alignment)
-> (Int -> Alignment)
-> (Alignment -> Int)
-> (Alignment -> [Alignment])
-> (Alignment -> Alignment -> [Alignment])
-> (Alignment -> Alignment -> [Alignment])
-> (Alignment -> Alignment -> Alignment -> [Alignment])
-> Enum Alignment
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Alignment -> Alignment
succ :: Alignment -> Alignment
$cpred :: Alignment -> Alignment
pred :: Alignment -> Alignment
$ctoEnum :: Int -> Alignment
toEnum :: Int -> Alignment
$cfromEnum :: Alignment -> Int
fromEnum :: Alignment -> Int
$cenumFrom :: Alignment -> [Alignment]
enumFrom :: Alignment -> [Alignment]
$cenumFromThen :: Alignment -> Alignment -> [Alignment]
enumFromThen :: Alignment -> Alignment -> [Alignment]
$cenumFromTo :: Alignment -> Alignment -> [Alignment]
enumFromTo :: Alignment -> Alignment -> [Alignment]
$cenumFromThenTo :: Alignment -> Alignment -> Alignment -> [Alignment]
enumFromThenTo :: Alignment -> Alignment -> Alignment -> [Alignment]
Enum, Eq Alignment
Eq Alignment
-> (Alignment -> Alignment -> Ordering)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Alignment)
-> (Alignment -> Alignment -> Alignment)
-> Ord Alignment
Alignment -> Alignment -> Bool
Alignment -> Alignment -> Ordering
Alignment -> Alignment -> Alignment
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Alignment -> Alignment -> Ordering
compare :: Alignment -> Alignment -> Ordering
$c< :: Alignment -> Alignment -> Bool
< :: Alignment -> Alignment -> Bool
$c<= :: Alignment -> Alignment -> Bool
<= :: Alignment -> Alignment -> Bool
$c> :: Alignment -> Alignment -> Bool
> :: Alignment -> Alignment -> Bool
$c>= :: Alignment -> Alignment -> Bool
>= :: Alignment -> Alignment -> Bool
$cmax :: Alignment -> Alignment -> Alignment
max :: Alignment -> Alignment -> Alignment
$cmin :: Alignment -> Alignment -> Alignment
min :: Alignment -> Alignment -> Alignment
Ord, Alignment -> Alignment -> Bool
(Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool) -> Eq Alignment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Alignment -> Alignment -> Bool
== :: Alignment -> Alignment -> Bool
$c/= :: Alignment -> Alignment -> Bool
/= :: Alignment -> Alignment -> Bool
Eq, (forall x. Alignment -> Rep Alignment x)
-> (forall x. Rep Alignment x -> Alignment) -> Generic Alignment
forall x. Rep Alignment x -> Alignment
forall x. Alignment -> Rep Alignment x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Alignment -> Rep Alignment x
from :: forall x. Alignment -> Rep Alignment x
$cto :: forall x. Rep Alignment x -> Alignment
to :: forall x. Rep Alignment x -> Alignment
Generic)
instance NFData Alignment

-- | Constructs a track with default (to-be-computed) values & given cell sizes.
buildTrack :: CastDouble x => [Either x Double] -> Track x
buildTrack :: forall x. CastDouble x => [Either x Double] -> Track x
buildTrack [Either x Double]
cells = [Either x Double] -> [Double] -> [Double] -> x -> Track x
forall x. [Either x Double] -> [Double] -> [Double] -> x -> Track x
Track [Either x Double]
cells [] [] (x -> Track x) -> x -> Track x
forall a b. (a -> b) -> a -> b
$ Double -> x
forall a. CastDouble a => Double -> a
fromDouble Double
0
-- | Constructs a grid with default (to-be-computed) values & given cell sizes.
buildGrid :: (CastDouble m, CastDouble n) =>
        [Either m Double] -> [Either n Double] -> Grid m n
buildGrid :: forall m n.
(CastDouble m, CastDouble n) =>
[Either m Double] -> [Either n Double] -> Grid m n
buildGrid [Either m Double]
rows [Either n Double]
cols = Track n -> Track m -> Size (Track m) (Track n)
forall m n. n -> m -> Size m n
Size ([Either n Double] -> Track n
forall x. CastDouble x => [Either x Double] -> Track x
buildTrack [Either n Double]
cols) ([Either m Double] -> Track m
forall x. CastDouble x => [Either x Double] -> Track x
buildTrack [Either m Double]
rows)

-- | Verify that the track is properly formed & can be validly processed.
verifyTrack :: Track x -> [GridItem'] -> Bool
verifyTrack :: forall x. Track x -> [GridItem'] -> Bool
verifyTrack Track x
track [GridItem']
cells' = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [
    GridItem' -> Int
cellStart GridItem'
cell Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Either x Double] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Track x -> [Either x Double]
forall x. Track x -> [Either x Double]
cells Track x
track) Bool -> Bool -> Bool
&& GridItem' -> Int
cellStart GridItem'
cell Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&&
    GridItem' -> Int
cellEnd GridItem'
cell Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Either x Double] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Track x -> [Either x Double]
forall x. Track x -> [Either x Double]
cells Track x
track) Bool -> Bool -> Bool
&& GridItem' -> Int
cellEnd GridItem'
cell Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> GridItem' -> Int
cellStart GridItem'
cell
  | GridItem'
cell <- [GridItem']
cells']
-- | Verify that the grid is properly formed & can be validly processed.
verifyGrid :: Grid m n -> [GridItem] -> Bool
verifyGrid :: forall m n. Grid m n -> [GridItem] -> Bool
verifyGrid Grid m n
grid [GridItem]
cells =
    Track n -> [GridItem'] -> Bool
forall x. Track x -> [GridItem'] -> Bool
verifyTrack (Grid m n -> Track n
forall m n. Size m n -> n
inline Grid m n
grid) ((GridItem -> GridItem') -> [GridItem] -> [GridItem']
forall a b. (a -> b) -> [a] -> [b]
map GridItem -> GridItem'
forall m n. Size m n -> n
inline [GridItem]
cells) Bool -> Bool -> Bool
&& Track m -> [GridItem'] -> Bool
forall x. Track x -> [GridItem'] -> Bool
verifyTrack (Grid m n -> Track m
forall m n. Size m n -> m
block Grid m n
grid) ((GridItem -> GridItem') -> [GridItem] -> [GridItem']
forall a b. (a -> b) -> [a] -> [b]
map GridItem -> GridItem'
forall m n. Size m n -> m
block [GridItem]
cells)

-- | Compute the minimum size for the track given cell sizes.
-- Refers to computed min sizes if cached.
trackMin :: (n -> Double) -> Track n -> Double
trackMin :: forall n. (n -> Double) -> Track n -> Double
trackMin n -> Double
cb self :: Track n
self@Track { trackMins :: forall x. Track x -> [Double]
trackMins = [] } =
    [Double] -> Double
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
intersperse (n -> Double
cb (n -> Double) -> n -> Double
forall a b. (a -> b) -> a -> b
$ Track n -> n
forall x. Track x -> x
gap Track n
self) [n -> Double
cb n
x | Left n
x <- Track n -> [Either n Double]
forall x. Track x -> [Either x Double]
cells Track n
self]
trackMin n -> Double
cb Track n
self = [Double] -> Double
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
intersperse (n -> Double
cb (n -> Double) -> n -> Double
forall a b. (a -> b) -> a -> b
$ Track n -> n
forall x. Track x -> x
gap Track n
self) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$ Track n -> [Double]
forall x. Track x -> [Double]
trackMins Track n
self
-- | Compute the natural size for the track given cell sizes.
-- Refers to compute natural sizes if cached.
trackNat :: (n -> Double) -> Track n -> Double
trackNat :: forall n. (n -> Double) -> Track n -> Double
trackNat n -> Double
cb self :: Track n
self@Track { trackNats :: forall x. Track x -> [Double]
trackNats = [] } =
    [Double] -> Double
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
intersperse (n -> Double
cb (n -> Double) -> n -> Double
forall a b. (a -> b) -> a -> b
$ Track n -> n
forall x. Track x -> x
gap Track n
self) [n -> Double
cb n
x | Left n
x <- Track n -> [Either n Double]
forall x. Track x -> [Either x Double]
cells Track n
self]
trackNat n -> Double
cb Track n
self = [Double] -> Double
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
intersperse (n -> Double
cb (n -> Double) -> n -> Double
forall a b. (a -> b) -> a -> b
$ Track n -> n
forall x. Track x -> x
gap Track n
self) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$ Track n -> [Double]
forall x. Track x -> [Double]
trackNats Track n
self

-- | Selects all children entirely on the specified cell.
cellsForIndex :: [GridItem'] -> Int -> [GridItem']
cellsForIndex :: [GridItem'] -> Int -> [GridItem']
cellsForIndex [GridItem']
cells Int
ix =
    [GridItem'
cell | GridItem'
cell <- [GridItem']
cells, GridItem' -> Int
cellStart GridItem'
cell Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ix, GridItem' -> Int
cellStart GridItem'
cell Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Int
forall a. Enum a => a -> a
pred (GridItem' -> Int
cellEnd GridItem'
cell)]
-- | Sets minimum & natural sizes from the given padded box.
setCellBox :: (CastDouble m, CastDouble n) => GridItem -> PaddedBox m n -> GridItem
setCellBox :: forall m n.
(CastDouble m, CastDouble n) =>
GridItem -> PaddedBox m n -> GridItem
setCellBox (Size GridItem'
x GridItem'
y) PaddedBox m n
box = GridItem' -> GridItem' -> GridItem
forall m n. n -> m -> Size m n
Size GridItem'
x {
    minSize :: Double
minSize = PaddedBox m Double -> Double
forall {a} {m}. Num a => PaddedBox m a -> a
B.minWidth (PaddedBox m Double -> Double) -> PaddedBox m Double -> Double
forall a b. (a -> b) -> a -> b
$ (n -> Double) -> PaddedBox m n -> PaddedBox m Double
forall n nn m. (n -> nn) -> PaddedBox m n -> PaddedBox m nn
mapX' n -> Double
forall a. CastDouble a => a -> Double
toDouble PaddedBox m n
box,
    natSize :: Double
natSize = PaddedBox m Double -> Double
forall {a} {m}. Num a => PaddedBox m a -> a
B.width (PaddedBox m Double -> Double) -> PaddedBox m Double -> Double
forall a b. (a -> b) -> a -> b
$ (n -> Double) -> PaddedBox m n -> PaddedBox m Double
forall n nn m. (n -> nn) -> PaddedBox m n -> PaddedBox m nn
mapX' n -> Double
forall a. CastDouble a => a -> Double
toDouble PaddedBox m n
box
  } GridItem'
y {
    minSize :: Double
minSize = PaddedBox Double n -> Double
forall {a} {n}. Num a => PaddedBox a n -> a
B.minHeight (PaddedBox Double n -> Double) -> PaddedBox Double n -> Double
forall a b. (a -> b) -> a -> b
$ (m -> Double) -> PaddedBox m n -> PaddedBox Double n
forall m mm n. (m -> mm) -> PaddedBox m n -> PaddedBox mm n
mapY' m -> Double
forall a. CastDouble a => a -> Double
toDouble PaddedBox m n
box,
    natSize :: Double
natSize = PaddedBox Double n -> Double
forall {a} {n}. Num a => PaddedBox a n -> a
B.height (PaddedBox Double n -> Double) -> PaddedBox Double n -> Double
forall a b. (a -> b) -> a -> b
$ (m -> Double) -> PaddedBox m n -> PaddedBox Double n
forall m mm n. (m -> mm) -> PaddedBox m n -> PaddedBox mm n
mapY' m -> Double
forall a. CastDouble a => a -> Double
toDouble PaddedBox m n
box
  }

-- | Estimate grid width to inform proper width calculation.
gridEstWidth :: Grid y Length -> [GridItem] -> Double
gridEstWidth :: forall y. Grid y Length -> [GridItem] -> Double
gridEstWidth (Size Track Length
cols Track y
_) [GridItem]
childs = (Length -> Double) -> Track Length -> Double
forall n. (n -> Double) -> Track n -> Double
trackNat Length -> Double
forall a. CastDouble a => a -> Double
toDouble Track Length
cols {
    trackMins :: [Double]
trackMins = Double -> Track Length -> [GridItem'] -> [Double]
sizeTrackMins Double
0 Track Length
cols ([GridItem'] -> [Double]) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> a -> b
$ (GridItem -> GridItem') -> [GridItem] -> [GridItem']
forall a b. (a -> b) -> [a] -> [b]
map GridItem -> GridItem'
forall m n. Size m n -> n
inline [GridItem]
childs,
    trackNats :: [Double]
trackNats = Double -> Track Length -> [GridItem'] -> [Double]
sizeTrackNats Double
0 Track Length
cols ([GridItem'] -> [Double]) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> a -> b
$ (GridItem -> GridItem') -> [GridItem] -> [GridItem']
forall a b. (a -> b) -> [a] -> [b]
map GridItem -> GridItem'
forall m n. Size m n -> n
inline [GridItem]
childs
  }
-- | Calculate minimum sizes for all cells in the track.
-- Sized to fit given children.
sizeTrackMins :: Double -> Track Length -> [GridItem'] -> [Double]
sizeTrackMins :: Double -> Track Length -> [GridItem'] -> [Double]
sizeTrackMins Double
parent Track Length
track [GridItem']
childs = ((Int, Either Length Double) -> Double)
-> [(Int, Either Length Double)] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Either Length Double) -> Double
forall {b}. (Int, Either Length b) -> Double
inner ([(Int, Either Length Double)] -> [Double])
-> [(Int, Either Length Double)] -> [Double]
forall a b. (a -> b) -> a -> b
$ [Either Length Double] -> [(Int, Either Length Double)]
forall {b}. [b] -> [(Int, b)]
enumerate ([Either Length Double] -> [(Int, Either Length Double)])
-> [Either Length Double] -> [(Int, Either Length Double)]
forall a b. (a -> b) -> a -> b
$ Track Length -> [Either Length Double]
forall x. Track x -> [Either x Double]
cells Track Length
track
  where
    inner :: (Int, Either Length b) -> Double
inner (Int
_, Left (Pixels Double
x)) = Double
x
    inner (Int
_, Left (Percent Double
x)) = Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
parent
    inner arg :: (Int, Either Length b)
arg@(Int
ix, Left Length
Preferred) =
        [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ (Double
0Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
:) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$ (GridItem' -> Double) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map GridItem' -> Double
natSize ([GridItem'] -> [Double]) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> a -> b
$ [GridItem'] -> Int -> [GridItem']
cellsForIndex [GridItem']
childs Int
ix
    inner (Int
ix, Either Length b
_) =
        [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ (Double
0Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
:) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$ (GridItem' -> Double) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map GridItem' -> Double
minSize ([GridItem'] -> [Double]) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> a -> b
$ [GridItem'] -> Int -> [GridItem']
cellsForIndex [GridItem']
childs Int
ix
-- | Compute natural sizes for all cells in the track.
-- Sized to fit given children.
sizeTrackNats :: Double -> Track Length -> [GridItem'] -> [Double]
sizeTrackNats :: Double -> Track Length -> [GridItem'] -> [Double]
sizeTrackNats Double
parent Track Length
track [GridItem']
childs = ((Int, Either Length Double) -> Double)
-> [(Int, Either Length Double)] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Either Length Double) -> Double
forall {b}. (Int, Either Length b) -> Double
inner ([(Int, Either Length Double)] -> [Double])
-> [(Int, Either Length Double)] -> [Double]
forall a b. (a -> b) -> a -> b
$ [Either Length Double] -> [(Int, Either Length Double)]
forall {b}. [b] -> [(Int, b)]
enumerate ([Either Length Double] -> [(Int, Either Length Double)])
-> [Either Length Double] -> [(Int, Either Length Double)]
forall a b. (a -> b) -> a -> b
$ Track Length -> [Either Length Double]
forall x. Track x -> [Either x Double]
cells Track Length
track
  where
    inner :: (Int, Either Length b) -> Double
inner (Int
_, Left (Pixels Double
x)) = Double
x
    inner (Int
_, Left (Percent Double
x)) = Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
parent
    inner arg :: (Int, Either Length b)
arg@(Int
ix, Left Length
Min) =
        [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ (Double
0Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
:) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$ (GridItem' -> Double) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map GridItem' -> Double
minSize ([GridItem'] -> [Double]) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> a -> b
$ [GridItem'] -> Int -> [GridItem']
cellsForIndex [GridItem']
childs Int
ix
    inner (Int
ix, Either Length b
_) =
        [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ (Double
0Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
:) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$ (GridItem' -> Double) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map GridItem' -> Double
natSize ([GridItem'] -> [Double]) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> a -> b
$ [GridItem'] -> Int -> [GridItem']
cellsForIndex [GridItem']
childs Int
ix
-- | Compute maximum sizes for all cells in the track, sized to the parent element.
sizeTrackMaxs :: Double -> Track Length -> [Double]
sizeTrackMaxs :: Double -> Track Length -> [Double]
sizeTrackMaxs Double
parent Track Length
track = (((Double, Double), Either Length Double) -> Double)
-> [((Double, Double), Either Length Double)] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> ((Double, Double), Either Length Double) -> Double
inner Double
fr) ([((Double, Double), Either Length Double)] -> [Double])
-> [((Double, Double), Either Length Double)] -> [Double]
forall a b. (a -> b) -> a -> b
$ [(Double, Double)]
-> [Either Length Double]
-> [((Double, Double), Either Length Double)]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Double, Double)]
subsizes ([Either Length Double]
 -> [((Double, Double), Either Length Double)])
-> [Either Length Double]
-> [((Double, Double), Either Length Double)]
forall a b. (a -> b) -> a -> b
$ Track Length -> [Either Length Double]
forall x. Track x -> [Either x Double]
cells Track Length
track
  where
    subsizes :: [(Double, Double)]
subsizes = [Double] -> [Double] -> [(Double, Double)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Track Length -> [Double]
forall x. Track x -> [Double]
trackMins Track Length
track) (Track Length -> [Double]
forall x. Track x -> [Double]
trackNats Track Length
track)
    fr :: Double
fr = Double -> Double -> Double
forall a. Ord a => a -> a -> a
Prelude.max Double
0 Double
fr'
    fr' :: Double
fr' = (Double
parent Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
estimate)Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/([Either Length Double] -> Double
forall {a}. (Enum a, Num a) => [Either Length a] -> a
countFRs ([Either Length Double] -> Double)
-> [Either Length Double] -> Double
forall a b. (a -> b) -> a -> b
$ Track Length -> [Either Length Double]
forall x. Track x -> [Either x Double]
cells Track Length
track)
    estimate :: Double
estimate = [Double] -> Double
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Double] -> Double) -> [Double] -> Double
forall a b. (a -> b) -> a -> b
$ Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
intersperse (Double -> Length -> Double
lowerLength Double
parent (Length -> Double) -> Length -> Double
forall a b. (a -> b) -> a -> b
$ Track Length -> Length
forall x. Track x -> x
gap Track Length
track) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$
            (((Double, Double), Either Length Double) -> Double)
-> [((Double, Double), Either Length Double)] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> ((Double, Double), Either Length Double) -> Double
inner Double
0) ([((Double, Double), Either Length Double)] -> [Double])
-> [((Double, Double), Either Length Double)] -> [Double]
forall a b. (a -> b) -> a -> b
$ [(Double, Double)]
-> [Either Length Double]
-> [((Double, Double), Either Length Double)]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Double, Double)]
subsizes ([Either Length Double]
 -> [((Double, Double), Either Length Double)])
-> [Either Length Double]
-> [((Double, Double), Either Length Double)]
forall a b. (a -> b) -> a -> b
$ Track Length -> [Either Length Double]
forall x. Track x -> [Either x Double]
cells Track Length
track
    inner :: Double -> ((Double, Double), Either Length Double) -> Double
inner Double
_ ((Double, Double)
_, Left (Pixels Double
x)) = Double
x
    inner Double
_ ((Double, Double)
_, Left (Percent Double
x)) = Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
parent
    inner Double
_ ((Double
_, Double
nat), Left Length
Preferred) = Double
nat
    inner Double
_ ((Double
min, Double
_), Left Length
Min) = Double
min
    inner Double
fr ((Double
_, Double
nat), Left Length
Auto) = Double -> Double -> Double
forall a. Ord a => a -> a -> a
Prelude.min Double
nat Double
fr
    inner Double
fr ((Double, Double)
_, Right Double
x) = Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
fr

-- | Compute the position of all children within the grid.
trackPosition :: Track Double -> [GridItem'] -> [Double]
trackPosition :: Track Double -> [GridItem'] -> [Double]
trackPosition Track Double
self [GridItem']
childs = (GridItem' -> Double) -> [GridItem'] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map GridItem' -> Double
gridCellPosition [GridItem']
childs
  where
    gridCellPosition :: GridItem' -> Double
gridCellPosition GridItem'
child = Int -> Double
track (GridItem' -> Int
cellStart GridItem'
child) Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Alignment -> Double
forall {a}. Fractional a => a -> Alignment -> a
align Double
whitespace (GridItem' -> Alignment
alignment GridItem'
child)
      where
        whitespace :: Double
whitespace = Int -> Double
track (GridItem' -> Int
cellEnd GridItem'
child) Double -> Double -> Double
forall a. Num a => a -> a -> a
- Int -> Double
track (GridItem' -> Int
cellStart GridItem'
child) Double -> Double -> Double
forall a. Num a => a -> a -> a
- GridItem' -> Double
natSize GridItem'
child
    track :: Int -> Double
track = (Int -> [Either Double Double] -> Double)
-> [Either Double Double] -> Int -> Double
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> [Either Double Double] -> Double
forall {t} {a} {a}.
(Enum t, Eq t, Num a, Num t) =>
t -> [Either a a] -> a
track' ([Either Double Double] -> Int -> Double)
-> [Either Double Double] -> Int -> Double
forall a b. (a -> b) -> a -> b
$ Track Double -> [Either Double Double]
forall x. Track x -> [Either x Double]
cells Track Double
self
    track' :: t -> [Either a a] -> a
track' t
ix (Either a a
size:[Either a a]
sizes) = a -> Either a a -> a
forall b a. b -> Either a b -> b
fromRight a
0 Either a a
size a -> a -> a
forall a. Num a => a -> a -> a
+ t -> [Either a a] -> a
track' (t -> t
forall a. Enum a => a -> a
pred t
ix) [Either a a]
sizes
    track' t
0 [Either a a]
_ = a
0
    track' t
ix [] = String -> a -> a
forall a. String -> a -> a
trace String
"WARNING! Malformed input table!" a
0
    align :: a -> Alignment -> a
align a
_ Alignment
Start = a
0
    align a
excess Alignment
Mid = a
excessa -> a -> a
forall a. Fractional a => a -> a -> a
/a
2
    align a
excess Alignment
End = a
excess
-- | Compute the maximum size along an axis of a child, for it to be sized to.
cellSize :: CastDouble x => Track x -> GridItem' -> Double
cellSize :: forall x. CastDouble x => Track x -> GridItem' -> Double
cellSize Track x
self GridItem'
child = Int -> Double
track (GridItem' -> Int
cellEnd GridItem'
child) Double -> Double -> Double
forall a. Num a => a -> a -> a
- Int -> Double
track (GridItem' -> Int
cellStart GridItem'
child)
  where
    track :: Int -> Double
track = (Int -> [Either x Double] -> Double)
-> [Either x Double] -> Int -> Double
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> [Either x Double] -> Double
forall {a} {t} {a}.
(CastDouble a, Enum t, Eq t, Num t) =>
t -> [Either a a] -> Double
track' ([Either x Double] -> Int -> Double)
-> [Either x Double] -> Int -> Double
forall a b. (a -> b) -> a -> b
$ Track x -> [Either x Double]
forall x. Track x -> [Either x Double]
cells Track x
self
    track' :: t -> [Either a a] -> Double
track' t
ix (Either a a
size:[Either a a]
sizes) =
        (a -> Double
forall a. CastDouble a => a -> Double
toDouble (a -> Double) -> a -> Double
forall a b. (a -> b) -> a -> b
$ a -> Either a a -> a
forall b a. b -> Either a b -> b
fromRight (Double -> a
forall a. CastDouble a => Double -> a
fromDouble Double
0) Either a a
size) Double -> Double -> Double
forall a. Num a => a -> a -> a
+ t -> [Either a a] -> Double
track' (t -> t
forall a. Enum a => a -> a
pred t
ix) [Either a a]
sizes
    track' t
0 [Either a a]
_ = Double
0
    track' t
ix [] = String -> Double -> Double
forall a. String -> a -> a
trace String
"WARNING! Malformed input table!" Double
0
-- | Compute the maximum size as a PaddedBox of a child, for it to be sized to.
gridItemBox :: (CastDouble x, CastDouble y) => Grid y x -> GridItem -> PaddedBox Double Double
gridItemBox :: forall x y.
(CastDouble x, CastDouble y) =>
Grid y x -> GridItem -> PaddedBox Double Double
gridItemBox (Size Track x
cols Track y
rows) GridItem
cell =
    Size Double Double -> PaddedBox Double Double
forall {m} {n}. (Zero m, Zero n) => Size m n -> PaddedBox m n
size2box (Track x -> GridItem' -> Double
forall x. CastDouble x => Track x -> GridItem' -> Double
cellSize Track x
cols (GridItem -> GridItem'
forall m n. Size m n -> n
inline GridItem
cell) Double -> Double -> Size Double Double
forall m n. n -> m -> Size m n
`Size` Track y -> GridItem' -> Double
forall x. CastDouble x => Track x -> GridItem' -> Double
cellSize Track y
rows (GridItem -> GridItem'
forall m n. Size m n -> m
block GridItem
cell))
  where
    size2box :: Size m n -> PaddedBox m n
size2box Size m n
size = PaddedBox m n
forall a. Zero a => a
zero { min :: Size m n
B.min = Size m n
size, max :: Size m n
B.max = Size m n
size, size :: Size m n
B.size = Size m n
size }
-- | Compute the position of all children in a grid.
gridPosition :: Grid Double Double -> [GridItem] -> [(Double, Double)]
gridPosition :: Grid Double Double -> [GridItem] -> [(Double, Double)]
gridPosition (Size Track Double
cols Track Double
rows) [GridItem]
childs =
    Track Double -> [GridItem'] -> [Double]
trackPosition Track Double
rows ((GridItem -> GridItem') -> [GridItem] -> [GridItem']
forall a b. (a -> b) -> [a] -> [b]
map GridItem -> GridItem'
forall m n. Size m n -> n
inline [GridItem]
childs) [Double] -> [Double] -> [(Double, Double)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` Track Double -> [GridItem'] -> [Double]
trackPosition Track Double
cols ((GridItem -> GridItem') -> [GridItem] -> [GridItem']
forall a b. (a -> b) -> [a] -> [b]
map GridItem -> GridItem'
forall m n. Size m n -> m
block [GridItem]
childs)
-- | Compute the track sizes & child positions along a single axis.
trackLayout :: Double -> Double -> Track Length -> [GridItem'] ->
        (Track Double, [(Double, GridItem')])
trackLayout :: Double
-> Double
-> Track Length
-> [GridItem']
-> (Track Double, [(Double, GridItem')])
trackLayout Double
parent Double
width Track Length
self [GridItem']
childs = (Track Double
self', [Double] -> [GridItem'] -> [(Double, GridItem')]
forall a b. [a] -> [b] -> [(a, b)]
zip [Double]
positions [GridItem']
childs)
  where
    positions :: [Double]
positions = Track Double -> [GridItem'] -> [Double]
trackPosition Track Double
self' [GridItem']
childs
    self' :: Track Double
self' = Track Length
self {
        cells :: [Either Double Double]
cells = (Double -> Either Double Double)
-> [Double] -> [Either Double Double]
forall a b. (a -> b) -> [a] -> [b]
map Double -> Either Double Double
forall a b. a -> Either a b
Left [Double]
sizes,
        trackMins :: [Double]
trackMins = [Double]
mins, trackNats :: [Double]
trackNats = [Double]
nats,
        gap :: Double
gap = Double -> Length -> Double
lowerLength Double
width (Length -> Double) -> Length -> Double
forall a b. (a -> b) -> a -> b
$ Track Length -> Length
forall x. Track x -> x
gap Track Length
self
      }
    sizes :: [Double]
sizes = Double -> Track Length -> [Double]
sizeTrackMaxs Double
parent Track Length
self { trackMins :: [Double]
trackMins = [Double]
mins, trackNats :: [Double]
trackNats = [Double]
nats }
    mins :: [Double]
mins = Double -> Track Length -> [GridItem'] -> [Double]
sizeTrackMins Double
parent Track Length
self [GridItem']
childs
    nats :: [Double]
nats = Double -> Track Length -> [GridItem'] -> [Double]
sizeTrackNats Double
parent Track Length
self [GridItem']
childs
-- | Compute the track sizes & child positions along both axes.
gridLayout :: Size Double Double -> Grid Length Length -> [GridItem] ->
        (Grid Double Double, [((Double, Double), GridItem)])
gridLayout :: Size Double Double
-> Grid Length Length
-> [GridItem]
-> (Grid Double Double, [((Double, Double), GridItem)])
gridLayout Size Double Double
parent (Size Track Length
cols Track Length
rows) [GridItem]
childs = (Grid Double Double
self', [(Double, Double)] -> [GridItem] -> [((Double, Double), GridItem)]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Double, Double)]
positions [GridItem]
childs)
  where
    positions :: [(Double, Double)]
positions = Grid Double Double -> [GridItem] -> [(Double, Double)]
gridPosition Grid Double Double
self' [GridItem]
childs
    self' :: Grid Double Double
self' = Track Double -> Track Double -> Grid Double Double
forall m n. n -> m -> Size m n
Size Track Double
cols' { gap :: Double
gap = Double -> Length -> Double
lowerLength Double
width (Length -> Double) -> Length -> Double
forall a b. (a -> b) -> a -> b
$ Track Length -> Length
forall x. Track x -> x
gap Track Length
cols } Track Double
rows'
    (Track Double
rows', [(Double, GridItem')]
_) = Double
-> Double
-> Track Length
-> [GridItem']
-> (Track Double, [(Double, GridItem')])
trackLayout (Size Double Double -> Double
forall m n. Size m n -> m
block Size Double Double
parent) Double
width Track Length
rows ([GridItem'] -> (Track Double, [(Double, GridItem')]))
-> [GridItem'] -> (Track Double, [(Double, GridItem')])
forall a b. (a -> b) -> a -> b
$ (GridItem -> GridItem') -> [GridItem] -> [GridItem']
forall a b. (a -> b) -> [a] -> [b]
map GridItem -> GridItem'
forall m n. Size m n -> m
block [GridItem]
childs
    width :: Double
width = (Double -> Double) -> Track Double -> Double
forall n. (n -> Double) -> Track n -> Double
trackNat Double -> Double
forall a. a -> a
id Track Double
cols'
    (Track Double
cols', [(Double, GridItem')]
_) = Double
-> Double
-> Track Length
-> [GridItem']
-> (Track Double, [(Double, GridItem')])
trackLayout (Size Double Double -> Double
forall m n. Size m n -> n
inline Size Double Double
parent) Double
0 Track Length
cols ([GridItem'] -> (Track Double, [(Double, GridItem')]))
-> [GridItem'] -> (Track Double, [(Double, GridItem')])
forall a b. (a -> b) -> a -> b
$ (GridItem -> GridItem') -> [GridItem] -> [GridItem']
forall a b. (a -> b) -> [a] -> [b]
map GridItem -> GridItem'
forall m n. Size m n -> n
inline [GridItem]
childs

-- | Utility for associate an index with each item in a list.
enumerate :: [b] -> [(Int, b)]
enumerate = [Int] -> [b] -> [(Int, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..]

-- | Utility for summing the divisor used to compute the fr unit.
countFRs :: [Either Length a] -> a
countFRs (Left Length
Auto:[Either Length a]
rest) = a -> a
forall a. Enum a => a -> a
succ (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ [Either Length a] -> a
countFRs [Either Length a]
rest
countFRs (Right a
x:[Either Length a]
rest) = a
x a -> a -> a
forall a. Num a => a -> a -> a
+ [Either Length a] -> a
countFRs [Either Length a]
rest
countFRs (Either Length a
_:[Either Length a]
rest) = [Either Length a] -> a
countFRs [Either Length a]
rest
countFRs [] = a
0