use crate::core::geometry::{Point, Rect};
use crate::core::event::{Event, EventType, MB_LEFT_BUTTON};
use crate::core::palette::colors;
use crate::core::draw::DrawBuffer;
use crate::core::state::StateFlags;
use crate::core::history::HistoryManager;
use crate::terminal::Terminal;
use super::view::{View, write_line_to_terminal};
use super::history_window::HistoryWindow;
pub struct History {
bounds: Rect,
history_id: u16,
state: StateFlags,
pub selected_item: Option<String>, }
impl History {
pub fn new(pos: Point, history_id: u16) -> Self {
Self {
bounds: Rect::new(pos.x, pos.y, pos.x + 2, pos.y + 1),
history_id,
state: 0,
selected_item: None,
}
}
pub fn has_items(&self) -> bool {
HistoryManager::has_history(self.history_id)
}
fn show_history(&mut self, terminal: &mut Terminal) {
if !self.has_items() {
return;
}
let window_pos = Point::new(
(self.bounds.a.x - 20).max(0),
self.bounds.a.y + 1,
);
let mut window = HistoryWindow::new(window_pos, self.history_id, 30);
if let Some(selected) = window.execute(terminal) {
self.selected_item = Some(selected);
}
}
}
impl View for History {
fn bounds(&self) -> Rect {
self.bounds
}
fn set_bounds(&mut self, bounds: Rect) {
self.bounds = bounds;
}
fn draw(&mut self, terminal: &mut Terminal) {
let mut buf = DrawBuffer::new(2);
let arrow = if self.has_items() { "▼" } else { " " };
let color = if self.is_focused() {
colors::BUTTON_SELECTED
} else {
colors::BUTTON_NORMAL
};
buf.move_str(0, arrow, color);
write_line_to_terminal(terminal, self.bounds.a.x, self.bounds.a.y, &buf);
}
fn handle_event(&mut self, event: &mut Event) {
match event.what {
EventType::MouseDown => {
if self.bounds.contains(event.mouse.pos) && event.mouse.buttons & MB_LEFT_BUTTON != 0 {
event.clear();
}
}
_ => {}
}
}
fn can_focus(&self) -> bool {
false }
fn state(&self) -> StateFlags {
self.state
}
fn set_state(&mut self, state: StateFlags) {
self.state = state;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_history_button_creation() {
HistoryManager::clear_all();
let button = History::new(Point::new(20, 5), 1);
assert!(!button.has_items());
assert_eq!(button.bounds.width(), 2);
}
#[test]
fn test_history_button_with_items() {
HistoryManager::clear_all();
HistoryManager::add(2, "test".to_string());
let button = History::new(Point::new(20, 5), 2);
assert!(button.has_items());
}
}