use crate::core::{Bounds, HitboxId, HitboxRegistry, Pixels, Point};
use crate::gpu::{Scene, TextTraits};
use crate::view::dispatch::DispatchTree;
use crate::view::interactivity::HandlerEntry;
use crate::view::overlay::DeferredOverlay;
use crate::view::style_extra::TextRefine;
use crate::view::text_layout::TextLeaf;
use crate::view::theme::{ColorSpec, Token};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use std::rc::Rc;
use taffy::TaffyTree;
pub struct FrameState {
pub taffy: TaffyTree<TextLeaf>,
pub scene: Scene,
pub hitboxes: HitboxRegistry,
pub handlers: Vec<HandlerEntry>,
pub dispatch: DispatchTree,
pub deferred: Vec<DeferredOverlay>,
pub ime_area: Option<Bounds>,
pub wants_animation_frame: bool,
pub access: Vec<crate::view::accessibility::AccessNode>,
pub access_enabled: bool,
pub groups: FxHashMap<Rc<str>, SmallVec<[HitboxId; 2]>>,
}
impl Default for FrameState {
fn default() -> Self {
Self {
taffy: TaffyTree::new(),
scene: Scene::default(),
hitboxes: HitboxRegistry::default(),
handlers: Vec::new(),
dispatch: DispatchTree::default(),
deferred: Vec::new(),
ime_area: None,
wants_animation_frame: false,
access: Vec::new(),
access_enabled: false,
groups: FxHashMap::default(),
}
}
}
impl FrameState {
pub fn begin(&mut self) {
self.taffy.clear();
self.scene.clear();
self.hitboxes.clear();
self.handlers.clear();
self.dispatch.clear();
self.deferred.clear();
self.ime_area = None;
self.wants_animation_frame = false;
self.access.clear();
self.groups.clear();
}
}
#[derive(Clone, Copy, Debug)]
pub struct MouseState {
pub position: Point,
pub pressed: Option<HitboxId>,
}
impl MouseState {
pub const OUTSIDE: MouseState = MouseState { position: Point::new(Pixels(-1.0e6), Pixels(-1.0e6)), pressed: None };
}
#[derive(Clone, Copy)]
pub struct InheritedText {
pub color: ColorSpec,
pub size: Pixels,
pub bold: bool,
pub italic: bool,
pub underline: bool,
pub wrap: bool,
pub strike: bool,
pub mono: bool,
pub leading: f32,
pub traits: TextTraits,
}
impl Default for InheritedText {
fn default() -> Self {
Self {
color: Token::Text.into(),
size: Pixels(14.0),
bold: false,
italic: false,
underline: false,
wrap: true,
strike: false,
mono: false,
leading: DEFAULT_LEADING,
traits: TextTraits::default(),
}
}
}
pub const DEFAULT_LEADING: f32 = 1.4;
impl InheritedText {
pub fn refine(&mut self, text: &TextRefine) {
self.traits.weight = text.weight.unwrap_or(self.traits.weight);
self.traits.align = text.align.or(self.traits.align);
self.traits.tracking = text.tracking.unwrap_or(self.traits.tracking);
self.traits.lines = text.lines.unwrap_or(self.traits.lines);
self.traits.transform = text.transform.or(self.traits.transform);
self.leading = text.leading.unwrap_or(self.leading);
self.strike = text.strike.unwrap_or(self.strike);
self.mono = text.mono.unwrap_or(self.mono);
self.wrap |= self.traits.lines > 0;
}
pub fn line_height(&self) -> f32 {
(self.size.0 * self.leading).round()
}
}