pub struct Model {
pub width: usize,
pub height: usize,
pub style: Style,
pub mouse_wheel_enabled: bool,
pub mouse_wheel_delta: usize,
pub y_offset: usize,
pub x_offset: usize,
pub horizontal_step: usize,
pub y_position: usize,
pub keymap: ViewportKeyMap,
/* private fields */
}Expand description
High-performance scrollable viewport for displaying large content efficiently.
This struct represents a complete viewport implementation that can handle content larger than the available display area. It provides smooth scrolling in both vertical and horizontal directions, efficient rendering of only visible content, and comprehensive keyboard navigation.
§Core Features
- Efficient Rendering: Only visible content is processed, enabling smooth performance with large datasets
- Bidirectional Scrolling: Full support for both vertical and horizontal content navigation
- Content Management: Flexible content input via strings or line vectors
- Styling Integration: Full lipgloss styling support with automatic frame calculations
- Position Tracking: Precise scroll percentages and boundary detection
- Keyboard Navigation: Comprehensive key bindings with Vim-style alternatives
§Examples
Basic viewport setup:
use bubbletea_widgets::viewport::Model;
// Create a viewport with specific dimensions
let mut viewport = Model::new(80, 24);
// Add content to display
let content = "Line 1\nLine 2\nLine 3\nVery long line that extends beyond viewport width\nLine 5";
viewport.set_content(content);
// Navigate through content
viewport.scroll_down(2); // Move down 2 lines
viewport.page_down(); // Move down one page
// Check current state
println!("At bottom: {}", viewport.at_bottom());
println!("Scroll progress: {:.1}%", viewport.scroll_percent() * 100.0);Integration with styling:
use bubbletea_widgets::viewport::Model;
use lipgloss::{Style, Color};
let viewport = Model::new(60, 20)
.with_style(
Style::new()
.border_style(lipgloss::normal_border())
.border_foreground(Color::from("#874BFD"))
.padding(1, 2, 1, 2)
);Working with line-based content:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(50, 15);
// Set content from individual lines
let lines = vec![
"Header Line".to_string(),
"Content Line 1".to_string(),
"Content Line 2".to_string(),
];
viewport.set_content_lines(lines);
// Get currently visible content
let visible = viewport.visible_lines();
println!("Displaying {} lines", visible.len());§Performance Characteristics
- Memory: Only stores content lines, not rendered output
- CPU: Rendering scales with viewport size, not content size
- Scrolling: Incremental updates return only affected lines
- Unicode: Proper width calculation for international content
§Thread Safety
The Model struct is Clone and can be safely used across threads.
All internal state is self-contained and doesn’t rely on external resources.
§State Management
The viewport maintains several key pieces of state:
- Content: Lines of text stored internally
- Position: Current scroll offsets for both axes
- Dimensions: Viewport size and styling frame calculations
- Configuration: Mouse settings, scroll steps, and key bindings
Fields§
§width: usizeDisplay width of the viewport in characters.
This determines how many characters are visible horizontally. Content wider than this will require horizontal scrolling to view.
height: usizeDisplay height of the viewport in lines.
This determines how many lines of content are visible at once. Content with more lines will require vertical scrolling to view.
style: StyleLipgloss style applied to the viewport content.
This style affects the entire viewport area and can include borders, padding, margins, and background colors. Frame sizes are automatically calculated and subtracted from the available content area.
mouse_wheel_enabled: boolWhether mouse wheel scrolling is enabled.
When true, mouse wheel events will scroll the viewport content.
Note: Actual mouse wheel support depends on the terminal and
bubbletea-rs mouse event capabilities.
mouse_wheel_delta: usizeNumber of lines to scroll per mouse wheel event.
Default is 3 lines per wheel “click”, which provides smooth scrolling without being too sensitive. Adjust based on content density.
y_offset: usizeCurrent vertical scroll position (lines from top).
This value indicates how many lines have been scrolled down from the beginning of the content. 0 means showing from the first line.
x_offset: usizeCurrent horizontal scroll position (characters from left).
This value indicates how many characters have been scrolled right from the beginning of each line. 0 means showing from column 0.
horizontal_step: usizeNumber of characters to scroll horizontally per step.
Controls the granularity of horizontal scrolling. Smaller values provide finer control, larger values enable faster navigation.
y_position: usizeVertical position of viewport in terminal for performance rendering.
Used for optimized rendering in some terminal applications. Generally can be left at default (0) unless implementing advanced rendering optimizations.
keymap: ViewportKeyMapKeyboard binding configuration for navigation.
Defines which keys control scrolling behavior. Can be customized to match application-specific navigation patterns or user preferences.
Implementations§
Source§impl Model
impl Model
Sourcepub fn new(width: usize, height: usize) -> Self
pub fn new(width: usize, height: usize) -> Self
Creates a new viewport with the specified dimensions.
This constructor initializes a viewport with the given width and height,
along with sensible defaults for all configuration options. The viewport
starts with no content and is ready to receive text via set_content()
or set_content_lines().
§Arguments
width- Display width in characters (horizontal viewport size)height- Display height in lines (vertical viewport size)
§Returns
A new Model instance with default configuration
§Examples
use bubbletea_widgets::viewport::Model;
// Create a standard terminal-sized viewport
let viewport = Model::new(80, 24);
assert_eq!(viewport.width, 80);
assert_eq!(viewport.height, 24);
assert!(viewport.mouse_wheel_enabled);Different viewport sizes for various use cases:
use bubbletea_widgets::viewport::Model;
// Compact viewport for sidebar content
let sidebar = Model::new(30, 20);
// Wide viewport for code display
let code_view = Model::new(120, 40);
// Small preview viewport
let preview = Model::new(40, 10);§Default Configuration
- Mouse wheel: Enabled with 3-line scroll delta
- Scroll position: At top-left (0, 0)
- Horizontal step: 1 character per scroll
- Style: No styling applied
- Key bindings: Vim-style with arrow key alternatives
§Performance
Viewport creation is very fast as no content processing occurs during construction. Memory usage scales with content size, not viewport dimensions.
Sourcepub fn with_dimensions(self, width: usize, height: usize) -> Self
pub fn with_dimensions(self, width: usize, height: usize) -> Self
Builder method to set viewport dimensions during construction.
This method allows for fluent construction by updating the viewport dimensions after creation. Useful when dimensions are computed or provided by external sources.
§Arguments
width- New width in charactersheight- New height in lines
§Returns
The modified viewport for method chaining
§Examples
use bubbletea_widgets::viewport::Model;
use lipgloss::Style;
// Fluent construction with dimensions
let viewport = Model::new(40, 10)
.with_dimensions(80, 24)
.with_style(Style::new().padding(1, 2, 1, 2));
assert_eq!(viewport.width, 80);
assert_eq!(viewport.height, 24);Dynamic viewport sizing:
use bubbletea_widgets::viewport::Model;
fn create_responsive_viewport(terminal_width: usize, terminal_height: usize) -> Model {
Model::new(20, 10) // Default size
.with_dimensions(
(terminal_width * 80) / 100, // 80% of terminal width
(terminal_height * 60) / 100 // 60% of terminal height
)
}Sourcepub fn with_style(self, style: Style) -> Self
pub fn with_style(self, style: Style) -> Self
Builder method to apply lipgloss styling to the viewport.
This method sets the visual styling for the entire viewport area. The style can include borders, padding, margins, colors, and other lipgloss formatting. Frame sizes are automatically calculated and subtracted from the content display area.
§Arguments
style- Lipgloss style to apply to the viewport
§Returns
The styled viewport for method chaining
§Examples
use bubbletea_widgets::viewport::Model;
use lipgloss::{Style, Color};
// Create viewport with border and padding
let viewport = Model::new(60, 20)
.with_style(
Style::new()
.border_style(lipgloss::normal_border())
.border_foreground(Color::from("#874BFD"))
.padding(1, 2, 1, 2)
);Themed viewport styling:
use bubbletea_widgets::viewport::Model;
use lipgloss::{Style, Color};
// Dark theme viewport
let dark_viewport = Model::new(80, 24)
.with_style(
Style::new()
.background(Color::from("#1a1a1a"))
.foreground(Color::from("#ffffff"))
.border_style(lipgloss::normal_border())
.border_foreground(Color::from("#444444"))
);
// Light theme viewport
let light_viewport = Model::new(80, 24)
.with_style(
Style::new()
.background(Color::from("#ffffff"))
.foreground(Color::from("#000000"))
.border_style(lipgloss::normal_border())
.border_foreground(Color::from("#cccccc"))
);§Frame Size Impact
Styling with borders and padding reduces the available content area:
use bubbletea_widgets::viewport::Model;
use lipgloss::Style;
// 80x24 viewport with 2-character padding
let viewport = Model::new(80, 24)
.with_style(
Style::new().padding(1, 2, 1, 2) // top, right, bottom, left
);
// Effective content area is now ~76x22 due to paddingSourcepub fn at_top(&self) -> bool
pub fn at_top(&self) -> bool
Returns whether the viewport is scrolled to the very top of the content.
This method checks if the vertical scroll position is at the beginning, meaning no content is hidden above the current view. Useful for determining when scroll-up operations should be disabled or when displaying scroll indicators.
§Returns
true if at the top (y_offset == 0), false if content is scrolled
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
let content = (1..=20).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n");
viewport.set_content(&content);
// Initially at top
assert!(viewport.at_top());
// After scrolling down
viewport.scroll_down(1);
assert!(!viewport.at_top());
// After returning to top
viewport.goto_top();
assert!(viewport.at_top());UI integration example:
use bubbletea_widgets::viewport::Model;
fn render_scroll_indicator(viewport: &Model) -> String {
let up_arrow = if viewport.at_top() { " " } else { "↑" };
let down_arrow = if viewport.at_bottom() { " " } else { "↓" };
format!("{} Content {} ", up_arrow, down_arrow)
}Sourcepub fn at_bottom(&self) -> bool
pub fn at_bottom(&self) -> bool
Returns whether the viewport is scrolled to or past the bottom of the content.
This method checks if the vertical scroll position has reached the end, meaning no more content is available below the current view. Useful for determining when scroll-down operations should be disabled or when implementing infinite scroll detection.
§Returns
true if at or past the bottom, false if more content is available below
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 3); // Small viewport
viewport.set_content("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
// Initially not at bottom (more content below)
assert!(!viewport.at_bottom());
// Scroll to bottom
viewport.goto_bottom();
assert!(viewport.at_bottom());Scroll control logic:
use bubbletea_widgets::viewport::Model;
fn handle_scroll_down(viewport: &mut Model) -> bool {
if viewport.at_bottom() {
// Can't scroll further down
false
} else {
viewport.scroll_down(1);
true
}
}§Difference from past_bottom()
at_bottom(): Returnstruewhen at the maximum valid scroll positionpast_bottom(): Returnstrueonly when scrolled beyond valid content
Sourcepub fn past_bottom(&self) -> bool
pub fn past_bottom(&self) -> bool
Returns whether the viewport has been scrolled beyond valid content.
This method detects an invalid scroll state where the y_offset exceeds the maximum valid position. This can occur during content changes or viewport resizing. Generally indicates a need for scroll position correction.
§Returns
true if scrolled past valid content, false if within valid range
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
viewport.set_content("Line 1\nLine 2\nLine 3");
// Normal scroll position
assert!(!viewport.past_bottom());
// This would typically be prevented by normal scroll methods,
// but could occur during content changesAuto-correction usage:
use bubbletea_widgets::viewport::Model;
fn ensure_valid_scroll(viewport: &mut Model) {
if viewport.past_bottom() {
viewport.goto_bottom(); // Correct invalid position
}
}§Use Cases
- Detecting invalid state after content changes
- Validation in custom scroll implementations
- Debug assertion checks
- Auto-correction logic
Sourcepub fn scroll_percent(&self) -> f64
pub fn scroll_percent(&self) -> f64
Returns the vertical scroll progress as a percentage from 0.0 to 1.0.
This method calculates how far through the content the viewport has scrolled vertically. 0.0 indicates the top, 1.0 indicates the bottom. Useful for implementing scroll indicators, progress bars, or proportional navigation controls.
§Returns
A float between 0.0 and 1.0 representing scroll progress:
0.0: At the very top of content0.5: Halfway through content1.0: At or past the bottom of content
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content("Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8\nLine 9\nLine 10");
// At top
assert_eq!(viewport.scroll_percent(), 0.0);
// Scroll partway down
viewport.scroll_down(2);
let progress = viewport.scroll_percent();
assert!(progress > 0.0 && progress < 1.0);
// At bottom
viewport.goto_bottom();
assert_eq!(viewport.scroll_percent(), 1.0);Progress bar implementation:
use bubbletea_widgets::viewport::Model;
fn render_progress_bar(viewport: &Model, width: usize) -> String {
let progress = viewport.scroll_percent();
let filled_chars = (progress * width as f64) as usize;
let empty_chars = width - filled_chars;
format!(
"[{}{}] {:.1}%",
"█".repeat(filled_chars),
"░".repeat(empty_chars),
progress * 100.0
)
}§Special Cases
- If viewport height >= content lines, returns 1.0 (all content visible)
- Result is clamped to [0.0, 1.0] range for safety
- Calculation accounts for viewport height in determining valid scroll range
Sourcepub fn horizontal_scroll_percent(&self) -> f64
pub fn horizontal_scroll_percent(&self) -> f64
Returns the horizontal scroll progress as a percentage from 0.0 to 1.0.
This method calculates how far through the content width the viewport has scrolled horizontally. 0.0 indicates the leftmost position, 1.0 indicates the rightmost position. Useful for implementing horizontal scroll indicators or proportional navigation controls for wide content.
§Returns
A float between 0.0 and 1.0 representing horizontal scroll progress:
0.0: At the leftmost edge of content0.5: Halfway through the content width1.0: At or past the rightmost edge of content
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(20, 5);
viewport.set_content("Short line\nThis is a very long line that extends beyond viewport width\nAnother line");
// At left edge
assert_eq!(viewport.horizontal_scroll_percent(), 0.0);
// Scroll horizontally
// Scroll right 10 times
for _ in 0..10 {
viewport.scroll_right();
}
let h_progress = viewport.horizontal_scroll_percent();
assert!(h_progress > 0.0 && h_progress <= 1.0);
// At right edge
// Scroll far to ensure we reach the end
for _ in 0..1000 {
viewport.scroll_right();
}
assert_eq!(viewport.horizontal_scroll_percent(), 1.0);Horizontal progress indicator:
use bubbletea_widgets::viewport::Model;
fn render_horizontal_indicator(viewport: &Model, width: usize) -> String {
let h_progress = viewport.horizontal_scroll_percent();
let position = (h_progress * width as f64) as usize;
let mut indicator = vec!['-'; width];
if position < width {
indicator[position] = '|';
}
indicator.into_iter().collect()
}§Special Cases
- If viewport width >= longest line width, returns 1.0 (all content visible)
- Result is clamped to [0.0, 1.0] range for safety
- Based on the longest line in the content, not current visible lines
Sourcepub fn set_content(&mut self, content: &str)
pub fn set_content(&mut self, content: &str)
Sets the viewport’s text content from a multi-line string.
This method processes the provided string by splitting it into individual lines
and storing them internally for display. Line endings are normalized to Unix-style
(\n), and the longest line width is calculated for horizontal scrolling support.
§Arguments
content- The text content as a multi-line string
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
viewport.set_content("Line 1\nLine 2\nVery long line that extends beyond viewport width\nLine 4");
// Content is now available for display
let visible = viewport.visible_lines();
assert!(!visible.is_empty());Loading file content:
use bubbletea_widgets::viewport::Model;
use std::fs;
let mut viewport = Model::new(80, 24);
// Load file content into viewport
let file_content = fs::read_to_string("example.txt").unwrap_or_default();
viewport.set_content(&file_content);Dynamic content updates:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(50, 15);
// Initial content
viewport.set_content("Initial content\nLine 2");
// Update with new content
let new_content = (1..=100)
.map(|i| format!("Generated line {}", i))
.collect::<Vec<_>>()
.join("\n");
viewport.set_content(&new_content);§Behavior
- Line Ending Normalization: Converts
\r\nto\nfor consistency - Width Calculation: Automatically computes the longest line for horizontal scrolling
- Scroll Position: If the current scroll position becomes invalid, scrolls to bottom
- Performance: Content processing occurs immediately; consider using
set_content_lines()for pre-split content
§Cross-Platform Compatibility
Content from Windows systems with \r\n line endings is automatically normalized,
ensuring consistent behavior across all platforms.
Sourcepub fn set_content_lines(&mut self, lines: Vec<String>)
pub fn set_content_lines(&mut self, lines: Vec<String>)
Sets the viewport content from a pre-split vector of lines.
This method directly sets the viewport content from an existing vector of
strings, avoiding the string splitting overhead of set_content(). Each
string represents one line of content. This is more efficient when content
is already available as individual lines.
§Arguments
lines- Vector of strings where each string is a content line
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
let lines = vec![
"Header Line".to_string(),
"Content Line 1".to_string(),
"Content Line 2".to_string(),
"A very long line that extends beyond the viewport width".to_string(),
];
viewport.set_content_lines(lines);
let visible = viewport.visible_lines();
assert_eq!(visible.len(), 4); // All lines fit in viewport heightProcessing structured data:
use bubbletea_widgets::viewport::Model;
#[derive(Debug)]
struct LogEntry {
timestamp: String,
level: String,
message: String,
}
let mut viewport = Model::new(80, 20);
let log_entries = vec![
LogEntry { timestamp: "2024-01-01T10:00:00".to_string(), level: "INFO".to_string(), message: "Application started".to_string() },
LogEntry { timestamp: "2024-01-01T10:01:00".to_string(), level: "ERROR".to_string(), message: "Connection failed".to_string() },
];
let formatted_lines: Vec<String> = log_entries
.iter()
.map(|entry| format!("[{}] {}: {}", entry.timestamp, entry.level, entry.message))
.collect();
viewport.set_content_lines(formatted_lines);Reading from various sources:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(60, 15);
// Use pre-split lines for better performance
let lines: Vec<String> = vec![
"Line 1".to_string(),
"Line 2".to_string(),
"Line 3".to_string(),
];
viewport.set_content_lines(lines);
assert_eq!(viewport.line_count(), 3);§Performance Benefits
- No String Processing: Avoids the overhead of splitting a large string
- Memory Efficient: Directly moves the vector into internal storage
- Ideal for Streaming: Perfect for incrementally building content
- Pre-formatted Content: Useful when lines are already processed/formatted
§Behavior
- Width Calculation: Automatically computes the longest line for horizontal scrolling
- Scroll Position: If current scroll position becomes invalid, scrolls to bottom
- Ownership: Takes ownership of the provided vector
- No Normalization: Lines are used as-is without line ending processing
Sourcepub fn visible_lines(&self) -> Vec<String>
pub fn visible_lines(&self) -> Vec<String>
Returns the lines currently visible in the viewport.
This method calculates which lines should be displayed based on the current scroll position, viewport dimensions, and applied styling. It handles both vertical scrolling (which lines to show) and horizontal scrolling (which portion of each line to show). The result accounts for frame sizes from lipgloss styling like borders and padding.
§Returns
A vector of strings representing the currently visible content lines. Each string is horizontally clipped to fit within the viewport width.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(20, 5);
viewport.set_content("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
// Get initial visible lines (height 5 minus 2 frame = 3 effective)
let visible = viewport.visible_lines();
assert_eq!(visible.len(), 3);
assert_eq!(visible[0], "Line 1");
assert_eq!(visible[1], "Line 2");
assert_eq!(visible[2], "Line 3");
// After scrolling down
viewport.scroll_down(2);
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 3");
assert_eq!(visible[1], "Line 4");
assert_eq!(visible[2], "Line 5");Horizontal scrolling example:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(10, 4); // Narrow viewport (4 height minus 2 frame = 2 effective)
viewport.set_content("Short\nThis is a very long line that gets clipped");
// Initial view shows left portion
let visible = viewport.visible_lines();
assert_eq!(visible[1], "This is ");
// After horizontal scrolling
// Scroll right 5 times
for _ in 0..5 {
viewport.scroll_right();
}
let visible = viewport.visible_lines();
assert_eq!(visible[1], "is a ver"); // Shifted right (8 chars max)Working with styled viewport:
use bubbletea_widgets::viewport::Model;
use lipgloss::Style;
let mut viewport = Model::new(20, 5)
.with_style(
Style::new().padding(1, 2, 1, 2) // Reduces effective size
);
viewport.set_content("Line 1\nLine 2\nLine 3");
let visible = viewport.visible_lines();
// Available content area is reduced by padding
// Each visible line is also clipped to account for horizontal padding§Performance Considerations
- Efficient Rendering: Only processes lines within the visible area
- Frame Calculation: Style frame sizes are computed once per call
- Clipping: Horizontal clipping is applied only when needed
- Memory: Returns a new vector; consider caching for frequent calls
§Integration Patterns
This method is typically used in the view/render phase:
use bubbletea_widgets::viewport::Model;
use lipgloss::Style;
fn render_viewport_content(viewport: &Model) -> String {
let visible_lines = viewport.visible_lines();
if visible_lines.is_empty() {
return "No content to display".to_string();
}
visible_lines.join("\n")
}Sourcepub fn set_y_offset(&mut self, n: usize)
pub fn set_y_offset(&mut self, n: usize)
Sets the vertical scroll position to a specific line offset.
This method directly positions the viewport at the specified line offset from the beginning of the content. The offset is automatically clamped to ensure it remains within valid bounds (0 to maximum valid offset).
§Arguments
n- The line number to scroll to (0-based indexing)
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content(&(1..=20).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Jump to line 10 (0-based, so content shows "Line 11")
viewport.set_y_offset(10);
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 11");
// Attempt to scroll beyond content (gets clamped)
viewport.set_y_offset(1000);
assert!(viewport.at_bottom());Direct positioning for navigation:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(80, 20);
viewport.set_content("Line content...");
// Jump to 25% through the content
let total_lines = 100; // Assume we know content size
let quarter_position = total_lines / 4;
viewport.set_y_offset(quarter_position);§Clamping Behavior
- Values less than 0: Set to 0 (top of content)
- Values greater than maximum valid offset: Set to maximum (bottom view)
- Maximum offset ensures at least one line is visible when possible
§Use Cases
- Direct Navigation: Jump to specific locations
- Proportional Scrolling: Navigate based on percentages
- Search Results: Position at specific line numbers
- Bookmarks: Return to saved positions
Sourcepub fn page_down(&mut self) -> Vec<String>
pub fn page_down(&mut self) -> Vec<String>
Scrolls down by one full page (viewport height).
This method moves the viewport down by exactly the viewport height, effectively showing the next “page” of content. This is the standard page-down operation found in most text viewers and editors.
§Returns
A vector of strings representing the newly visible lines that scrolled into view. Returns an empty vector if already at the bottom or no scrolling occurred.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content(&(1..=20).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Initially shows lines 1-5
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 1");
// Page down shows lines 6-10
let new_lines = viewport.page_down();
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 6");
assert!(!new_lines.is_empty());Handling bottom boundary:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content("Line 1\nLine 2\nLine 3"); // Only 3 lines
// At bottom already, page_down returns empty
viewport.goto_bottom();
let result = viewport.page_down();
assert!(result.is_empty());§Performance Optimization
The returned vector contains only the newly visible lines for efficient rendering updates. Applications can use this for incremental display updates.
Sourcepub fn page_up(&mut self) -> Vec<String>
pub fn page_up(&mut self) -> Vec<String>
Scrolls up by one full page (viewport height).
This method moves the viewport up by exactly the viewport height, effectively showing the previous “page” of content. This is the standard page-up operation found in most text viewers and editors.
§Returns
A vector of strings representing the newly visible lines that scrolled into view. Returns an empty vector if already at the top or no scrolling occurred.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content(&(1..=20).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Scroll to middle, then page up
viewport.set_y_offset(10);
let new_lines = viewport.page_up();
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 6"); // Moved up by 5 linesHandling top boundary:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content("Line 1\nLine 2\nLine 3");
// Already at top, page_up returns empty
let result = viewport.page_up();
assert!(result.is_empty());
assert!(viewport.at_top());Sourcepub fn half_page_down(&mut self) -> Vec<String>
pub fn half_page_down(&mut self) -> Vec<String>
Scrolls down by half the viewport height.
This method provides a more granular scrolling option than full page scrolling, moving the viewport down by half its height. This is commonly mapped to Ctrl+D in Vim-style navigation.
§Returns
A vector of strings representing the newly visible lines that scrolled into view. Returns an empty vector if already at the bottom or no scrolling occurred.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10); // Height of 10
viewport.set_content(&(1..=30).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Half page down moves by 5 lines (10/2)
viewport.half_page_down();
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 6"); // Moved down 5 lines§Use Cases
- Gradual Navigation: More controlled scrolling than full pages
- Vim Compatibility: Matches Ctrl+D behavior
- Reading Flow: Maintains better context when scrolling through text
Sourcepub fn half_page_up(&mut self) -> Vec<String>
pub fn half_page_up(&mut self) -> Vec<String>
Scrolls up by half the viewport height.
This method provides a more granular scrolling option than full page scrolling, moving the viewport up by half its height. This is commonly mapped to Ctrl+U in Vim-style navigation.
§Returns
A vector of strings representing the newly visible lines that scrolled into view. Returns an empty vector if already at the top or no scrolling occurred.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10); // Height of 10
viewport.set_content(&(1..=30).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Move to middle, then half page up
viewport.set_y_offset(15);
viewport.half_page_up();
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 11"); // Moved up 5 lines (15-5+1)§Use Cases
- Gradual Navigation: More controlled scrolling than full pages
- Vim Compatibility: Matches Ctrl+U behavior
- Reading Flow: Maintains better context when scrolling through text
Sourcepub fn scroll_down(&mut self, n: usize) -> Vec<String>
pub fn scroll_down(&mut self, n: usize) -> Vec<String>
Scrolls down by the specified number of lines.
This is the fundamental vertical scrolling method that moves the viewport down by the specified number of lines. All other downward scrolling methods (page_down, half_page_down) ultimately delegate to this method.
§Arguments
n- Number of lines to scroll down
§Returns
A vector containing the newly visible lines for performance rendering. Returns empty vector if no scrolling occurred.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content(&(1..=20).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Scroll down 3 lines
let new_lines = viewport.scroll_down(3);
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 4"); // Now starting from line 4
assert_eq!(new_lines.len(), 3); // 3 new lines scrolled inEdge case handling:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content("Line 1\nLine 2");
// No scrolling at bottom
viewport.goto_bottom();
let result = viewport.scroll_down(5);
assert!(result.is_empty());
// No scrolling with n=0
viewport.goto_top();
let result = viewport.scroll_down(0);
assert!(result.is_empty());§Performance Optimization
The returned vector contains only the lines that scrolled into view, enabling efficient incremental rendering in terminal applications. This avoids re-rendering the entire viewport when only a few lines changed.
§Boundary Behavior
- Automatically stops at the bottom of content
- Returns empty vector if already at bottom
- Handles viewport larger than content gracefully
Sourcepub fn scroll_up(&mut self, n: usize) -> Vec<String>
pub fn scroll_up(&mut self, n: usize) -> Vec<String>
Scrolls up by the specified number of lines.
This is the fundamental vertical scrolling method that moves the viewport up by the specified number of lines. All other upward scrolling methods (page_up, half_page_up) ultimately delegate to this method.
§Arguments
n- Number of lines to scroll up
§Returns
A vector containing the newly visible lines for performance rendering. Returns empty vector if no scrolling occurred.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content(&(1..=20).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Start from middle
viewport.set_y_offset(10);
// Scroll up 3 lines
let new_lines = viewport.scroll_up(3);
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 8"); // Now starting from line 8 (10-3+1)
assert_eq!(new_lines.len(), 3); // 3 new lines scrolled inEdge case handling:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content("Line 1\nLine 2");
// No scrolling at top
let result = viewport.scroll_up(5);
assert!(result.is_empty());
assert!(viewport.at_top());
// No scrolling with n=0
let result = viewport.scroll_up(0);
assert!(result.is_empty());§Performance Optimization
The returned vector contains only the lines that scrolled into view, enabling efficient incremental rendering. Applications can update only the changed portions of the display.
§Boundary Behavior
- Automatically stops at the top of content
- Returns empty vector if already at top
- Uses saturating subtraction to prevent underflow
Sourcepub fn goto_top(&mut self)
pub fn goto_top(&mut self)
Jumps directly to the beginning of the content.
This method immediately positions the viewport at the very top of the content, setting the vertical offset to 0. This is equivalent to pressing the “Home” key in most text viewers.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content(&(1..=20).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Scroll to middle first
viewport.set_y_offset(10);
assert!(!viewport.at_top());
// Jump to top
viewport.goto_top();
assert!(viewport.at_top());
let visible = viewport.visible_lines();
assert_eq!(visible[0], "Line 1");§Use Cases
- Navigation shortcuts: Quick return to document start
- Reset position: Return to initial state after scrolling
- Search results: Jump to first occurrence
- Content refresh: Start from beginning after content changes
Sourcepub fn goto_bottom(&mut self)
pub fn goto_bottom(&mut self)
Jumps directly to the end of the content.
This method immediately positions the viewport at the bottom of the content, showing the last possible page. This is equivalent to pressing the “End” key in most text viewers.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 5);
viewport.set_content(&(1..=20).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
// Jump to bottom
viewport.goto_bottom();
assert!(viewport.at_bottom());
let visible = viewport.visible_lines();
// With 20 lines total and height 5 (minus 2 for frame), bottom shows last 3 lines
assert_eq!(visible[0], "Line 18");
assert_eq!(visible[2], "Line 20");Auto-correction after content changes:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
// Set initial content and scroll down
viewport.set_content(&(1..=50).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
viewport.set_y_offset(30);
// Replace with shorter content
viewport.set_content("Line 1\nLine 2\nLine 3");
// goto_bottom() is called automatically to fix invalid offset
assert!(viewport.at_bottom());§Use Cases
- Navigation shortcuts: Quick jump to document end
- Log viewing: Jump to latest entries
- Content appending: Position for new content
- Auto-correction: Fix invalid positions after content changes
Sourcepub fn set_horizontal_step(&mut self, step: usize)
pub fn set_horizontal_step(&mut self, step: usize)
Sets the horizontal scrolling step size in characters.
This method configures how many characters the viewport scrolls
horizontally with each left/right scroll operation. The step size
affects both scroll_left() and scroll_right() methods.
§Arguments
step- Number of characters to scroll per horizontal step
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(20, 5);
viewport.set_content("This is a very long line that extends far beyond the viewport width");
// Default step is 1 character
viewport.scroll_right();
assert_eq!(viewport.x_offset, 1);
// Set larger step for faster scrolling
viewport.set_horizontal_step(5);
viewport.scroll_right();
assert_eq!(viewport.x_offset, 6); // 1 + 5Different step sizes for different content types:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
// Fine scrolling for precise text viewing
viewport.set_horizontal_step(1);
// Coarse scrolling for wide data tables
viewport.set_horizontal_step(8); // Tab-like steps
// Word-based scrolling
viewport.set_horizontal_step(4); // Average word length§Use Cases
- Fine Control: Single-character precision (step=1)
- Tab Columns: Align with tab stops (step=4 or 8)
- Word Navigation: Approximate word-based scrolling
- Performance: Larger steps for faster navigation of wide content
Sourcepub fn scroll_left(&mut self)
pub fn scroll_left(&mut self)
Scrolls the viewport left by the configured horizontal step.
This method moves the horizontal view to the left, revealing content
that was previously hidden on the left side. The scroll amount is
determined by the horizontal_step setting.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(10, 3);
viewport.set_content("This is a very long line that needs horizontal scrolling");
// Scroll right first to see the effect of scrolling left
viewport.scroll_right();
viewport.scroll_right();
assert_eq!(viewport.x_offset, 2);
// Scroll left
viewport.scroll_left();
assert_eq!(viewport.x_offset, 1);Boundary handling:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(20, 5);
viewport.set_content("Short content");
// Already at leftmost position, scroll_left has no effect
assert_eq!(viewport.x_offset, 0);
viewport.scroll_left();
assert_eq!(viewport.x_offset, 0); // Still 0, can't scroll further left§Behavior
- Boundary Safe: Uses saturating subtraction to prevent underflow
- Step-based: Scrolls by
horizontal_stepamount - Immediate: Takes effect immediately, no animation
- Absolute Minimum: Cannot scroll past offset 0 (leftmost position)
Sourcepub fn scroll_right(&mut self)
pub fn scroll_right(&mut self)
Scrolls the viewport right by the configured horizontal step.
This method moves the horizontal view to the right, revealing content
that was previously hidden on the right side. The scroll amount is
determined by the horizontal_step setting, and scrolling is limited
by the longest line in the content.
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(10, 3);
viewport.set_content("This is a very long line that needs horizontal scrolling");
// Initial view shows "This is " (width 10 minus 2 for frame = 8 chars)
let visible = viewport.visible_lines();
assert_eq!(visible[0].len(), 8);
// Scroll right to see more
viewport.scroll_right();
let visible = viewport.visible_lines();
// Now shows "his is a v" (shifted 1 character right)Boundary handling:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(20, 5);
viewport.set_content("Short"); // Line shorter than viewport
// Cannot scroll right when content fits in viewport
viewport.scroll_right();
assert_eq!(viewport.x_offset, 0); // No changeMultiple step sizes:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(10, 3);
viewport.set_content("Very long line for testing horizontal scrolling behavior");
// Default single-character scrolling
viewport.scroll_right();
assert_eq!(viewport.x_offset, 1);
// Change to larger steps
viewport.set_horizontal_step(5);
viewport.scroll_right();
assert_eq!(viewport.x_offset, 6); // 1 + 5§Behavior
- Content-aware: Maximum scroll is based on longest line width
- Viewport-relative: Considers viewport width in maximum calculation
- Step-based: Scrolls by
horizontal_stepamount - Clamped: Cannot scroll past the rightmost useful position
Sourcepub fn lines(&self) -> &[String]
pub fn lines(&self) -> &[String]
Returns a reference to the internal content lines.
This method provides read-only access to all content lines stored in the viewport. Useful for inspection, searching, or analysis of content without copying.
§Returns
A slice containing all content lines as strings
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
viewport.set_content("Line 1\nLine 2\nLine 3");
let lines = viewport.lines();
assert_eq!(lines.len(), 3);
assert_eq!(lines[0], "Line 1");
assert_eq!(lines[2], "Line 3");Content inspection and search:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
viewport.set_content("Line 1\nImportant line\nLine 3");
// Search for specific content
let lines = viewport.lines();
let important_line = lines.iter().find(|line| line.contains("Important"));
assert!(important_line.is_some());Sourcepub fn line_count(&self) -> usize
pub fn line_count(&self) -> usize
Returns the total number of content lines.
This method returns the count of all content lines, regardless of viewport dimensions or scroll position. Useful for determining content size, calculating scroll percentages, or implementing navigation features.
§Returns
The total number of lines in the content
§Examples
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
viewport.set_content("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
assert_eq!(viewport.line_count(), 5);
// Empty content
viewport.set_content("");
assert_eq!(viewport.line_count(), 1); // Empty string creates one empty lineNavigation calculations:
use bubbletea_widgets::viewport::Model;
let mut viewport = Model::new(40, 10);
viewport.set_content(&(1..=100).map(|i| format!("Line {}", i)).collect::<Vec<_>>().join("\n"));
let total_lines = viewport.line_count();
let viewport_height = viewport.height;
// Calculate if scrolling is needed
let needs_scrolling = total_lines > viewport_height;
assert!(needs_scrolling);
// Calculate maximum number of pages
let max_pages = (total_lines + viewport_height - 1) / viewport_height;
assert_eq!(max_pages, 10); // 100 lines / 10 height = 10 pagesTrait Implementations§
Source§impl Default for Model
impl Default for Model
Source§fn default() -> Self
fn default() -> Self
Creates a default viewport with standard terminal dimensions.
The default viewport is sized for typical terminal windows (80x24) and
includes all default configuration options. This is equivalent to calling
Model::new(80, 24).
§Examples
use bubbletea_widgets::viewport::Model;
let viewport = Model::default();
assert_eq!(viewport.width, 80);
assert_eq!(viewport.height, 24);
assert!(viewport.mouse_wheel_enabled);§Default Configuration
- Dimensions: 80 characters × 24 lines (standard terminal size)
- Mouse wheel: Enabled with 3-line scroll delta
- Scroll position: At top-left (0, 0)
- Horizontal step: 1 character per scroll
- Style: No styling applied
- Key bindings: Vim-style with arrow key alternatives
Source§impl Model for Model
impl Model for Model
Source§fn init() -> (Self, Option<Cmd>)
fn init() -> (Self, Option<Cmd>)
Initializes a new viewport instance for Bubble Tea applications.
Creates a default viewport with standard terminal dimensions and no initial commands. This follows the Bubble Tea initialization pattern where components return their initial state and any startup commands.
§Returns
A tuple containing:
- A default viewport instance (80x24)
None(no initialization commands needed)
§Examples
use bubbletea_widgets::viewport::Model;
use bubbletea_rs::Model as BubbleTeaModel;
let (viewport, cmd) = Model::init();
assert_eq!(viewport.width, 80);
assert_eq!(viewport.height, 24);
assert!(cmd.is_none());Source§fn update(&mut self, msg: Msg) -> Option<Cmd>
fn update(&mut self, msg: Msg) -> Option<Cmd>
Processes messages and updates viewport state.
This method handles keyboard input for viewport navigation, implementing the standard Bubble Tea update pattern. It processes key messages against the configured key bindings and updates the viewport scroll position accordingly.
§Arguments
msg- The message to process (typically keyboard input)
§Returns
Always returns None as viewport operations don’t generate commands
§Supported Key Bindings
The default key bindings include:
- Page navigation:
f/PgDn/Space(page down),b/PgUp(page up) - Half-page navigation:
d(half page down),u(half page up) - Line navigation:
j/↓(line down),k/↑(line up) - Horizontal navigation:
l/→(scroll right),h/←(scroll left)
§Examples
use bubbletea_widgets::viewport::Model;
use bubbletea_rs::{Model as BubbleTeaModel, KeyMsg};
use crossterm::event::{KeyCode, KeyModifiers};
let mut viewport = Model::default();
viewport.set_content("Line 1\nLine 2\nLine 3\nLine 4\nLine 5");
// Simulate pressing 'j' to scroll down
let key_msg = KeyMsg {
key: KeyCode::Char('j'),
modifiers: KeyModifiers::NONE,
};
let cmd = viewport.update(Box::new(key_msg));
assert!(cmd.is_none());§Integration with Bubble Tea
This method integrates seamlessly with Bubble Tea’s message-driven architecture:
use bubbletea_widgets::viewport::Model;
use bubbletea_rs::{Model as BubbleTeaModel, Msg};
struct App {
viewport: Model,
}
impl BubbleTeaModel for App {
fn update(&mut self, msg: Msg) -> Option<bubbletea_rs::Cmd> {
// Forward messages to viewport
self.viewport.update(msg);
None
}
}Source§fn view(&self) -> String
fn view(&self) -> String
Renders the viewport content as a styled string.
This method generates the visual representation of the viewport by retrieving the currently visible lines and applying any configured lipgloss styling. The output is ready for display in a terminal interface.
§Returns
A styled string containing the visible content, ready for terminal output
§Examples
use bubbletea_widgets::viewport::Model;
use bubbletea_rs::Model as BubbleTeaModel;
let mut viewport = Model::new(20, 5);
viewport.set_content("Line 1\nLine 2\nLine 3\nLine 4");
let output = viewport.view();
assert!(output.contains("Line 1"));
assert!(output.contains("Line 2"));
assert!(output.contains("Line 3"));
assert!(!output.contains("Line 4")); // Not visible in 5-line viewport (3 effective)With styling applied:
use bubbletea_widgets::viewport::Model;
use bubbletea_rs::Model as BubbleTeaModel;
use lipgloss::{Style, Color};
let mut viewport = Model::new(20, 3)
.with_style(
Style::new()
.foreground(Color::from("#FF0000"))
.background(Color::from("#000000"))
);
viewport.set_content("Styled content");
let styled_output = viewport.view();
// Output includes ANSI escape codes for styling§Rendering Behavior
- Visible Lines Only: Only renders content within the current viewport
- Horizontal Clipping: Content wider than viewport is clipped appropriately
- Style Application: Applied lipgloss styles are rendered into the output
- Line Joining: Multiple lines are joined with newline characters
- Frame Accounting: Styling frame sizes are automatically considered
Auto Trait Implementations§
impl Freeze for Model
impl !RefUnwindSafe for Model
impl Send for Model
impl Sync for Model
impl Unpin for Model
impl !UnwindSafe for Model
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
Source§fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
Source§impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Source§fn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Source§impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Source§fn arrays_into(self) -> C
fn arrays_into(self) -> C
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Source§type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters when converting.Source§fn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self into C, using the provided parameters.Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Source§fn components_from(colors: C) -> T
fn components_from(colors: C) -> T
Source§impl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Source§fn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle.Source§impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Source§fn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other into Self, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Source§fn into_angle(self) -> U
fn into_angle(self) -> U
T.Source§impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Source§type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters when converting.Source§fn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self into C, using the provided parameters.Source§impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Source§fn into_color(self) -> U
fn into_color(self) -> U
Source§impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Source§fn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
Source§impl<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Source§fn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self into T, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Source§type Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors fails to cast.Source§fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Source§impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Source§fn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds error is returned which contains
the unclamped color. Read more