use super::{WidgetContext, WidgetCtxImpl, WindowCtx};
use crate::{
widget::{BoxClamp, DirtySet, LayoutStore, Layouter, TreeArena},
widget_tree::WidgetId,
};
use ribir_geom::Size;
pub struct LayoutCtx<'a> {
pub(crate) id: WidgetId,
pub(crate) arena: &'a mut TreeArena,
pub(crate) store: &'a mut LayoutStore,
pub(crate) wnd_ctx: &'a mut WindowCtx,
pub(crate) dirty_set: &'a DirtySet,
}
impl<'a> LayoutCtx<'a> {
#[inline]
pub fn has_child(&self) -> bool { self.id.first_child(self.tree_arena()).is_some() }
pub fn perform_single_child_layout(&mut self, clamp: BoxClamp) -> Option<Size> {
self
.single_child_layouter()
.map(|mut l| l.perform_widget_layout(clamp))
}
pub fn assert_perform_single_child_layout(&mut self, clamp: BoxClamp) -> Size {
self
.assert_single_child_layouter()
.perform_widget_layout(clamp)
}
pub fn first_child_layouter(&mut self) -> Option<Layouter> {
self.first_child().map(|wid| self.new_layouter(wid, false))
}
pub fn single_child_layouter(&mut self) -> Option<Layouter> {
self.single_child().map(|wid| self.new_layouter(wid, false))
}
pub fn assert_single_child_layouter(&mut self) -> Layouter {
let wid = self.assert_single_child();
self.new_layouter(wid, false)
}
#[inline]
pub fn force_child_relayout(&mut self, child: WidgetId) -> bool {
assert_eq!(child.parent(self.arena), Some(self.id));
self.store.force_layout(child).is_some()
}
fn new_layouter(&mut self, wid: WidgetId, is_layout_root: bool) -> Layouter {
let Self { arena, store, wnd_ctx, dirty_set, .. } = self;
Layouter {
wid,
arena,
store,
wnd_ctx,
dirty_set,
is_layout_root,
}
}
}
impl<'a> WidgetCtxImpl for LayoutCtx<'a> {
fn id(&self) -> WidgetId { self.id }
fn tree_arena(&self) -> &TreeArena { self.arena }
fn layout_store(&self) -> &LayoutStore { self.store }
fn wnd_ctx(&self) -> &WindowCtx { self.wnd_ctx }
}