use ratatui::{
buffer::Buffer,
layout::Rect,
style::{Modifier, Style},
widgets::{Block, BorderType, Widget},
};
use super::layout_mode::LayoutMode;
use crate::ui::tui::session::styling::SessionStyles;
use crate::ui::tui::session::terminal_capabilities;
pub struct Panel<'a> {
styles: &'a SessionStyles,
title: Option<&'a str>,
active: bool,
mode: LayoutMode,
border_type: Option<BorderType>,
}
impl<'a> Panel<'a> {
pub fn new(styles: &'a SessionStyles) -> Self {
Self {
styles,
title: None,
active: false,
mode: LayoutMode::Standard,
border_type: None,
}
}
#[must_use]
pub fn title(mut self, title: &'a str) -> Self {
self.title = Some(title);
self
}
#[must_use]
pub fn active(mut self, active: bool) -> Self {
self.active = active;
self
}
#[must_use]
pub fn mode(mut self, mode: LayoutMode) -> Self {
self.mode = mode;
self
}
#[must_use]
pub fn border_type(mut self, border_type: BorderType) -> Self {
self.border_type = Some(border_type);
self
}
pub fn render_and_get_inner(self, area: Rect, buf: &mut Buffer) -> Rect {
if !self.mode.show_borders() {
return area;
}
let border_style = if self.active {
self.styles.accent_style()
} else {
self.styles.border_style()
};
let border_type = self
.border_type
.unwrap_or_else(terminal_capabilities::get_border_type);
let mut block = Block::bordered()
.border_type(border_type)
.style(self.styles.default_style())
.border_style(border_style);
if self.mode.show_titles()
&& let Some(title) = self.title
{
let title_style = if self.active {
self.styles.accent_style().add_modifier(Modifier::BOLD)
} else {
self.styles.default_style().add_modifier(Modifier::BOLD)
};
block = block.title(title).title_style(title_style);
}
let inner = block.inner(area);
block.render(area, buf);
inner
}
}
pub trait PanelStyles {
fn muted_style(&self) -> Style;
fn title_style(&self) -> Style;
fn border_active_style(&self) -> Style;
fn divider_style(&self) -> Style;
}
impl PanelStyles for SessionStyles {
fn muted_style(&self) -> Style {
self.default_style().add_modifier(Modifier::DIM)
}
fn title_style(&self) -> Style {
self.accent_style().add_modifier(Modifier::BOLD)
}
fn border_active_style(&self) -> Style {
self.border_style()
.remove_modifier(Modifier::DIM)
.add_modifier(Modifier::BOLD)
}
fn divider_style(&self) -> Style {
self.border_style().add_modifier(Modifier::DIM)
}
}