Show viewport position with a scrollbar
Scrollbar describes position using caller-defined units. All lengths may be
rows, columns, items, or another uniform unit, as long as they use the same
unit.
use urushi::{ Available, Scrollbar, ScrollbarOrientation, ThemePreset, resolve,};
let theme = ThemePreset::get("Catppuccin Mocha") .expect("built-in theme") .theme();let scrollbar = Scrollbar::new( ScrollbarOrientation::Vertical, 100, 25,).position(50);
let view = theme.scrollbar(&scrollbar);let resolved = resolve(&view, Available::size(1, 8))?;assert_eq!(resolved.size().height(), 8);↑│││██│↓The presentation clamps an out-of-range position to the final origin where the viewport remains inside content. Orientation selects the main axis, not the edge; place the returned one-cell-cross-axis View beside content with a row or column.
Clone theme.components().scrollbar() to choose proportional or one-cell
marker thumb sizing, replace vertical or horizontal glyph sets, or style the
thumb, track, and endpoints independently. Present glyphs must be one printable,
one-cell grapheme.
Use a marker or replace glyphs
Section titled “Use a marker or replace glyphs”use urushi::{ Available, Scrollbar, ScrollbarGlyphs, ScrollbarOrientation, ScrollbarThumbSizing, ThemePreset, resolve,};
let theme = ThemePreset::get("Catppuccin Mocha") .expect("built-in theme") .theme();let scrollbar = Scrollbar::new(ScrollbarOrientation::Horizontal, 100, 25) .position(50);let presentation = theme .components() .scrollbar() .clone() .thumb_sizing(ScrollbarThumbSizing::Marker) .glyphs( ScrollbarOrientation::Horizontal, ScrollbarGlyphs::new("◆") .track(Some("·")) .begin(Some("[")) .end(Some("]")), );let view = presentation.compose(&scrollbar);let resolved = resolve(&view, Available::size(12, 1))?;assert_eq!(resolved.size().width(), 12);[······◆···]Proportional uses the viewport-to-content ratio for the thumb length;
Marker always uses one cell. Endpoints are shown only when the allocation can
hold both endpoints and at least one track cell. An out-of-range position is
clamped to content_length - viewport_length.
proportional, 12 cells [···███····]marker, 12 cells [······◆···]marker, 2 cells ·◆ (endpoints omitted)position 500 same as position 75: the last valid originlet clamped = Scrollbar::new(ScrollbarOrientation::Horizontal, 100, 25) .position(500);let wide = resolve(&theme.scrollbar(&clamped), Available::size(12, 1))?;let narrow = resolve(&theme.scrollbar(&clamped), Available::size(2, 1))?;assert_eq!(wide.size().width(), 12);assert_eq!(narrow.size().width(), 2);position 500 is clamped to 75; both finite allocations resolve successfully.wide width = 12 cells; narrow width = 2 cellsStyles apply independently to the four logical parts:
let presentation = theme.components().scrollbar().clone() .begin_style(TextStyle::new().foreground(Color::CYAN)) .track_style(TextStyle::new().dim()) .thumb_style(TextStyle::new().foreground(Color::GREEN).bold()) .end_style(TextStyle::new().foreground(Color::CYAN));[····◆····]