Skip to main content

ScrollState

Struct ScrollState 

Source
pub struct ScrollState { /* private fields */ }
Expand description

Tracks scroll position for virtual scrolling in TUI components.

ScrollState is a composable building block that any component can embed in its state to gain scroll offset tracking, visible range calculation, and scrollbar rendering support.

It supports two usage patterns:

  • Offset mode: The scroll offset is controlled directly via scroll_up, scroll_down, etc. Used by LogViewer, ChatView, ScrollableText.
  • Selection mode: The scroll offset follows a selected index via ensure_visible, keeping it within the viewport. Used by SelectableList, Table, DataGrid, etc.

§Example

use envision::scroll::ScrollState;

let mut scroll = ScrollState::new(500);
scroll.set_viewport_height(20);

assert_eq!(scroll.offset(), 0);
assert!(scroll.can_scroll());
assert!(scroll.at_start());

scroll.scroll_down();
assert_eq!(scroll.offset(), 1);

scroll.scroll_to_end();
assert_eq!(scroll.offset(), 480); // 500 - 20

Implementations§

Source§

impl ScrollState

Source

pub fn new(content_length: usize) -> Self

Creates a new ScrollState with the given content length.

The scroll offset starts at 0 and viewport height defaults to 0 (set it in view() once the render area is known).

§Example
use envision::scroll::ScrollState;

let scroll = ScrollState::new(100);
assert_eq!(scroll.content_length(), 100);
assert_eq!(scroll.offset(), 0);
Source

pub fn set_content_length(&mut self, len: usize)

Sets the total number of scrollable items or lines.

If the current offset exceeds the new maximum, it is clamped.

Source

pub fn set_viewport_height(&mut self, height: usize)

Sets the viewport height (number of visible items).

Typically called in view() after computing the inner render area. If the current offset exceeds the new maximum, it is clamped.

Source

pub fn set_offset(&mut self, offset: usize)

Sets the scroll offset directly, clamped to the valid range.

Source

pub fn scroll_up(&mut self) -> bool

Scrolls up by one item. Returns true if the offset changed.

Source

pub fn scroll_down(&mut self) -> bool

Scrolls down by one item. Returns true if the offset changed.

Source

pub fn scroll_up_by(&mut self, n: usize) -> bool

Scrolls up by n items. Returns true if the offset changed.

Source

pub fn scroll_down_by(&mut self, n: usize) -> bool

Scrolls down by n items. Returns true if the offset changed.

Source

pub fn page_up(&mut self, page_size: usize) -> bool

Scrolls up by one page (viewport height). Returns true if the offset changed.

Source

pub fn page_down(&mut self, page_size: usize) -> bool

Scrolls down by one page (viewport height). Returns true if the offset changed.

Source

pub fn scroll_to_start(&mut self) -> bool

Scrolls to the first item. Returns true if the offset changed.

Source

pub fn scroll_to_end(&mut self) -> bool

Scrolls to the last page. Returns true if the offset changed.

Source

pub fn ensure_visible(&mut self, index: usize) -> bool

Adjusts the scroll offset to ensure the given index is visible.

If the index is above the viewport, scrolls up. If below, scrolls down. If already visible, does nothing. Returns true if the offset changed.

This is the key method for selection-based components: after changing the selected index, call this to keep the selection in view.

§Example
use envision::scroll::ScrollState;

let mut scroll = ScrollState::new(100);
scroll.set_viewport_height(10);

// Selection at item 25 — scrolls viewport to show it
assert!(scroll.ensure_visible(25));
assert_eq!(scroll.offset(), 16); // 25 - 10 + 1

// Selection at item 20 — already visible, no change
assert!(!scroll.ensure_visible(20));
Source

pub fn offset(&self) -> usize

Returns the current scroll offset (index of the first visible item).

Source

pub fn content_length(&self) -> usize

Returns the total content length.

Source

pub fn viewport_height(&self) -> usize

Returns the viewport height.

Source

pub fn visible_range(&self) -> Range<usize>

Returns the range of visible item indices.

The range is offset..min(offset + viewport_height, content_length).

§Example
use envision::scroll::ScrollState;

let mut scroll = ScrollState::new(50);
scroll.set_viewport_height(10);
assert_eq!(scroll.visible_range(), 0..10);

scroll.scroll_to_end();
assert_eq!(scroll.visible_range(), 40..50);
Source

pub fn max_offset(&self) -> usize

Returns the maximum valid scroll offset.

This is content_length.saturating_sub(viewport_height).

Source

pub fn can_scroll(&self) -> bool

Returns true if scrolling is possible (content exceeds viewport).

Source

pub fn at_start(&self) -> bool

Returns true if at the top (offset is 0).

Source

pub fn at_end(&self) -> bool

Returns true if at the bottom (offset is at max).

Source

pub fn scrollbar_state(&self) -> ScrollbarState

Creates a ratatui ScrollbarState configured for this scroll state.

Use this with ratatui’s Scrollbar widget for visual scroll indicators.

Trait Implementations§

Source§

impl Clone for ScrollState

Source§

fn clone(&self) -> ScrollState

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ScrollState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ScrollState

Source§

fn default() -> ScrollState

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for ScrollState

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for ScrollState

Source§

fn eq(&self, other: &ScrollState) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for ScrollState

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for ScrollState

Source§

impl StructuralPartialEq for ScrollState

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> StateExt for T

Source§

fn updated(self, cmd: Command<impl Clone>) -> UpdateResult<Self, impl Clone>

Updates self and returns a command.
Source§

fn unchanged(self) -> UpdateResult<Self, ()>

Returns self with no command.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,