diff --git a/Cargo.toml b/Cargo.toml index b3ccafe..88a6383 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,9 @@ repository = "https://github.com/shuoli84/tui-menu" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -ratatui = "0.29.0" +ratatui-core = "0.1.0" +ratatui-widgets = "0.3.0" [dev-dependencies] color-eyre = "0.6.3" +ratatui = { version = "0.30.0", features = ["crossterm"] } diff --git a/examples/basic.rs b/examples/basic.rs index bd2d801..a2185bd 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,55 +1,17 @@ -use color_eyre::config::HookBuilder; use ratatui::{ - crossterm::{ - event::{self, Event, KeyCode}, - execute, - terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, - }, - prelude::{ - Backend, Buffer, Constraint, CrosstermBackend, Layout, Rect, StatefulWidget, Stylize, - Terminal, Widget, - }, + crossterm::event::{self, Event, KeyCode}, + prelude::{Buffer, Constraint, Layout, Rect, StatefulWidget, Stylize, Widget}, widgets::{Block, Paragraph}, }; -use std::io::{self, stdout, Stdout}; use tui_menu::{Menu, MenuEvent, MenuItem, MenuState}; fn main() -> color_eyre::Result<()> { - let mut terminal = init_terminal()?; - App::new().run(&mut terminal)?; - restore_terminal()?; - Ok(()) -} - -/// Install panic and error hooks that restore the terminal before printing the error. -pub fn init_hooks() -> color_eyre::Result<()> { - let (panic, error) = HookBuilder::default().into_hooks(); - let panic = panic.into_panic_hook(); - let error = error.into_eyre_hook(); - - std::panic::set_hook(Box::new(move |info| { - let _ = restore_terminal(); // ignore failure to restore terminal - panic(info); - })); - color_eyre::eyre::set_hook(Box::new(move |e| { - let _ = restore_terminal(); // ignore failure to restore terminal - error(e) - }))?; + color_eyre::install()?; + ratatui::run(|t| App::new().run(t))?; Ok(()) } -fn init_terminal() -> io::Result>> { - enable_raw_mode()?; - execute!(stdout(), EnterAlternateScreen)?; - Terminal::new(CrosstermBackend::new(stdout())) -} - -fn restore_terminal() -> io::Result<()> { - disable_raw_mode()?; - execute!(stdout(), LeaveAlternateScreen,) -} - struct App { content: String, menu: MenuState, @@ -111,7 +73,7 @@ enum Action { } impl App { - fn run(mut self, terminal: &mut Terminal) -> io::Result<()> { + fn run(mut self, terminal: &mut ratatui::DefaultTerminal) -> std::io::Result<()> { loop { terminal.draw(|frame| frame.render_widget(&mut self, frame.area()))?; diff --git a/examples/nested_group.rs b/examples/nested_group.rs index 40d3bd5..aeeb50d 100644 --- a/examples/nested_group.rs +++ b/examples/nested_group.rs @@ -1,52 +1,17 @@ -use color_eyre::config::HookBuilder; use ratatui::{ - crossterm::{ - event::{self, Event, KeyCode}, - execute, - terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, - }, + crossterm::event::{self, Event, KeyCode}, prelude::*, widgets::{Block, Paragraph}, }; -use std::io::{self, stdout, Stdout}; use tui_menu::{Menu, MenuEvent, MenuItem, MenuState}; fn main() -> color_eyre::Result<()> { - let mut terminal = init_terminal()?; - App::new().run(&mut terminal)?; - restore_terminal()?; - Ok(()) -} - -/// Install panic and error hooks that restore the terminal before printing the error. -pub fn init_hooks() -> color_eyre::Result<()> { - let (panic, error) = HookBuilder::default().into_hooks(); - let panic = panic.into_panic_hook(); - let error = error.into_eyre_hook(); - - std::panic::set_hook(Box::new(move |info| { - let _ = restore_terminal(); // ignore failure to restore terminal - panic(info); - })); - color_eyre::eyre::set_hook(Box::new(move |e| { - let _ = restore_terminal(); // ignore failure to restore terminal - error(e) - }))?; + color_eyre::install()?; + ratatui::run(|t| App::new().run(t))?; Ok(()) } -fn init_terminal() -> io::Result>> { - enable_raw_mode()?; - execute!(stdout(), EnterAlternateScreen)?; - Terminal::new(CrosstermBackend::new(stdout())) -} - -fn restore_terminal() -> io::Result<()> { - disable_raw_mode()?; - execute!(stdout(), LeaveAlternateScreen,) -} - struct App { content: String, menu: MenuState, @@ -100,7 +65,7 @@ enum Action { } impl App { - fn run(mut self, terminal: &mut Terminal) -> io::Result<()> { + fn run(mut self, terminal: &mut ratatui::DefaultTerminal) -> std::io::Result<()> { loop { terminal.draw(|frame| frame.render_widget(&mut self, frame.area()))?; @@ -118,7 +83,6 @@ impl App { } }, } - self.menu.reset(); } } } diff --git a/src/lib.rs b/src/lib.rs index f859380..0e9dfff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,13 +17,14 @@ will be stored in MenuState.events. To define a menu, see examples in [MenuState]. */ -use ratatui::{ - layout::Rect, - prelude::*, +use ratatui_core::{ + buffer::Buffer, + layout::{Margin, Rect}, style::{Color, Style}, text::{Line, Span}, - widgets::{Block, Borders, Clear, StatefulWidget, Widget}, + widgets::{StatefulWidget, Widget}, }; +use ratatui_widgets::{block::Block, borders::Borders, clear::Clear}; use std::{borrow::Cow, marker::PhantomData}; /// Events this widget produce @@ -116,7 +117,7 @@ impl MenuState { /// /// case 3: /// - /// group 1 group 2 + /// group 1 group 2 /// sub item 1 /// > sub item 2 > sub sub item 1 /// sub sub item 2 @@ -163,7 +164,7 @@ impl MenuState { /// down does nothing /// /// case 3: - /// group 1 group 2 + /// group 1 group 2 /// > sub item 1 /// sub item 2 /// @@ -193,7 +194,7 @@ impl MenuState { /// left first pop "sub item group", then highlights "group 1" /// /// case 3: - /// group 1 group 2 + /// group 1 group 2 /// > sub item 1 sub sub item 1 /// sub item 2 > sub sub item 2 /// @@ -593,7 +594,7 @@ impl Menu { x: u16, y: u16, group: &[MenuItem], - buf: &mut ratatui::buffer::Buffer, + buf: &mut Buffer, dropdown_count_to_go: u16, // including current, it is not drawn yet ) { // Compute width of all menu items @@ -695,7 +696,7 @@ impl Default for Menu { impl StatefulWidget for Menu { type State = MenuState; - fn render(self, area: Rect, buf: &mut ratatui::buffer::Buffer, state: &mut Self::State) { + fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { let area = area.clamp(*buf.area()); let mut spans = vec![];