osui::elements::paginator
The Paginator
element is a container that manages a collection of child widgets, displaying only one child at a time. It provides built-in logic to navigate between these "pages" using keyboard events (specifically, Tab
and Shift+Tab
).
Paginator
Struct
pub struct Paginator {
children: Vec<Arc<Widget>>, // The list of pages/children
size: (u16, u16), // Internal tracking of the Paginator's calculated size
index: usize, // The index of the currently displayed child
}
Associated Methods
Paginator::new() -> Self
Creates a new Paginator
instance with no children and an initial index
of 0
.
Example:
use osui::prelude::*;
let my_paginator = Paginator::new();
Element
Trait Implementation
render(&mut self, scope: &mut RenderScope, _: &RenderContext)
This method primarily focuses on setting the RenderScope
's area based on its calculated size. It does not draw any visual elements for the Paginator
itself, acting as a "ghost" element.
after_render(&mut self, scope: &mut RenderScope, render_context: &RenderContext)
This is the core rendering logic for Paginator
:
- It checks if
self.index
points to a valid child inself.children
. - If a child exists at the current
index
, it prepares aRenderScope
(cloning its ownRawTransform
). - It sets the
RenderScope
'sparent_size
to its own (Paginator's) determinedwidth
andheight
, so the child lays out correctly within the Paginator's bounds. - It creates a
DivRenderer
helper to manage the child's positioning. - It calls
scope.render_widget
for only the currently active child widget. - After the child is rendered, it restores the original
parent_size
to theRenderScope
. - It updates its internal
self.size
to reflect the size of the currently displayed child (plus any accumulated size fromDivRenderer
).
event(&mut self, event: &dyn Event)
This method handles keyboard events for navigation:
- It listens for
crossterm::event::Event::Key
events. - If
KeyCode::Tab
is pressed:- It increments
self.index
. Ifself.index
goes beyond the last child, it wraps around to0
.
- It increments
- If
KeyCode::BackTab
(Shift+Tab) is pressed:- It decrements
self.index
. Ifself.index
goes below0
, it wraps around to the last child. These index changes will trigger a re-render in the next frame, displaying the new page.
- It decrements
is_ghost(&mut self) -> bool
Returns true
. Paginator
is a "ghost" element because it is a logical container that controls which of its children is visible, but it does not draw itself. Any styling applied to the Paginator
widget will apply to the area it manages.
draw_child(&mut self, element: &Arc<Widget>)
This method is called when a widget is declared as a child of this Paginator
in rsx!
.
- It adds the
element
to its internalchildren
Vec
. - It injects a
NoRenderRoot
component into the child to ensure the mainScreen
rendering loop doesn't render it directly (thePaginator
handles rendering the active child).
as_any(&self) -> &dyn std::any::Any
/ as_any_mut(&mut self) -> &mut dyn std::any::Any
Standard implementations for downcasting.
Usage in rsx!
The direct children of a Paginator
element become its pages. You can use any other element (e.g., Div
, FlexCol
) as a page container.
use osui::prelude::*;
rsx! {
// Paginator often needs explicit dimensions to define the space for its pages
@Transform::new().dimensions(60, 20).center();
@Style { background: Background::Solid(0x222222) }; // Optional background for the paginator's area
Paginator {
// Page 1: Simple text and instructions
FlexCol {
"Welcome to the first page!"
"Press TAB to go to the next page."
}
// Page 2: Contains an input field
FlexCol {
"This is the second page."
"Type something here:"
@Transform::new().dimensions(30, 1);
@Style { background: Background::Outline(0x555555) };
Input { }
}
// Page 3: A heading
FlexCol {
Heading { "The End" }
"This is the last page. Shift+TAB to go back."
}
}
}
Paginator
is useful for organizing complex UIs into logical sections, preventing clutter, and improving user experience by allowing easy navigation between distinct views.