-module(etui@widgets@paragraph).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/etui/widgets/paragraph.gleam").
-export([paragraph_new/1, with_alignment/2, with_style/2, paragraph_new_lines/1, render_styled/3, render_lines_styled/3, render/3]).
-export_type([paragraph/0, span_paragraph/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type paragraph() :: {paragraph,
binary(),
etui@text:alignment(),
etui@style:color(),
etui@style:color(),
etui@style:modifier()}.
-type span_paragraph() :: {span_paragraph, list(etui@span:line())}.
-file("src/etui/widgets/paragraph.gleam", 24).
?DOC(" New paragraph with left-aligned text and default colors.\n").
-spec paragraph_new(binary()) -> paragraph().
paragraph_new(Text) ->
{paragraph, Text, left, default, default, etui@style:none()}.
-file("src/etui/widgets/paragraph.gleam", 35).
?DOC(" Set text alignment (Left, Center, Right).\n").
-spec with_alignment(paragraph(), etui@text:alignment()) -> paragraph().
with_alignment(P, Alignment) ->
{paragraph,
erlang:element(2, P),
Alignment,
erlang:element(4, P),
erlang:element(5, P),
erlang:element(6, P)}.
-file("src/etui/widgets/paragraph.gleam", 40).
?DOC(" Apply a style (colors + modifier) to the paragraph text.\n").
-spec with_style(paragraph(), etui@style:style()) -> paragraph().
with_style(P, S) ->
{paragraph,
erlang:element(2, P),
erlang:element(3, P),
erlang:element(2, S),
erlang:element(3, S),
erlang:element(4, S)}.
-file("src/etui/widgets/paragraph.gleam", 62).
?DOC(
" Build a `SpanParagraph` from a list of `span.Line` values.\n"
"\n"
" ```gleam\n"
" paragraph.paragraph_new_lines([\n"
" span.line_new([span.span_plain(\"normal \"), span.span_styled(\"bold\", style.bold_style())]),\n"
" span.line_plain(\"second line\"),\n"
" ])\n"
" |> paragraph.render_lines_styled(buf, area, _)\n"
" ```\n"
).
-spec paragraph_new_lines(list(etui@span:line())) -> span_paragraph().
paragraph_new_lines(Lines) ->
{span_paragraph, Lines}.
-file("src/etui/widgets/paragraph.gleam", 89).
-spec render_span_rows(
etui@buffer:buffer(),
etui@geometry:rect(),
list(etui@span:line()),
integer()
) -> etui@buffer:buffer().
render_span_rows(Buf, Area, Lines, Row) ->
case Lines of
[] ->
Buf;
[Line | Rest] ->
case Row >= erlang:element(3, erlang:element(3, Area)) of
true ->
Buf;
false ->
Pos = {position,
erlang:element(2, erlang:element(2, Area)),
erlang:element(3, erlang:element(2, Area)) + Row},
Buf2 = etui@span:render_line(
Buf,
Pos,
Line,
erlang:element(2, erlang:element(3, Area))
),
render_span_rows(Buf2, Area, Rest, Row + 1)
end
end.
-file("src/etui/widgets/paragraph.gleam", 78).
?DOC(
" Render a list of `span.Line` values, one per row, into `area`.\n"
" Each `Line` is drawn with per-span styles. Lines beyond area height\n"
" are clipped; the list may be shorter than the area (remaining rows unchanged).\n"
).
-spec render_styled(
etui@buffer:buffer(),
etui@geometry:rect(),
list(etui@span:line())
) -> etui@buffer:buffer().
render_styled(Buf, Area, Lines) ->
case (erlang:element(2, erlang:element(3, Area)) =< 0) orelse (erlang:element(
3,
erlang:element(3, Area)
)
=< 0) of
true ->
Buf;
false ->
render_span_rows(Buf, Area, Lines, 0)
end.
-file("src/etui/widgets/paragraph.gleam", 67).
?DOC(" Render a `SpanParagraph` into `area`. Lines beyond area height are clipped.\n").
-spec render_lines_styled(
etui@buffer:buffer(),
etui@geometry:rect(),
span_paragraph()
) -> etui@buffer:buffer().
render_lines_styled(Buf, Area, Para) ->
render_styled(Buf, Area, erlang:element(2, Para)).
-file("src/etui/widgets/paragraph.gleam", 131).
-spec render_lines(
etui@buffer:buffer(),
etui@geometry:rect(),
paragraph(),
list(binary()),
integer()
) -> etui@buffer:buffer().
render_lines(Buf, Area, Para, Lines, Line_idx) ->
case Lines of
[] ->
Buf;
[Line | Rest] ->
case Line_idx >= erlang:element(3, erlang:element(3, Area)) of
true ->
Buf;
false ->
Y = erlang:element(3, erlang:element(2, Area)) + Line_idx,
Aligned_line = etui@text:align(
Line,
erlang:element(2, erlang:element(3, Area)),
erlang:element(3, Para)
),
Buf_new = etui@buffer:set_string(
Buf,
{position,
erlang:element(2, erlang:element(2, Area)),
Y},
Aligned_line,
erlang:element(4, Para),
erlang:element(5, Para),
erlang:element(6, Para)
),
render_lines(Buf_new, Area, Para, Rest, Line_idx + 1)
end
end.
-file("src/etui/widgets/paragraph.gleam", 115).
?DOC(
" Render paragraph into buffer at `area`. Word-wraps to area width.\n"
" Rows beyond area height are clipped. Short lines are padded to area width.\n"
).
-spec render(etui@buffer:buffer(), etui@geometry:rect(), paragraph()) -> etui@buffer:buffer().
render(Buf, Area, Para) ->
case (erlang:element(2, erlang:element(3, Area)) =< 0) orelse (erlang:element(
3,
erlang:element(3, Area)
)
=< 0) of
true ->
Buf;
false ->
Lines = etui@text:wrap(
erlang:element(2, Para),
erlang:element(2, erlang:element(3, Area))
),
render_lines(Buf, Area, Para, Lines, 0)
end.