etui/widgets/list

Types

Scroll and selection state for a list. Kept external so state persists across renders.

pub type ListState {
  ListState(selected: Int, offset: Int)
}

Constructors

  • ListState(selected: Int, offset: Int)

Scrollable list of styled items with selection highlight.

pub type ListWidget {
  ListWidget(
    items: List(span.Line),
    fg: style.Color,
    bg: style.Color,
    highlight_style: style.Style,
    blink_period: Int,
  )
}

Constructors

Values

pub fn clamp_state(
  state: ListState,
  item_count: Int,
) -> ListState

Clamp selected to [0, item_count - 1]. Call after replacing the item list to avoid a stale selection index.

pub fn effective_offset(state: ListState, height: Int) -> Int

Effective scroll offset for a viewport of height rows.

pub fn list_new(items: List(String)) -> ListWidget

New list from plain strings. Default colors, reverse-video selection.

pub fn list_new_styled(items: List(span.Line)) -> ListWidget

New list from styled span.Line items.

list.list_new_styled([
  span.line_new([span.span_styled("ERROR", style.bold_style()), span.span_plain(" file")]),
  span.line_plain("normal item"),
])
pub fn render(
  buf: buffer.Buffer,
  area: geometry.Rect,
  l: ListWidget,
) -> buffer.Buffer

Render the list with no selection (e.g. for a static table of contents).

pub fn render_animated(
  buf: buffer.Buffer,
  area: geometry.Rect,
  l: ListWidget,
  state: ListState,
  frame: Int,
) -> buffer.Buffer

Like render_stateful, but the highlight blinks on blink_period frames.

pub fn render_stateful(
  buf: buffer.Buffer,
  area: geometry.Rect,
  l: ListWidget,
  state: ListState,
) -> buffer.Buffer

Render the list, scrolling to keep the selection in view.

pub fn select(state: ListState, idx: Int) -> ListState

Jump the selection to idx. Negative indices clamp to 0.

pub fn select_next(
  state: ListState,
  item_count: Int,
) -> ListState

Move the selection down one, stopping at the last item.

pub fn select_prev(state: ListState) -> ListState

Move the selection up one, stopping at the first item.

pub fn settle(state: ListState, height: Int) -> ListState

The state this list settles on once it knows it has height rows.

A list cannot work out its scroll offset until it knows how tall its area is, and that is decided by the layout, not by the model. Call this with the height you are about to render into and keep the result:

let inner = block.inner(area, blk)
let listed = list.settle(model.list, inner.size.height)
let buf = list.render_stateful(buf, inner, widget, listed)
// store `listed` back in the model

Rendering without doing this still draws the right rows, because render_stateful works the offset out for itself. What it costs is that the offset never persists, so the viewport slides one row with every step instead of holding still until the selection leaves it.

pub fn state_new() -> ListState

Selection at the first item, viewport at the top.

pub fn with_blink(l: ListWidget, period: Int) -> ListWidget

Blink period in frames. 0 = steady (no blink). Use with render_animated.

pub fn with_colors(
  l: ListWidget,
  fg: style.Color,
  bg: style.Color,
) -> ListWidget

Colors of unselected rows.

pub fn with_highlight_style(
  l: ListWidget,
  s: style.Style,
) -> ListWidget

Style of the selected row (default: reverse video).

pub fn with_style(l: ListWidget, s: style.Style) -> ListWidget

Take only fg/bg from a Style.

✨ Search Document