~alcinnz/CatTrap

7301a4893d99b4a5bf016000097369b492f23aea — Adrian Cochrane 6 months ago 1a650ed
Integrate flexbox CSS property parsing.
4 files changed, 41 insertions(+), 9 deletions(-)

M Graphics/Layout.hs
M Graphics/Layout/CSS.hs
M Graphics/Layout/CSS/Parse.hs
M Graphics/Layout/Flex.hs
M Graphics/Layout.hs => Graphics/Layout.hs +2 -0
@@ 23,6 23,7 @@ import Graphics.Layout.Grid as G
import Graphics.Layout.Flow as F
import Graphics.Layout.Inline as I
import Graphics.Layout.CSS.Font (Font'(..))
import Graphics.Layout.Flex as Fl

import Data.Maybe (fromMaybe)



@@ 57,6 58,7 @@ data LayoutItem m n x =
    | LayoutConst x (PaddedBox m n) [LayoutItem m n x]
    -- | Children of a `LayoutInline` or `LayoutInline'`.
    | LayoutSpan (FragmentTree (UserData m n x))
    | LayoutFlex x (PaddedBox m n) (FlexParent (LayoutItem m n x) m)
    deriving (Show, Eq)
-- | An empty box.
nullLayout :: (PropertyParser x, Zero m, Zero n) => LayoutItem m n x

M Graphics/Layout/CSS.hs => Graphics/Layout/CSS.hs +11 -0
@@ 20,6 20,7 @@ import Graphics.Layout.Grid.CSS
import Graphics.Layout.Grid
import Graphics.Layout.Grid.Table
import Graphics.Layout.Inline.CSS
import Graphics.Layout.Flex.CSS

import Data.Char (isSpace)
import Graphics.Layout.CSS.Parse


@@ 70,6 71,16 @@ finalizeCSS root parent self@StyleTree {
  where
    font_ = pattern2font (font self') (font' self') parent root
finalizeCSS root parent self@StyleTree {
        style = self'@CSSBox { display = Flex, flexOptions = flex },
        children = childs
    } = LayoutFlex (inner' font_ self' ) (finalizeBox self' font_) $
        lowerFlex flex font_ (map flexOptions childs')
            (flip map childs $ finalizeCSS root font_) (map style2font childs')
  where
    font_ = style2font self'
    style2font style = pattern2font (font style) (font' style) parent root
    childs' = map style childs
finalizeCSS root parent self@StyleTree {
    style = self', children = childs
  } = LayoutFlow (inner' font_ self') (finalizeBox self' font_)
        (finalizeChilds root font_ self' childs)

M Graphics/Layout/CSS/Parse.hs => Graphics/Layout/CSS/Parse.hs +22 -5
@@ 16,6 16,7 @@ import Graphics.Layout.CSS.Font (CSSFont)
import Graphics.Layout.Grid.CSS (CSSGrid(..), CSSCell(..), Placement(..))
import Graphics.Layout.Grid.Table (TableOptions)
import Graphics.Layout.Inline.CSS (CSSInline(..))
import Graphics.Layout.Flex.CSS (CSSFlex(..))

import Data.Maybe (isJust, fromMaybe)
import Text.Read (readMaybe)


@@ 54,8 55,12 @@ data CSSBox a = CSSBox {
    paragraphOptions :: ParagraphOptions,
    -- | (Semi-)parsed CSS properties & HTML attributes relating to laying out
    -- HTML table elements.
    tableOptions :: TableOptions
    tableOptions :: TableOptions,
    -- | Semi-parsed CSS properties relating to FlexBox layouts.
    flexOptions :: CSSFlex
}
-- | FlexOptions getter with `textLTR` set
flexOpts' self@CSSBox { flexOptions = ret } = ret { textRTL = direction self == DirRTL }
-- | Accessor for inlineStyle's `textDirection` attribute.
direction CSSBox { inlineStyles = CSSInline _ opts _ } = textDirection opts
-- | Accessor for inlineStyle's options.


@@ 68,7 73,7 @@ noborder = Border (0,"px") (0,"px") (0,"px") (0,"px")
-- | Possibly values for CSS display property.
data Display = Block | Grid | Inline | Table | None |
    TableRow | TableHeaderGroup | TableRowGroup | TableFooterGroup | TableCell |
    TableColumn | TableColumnGroup | TableCaption deriving Eq
    TableColumn | TableColumnGroup | TableCaption | Flex deriving Eq
-- | Can the display value contain table-rows?
rowContainer CSSBox { display = d } =
    d `elem` [Table, TableHeaderGroup, TableRowGroup, TableFooterGroup]


@@ 99,7 104,8 @@ instance PropertyParser a => PropertyParser (CSSBox a) where
        paragraphOptions = defaultParagraphOptions {
            paragraphAlignment = AlignStart
        },
        tableOptions = temp
        tableOptions = temp,
        flexOptions = temp
      }
    inherit parent = CSSBox {
        boxSizing = boxSizing parent,


@@ 115,9 121,11 @@ instance PropertyParser a => PropertyParser (CSSBox a) where
        inlineStyles = inherit $ inlineStyles parent,
        pageOptions = pageOptions parent,
        paragraphOptions = paragraphOptions parent,
        tableOptions = inherit $ tableOptions parent
        tableOptions = inherit $ tableOptions parent,
        flexOptions = inherit $ flexOptions parent
      }
    priority self = concat [x font, x font', x gridStyles, x cellStyles, x inner]
    priority self = concat [x inlineStyles, x font, x font', x gridStyles,
        x cellStyles, x flexOptions, x inner]
      where x getter = priority $ getter self

    -- Wasn't sure how to implement in FontConfig-Pure


@@ 254,6 262,7 @@ instance PropertyParser a => PropertyParser (CSSBox a) where
    longhand CSSBox { display = Table } self "display" [Ident "table-caption"] =
        Just self { display=TableCaption }
    longhand _ self "display" [Ident "inline"] = Just self { display = Inline }
    longhand _ self "display" [Ident "flex"] = Just self { display = Flex }
    longhand _ self "display" [Ident "initial"] = Just self { display = Inline }

    longhand _ self "orphans" [Number _ (NVInteger x)] =


@@ 294,12 303,20 @@ instance PropertyParser a => PropertyParser (CSSBox a) where
      }
    longhand a b c d | Just inline' <- longhand (inlineStyles a) (inlineStyles b) c d =
        Just b { inlineStyles = inline' }
    longhand a b c d | Just grid' <- longhand (gridStyles a) (gridStyles b) c d,
            Just flex' <- longhand (flexOpts' a) (flexOpts' b) c d =
        Just b { gridStyles = grid', flexOptions = flex' }
    longhand a b c d | Just cell' <- longhand (cellStyles a) (cellStyles b) c d,
            Just flex' <- longhand (flexOpts' a) (flexOpts' b) c d =
        Just b { cellStyles = cell', flexOptions = flex' }
    longhand a b c d | Just grid' <- longhand (gridStyles a) (gridStyles b) c d =
        Just b { gridStyles = grid' }
    longhand a b c d | Just cell' <- longhand (cellStyles a) (cellStyles b) c d =
        Just b { cellStyles = cell' }
    longhand a b c d | Just table'<-longhand (tableOptions a) (tableOptions b) c d
        = Just b { tableOptions = table' }
    longhand a b c d | Just flex' <- longhand (flexOpts' a) (flexOpts' b) c d =
        Just b { flexOptions = flex' }
    longhand a b c d
        | (d', _:_)<-testLengthProp d, Just _<-longhand (inner a) (inner b) c d' =
            Just b {

M Graphics/Layout/Flex.hs => Graphics/Layout/Flex.hs +6 -4
@@ 15,19 15,21 @@ data FlexParent a b = FlexParent {
    baseGap :: b,
    crossGap :: b,
    children :: [[FlexChild a b]] -- 2D list to store lines once split.
}
} deriving (Eq, Show, Read)
data FlexChild a b = FlexChild {
    grow :: Double,
    shrink :: Double,
    basis :: b,
    alignment :: Alignment,
    flexInner :: a
}
} deriving (Eq, Show, Read)

data Direction = Row | Column
data FlexWrapping = NoWrap | Wrap | WrapReverse
data Direction = Row | Column deriving (Eq, Show, Read)
data FlexWrapping = NoWrap | Wrap | WrapReverse deriving (Eq, Show, Read)
data Justification = JStart | JEnd | JCenter | JSpaceBetween | JSpaceAround | JSpaceEvenly
    deriving (Eq, Show, Read)
data Alignment = AlStretch | AlStart | AlEnd | AlCenter | AlBaseline
    deriving (Eq, Show, Read)

flexMaxBasis :: FlexParent a Length -> Double -> Double
flexMaxBasis self outersize = maximum [lowerLength outersize $ basis child |