fret_ui_kit/declarative/
cached_subtree.rs1use fret_core::{Corners, Rect, TextStyle};
2use fret_ui::element::{AnyElement, LayoutStyle, ViewCacheProps};
3use fret_ui::{ElementContext, UiHost};
4
5use crate::{IntoUiElement, collect_children};
6
7pub trait CachedSubtreeExt {
12 type Host: UiHost;
13
14 fn cached_subtree<I, T>(&mut self, f: impl FnOnce(&mut Self) -> I) -> AnyElement
16 where
17 I: IntoIterator<Item = T>,
18 T: IntoUiElement<Self::Host>,
19 {
20 self.cached_subtree_with(CachedSubtreeProps::default(), f)
21 }
22
23 fn cached_subtree_with<I, T>(
25 &mut self,
26 props: CachedSubtreeProps,
27 f: impl FnOnce(&mut Self) -> I,
28 ) -> AnyElement
29 where
30 I: IntoIterator<Item = T>,
31 T: IntoUiElement<Self::Host>;
32}
33
34#[derive(Debug, Clone, Copy, Default)]
35pub struct CachedSubtreeProps {
36 pub layout: LayoutStyle,
37 pub contained_layout: bool,
38 pub cache_key: u64,
39}
40
41impl CachedSubtreeProps {
42 pub fn layout(mut self, layout: LayoutStyle) -> Self {
43 self.layout = layout;
44 self
45 }
46
47 pub fn contained_layout(mut self, contained_layout: bool) -> Self {
48 self.contained_layout = contained_layout;
49 self
50 }
51
52 pub fn cache_key(mut self, cache_key: u64) -> Self {
53 self.cache_key = cache_key;
54 self
55 }
56
57 pub fn cache_key_text_style(mut self, style: &TextStyle) -> Self {
58 self.cache_key =
59 fret_ui::cache_key::mix(self.cache_key, fret_ui::cache_key::text_style_key(style));
60 self
61 }
62
63 pub fn cache_key_clip_rect(mut self, rect: Rect) -> Self {
64 self.cache_key =
65 fret_ui::cache_key::mix(self.cache_key, fret_ui::cache_key::rect_key(rect));
66 self
67 }
68
69 pub fn cache_key_clip_rrect(mut self, rect: Rect, corners: Corners) -> Self {
70 self.cache_key =
71 fret_ui::cache_key::mix(self.cache_key, fret_ui::cache_key::rect_key(rect));
72 self.cache_key =
73 fret_ui::cache_key::mix(self.cache_key, fret_ui::cache_key::corners_key(corners));
74 self
75 }
76}
77
78impl<'a, H: UiHost> CachedSubtreeExt for ElementContext<'a, H> {
79 type Host = H;
80
81 fn cached_subtree_with<I, T>(
82 &mut self,
83 props: CachedSubtreeProps,
84 f: impl FnOnce(&mut Self) -> I,
85 ) -> AnyElement
86 where
87 I: IntoIterator<Item = T>,
88 T: IntoUiElement<Self::Host>,
89 {
90 let view_cache = ViewCacheProps {
91 layout: props.layout,
92 contained_layout: props.contained_layout,
93 cache_key: props.cache_key,
94 };
95 self.view_cache(view_cache, move |cx| {
96 let items = f(cx);
97 collect_children(cx, items)
98 })
99 }
100}