generic library now instead of string based

This commit is contained in:
Priec
2026-01-19 15:58:44 +01:00
parent feb22d270c
commit f30a2a2758
16 changed files with 1068 additions and 670 deletions

132
examples/simple.rs Normal file
View File

@@ -0,0 +1,132 @@
// path_from_the_root: examples/simple.rs
//
// Simple example that works with any feature configuration.
//
// Run with alloc: cargo run --example simple --features alloc
// Run without alloc: cargo run --example simple
use pages_tui::prelude::*;
// =============================================================================
// Types
// =============================================================================
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Focus {
Item(usize),
}
impl FocusId for Focus {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Act {
Select,
Up,
Down,
}
impl Action for Act {}
#[derive(Debug, Clone)]
pub enum Evt {
Selected(usize),
}
// =============================================================================
// Pages
// =============================================================================
#[derive(Debug, Clone)]
pub enum AppPage {
List { cursor: usize },
Detail { item_id: usize },
}
// Static focus targets
const LIST_FOCUS: &[Focus] = &[Focus::Item(0), Focus::Item(1), Focus::Item(2)];
const DETAIL_FOCUS: &[Focus] = &[Focus::Item(0)];
impl Page for AppPage {
type Focus = Focus;
type Action = Act;
type Event = Evt;
fn targets(&self) -> &[Self::Focus] {
match self {
AppPage::List { .. } => LIST_FOCUS,
AppPage::Detail { .. } => DETAIL_FOCUS,
}
}
fn handle(
&mut self,
focus: &Self::Focus,
action: Self::Action,
) -> Result<Option<Self::Event>, ComponentError> {
match (self, action) {
(AppPage::List { cursor }, Act::Select) => {
if let Focus::Item(idx) = focus {
*cursor = *idx;
return Ok(Some(Evt::Selected(*idx)));
}
}
_ => {}
}
Ok(None)
}
}
// =============================================================================
// Main
// =============================================================================
fn main() {
// Works with both alloc and no_std!
// Default capacities are used, override with const generics if needed:
// Orchestrator::<AppPage, 4, 8, 8, 16, 4, 4>::new()
let mut app: Orchestrator<AppPage> = Orchestrator::new();
// Register pages
app.register(AppPage::List { cursor: 0 });
app.register(AppPage::Detail { item_id: 0 });
// Bind keys
app.bind(Key::enter(), Act::Select);
app.bind(Key::up(), Act::Up);
app.bind(Key::down(), Act::Down);
// Navigate to list
app.navigate_to(AppPage::List { cursor: 0 }).unwrap();
// Process a key
#[cfg(feature = "alloc")]
{
let events = app.process_frame(Key::enter()).unwrap();
for e in events {
println!("Event: {:?}", e);
}
}
#[cfg(not(feature = "alloc"))]
{
if let Ok(Some(e)) = app.process_frame(Key::enter()) {
// In no_std, you'd handle this differently
let _ = e;
}
}
// Check current page
match app.current() {
Some(AppPage::List { cursor }) => {
println!("On list page, cursor at {}", cursor);
}
Some(AppPage::Detail { item_id }) => {
println!("On detail page for item {}", item_id);
}
None => {
println!("No page");
}
}
println!("✅ Simple example complete");
}