use crate::layout::{
Border, Direction, LayoutRect, Length, Overflow, Padding, Position, Size, ZIndex,
};
use crate::render::inline::InlineLayout;
use crate::runtime::editing::EditorState;
use crate::style::{Color, ComputedStyle, TuiStyle};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PseudoLayout {
pub rect: LayoutRect,
pub position: Position,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AnonymousIfc {
pub rect: LayoutRect,
pub inline_layout: InlineLayout,
pub child_range: (usize, usize),
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct PresentationStyle {
pub fg: Option<Color>,
pub bg: Option<Color>,
pub border_fg: Option<Color>,
pub width: Option<Size>,
pub height: Option<Size>,
pub padding: Option<Padding>,
pub gap: Option<u16>,
pub top: Option<Length>,
pub right: Option<Length>,
pub bottom: Option<Length>,
pub left: Option<Length>,
pub z_index: Option<ZIndex>,
}
impl PresentationStyle {
pub fn is_empty(&self) -> bool {
self.fg.is_none()
&& self.bg.is_none()
&& self.border_fg.is_none()
&& self.width.is_none()
&& self.height.is_none()
&& self.padding.is_none()
&& self.gap.is_none()
&& self.top.is_none()
&& self.right.is_none()
&& self.bottom.is_none()
&& self.left.is_none()
&& self.z_index.is_none()
}
pub fn clear(&mut self) {
*self = PresentationStyle::default();
}
}
#[derive(Debug, Default, Clone, PartialEq)]
pub struct TuiExt {
pub inline_style: TuiStyle,
pub before_content: Option<String>,
pub after_content: Option<String>,
pub width: Size,
pub height: Size,
pub min_width: Option<rdom_style::layout::MinSize>,
pub max_width: Option<u16>,
pub min_height: Option<rdom_style::layout::MinSize>,
pub max_height: Option<u16>,
pub direction: Direction,
pub padding: Padding,
pub border: Border,
pub gap: u16,
pub overflow: Overflow,
pub scroll_x: usize,
pub scroll_y: usize,
pub scroll_content_width: usize,
pub scroll_content_height: usize,
pub layout: LayoutRect,
pub content_layout: LayoutRect,
pub before_layout: Option<PseudoLayout>,
pub after_layout: Option<PseudoLayout>,
pub tree_has_positioned_pseudo: bool,
pub tree_has_collapse: bool,
pub inline_layout: Option<InlineLayout>,
pub anonymous_blocks: Vec<AnonymousIfc>,
pub computed: Option<ComputedStyle>,
pub computed_prev: Option<ComputedStyle>,
pub presentation: PresentationStyle,
pub computed_before: Option<ComputedStyle>,
pub computed_after: Option<ComputedStyle>,
pub computed_backdrop: Option<ComputedStyle>,
pub computed_selection: Option<ComputedStyle>,
pub computed_scrollbar: Option<ComputedStyle>,
pub computed_scrollbar_thumb: Option<ComputedStyle>,
pub style_dirty: bool,
pub layout_dirty: bool,
pub editor_state: Option<Box<EditorState>>,
pub canvas_paint: Option<crate::runtime::builtins::canvas::CanvasPaint>,
}
impl TuiExt {
pub fn new() -> Self {
Self::default()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::style::Color;
#[test]
fn defaults_are_sensible() {
let ext = TuiExt::new();
assert_eq!(ext.direction, Direction::Column);
assert_eq!(ext.width, Size::Auto);
assert_eq!(ext.height, Size::Auto);
assert_eq!(ext.overflow, Overflow::Visible);
assert_eq!(ext.border, Border::none());
assert_eq!(ext.gap, 0);
assert_eq!(ext.scroll_x, 0);
assert_eq!(ext.scroll_y, 0);
assert!(ext.inline_style.is_empty());
assert!(ext.before_content.is_none());
assert!(ext.after_content.is_none());
assert_eq!(ext.layout, LayoutRect::default());
assert!(ext.computed.is_none());
assert!(ext.computed_before.is_none());
assert!(ext.computed_after.is_none());
assert!(!ext.style_dirty);
assert!(!ext.layout_dirty);
}
#[test]
fn clone_preserves_fields() {
let ext = TuiExt {
inline_style: TuiStyle::new().fg(Color::Rgb(255, 0, 0)),
width: Size::Fixed(80),
padding: Padding::all(2),
..Default::default()
};
let cloned = ext.clone();
assert_eq!(
cloned.inline_style.fg,
Some(crate::style::Value::Specified(
crate::style::TuiColor::Literal(Color::Rgb(255, 0, 0))
))
);
assert_eq!(cloned.width, Size::Fixed(80));
assert_eq!(cloned.padding, Padding::all(2));
}
#[test]
fn partial_eq_works() {
let a = TuiExt {
width: Size::Fixed(10),
..Default::default()
};
let b = TuiExt {
width: Size::Fixed(10),
..Default::default()
};
let c = TuiExt {
width: Size::Fixed(11),
..Default::default()
};
assert_eq!(a, b);
assert_ne!(a, c);
}
}