Current section
Files
Jump to
Current section
Files
lib/elementtui.ex
defmodule ElementTui do
@moduledoc """
Main interface to the ElementTui library, for running a terminal user interface (TUI). Functions in this module allow parsing
elements and rendering them to the screen. The function `run_loop/3` is a good starting point for running a TUI loop.
To see the type of elements that can be rendered, check the `ElementTui.Element` module documentation and struct. Also check the
examples repository: [https://codeberg.org/edwinvanl/elementtui_examples](https://codeberg.org/edwinvanl/elementtui_examples)
"""
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, opts \\ []) do
opts = Keyword.merge([clear: true], opts)
if opts[:clear] do
ElementTui.Tui.clear_region(x, y, width, height)
end
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