Current section
Files
Jump to
Current section
Files
lib/elementtui/tui.ex
defmodule ElementTui.Tui do
@moduledoc """
This genserver will be started by the application. It will also handle drawing, in order to make sure we write single threaded. In general a user should not need to use this directly, but instead use the main ElementTui module.
"""
use GenServer
alias ElementTui.TermBox2Ex
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, %{}, opts)
end
def puts(x, y, attr, bg_attr, line) do
GenServer.cast(ElementTui.Tui, {:puts, x, y, attr, bg_attr, line})
end
def clear do
GenServer.cast(ElementTui.Tui, :clear)
end
def clear_region(x, y, width, height) do
GenServer.cast(ElementTui.Tui, {:clear_region, x, y, width, height})
end
def present() do
GenServer.cast(ElementTui.Tui, {:present})
end
def poll(timeout_ms) do
# TODO: we should pass current time, so we account for potential delay in message handling
GenServer.call(ElementTui.Tui, {:poll, timeout_ms})
end
@impl true
def init(init) do
TermBox2Ex.ex_start()
Process.flag(:trap_exit, true)
{:ok, init}
end
@impl true
def terminate(_reason, _state) do
TermBox2Ex.ex_stop()
# IO.puts "Going Down: #{inspect(state)}"
:normal
end
@impl true
def handle_call({:poll, timeout_ms}, _from, state) when is_integer(timeout_ms) do
ev = TermBox2Ex.poll(timeout_ms)
{:reply, ev, state}
end
@impl true
def handle_cast({:puts, x, y, attr, bg_attr, line}, state)
when is_integer(x) and is_integer(y) and is_binary(line) do
TermBox2Ex.puts(x, y, attr, bg_attr, line)
{:noreply, state}
end
def handle_cast(:clear, state) do
TermBox2Ex.clear()
{:noreply, state}
end
def handle_cast({:clear_region, x, y, width, height}, state)
when is_integer(x) and is_integer(y) and is_integer(width) and is_integer(height) do
TermBox2Ex.clear_region(x, y, width, height)
{:noreply, state}
end
def handle_cast({:present}, state) do
TermBox2Ex.present()
# NOTE: This currently relies on good behaviour by the user, who will need to call present only once every "draw"
# but I currently do not see a way around that without requiring the user to unset the cursor manually, could have an opt
# passed to present?
TermBox2Ex.hide_cursor()
{:noreply, state}
end
end