use super::{AppCtx, WidgetCtx, WidgetCtxImpl};
use crate::{
widget::{BoxClamp, Layouter, WidgetTree},
widget_tree::WidgetId,
window::{Window, WindowId},
};
use ribir_geom::Size;
use std::rc::Rc;
pub struct LayoutCtx<'a> {
pub(crate) id: WidgetId,
pub(crate) wnd_id: WindowId,
pub(crate) tree: &'a mut WidgetTree,
}
impl<'a> WidgetCtxImpl for LayoutCtx<'a> {
fn id(&self) -> WidgetId { self.id }
fn current_wnd(&self) -> Rc<Window> { AppCtx::get_window_assert(self.wnd_id) }
fn with_tree<F: FnOnce(&WidgetTree) -> R, R>(&self, f: F) -> R { f(self.tree) }
}
impl<'a> LayoutCtx<'a> {
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))
}
pub fn single_child_layouter(&mut self) -> Option<Layouter> {
self.single_child().map(|wid| self.new_layouter(wid))
}
pub fn assert_single_child_layouter(&mut self) -> Layouter {
let wid = self.assert_single_child();
self.new_layouter(wid)
}
#[inline]
pub fn force_child_relayout(&mut self, child: WidgetId) -> bool {
assert_eq!(child.parent(&self.tree.arena), Some(self.id));
self.tree.store.force_layout(child).is_some()
}
pub(crate) fn new_layouter(&mut self, id: WidgetId) -> Layouter {
let LayoutCtx { wnd_id, tree, .. } = self;
Layouter::new(id, *wnd_id, false, tree)
}
}