use std::cell::{Cell, RefCell};
use std::rc::Rc;
use smallvec::SmallVec;
use crate::pivot::Pivot;
use crate::transform::Transform;
use crate::widgets::Rect;
use super::clip::CachedClip;
use super::commands::DrawCommand;
use super::flatten::FlattenedCommand;
#[derive(Debug, Clone)]
pub struct ClipRegion {
pub rect: Rect,
pub corner_radius: crate::renderer::CornerRadii,
pub curvature: f32,
}
pub type NodeId = u64;
#[derive(Debug, Clone)]
pub struct CachedFlatten {
pub commands: Vec<FlattenedCommand>,
pub clips: Vec<CachedClip>,
pub world_transform: Transform,
pub opacity: f32,
}
impl CachedFlatten {
pub fn replay_offset(&self, world_transform: Transform) -> Option<(f32, f32)> {
if !self.world_transform.is_translation_only() || !world_transform.is_translation_only() {
return None;
}
Some((
world_transform.tx() - self.world_transform.tx(),
world_transform.ty() - self.world_transform.ty(),
))
}
pub fn replay_fade(&self, opacity: f32) -> Option<f32> {
if opacity == self.opacity {
return Some(1.0);
}
(self.opacity > 0.0).then(|| opacity / self.opacity)
}
}
#[derive(Debug, Clone)]
pub struct RenderNode {
pub id: NodeId,
pub local_transform: Transform,
pub parent_position: Transform,
pub pivot: Pivot,
pub opacity: f32,
pub bounds: Rect,
pub commands: SmallVec<[Rc<DrawCommand>; 2]>,
pub children: Vec<Rc<RenderNode>>,
pub overlay_commands: SmallVec<[Rc<DrawCommand>; 4]>,
pub clip: Option<ClipRegion>,
pub overlay_clip: Option<ClipRegion>,
pub repainted: Cell<bool>,
pub partial: bool,
pub cached_flatten: RefCell<Option<Rc<CachedFlatten>>>,
}
impl RenderNode {
pub fn new(id: NodeId) -> Self {
Self {
id,
local_transform: Transform::IDENTITY,
parent_position: Transform::IDENTITY,
pivot: Pivot::CENTER,
opacity: 1.0,
bounds: Rect::new(0.0, 0.0, 0.0, 0.0),
commands: SmallVec::new(),
children: Vec::new(),
overlay_commands: SmallVec::new(),
clip: None,
overlay_clip: None,
repainted: Cell::new(true),
partial: false,
cached_flatten: RefCell::new(None),
}
}
pub fn with_bounds(id: NodeId, bounds: Rect) -> Self {
Self {
bounds,
..Self::new(id)
}
}
pub fn clear(&mut self) {
self.local_transform = Transform::IDENTITY;
self.parent_position = Transform::IDENTITY;
self.pivot = Pivot::CENTER;
self.opacity = 1.0;
self.commands.clear();
self.children.clear();
self.overlay_commands.clear();
self.clip = None;
self.overlay_clip = None;
self.repainted.set(true);
self.partial = false;
*self.cached_flatten.borrow_mut() = None;
}
}