-module(etui@widgets@scrollbar). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/etui/widgets/scrollbar.gleam"). -export([scrollbar_new/3, with_chars/3, with_arrows/3, with_colors/3, with_thumb_colors/3, render_vertical/3, render_horizontal/3]). -export_type([scrollbar/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 scrollbar() :: {scrollbar, integer(), integer(), integer(), binary(), binary(), binary(), binary(), etui@style:color(), etui@style:color(), etui@style:color(), etui@style:color()}. -file("src/etui/widgets/scrollbar.gleam", 48). ?DOC( " New scrollbar. `total` = total items, `visible` = viewport size,\n" " `offset` = first visible item index.\n" ). -spec scrollbar_new(integer(), integer(), integer()) -> scrollbar(). scrollbar_new(Total, Visible, Offset) -> {scrollbar, gleam@int:max(1, Total), gleam@int:max(1, Visible), gleam@int:max(0, Offset), <<"░"/utf8>>, <<"█"/utf8>>, <<"▲"/utf8>>, <<"▼"/utf8>>, default, default, default, default}. -file("src/etui/widgets/scrollbar.gleam", 65). ?DOC(" Override track and thumb characters.\n"). -spec with_chars(scrollbar(), binary(), binary()) -> scrollbar(). with_chars(S, Track, Thumb) -> {scrollbar, erlang:element(2, S), erlang:element(3, S), erlang:element(4, S), Track, Thumb, erlang:element(7, S), erlang:element(8, S), erlang:element(9, S), erlang:element(10, S), erlang:element(11, S), erlang:element(12, S)}. -file("src/etui/widgets/scrollbar.gleam", 70). ?DOC(" Override arrow characters. Pass `\"\"` to hide arrows.\n"). -spec with_arrows(scrollbar(), binary(), binary()) -> scrollbar(). with_arrows(S, Start, End_ch) -> {scrollbar, erlang:element(2, S), erlang:element(3, S), erlang:element(4, S), erlang:element(5, S), erlang:element(6, S), Start, End_ch, erlang:element(9, S), erlang:element(10, S), erlang:element(11, S), erlang:element(12, S)}. -file("src/etui/widgets/scrollbar.gleam", 75). ?DOC(" Set colors for the track.\n"). -spec with_colors(scrollbar(), etui@style:color(), etui@style:color()) -> scrollbar(). with_colors(S, Fg, Bg) -> {scrollbar, erlang:element(2, S), erlang:element(3, S), erlang:element(4, S), erlang:element(5, S), erlang:element(6, S), erlang:element(7, S), erlang:element(8, S), Fg, Bg, erlang:element(11, S), erlang:element(12, S)}. -file("src/etui/widgets/scrollbar.gleam", 84). ?DOC(" Set colors for the thumb.\n"). -spec with_thumb_colors(scrollbar(), etui@style:color(), etui@style:color()) -> scrollbar(). with_thumb_colors(S, Fg, Bg) -> {scrollbar, erlang:element(2, S), erlang:element(3, S), erlang:element(4, S), erlang:element(5, S), erlang:element(6, S), erlang:element(7, S), erlang:element(8, S), erlang:element(9, S), erlang:element(10, S), Fg, Bg}. -file("src/etui/widgets/scrollbar.gleam", 265). -spec render_vertical_track( etui@buffer:buffer(), etui@geometry:rect(), scrollbar(), integer(), integer(), integer(), integer() ) -> etui@buffer:buffer(). render_vertical_track(Buf, Area, S, Track_len, Thumb_start, Thumb_size, I) -> case I >= Track_len of true -> Buf; false -> Pos = {position, erlang:element(2, erlang:element(2, Area)), erlang:element(3, erlang:element(2, Area)) + I}, Is_thumb = (I >= Thumb_start) andalso (I < (Thumb_start + Thumb_size)), {Ch, Fg, Bg} = case Is_thumb of true -> {erlang:element(6, S), erlang:element(11, S), erlang:element(12, S)}; false -> {erlang:element(5, S), erlang:element(9, S), erlang:element(10, S)} end, Buf2 = etui@buffer:set_string( Buf, Pos, Ch, Fg, Bg, etui@style:none() ), render_vertical_track( Buf2, Area, S, Track_len, Thumb_start, Thumb_size, I + 1 ) end. -file("src/etui/widgets/scrollbar.gleam", 249). ?DOC(" Compute thumb start position and size within a track of `track_len` cells.\n"). -spec thumb_geometry(scrollbar(), integer()) -> {integer(), integer()}. thumb_geometry(S, Track_len) -> Total = gleam@int:max(1, erlang:element(2, S)), Visible = gleam@int:clamp(erlang:element(3, S), 1, Total), Offset = gleam@int:clamp(erlang:element(4, S), 0, Total - Visible), Thumb_size = gleam@int:max(1, case Total of 0 -> 0; Gleam@denominator -> Track_len * Visible div Gleam@denominator end), Scrollable = Total - Visible, Thumb_start = case Scrollable of 0 -> 0; _ -> case Scrollable of 0 -> 0; Gleam@denominator@1 -> (Track_len - Thumb_size) * Offset div Gleam@denominator@1 end end, {Thumb_start, Thumb_size}. -file("src/etui/widgets/scrollbar.gleam", 98). ?DOC( " Render a vertical scrollbar into the first column of `area`.\n" " Arrow characters (if non-empty) occupy the top and bottom cells;\n" " the track fills the remaining height.\n" ). -spec render_vertical(etui@buffer:buffer(), etui@geometry:rect(), scrollbar()) -> etui@buffer:buffer(). render_vertical(Buf, Area, S) -> case (erlang:element(3, erlang:element(3, Area)) =< 0) orelse (erlang:element( 2, erlang:element(3, Area) ) =< 0) of true -> Buf; false -> Has_start = erlang:element(7, S) /= <<""/utf8>>, Has_end = erlang:element(8, S) /= <<""/utf8>>, Arrow_top = case Has_start of true -> 1; false -> 0 end, Arrow_bot = case Has_end of true -> 1; false -> 0 end, Track_len = gleam@int:max( 0, (erlang:element(3, erlang:element(3, Area)) - Arrow_top) - Arrow_bot ), Buf@1 = case Has_start of false -> Buf; true -> etui@buffer:set_string( Buf, {position, erlang:element(2, erlang:element(2, Area)), erlang:element(3, erlang:element(2, Area))}, erlang:element(7, S), erlang:element(9, S), erlang:element(10, S), etui@style:none() ) end, Buf@2 = case Has_end of false -> Buf@1; true -> etui@buffer:set_string( Buf@1, {position, erlang:element(2, erlang:element(2, Area)), (erlang:element(3, erlang:element(2, Area)) + erlang:element( 3, erlang:element(3, Area) )) - 1}, erlang:element(8, S), erlang:element(9, S), erlang:element(10, S), etui@style:none() ) end, case Track_len =< 0 of true -> Buf@2; false -> Track_area = etui@geometry:rect_new( erlang:element(2, erlang:element(2, Area)), erlang:element(3, erlang:element(2, Area)) + Arrow_top, erlang:element(2, erlang:element(3, Area)), Track_len ), {Thumb_start, Thumb_size} = thumb_geometry(S, Track_len), render_vertical_track( Buf@2, Track_area, S, Track_len, Thumb_start, Thumb_size, 0 ) end end. -file("src/etui/widgets/scrollbar.gleam", 297). -spec render_horizontal_track( etui@buffer:buffer(), etui@geometry:rect(), scrollbar(), integer(), integer(), integer(), integer() ) -> etui@buffer:buffer(). render_horizontal_track(Buf, Area, S, Track_len, Thumb_start, Thumb_size, I) -> case I >= Track_len of true -> Buf; false -> Pos = {position, erlang:element(2, erlang:element(2, Area)) + I, erlang:element(3, erlang:element(2, Area))}, Is_thumb = (I >= Thumb_start) andalso (I < (Thumb_start + Thumb_size)), {Ch, Fg, Bg} = case Is_thumb of true -> {erlang:element(6, S), erlang:element(11, S), erlang:element(12, S)}; false -> {erlang:element(5, S), erlang:element(9, S), erlang:element(10, S)} end, Buf2 = etui@buffer:set_string( Buf, Pos, Ch, Fg, Bg, etui@style:none() ), render_horizontal_track( Buf2, Area, S, Track_len, Thumb_start, Thumb_size, I + 1 ) end. -file("src/etui/widgets/scrollbar.gleam", 173). ?DOC( " Render a horizontal scrollbar into the first row of `area`.\n" " Arrow characters (if non-empty) occupy the leftmost and rightmost cells;\n" " the track fills the remaining width.\n" ). -spec render_horizontal(etui@buffer:buffer(), etui@geometry:rect(), scrollbar()) -> etui@buffer:buffer(). render_horizontal(Buf, Area, S) -> case (erlang:element(3, erlang:element(3, Area)) =< 0) orelse (erlang:element( 2, erlang:element(3, Area) ) =< 0) of true -> Buf; false -> Has_start = erlang:element(7, S) /= <<""/utf8>>, Has_end = erlang:element(8, S) /= <<""/utf8>>, Arrow_left = case Has_start of true -> 1; false -> 0 end, Arrow_right = case Has_end of true -> 1; false -> 0 end, Track_len = gleam@int:max( 0, (erlang:element(2, erlang:element(3, Area)) - Arrow_left) - Arrow_right ), Buf@1 = case Has_start of false -> Buf; true -> etui@buffer:set_string( Buf, {position, erlang:element(2, erlang:element(2, Area)), erlang:element(3, erlang:element(2, Area))}, erlang:element(7, S), erlang:element(9, S), erlang:element(10, S), etui@style:none() ) end, Buf@2 = case Has_end of false -> Buf@1; true -> etui@buffer:set_string( Buf@1, {position, (erlang:element(2, erlang:element(2, Area)) + erlang:element( 2, erlang:element(3, Area) )) - 1, erlang:element(3, erlang:element(2, Area))}, erlang:element(8, S), erlang:element(9, S), erlang:element(10, S), etui@style:none() ) end, case Track_len =< 0 of true -> Buf@2; false -> Track_area = etui@geometry:rect_new( erlang:element(2, erlang:element(2, Area)) + Arrow_left, erlang:element(3, erlang:element(2, Area)), Track_len, erlang:element(3, erlang:element(3, Area)) ), {Thumb_start, Thumb_size} = thumb_geometry(S, Track_len), render_horizontal_track( Buf@2, Track_area, S, Track_len, Thumb_start, Thumb_size, 0 ) end end.