use crate::{event::Event, layout::Rect, render::Frame, style::Style};
use crossterm::event::KeyCode;
pub struct SelectItem {
text: String,
style: Style,
selected_style: Style,
}
impl SelectItem {
pub fn new(text: &str) -> Self {
Self { text: text.to_string(), style: Style::new(), selected_style: Style::new().reversed() }
}
pub fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn selected_style(mut self, style: Style) -> Self {
self.selected_style = style;
self
}
pub fn text(&self) -> &str {
&self.text
}
pub fn get_style(&self) -> &Style {
&self.style
}
pub fn get_selected_style(&self) -> &Style {
&self.selected_style
}
}
pub struct SelectMenu {
prompt: String,
items: Vec<SelectItem>,
selected: usize,
style: Style,
on_select: Option<Box<dyn Fn(usize)>>,
on_cancel: Option<Box<dyn Fn()>>,
}
impl SelectMenu {
pub fn new(prompt: &str, items: Vec<SelectItem>) -> Self {
Self { prompt: prompt.to_string(), items, selected: 0, style: Style::new(), on_select: None, on_cancel: None }
}
pub fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn on_select<F: Fn(usize) + 'static>(mut self, f: F) -> Self {
self.on_select = Some(Box::new(f));
self
}
pub fn on_cancel<F: Fn() + 'static>(mut self, f: F) -> Self {
self.on_cancel = Some(Box::new(f));
self
}
pub fn get_selected(&self) -> usize {
self.selected
}
fn handle_key(&mut self, key: KeyCode) -> bool {
match key {
KeyCode::Up => {
if self.selected > 0 {
self.selected -= 1;
}
true
}
KeyCode::Down => {
if self.selected < self.items.len() - 1 {
self.selected += 1;
}
true
}
KeyCode::Enter => {
if let Some(callback) = &self.on_select {
callback(self.selected);
}
true
}
KeyCode::Esc => {
if let Some(callback) = &self.on_cancel {
callback();
}
true
}
_ => false,
}
}
}
impl super::Component for SelectMenu {
fn render(&self, frame: &mut Frame, area: Rect) {
frame.render_select_menu(&self.prompt, &self.items, self.selected, area, self.style.clone());
}
fn handle_event(&mut self, event: &Event) -> bool {
match event {
Event::Key(key_event) => self.handle_key(key_event.code),
_ => false,
}
}
}