use ratatui::style::{Color, Style};
use ratatui::text::Span;
use ratatui::widgets::ListState;
#[derive(Debug)]
pub struct AppListState {
selected_item: usize,
selected_submatch: usize,
indicator: ListState,
window_start: usize,
}
impl AppListState {
pub fn new() -> AppListState {
let mut list_state = ListState::default();
list_state.select(Some(0));
AppListState {
selected_item: 0,
selected_submatch: 0,
indicator: list_state,
window_start: 0,
}
}
pub fn indicator_mut(&mut self) -> &mut ListState {
&mut self.indicator
}
pub fn set_indicator_pos(&mut self, idx: usize) {
self.indicator.select(Some(idx));
}
pub fn window_start(&self) -> usize {
self.window_start
}
pub fn set_window_start(&mut self, start: usize) {
self.window_start = start;
}
pub fn selected_item(&self) -> usize {
self.selected_item
}
pub fn selected_submatch(&self) -> usize {
self.selected_submatch
}
pub fn set_selected_item(&mut self, idx: usize) {
self.selected_item = idx
}
pub fn set_selected_submatch(&mut self, idx: usize) {
self.selected_submatch = idx
}
}
#[derive(Debug)]
pub enum AppState {
Running,
Cancelled,
Complete,
}
#[derive(Debug, Eq, PartialEq)]
pub enum AppUiState {
Help,
SelectMatches,
InputReplacement(String, usize),
ConfirmReplacement(String, usize),
}
impl AppUiState {
pub fn is_replacing(&self) -> bool {
matches!(
self,
AppUiState::InputReplacement(_, _) | AppUiState::ConfirmReplacement(_, _)
)
}
pub fn user_replacement_text(&self) -> Option<&str> {
match &self {
AppUiState::InputReplacement(replacement, _)
| AppUiState::ConfirmReplacement(replacement, _) => Some(replacement.as_str()),
_ => None,
}
}
pub fn to_span(&self) -> Span {
let style = Style::default().fg(Color::Black);
match self {
AppUiState::Help => Span::styled(" HELP ", style.bg(Color::Green)),
AppUiState::SelectMatches => Span::styled(" SELECT ", style.bg(Color::Cyan)),
AppUiState::InputReplacement(_, _) => Span::styled(" REPLACE ", style.bg(Color::White)),
AppUiState::ConfirmReplacement(_, _) => Span::styled(" CONFIRM ", style.bg(Color::Red)),
}
}
}
#[derive(Debug)]
pub struct HelpTextState {
pub pos: usize,
pub max: usize,
help_text: &'static str,
}
impl HelpTextState {
pub fn new(help_text: &'static str) -> HelpTextState {
HelpTextState {
pos: 0,
max: help_text.lines().count() - 1,
help_text,
}
}
pub fn incr(&mut self) {
if self.pos < self.max {
self.pos += 1;
}
}
pub fn decr(&mut self) {
self.pos = self.pos.saturating_sub(1);
}
pub fn text(&self, num_lines: usize) -> String {
self.help_text
.lines()
.skip(self.pos)
.take(num_lines)
.collect::<Vec<_>>()
.join("\n")
}
}