use crate::core::geometry::Rect;
use crate::core::event::{Event, EventType, MB_LEFT_BUTTON};
use crate::core::draw::DrawBuffer;
use crate::core::palette::colors;
use crate::core::command::CM_CLOSE;
use crate::terminal::Terminal;
use super::view::{View, write_line_to_terminal};
pub struct Frame {
bounds: Rect,
title: String,
}
impl Frame {
pub fn new(bounds: Rect, title: &str) -> Self {
Self {
bounds,
title: title.to_string(),
}
}
}
impl View for Frame {
fn bounds(&self) -> Rect {
self.bounds
}
fn set_bounds(&mut self, bounds: Rect) {
self.bounds = bounds;
}
fn draw(&mut self, terminal: &mut Terminal) {
let width = self.bounds.width() as usize;
let height = self.bounds.height() as usize;
let frame_attr = colors::DIALOG_FRAME_ACTIVE;
let mut buf = DrawBuffer::new(width);
buf.put_char(0, '╔', frame_attr); buf.put_char(width - 1, '╗', frame_attr); for i in 1..width - 1 {
buf.put_char(i, '═', frame_attr); }
if width > 5 {
buf.put_char(2, '[', frame_attr);
buf.put_char(3, '■', frame_attr); buf.put_char(4, ']', frame_attr);
}
if !self.title.is_empty() && width > self.title.len() + 8 {
buf.move_str(6, &format!(" {} ", self.title), colors::DIALOG_TITLE);
}
write_line_to_terminal(terminal, self.bounds.a.x, self.bounds.a.y, &buf);
let mut side_buf = DrawBuffer::new(width);
side_buf.put_char(0, '║', frame_attr); side_buf.put_char(width - 1, '║', frame_attr); for i in 1..width - 1 {
side_buf.put_char(i, ' ', frame_attr);
}
for y in 1..height - 1 {
write_line_to_terminal(terminal, self.bounds.a.x, self.bounds.a.y + y as i16, &side_buf);
}
let mut bottom_buf = DrawBuffer::new(width);
bottom_buf.put_char(0, '╚', frame_attr); bottom_buf.put_char(width - 1, '╝', frame_attr); for i in 1..width - 1 {
bottom_buf.put_char(i, '═', frame_attr); }
write_line_to_terminal(terminal, self.bounds.a.x, self.bounds.a.y + height as i16 - 1, &bottom_buf);
}
fn handle_event(&mut self, event: &mut Event) {
if event.what == EventType::MouseDown {
let mouse_pos = event.mouse.pos;
if event.mouse.buttons & MB_LEFT_BUTTON != 0
&& mouse_pos.y == self.bounds.a.y && mouse_pos.x >= self.bounds.a.x + 2 && mouse_pos.x <= self.bounds.a.x + 4 {
*event = Event::command(CM_CLOSE);
}
}
}
}