// This file is part of Deja-vu. // // Deja-vu is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Deja-vu is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Deja-vu. If not, see . // use std::collections::HashMap; use ratatui::widgets::ListState; #[derive(Default, Debug, Clone, PartialEq)] pub struct StatefulList { pub state: ListState, pub items: Vec, pub last_selected: Option, pub selected: HashMap, } impl StatefulList { pub fn clear_items(&mut self) { // Clear list and rebuild with provided items self.items.clear(); } pub fn get(&self, index: usize) -> Option<&T> { self.items.get(index) } pub fn get_selected(&self) -> Option { self.state.selected().map(|i| self.items[i].clone()) } pub fn is_empty(&self) -> bool { self.items.is_empty() } pub fn select(&mut self, index: usize) { if self.items.is_empty() { self.state.select(None); } else { self.state.select(Some(index)); } } pub fn selected(&self) -> Option { self.state.selected() } fn select_first_item(&mut self) { if self.items.is_empty() { self.state.select(None); } else { self.state.select(Some(0)); } self.last_selected = None; } pub fn set_items(&mut self, items: Vec) { // Clear list and rebuild with provided items self.clear_items(); for item in items { self.items.push(item); } // Reset state and select first item (if available) self.state = ListState::default(); self.select_first_item(); } pub fn next(&mut self) { if self.items.is_empty() { return; } let i = match self.state.selected() { Some(i) => { if i >= self.items.len() - 1 { 0 } else { i + 1 } } None => self.last_selected.unwrap_or(0), }; self.state.select(Some(i)); } pub fn previous(&mut self) { if self.items.is_empty() { return; } let i = match self.state.selected() { Some(i) => { if i == 0 { self.items.len() - 1 } else { i - 1 } } None => self.last_selected.unwrap_or(0), }; self.state.select(Some(i)); } }