use crate::event::Event;
use crate::{Component, Rect, Surface};
#[derive(Debug, Clone)]
pub struct OverlayOptions {
pub click_outside_close: bool,
pub escape_close: bool,
pub capture_keys: bool,
pub modal: bool,
pub backdrop_opacity: Option<f32>,
}
impl Default for OverlayOptions {
fn default() -> Self {
Self {
click_outside_close: true,
escape_close: true,
capture_keys: true,
modal: true,
backdrop_opacity: Some(0.5),
}
}
}
pub trait OverlayHandle: Send {
fn hide(&mut self);
fn set_hidden(&mut self, hidden: bool);
fn is_hidden(&self) -> bool;
fn bring_to_front(&mut self);
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
}
pub trait OverlayContent: Component {
fn on_close(&mut self) {}
fn should_close(&self, _event: &Event) -> bool {
false
}
}
pub struct OverlayBox<T: OverlayContent> {
content: T,
options: OverlayOptions,
hidden: bool,
id: usize,
}
impl<T: OverlayContent> OverlayBox<T> {
pub fn new(content: T, options: OverlayOptions) -> Self {
Self {
content,
options,
hidden: false,
id: 0, }
}
pub fn content(&self) -> &T {
&self.content
}
pub fn content_mut(&mut self) -> &mut T {
&mut self.content
}
pub fn options(&self) -> &OverlayOptions {
&self.options
}
pub fn id(&self) -> usize {
self.id
}
pub fn set_id(&mut self, id: usize) {
self.id = id;
}
}
impl<T: OverlayContent + 'static> OverlayHandle for OverlayBox<T> {
fn hide(&mut self) {
self.hidden = true;
}
fn set_hidden(&mut self, hidden: bool) {
self.hidden = hidden;
}
fn is_hidden(&self) -> bool {
self.hidden
}
fn bring_to_front(&mut self) {
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}
impl<T: OverlayContent> Component for OverlayBox<T> {
fn name(&self) -> &str {
self.content.name()
}
fn request_render(&mut self) {
self.content.request_render();
}
fn is_dirty(&self) -> bool {
self.content.is_dirty()
}
fn clear_dirty(&mut self) {
self.content.clear_dirty();
}
fn handle_event(&mut self, event: &Event) -> bool {
if self.hidden {
return false;
}
if self.options.escape_close {
if let Event::Key(key) = event {
if key.code == crate::event::KeyCode::Escape {
self.content.on_close();
return true;
}
}
}
self.content.handle_event(event)
}
fn render(&mut self, surface: &mut Surface, area: Rect) {
if self.hidden {
return;
}
if let Some(_opacity) = self.options.backdrop_opacity {
let mut backdrop_cell = crate::Cell::new(' ');
backdrop_cell.bg = crate::cell::Color::Indexed(0);
surface.fill(backdrop_cell);
}
self.content.render(surface, area);
}
fn min_size(&self) -> crate::terminal::Size {
self.content.min_size()
}
fn desired_size(&self) -> Option<crate::terminal::Size> {
self.content.desired_size()
}
}