defmodule ElementTui do @moduledoc """ Main interface to the ElementTui library, for running a terminal user interface. """ alias ElementTui.Element alias ElementTui.Parser @doc """ Create a loop for your tui. Allows passing along state and a function. The function will be called with the state and the event. Also possible to pass a timeout, which will be used for polling. """ def run_loop(render_function, state, opts \\ []) do opts = Keyword.merge([timeout: 100], opts) Stream.unfold({state, :none}, fn {s, ev} -> case render_function.(s, ev) do {:halt, _} -> nil {:cont, s} -> ev = ElementTui.Tui.poll(opts[:timeout]) {:cont, {s, ev}} v -> raise "Render function should return :cont or :halt, got: #{inspect(v)}" end end) |> Stream.run() {:ok} end @doc """ Render the passed elements to a window starting at column x and row y, with total width and height Will clear the region before rendering. """ def render(elements, x, y, width, height) do ElementTui.Tui.clear_region(x, y, width, height) parsed = elements |> Parser.parse(x, y, width, height) parsed.elements |> Enum.each(fn elem -> Element.render(elem) end) %{height: parsed.height, width: parsed.width} end @doc """ Draw the content to the terminal """ def present() do ElementTui.Tui.present() end @doc """ The width of the terminal """ def width() do ElementTui.TermBox2Ex.width() end @doc """ The height of the terminal """ def height() do ElementTui.TermBox2Ex.height() end end