Current section

Files

Jump to
elementtui lib component flex.ex
Raw

lib/component/flex.ex

defmodule ElementTui.Component.Flex do
defstruct weight: 1.0, element: nil, direction: :all
def new(element, direction, weight) do
%ElementTui.Component.Flex{element: element, weight: weight, direction: direction}
end
@doc """
Takes a list of sizes and their flex weights and redistributes the available space to the flex components
"""
def distribute(xs, available) do
# We need the cumulative sum of weights, so we can disperse properly
{cw, _} =
xs
|> Enum.reverse()
|> Enum.map_reduce(0, fn {_, kw}, acc ->
acc = acc + (Keyword.get(kw, :flex, nil) || 0)
{acc, acc}
end)
cw = cw |> Enum.reverse()
# Here we distribute the weights
{xs, _} =
xs
|> Enum.zip(cw)
|> Enum.map_reduce(available, fn {{x, kw}, total_weight}, acc ->
case Keyword.get(kw, :flex, nil) do
nil ->
{x, acc}
size ->
w = Kernel.round(size / total_weight * acc)
{w, acc - w}
end
end)
xs
end
end
defimpl ElementTui.Component, for: ElementTui.Component.Flex do
alias ElementTui.Component.Flex
def calculate_dim(%Flex{element: el, weight: weight, direction: dir}, width, height) do
{w, h, kw} = ElementTui.Parser.calculate_dim(el, width, height)
case dir do
:vertical ->
{w, h, Keyword.merge(kw, vflex: weight)}
:horizontal ->
{w, h, Keyword.merge(kw, hflex: weight)}
_ ->
{w, h, Keyword.merge(kw, hflex: weight, vflex: weight)}
end
end
def parse(%Flex{element: el, direction: dir}, x, y, width, height) do
parsed = ElementTui.Parser.parse(el, x, y, width, height)
case dir do
:vertical ->
%{parsed | height: height}
:horizontal ->
%{parsed | width: width}
_ ->
%{parsed | width: width, height: height}
end
end
end