use crate::mini_salsa::{MiniSalsaState, layout_grid, mock_init, run_ui, setup_logging};
use log::debug;
use rat_event::{HandleEvent, Popup, Regular, try_flow};
use rat_focus::{Focus, FocusBuilder};
use rat_menu::event::MenuOutcome;
use rat_menu::menuline::{MenuLine, MenuLineState};
use rat_theme4::WidgetStyle;
use rat_widget::choice::{Choice, ChoiceState};
use rat_widget::event::{ChoiceOutcome, Outcome};
use ratatui_core::buffer::Buffer;
use ratatui_core::layout::{Constraint, Flex, Layout, Rect};
use ratatui_core::style::Stylize;
use ratatui_core::text::{Line, Span};
use ratatui_core::widgets::StatefulWidget;
use ratatui_crossterm::crossterm::event::Event;
use ratatui_widgets::block::Block;
use ratatui_widgets::borders::BorderType;
mod mini_salsa;
fn main() -> Result<(), anyhow::Error> {
setup_logging()?;
let mut state = State {
c1: ChoiceState::named("c1"),
c2: ChoiceState::named("c2"),
c3: ChoiceState::named("c3"),
menu: MenuLineState::named("menu"),
};
run_ui("choice1", mock_init, event, render, &mut state)
}
struct State {
c1: ChoiceState,
c2: ChoiceState,
c3: ChoiceState<Option<usize>>,
menu: MenuLineState,
}
fn render(
buf: &mut Buffer,
area: Rect,
ctx: &mut MiniSalsaState,
state: &mut State,
) -> Result<(), anyhow::Error> {
let l1 = Layout::vertical([Constraint::Fill(1), Constraint::Length(1)]).split(area);
let lg = layout_grid::<2, 4>(
l1[0],
Layout::horizontal([
Constraint::Length(25), Constraint::Fill(1),
Constraint::Length(25),
])
.flex(Flex::Start),
Layout::vertical([
Constraint::Fill(1),
Constraint::Length(1),
Constraint::Length(2),
Constraint::Length(3),
])
.spacing(1),
);
let (w, p1) = Choice::new()
.auto_item("Carrots ๐ฅ")
.auto_item("Potatoes ๐ฅ")
.auto_item("Onions ๐ง
")
.auto_item("Peas")
.auto_item("Beans")
.auto_item(Line::from_iter([
Span::from("T").red(),
Span::from("omatoes ๐
"),
]))
.auto_item(Line::from_iter([
Span::from("Aubergines "),
Span::from("๐"),
]))
.auto_item("Chili")
.auto_item("รpfel ๐")
.auto_item("...")
.popup_boundary(l1[0])
.styles(ctx.theme.style(WidgetStyle::CHOICE))
.into_widgets();
w.render(lg[1][1], buf, &mut state.c1);
let (w, p2) = Choice::new()
.auto_item("wine")
.auto_item("beer")
.auto_item("water")
.popup_boundary(l1[0])
.styles(ctx.theme.style(WidgetStyle::CHOICE))
.into_widgets();
w.render(lg[1][2], buf, &mut state.c2);
let (w, p3) = Choice::<Option<usize>>::new()
.item(None, "red")
.item(Some(0), "blue")
.item(Some(1), "green")
.block(Block::bordered().border_type(BorderType::Rounded))
.popup_boundary(l1[0])
.styles(ctx.theme.style(WidgetStyle::CHOICE))
.popup_block(Block::bordered().border_type(BorderType::Rounded))
.into_widgets();
w.render(lg[1][3], buf, &mut state.c3);
p1.render(lg[1][1], buf, &mut state.c1);
p2.render(lg[1][2], buf, &mut state.c2);
p3.render(lg[1][3], buf, &mut state.c3);
MenuLine::new()
.title("a|b|c")
.item_parsed("_Quit")
.styles(ctx.theme.style(WidgetStyle::MENU))
.render(l1[1], buf, &mut state.menu);
Ok(())
}
fn focus(state: &mut State) -> Focus {
let mut fb = FocusBuilder::new(None);
fb.widget(&state.menu);
fb.widget(&state.c1);
fb.widget(&state.c2);
fb.widget(&state.c3);
let f = fb.build();
f.enable_log();
f
}
fn event(
event: &Event,
ctx: &mut MiniSalsaState,
state: &mut State,
) -> Result<Outcome, anyhow::Error> {
let mut focus = focus(state);
ctx.focus_outcome = focus.handle(event, Regular);
try_flow!(state.c1.handle(event, Popup));
try_flow!(state.c2.handle(event, Popup));
try_flow!(match state.c3.handle(event, Popup) {
ChoiceOutcome::Value => {
debug!("c3 {:?}", state.c3.value());
Outcome::Changed
}
r => r.into(),
});
try_flow!(match state.menu.handle(event, Regular) {
MenuOutcome::Activated(v) => {
match v {
0 => {
ctx.quit = true;
Outcome::Changed
}
_ => Outcome::Changed,
}
}
r => r.into(),
});
Ok(Outcome::Continue)
}