use crate::db::config::Config;
use crate::ui::cursor::CursorState;
use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use ratatui::style::{Color, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::{
Block, BorderType, Borders, Clear, List, ListItem, Padding, Paragraph, Widget, Wrap,
};
use std::str::FromStr;
pub struct AddListPopUp;
pub struct ModifyListPopUp;
fn render_list_popup_kernel<T: CursorState>(
config: Config,
state: &T,
area: Rect,
buf: &mut Buffer,
popup_title: &str,
) {
let fg = config.foreground();
let hl = config.highlight();
let bg = config.background();
let add_or_modify_list_command_hints = Line::from(vec![
Span::raw(" "),
Span::styled("[Esc]", Style::default().fg(Color::from_str(hl).unwrap())),
Span::raw(" "),
]);
let popup_width = (area.width * 3) / 4; let popup_height = 4;
let popup_x = area.x + (area.width.saturating_sub(popup_width)) / 2;
let popup_y = area.y + (area.height.saturating_sub(popup_height)) / 2;
let popup_area = Rect {
x: popup_x,
y: popup_y,
width: popup_width,
height: popup_height,
};
Clear.render(popup_area, buf);
Block::default()
.style(Style::default().bg(Color::from_str(bg).unwrap()))
.render(popup_area, buf);
let popup_block = Block::new()
.padding(Padding::new(2, 2, 1, 1))
.title(format!(" {} ", popup_title))
.title_style(Style::new().fg(Color::from_str(fg).unwrap()))
.title_bottom(add_or_modify_list_command_hints)
.borders(Borders::ALL)
.border_style(Style::new().fg(Color::from_str(fg).unwrap()))
.border_type(BorderType::Rounded)
.padding(Padding::horizontal(1));
let text_spans = state.create_cursor_text_spans(config);
let text_line = Line::from(text_spans);
Paragraph::new(text_line)
.wrap(Wrap { trim: true })
.block(popup_block)
.render(popup_area, buf);
}
impl AddListPopUp {
pub fn render<T: CursorState>(config: Config, state: &T, area: Rect, buf: &mut Buffer) {
render_list_popup_kernel(config, state, area, buf, "Add List");
}
}
impl ModifyListPopUp {
pub fn render<T: CursorState>(config: Config, state: &T, area: Rect, buf: &mut Buffer) {
render_list_popup_kernel(config, state, area, buf, "Modify List");
}
}
pub struct AddItemPopUp;
pub struct ModifyItemPopUp;
pub fn render_item_popup_kernel<T: CursorState>(
config: Config,
state: &T,
area: Rect,
buf: &mut Buffer,
popup_title: &str,
) {
let fg = config.foreground();
let hl = config.highlight();
let bg = config.background();
let add_item_command_hints = Line::from(vec![
Span::raw(" "),
Span::styled("[Esc]", Style::default().fg(Color::from_str(hl).unwrap())),
Span::raw(" "),
]);
let popup_width = (area.width * 3) / 4; let popup_height = 4;
let popup_x = area.x + (area.width.saturating_sub(popup_width)) / 2;
let popup_y = area.y + (area.height.saturating_sub(popup_height)) / 2;
let popup_area = Rect {
x: popup_x,
y: popup_y,
width: popup_width,
height: popup_height,
};
Clear.render(popup_area, buf);
Block::default()
.style(Style::default().bg(Color::from_str(bg).unwrap()))
.render(popup_area, buf);
let popup_block = Block::new()
.padding(Padding::new(2, 2, 1, 1))
.title(format!(" {} ", popup_title))
.title_style(Style::new().fg(Color::from_str(fg).unwrap()))
.title_bottom(add_item_command_hints)
.borders(Borders::ALL)
.border_style(Style::new().fg(Color::from_str(fg).unwrap()))
.border_type(BorderType::Rounded)
.padding(Padding::horizontal(1));
let text_spans = state.create_cursor_text_spans(config);
let text_line = Line::from(text_spans);
Paragraph::new(text_line)
.wrap(Wrap { trim: true })
.block(popup_block)
.render(popup_area, buf);
}
impl AddItemPopUp {
pub fn render<T: CursorState>(config: Config, state: &T, area: Rect, buf: &mut Buffer) {
render_item_popup_kernel(config, state, area, buf, "Add Item");
}
}
impl ModifyItemPopUp {
pub fn render<T: CursorState>(config: Config, state: &T, area: Rect, buf: &mut Buffer) {
render_item_popup_kernel(config, state, area, buf, "Modify Item");
}
}
pub struct ChangeDBPopUp;
impl ChangeDBPopUp {
pub fn render(config: &Config, selected_index: usize, area: Rect, buf: &mut Buffer) {
let fg = config.foreground();
let hl = config.highlight();
let bg = config.background();
let change_db_command_hints = Line::from(vec![
Span::raw(" "),
Span::styled(" ↑↓ ", Style::default()),
Span::styled("[A]", Style::default().fg(Color::from_str(hl).unwrap())),
Span::styled("dd", Style::default().fg(Color::from_str(fg).unwrap())),
Span::styled(" [S]", Style::default().fg(Color::from_str(hl).unwrap())),
Span::styled(
"et Default",
Style::default().fg(Color::from_str(fg).unwrap()),
),
Span::styled(" [Esc]", Style::default().fg(Color::from_str(hl).unwrap())),
Span::raw(" "),
]);
Block::default()
.style(
Style::default()
.bg(Color::from_str(bg).unwrap())
.fg(Color::from_str(fg).unwrap()),
)
.render(area, buf);
let popup_block = Block::new()
.padding(Padding::new(2, 2, 1, 1))
.title(" Select Database ")
.title_style(Style::new().fg(Color::from_str(fg).unwrap()))
.title_bottom(change_db_command_hints)
.borders(Borders::ALL)
.border_style(Style::new().fg(Color::from_str(fg).unwrap()))
.border_type(BorderType::Rounded);
let items: Vec<ListItem> = config
.dbs
.iter()
.map(|db| ListItem::from(db.name.clone()))
.collect();
let mut temp_list_state = ratatui::widgets::ListState::default();
temp_list_state.select(Some(selected_index));
let list = List::new(items)
.block(popup_block)
.highlight_symbol(" ▸ ") .highlight_style(
Style::default()
.bg(Color::from_str(fg).unwrap())
.fg(Color::from_str(bg).unwrap()),
)
.highlight_spacing(ratatui::widgets::HighlightSpacing::Always);
ratatui::widgets::StatefulWidget::render(list, area, buf, &mut temp_list_state);
}
}
pub struct AddDBPopUp;
impl AddDBPopUp {
pub fn render<T: CursorState>(config: Config, state: &T, area: Rect, buf: &mut Buffer) {
let fg = config.foreground();
let hl = config.highlight();
let bg = config.background();
let add_db_command_hints = Line::from(vec![
Span::raw(" "),
Span::styled("[Esc]", Style::default().fg(Color::from_str(hl).unwrap())),
Span::raw(" "),
]);
Clear.render(area, buf);
Block::default()
.style(
Style::default()
.bg(Color::from_str(bg).unwrap())
.fg(Color::from_str(fg).unwrap()),
)
.render(area, buf);
let popup_block = Block::new()
.padding(Padding::new(2, 2, 1, 1))
.title(" Add Database ")
.title_style(Style::new().fg(Color::from_str(fg).unwrap()))
.title_bottom(add_db_command_hints)
.borders(Borders::ALL)
.border_style(Style::new().fg(Color::from_str(fg).unwrap()))
.border_type(BorderType::Rounded)
.padding(Padding::horizontal(1));
let text_spans = state.create_cursor_text_spans(config);
let text_line = Line::from(text_spans);
Paragraph::new(text_line)
.wrap(Wrap { trim: true })
.block(popup_block)
.render(area, buf);
}
}