use super::core::Callout;
use super::types::{CalloutType, CalloutVariant};
use crate::event::Key;
use crate::widget::traits::WidgetState;
impl Callout {
pub fn new(content: impl Into<String>) -> Self {
Self {
content: content.into(),
title: None,
callout_type: CalloutType::default(),
variant: CalloutVariant::default(),
show_icon: true,
custom_icon: None,
collapsible: false,
expanded: true,
collapsed_icon: '▶',
expanded_icon: '▼',
state: WidgetState::new(),
props: crate::widget::traits::WidgetProps::new(),
}
}
pub fn note(content: impl Into<String>) -> Self {
Self::new(content).callout_type(CalloutType::Note)
}
pub fn tip(content: impl Into<String>) -> Self {
Self::new(content).callout_type(CalloutType::Tip)
}
pub fn important(content: impl Into<String>) -> Self {
Self::new(content).callout_type(CalloutType::Important)
}
pub fn warning(content: impl Into<String>) -> Self {
Self::new(content).callout_type(CalloutType::Warning)
}
pub fn danger(content: impl Into<String>) -> Self {
Self::new(content).callout_type(CalloutType::Danger)
}
pub fn info(content: impl Into<String>) -> Self {
Self::new(content).callout_type(CalloutType::Info)
}
pub fn callout_type(mut self, callout_type: CalloutType) -> Self {
self.callout_type = callout_type;
self
}
pub fn title(mut self, title: impl Into<String>) -> Self {
self.title = Some(title.into());
self
}
pub fn variant(mut self, variant: CalloutVariant) -> Self {
self.variant = variant;
self
}
pub fn icon(mut self, show: bool) -> Self {
self.show_icon = show;
self
}
pub fn custom_icon(mut self, icon: char) -> Self {
self.custom_icon = Some(icon);
self.show_icon = true;
self
}
pub fn collapsible(mut self, collapsible: bool) -> Self {
self.collapsible = collapsible;
self
}
pub fn expanded(mut self, expanded: bool) -> Self {
self.expanded = expanded;
self
}
pub fn collapse_icons(mut self, collapsed: char, expanded: char) -> Self {
self.collapsed_icon = collapsed;
self.expanded_icon = expanded;
self
}
pub fn toggle(&mut self) {
if self.collapsible {
self.expanded = !self.expanded;
}
}
pub fn expand(&mut self) {
self.expanded = true;
}
pub fn collapse(&mut self) {
self.expanded = false;
}
pub fn is_expanded(&self) -> bool {
self.expanded
}
pub fn is_collapsible(&self) -> bool {
self.collapsible
}
pub fn set_expanded(&mut self, expanded: bool) {
self.expanded = expanded;
}
pub fn get_icon(&self) -> char {
self.custom_icon.unwrap_or_else(|| self.callout_type.icon())
}
pub fn collapse_icon(&self) -> char {
if self.expanded {
self.expanded_icon
} else {
self.collapsed_icon
}
}
pub fn get_title(&self) -> &str {
self.title
.as_deref()
.unwrap_or_else(|| self.callout_type.default_title())
}
pub fn height(&self) -> u16 {
if self.collapsible && !self.expanded {
return 1; }
let content_lines = self.content.lines().count().max(1) as u16;
match self.variant {
CalloutVariant::Filled => {
2 + content_lines + 1
}
CalloutVariant::LeftBorder => {
1 + content_lines
}
CalloutVariant::Minimal => {
1 + content_lines
}
}
}
pub fn handle_key(&mut self, key: &Key) -> bool {
if !self.collapsible || self.state.disabled {
return false;
}
match key {
Key::Enter | Key::Char(' ') => {
self.toggle();
true
}
Key::Right | Key::Char('l') => {
self.expand();
true
}
Key::Left | Key::Char('h') => {
self.collapse();
true
}
_ => false,
}
}
}
impl Default for Callout {
fn default() -> Self {
Self::new("Callout")
}
}