pub struct LayoutContext<'a> {
pub scale: Scale,
pub text_system: Option<&'a mut TextSystem>,
pub debug_layouts: HashMap<ElementId, LayoutDebugInfo>,
/* private fields */
}Expand description
Mutable services and scoped hints available during one layout traversal.
Geometry is expressed in logical pixels. The context borrows its optional text system exclusively, so it is local to the current thread and layout pass rather than a shareable global service.
§Examples
use ailloli_ui_core::Scale;
use ailloli_ui_runtime::layout::LayoutContext;
let ctx = LayoutContext::new(Scale::new(2.0));
assert_eq!(ctx.scale.dpr, 2.0);
assert!(ctx.text_system.is_none());Fields§
§scale: ScaleDevice-pixel ratio used for snapping and layout-cache identity.
text_system: Option<&'a mut TextSystem>Shared text layout engine (optional for text-free tests).
debug_layouts: HashMap<ElementId, LayoutDebugInfo>Latest developer-tooling layout record for each element in this context.
Implementations§
Source§impl<'a> LayoutContext<'a>
Provides the operations defined for LayoutContext<'a>.
impl<'a> LayoutContext<'a>
Provides the operations defined for LayoutContext<'a>.
Sourcepub fn new(scale: Scale) -> Self
pub fn new(scale: Scale) -> Self
Creates a context without a text system or virtual viewport.
With devtools, the debug-record map also starts empty.
§Examples
use ailloli_ui_core::Scale;
use ailloli_ui_runtime::layout::LayoutContext;
let ctx = LayoutContext::new(Scale::new(1.25));
assert!(ctx.virtual_viewport().is_none());Sourcepub fn with_text_system(scale: Scale, text_system: &'a mut TextSystem) -> Self
pub fn with_text_system(scale: Scale, text_system: &'a mut TextSystem) -> Self
Creates a context borrowing text_system for this layout pass.
The virtual viewport starts as None; with devtools, debug records
start empty.
§Examples
use ailloli_ui_core::Scale;
use ailloli_ui_runtime::layout::LayoutContext;
use ailloli_ui_text::TextSystem;
let mut text = TextSystem::new();
let ctx = LayoutContext::with_text_system(Scale::new(1.0), &mut text);
assert!(ctx.text_system.is_some());Sourcepub const fn virtual_viewport(&self) -> Option<VirtualViewport>
pub const fn virtual_viewport(&self) -> Option<VirtualViewport>
Returns the currently scoped content viewport.
None means widgets should lay out without a virtualization hint.
§Examples
use ailloli_ui_core::{Rect, Scale};
use ailloli_ui_runtime::layout::{LayoutCtx, VirtualViewport};
let mut ctx = LayoutCtx::new(Scale::new(1.0));
ctx.replace_virtual_viewport(Some(VirtualViewport::new(
Rect::new(0.0, 50.0, 200.0, 100.0), 12.0,
)));
assert_eq!(ctx.virtual_viewport().unwrap().rect.y, 50.0);Sourcepub const fn layout_pass(&self) -> LayoutPass
pub const fn layout_pass(&self) -> LayoutPass
Returns the authority of geometry produced by the current traversal.
Widgets may always compute geometry, but must not persist effects based
on it while this returns LayoutPass::Measure.
Sourcepub fn with_layout_pass<R>(
&mut self,
requested: LayoutPass,
layout: impl FnOnce(&mut Self) -> R,
) -> R
pub fn with_layout_pass<R>( &mut self, requested: LayoutPass, layout: impl FnOnce(&mut Self) -> R, ) -> R
Runs a descendant traversal under a sticky requested layout pass.
Requesting LayoutPass::Commit beneath an existing measurement keeps
the descendant in LayoutPass::Measure. The previous pass is restored
after layout returns.
§Examples
use ailloli_ui_core::Scale;
use ailloli_ui_runtime::layout::{LayoutCtx, LayoutPass};
let mut ctx = LayoutCtx::new(Scale::new(1.0));
ctx.with_layout_pass(LayoutPass::Measure, |ctx| {
assert!(ctx.layout_pass().is_measure());
ctx.with_layout_pass(LayoutPass::Commit, |ctx| {
assert!(ctx.layout_pass().is_measure());
});
});
assert!(ctx.layout_pass().is_committed());Sourcepub fn replace_virtual_viewport(
&mut self,
viewport: Option<VirtualViewport>,
) -> Option<VirtualViewport>
pub fn replace_virtual_viewport( &mut self, viewport: Option<VirtualViewport>, ) -> Option<VirtualViewport>
Replaces the current content viewport and returns the previous value.
Layout containers use this to scope the hint to their child traversal.
Passing None clears the hint. The caller should restore the returned
value after laying out a scoped child.
§Examples
use ailloli_ui_core::{Rect, Scale};
use ailloli_ui_runtime::layout::{LayoutCtx, VirtualViewport};
let mut ctx = LayoutCtx::new(Scale::new(1.0));
let viewport = VirtualViewport::new(Rect::new(0.0, 0.0, 80.0, 60.0), 4.0);
assert!(ctx.replace_virtual_viewport(Some(viewport)).is_none());
assert_eq!(ctx.replace_virtual_viewport(None), Some(viewport));Sourcepub fn record_debug_layout(
&mut self,
element_id: ElementId,
constraints: Constraints,
size: Size,
) -> LayoutDebugInfo
pub fn record_debug_layout( &mut self, element_id: ElementId, constraints: Constraints, size: Size, ) -> LayoutDebugInfo
Records the latest layout and returns the stored debug snapshot.
The first call for an element fixes constraints_in. Every call sets
constraints_final to Some(constraints) and replaces layout_size.
The map grows by unique element ID for the lifetime of this context.
§Examples
use ailloli_ui_core::{Constraints, ElementId, Scale, Size};
use ailloli_ui_runtime::layout::LayoutCtx;
let mut ctx = LayoutCtx::new(Scale::new(1.0));
let info = ctx.record_debug_layout(
ElementId(7), Constraints::tight(20.0, 10.0), Size::new(20.0, 10.0),
);
assert_eq!(info.layout_size, Size::new(20.0, 10.0));
assert!(info.constraints_final.is_some());