use crate::widget_id::WidgetId;
use super::LayoutResponse;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StackAxis {
Horizontal,
Vertical,
}
pub struct LayoutContext<'a> {
pub stack_main_axis: Option<StackAxis>,
pub theme: &'a crate::styles::Theme,
pub layout_direction: crate::environment::LayoutDirection,
pub scale_factor: f32,
pub text_scale: f32,
pub text_backend: Option<&'a std::rc::Rc<std::cell::RefCell<dyn teksilo_canvas::TextBackend>>>,
pub(crate) arena: Option<&'a crate::arena::WidgetArena>,
pub(crate) extras: Option<LayoutExtras<'a>>,
}
#[derive(Clone, Copy)]
pub(crate) struct LayoutExtras<'a> {
pub focused: Option<WidgetId>,
pub shortcut_registry: Option<&'a crate::shortcut::ShortcutRegistry>,
pub overlay_manager: Option<&'a crate::overlay::OverlayManager>,
}
impl<'a> LayoutContext<'a> {
pub fn for_testing(theme: &'a crate::styles::Theme) -> Self {
Self {
theme,
layout_direction: crate::environment::LayoutDirection::LeftToRight,
scale_factor: 1.0,
text_scale: 1.0,
text_backend: None,
arena: None,
extras: None,
stack_main_axis: None,
}
}
pub fn stack_main_axis(&self) -> Option<StackAxis> {
self.stack_main_axis
}
pub fn with_stack_main_axis(&self, axis: StackAxis) -> LayoutContext<'a> {
LayoutContext {
stack_main_axis: Some(axis),
..*self
}
}
pub fn focused(&self) -> Option<WidgetId> {
self.extras.as_ref().and_then(|e| e.focused)
}
pub fn shortcut_registry(&self) -> Option<&crate::shortcut::ShortcutRegistry> {
self.extras.as_ref().and_then(|e| e.shortcut_registry)
}
pub fn overlay_manager(&self) -> Option<&crate::overlay::OverlayManager> {
self.extras.as_ref().and_then(|e| e.overlay_manager)
}
pub fn child_layout_response(
&self,
child_id: WidgetId,
proposal: teksilo_canvas::SizeProposal,
) -> Option<LayoutResponse> {
let arena = self.arena?;
arena.cached_layout_response(child_id, proposal, self)
}
pub fn measure_intrinsic(
&self,
id: WidgetId,
proposal: teksilo_canvas::SizeProposal,
) -> Option<teksilo_canvas::Size> {
self.arena?.measure_intrinsic(id, proposal, self)
}
pub fn child_size(
&self,
child_id: WidgetId,
proposal: teksilo_canvas::SizeProposal,
) -> Option<teksilo_canvas::Size> {
self.child_layout_response(child_id, proposal)
.map(|r| r.size)
}
pub fn widget_bounds(&self, id: WidgetId) -> Option<teksilo_canvas::Rect> {
let arena = self.arena?;
if !arena.is_active(id) {
return None;
}
Some(arena.bounds(id))
}
pub fn widget_at_point(
&self,
point: teksilo_canvas::Point,
exclude: Option<WidgetId>,
) -> Option<WidgetId> {
let arena = self.arena?;
arena.hit_test_at(point, exclude)
}
pub fn arena(&self) -> Option<&crate::arena::WidgetArena> {
self.arena
}
pub fn child_alignment(&self, child_id: WidgetId) -> Option<teksilo_tokens::Alignment> {
let arena = self.arena?;
arena.alignment_override(child_id)
}
pub fn is_rtl(&self) -> bool {
self.layout_direction == crate::environment::LayoutDirection::RightToLeft
}
}