Skip to content

Commit

Permalink
refactor(core): 💡 cache painting style and text style in the `LayoutC…
Browse files Browse the repository at this point in the history
…ontext`
  • Loading branch information
M-Adoo committed Nov 19, 2024
1 parent d5fd34f commit 1505f59
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 11 deletions.
23 changes: 21 additions & 2 deletions core/src/builtin_widgets/painting_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,30 @@ impl Declare for PaintingStyleWidget {
fn declarer() -> Self::Builder { FatObj::new(()) }
}

impl_compose_child_for_wrap_render!(PaintingStyleWidget);
impl<'c> ComposeChild<'c> for PaintingStyleWidget {
type Child = Widget<'c>;

fn compose_child(this: impl StateWriter<Value = Self>, child: Self::Child) -> Widget<'c> {
// We need to provide the text style for the children to access.
match this.try_into_value() {
Ok(this) => {
let style = this.painting_style.clone();
WrapRender::combine_child(State::value(this), child).attach_data(Box::new(Queryable(style)))
}
Err(this) => {
let style = this.map_reader(|w| PartData::from_ref(&w.painting_style));
WrapRender::combine_child(this, child).attach_data(Box::new(style))
}
}
}
}

impl WrapRender for PaintingStyleWidget {
fn perform_layout(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
host.perform_layout(clamp, ctx)
let old = ctx.set_painting_style(self.painting_style.clone());
let size = host.perform_layout(clamp, ctx);
ctx.set_painting_style(old);
size
}

fn paint(&self, host: &dyn Render, ctx: &mut PaintingCtx) {
Expand Down
5 changes: 4 additions & 1 deletion core/src/builtin_widgets/text_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ impl<'c> ComposeChild<'c> for TextStyleWidget {

impl WrapRender for TextStyleWidget {
fn perform_layout(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
host.perform_layout(clamp, ctx)
let old = ctx.set_text_style(self.text_style.clone());
let size = host.perform_layout(clamp, ctx);
ctx.set_text_style(old);
size
}

fn paint(&self, host: &dyn Render, ctx: &mut PaintingCtx) {
Expand Down
36 changes: 35 additions & 1 deletion core/src/context/layout_ctx.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use ribir_geom::{Point, Size};
use ribir_painter::{PaintingStyle, TextStyle};

use super::{WidgetCtx, WidgetCtxImpl};
use crate::{
Expand All @@ -17,6 +18,8 @@ pub struct LayoutCtx<'a> {
/// The widget tree of the window, not borrow it from `wnd` is because a
/// `LayoutCtx` always in a mutable borrow.
pub(crate) tree: &'a mut WidgetTree,
painting_style: PaintingStyle,
text_style: TextStyle,
}

impl<'a> WidgetCtxImpl for LayoutCtx<'a> {
Expand All @@ -28,6 +31,20 @@ impl<'a> WidgetCtxImpl for LayoutCtx<'a> {
}

impl<'a> LayoutCtx<'a> {
pub(crate) fn new(id: WidgetId, tree: &'a mut WidgetTree) -> Self {
let painting_style = if let Some(style) = id.query_ancestors_ref::<PaintingStyle>(tree) {
style.clone()
} else {
PaintingStyle::Fill
};
let text_style = if let Some(style) = id.query_ancestors_ref::<TextStyle>(tree) {
style.clone()
} else {
TextStyle::default()
};

Self { id, tree, painting_style, text_style }
}
/// Perform layout of the child widget referenced, resetting the widget
/// position to (0, 0) relative to the parent if its position is not set by
/// its layout logic, and return the resulting size after layout.
Expand All @@ -40,7 +57,12 @@ impl<'a> LayoutCtx<'a> {
// Safety: the `tree` just use to get the widget of `id`, and `tree2` not drop
// or modify it during perform layout.
let tree2 = unsafe { &mut *(self.tree as *mut WidgetTree) };
let mut ctx = LayoutCtx { id: child, tree: tree2 };
let mut ctx = LayoutCtx {
id: child,
tree: tree2,
painting_style: self.painting_style.clone(),
text_style: self.text_style.clone(),
};
let size = child
.assert_get(self.tree)
.perform_layout(clamp, &mut ctx);
Expand Down Expand Up @@ -129,4 +151,16 @@ impl<'a> LayoutCtx<'a> {
assert_eq!(child.parent(self.tree), Some(self.id));
self.tree.store.force_layout(child).is_some()
}

pub fn set_painting_style(&mut self, style: PaintingStyle) -> PaintingStyle {
std::mem::replace(&mut self.painting_style, style)
}

pub fn painting_style(&self) -> &PaintingStyle { &self.painting_style }

pub fn set_text_style(&mut self, style: TextStyle) -> TextStyle {
std::mem::replace(&mut self.text_style, style)
}

pub fn text_style(&self) -> &TextStyle { &self.text_style }
}
9 changes: 7 additions & 2 deletions core/src/render_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,13 @@ impl<R: Render> RenderProxy for Sc<R> {
}

impl Render for Resource<Path> {
fn perform_layout(&self, clamp: BoxClamp, _: &mut LayoutCtx) -> Size {
let size = self.bounds(None).max().to_vector().to_size();
fn perform_layout(&self, clamp: BoxClamp, ctx: &mut LayoutCtx) -> Size {
let line_width = ctx.painting_style().line_width();
let size = self
.bounds(line_width)
.max()
.to_vector()
.to_size();
clamp.clamp(size)
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/widget_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl WidgetTree {
.map(|info| info.clamp)
.unwrap_or_else(|| BoxClamp { min: Size::zero(), max: win_size });

let mut ctx = LayoutCtx { id: wid, tree: self };
let mut ctx = LayoutCtx::new(wid, self);
ctx.perform_child_layout(wid, clamp);
}
}
Expand Down
6 changes: 6 additions & 0 deletions core/src/widget_tree/widget_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ impl WidgetId {
.and_then(QueryHandle::into_ref)
}

pub(crate) fn query_ancestors_ref<T: Any>(self, tree: &WidgetTree) -> Option<QueryRef<T>> {
self
.ancestors(tree)
.find_map(|id| id.query_ref::<T>(tree))
}

/// return if this object contain type `T`
pub(crate) fn contain_type<T: Any>(self, tree: &WidgetTree) -> bool {
self
Expand Down
4 changes: 2 additions & 2 deletions widgets/src/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::text::*;
/// theme
/// .font_files
/// .push("the font file path".to_string());
/// theme.default_icon_font = FontFace {
/// theme.icon_font = FontFace {
/// families: Box::new([FontFamily::Name("Your icon font family name".into())]),
/// // The rest of the face configuration depends on your font file
/// ..<_>::default()
Expand Down Expand Up @@ -54,7 +54,7 @@ use crate::text::*;
/// class_impl: style_class! {
/// clamp: BoxClamp::fixed_size(Size::new(64., 64.)),
/// text_style: TextStyle {
/// font_face: Theme::of(BuildCtx::get()).default_icon_font.clone(),
/// font_face: Theme::of(BuildCtx::get()).icon_font.clone(),
/// line_height: 64.,
/// font_size: 64.,
/// ..<_>::default()
Expand Down
2 changes: 1 addition & 1 deletion widgets/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ mod tests {
})
.with_wnd_size(WND_SIZE)
.with_comparison(0.000025),
LayoutCase::default().with_size(SIZE_40)
LayoutCase::default().with_size(Size::splat(40.5))
);
}
2 changes: 1 addition & 1 deletion widgets/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct Text {

impl Render for Text {
fn perform_layout(&self, clamp: BoxClamp, ctx: &mut LayoutCtx) -> Size {
let style = Provider::of::<TextStyle>(&ctx).unwrap();
let style = ctx.text_style();
let info = AppCtx::typography_store()
.borrow_mut()
.typography(
Expand Down

0 comments on commit 1505f59

Please sign in to comment.