use crate::core::geometry::Rect;
use crate::core::event::Event;
use crate::core::state::{StateFlags, SF_SHADOW, SHADOW_ATTR};
use crate::core::palette::colors;
use crate::terminal::Terminal;
use super::view::{View, draw_shadow};
use super::frame::Frame;
use super::group::Group;
pub struct Window {
bounds: Rect,
frame: Frame,
interior: Group,
state: StateFlags,
}
impl Window {
pub fn new(bounds: Rect, title: &str) -> Self {
let frame = Frame::new(bounds, title);
let mut interior_bounds = bounds;
interior_bounds.grow(-1, -1);
let interior = Group::with_background(interior_bounds, colors::DIALOG_NORMAL);
Self {
bounds,
frame,
interior,
state: SF_SHADOW, }
}
pub fn add(&mut self, view: Box<dyn View>) {
self.interior.add(view);
}
pub fn set_initial_focus(&mut self) {
self.interior.set_initial_focus();
}
pub fn child_count(&self) -> usize {
self.interior.len()
}
pub fn child_at(&self, index: usize) -> &dyn View {
self.interior.child_at(index)
}
pub fn child_at_mut(&mut self, index: usize) -> &mut dyn View {
self.interior.child_at_mut(index)
}
}
impl View for Window {
fn bounds(&self) -> Rect {
self.bounds
}
fn set_bounds(&mut self, bounds: Rect) {
self.bounds = bounds;
self.frame.set_bounds(bounds);
let mut interior_bounds = bounds;
interior_bounds.grow(-1, -1);
self.interior.set_bounds(interior_bounds);
}
fn draw(&mut self, terminal: &mut Terminal) {
self.frame.draw(terminal);
self.interior.draw(terminal);
if self.has_shadow() {
draw_shadow(terminal, self.bounds, SHADOW_ATTR);
}
}
fn update_cursor(&self, terminal: &mut Terminal) {
self.interior.update_cursor(terminal);
}
fn handle_event(&mut self, event: &mut Event) {
self.frame.handle_event(event);
self.interior.handle_event(event);
}
fn can_focus(&self) -> bool {
true
}
fn set_focus(&mut self, focused: bool) {
if focused {
self.interior.set_initial_focus();
} else {
self.interior.clear_all_focus();
}
}
fn state(&self) -> StateFlags {
self.state
}
fn set_state(&mut self, state: StateFlags) {
self.state = state;
}
}