diff --git a/CHANGELOG.md b/CHANGELOG.md index 741844755..5ce4a8c70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he ## [@Unreleased] - @ReleaseDate +### Breaking + +- **core**: `GenWidget::gen_widget` no longer requires a `&mut BuildCtx` parameter. (#pr @M-Adoo) + ## [0.4.0-alpha.5] - 2024-08-14 ### Features diff --git a/core/src/builtin_widgets/theme.rs b/core/src/builtin_widgets/theme.rs index dc50d2ea8..adf15c652 100644 --- a/core/src/builtin_widgets/theme.rs +++ b/core/src/builtin_widgets/theme.rs @@ -73,9 +73,7 @@ pub struct ThemeWidget { impl ComposeChild<'static> for ThemeWidget { type Child = GenWidget; - fn compose_child( - this: impl StateWriter, mut child: Self::Child, - ) -> Widget<'static> { + fn compose_child(this: impl StateWriter, child: Self::Child) -> Widget<'static> { use crate::prelude::*; let f = move |ctx: &BuildCtx| { let theme = this.read().theme.clone(); @@ -95,7 +93,7 @@ impl ComposeChild<'static> for ThemeWidget { // shadow the context with the theme. let ctx = BuildCtx::new_with_data(Some(p), ctx.tree, themes); - let child = child.gen_widget(&ctx).build(&ctx); + let child = child.gen_widget().build(&ctx); p.append(child, &mut ctx.tree.borrow_mut()); p diff --git a/core/src/overlay.rs b/core/src/overlay.rs index d4cb1fce7..fa943941b 100644 --- a/core/src/overlay.rs +++ b/core/src/overlay.rs @@ -33,7 +33,7 @@ impl OverlayCloseHandle { pub fn close(&self) { self.0.close() } } -type Builder = Box Widget<'static>>; +type Builder = Box Widget<'static>>; struct OverlayData { builder: Builder, style: Option, @@ -67,8 +67,8 @@ impl Overlay { /// App::run(w); /// ``` pub fn new(gen: impl Into) -> Self { - let mut gen = gen.into(); - Self::inner_new(Box::new(move |_, ctx| gen.gen_widget(ctx))) + let gen = gen.into(); + Self::inner_new(Box::new(move |_| gen.gen_widget())) } /// Create overlay from a builder with a close_handle @@ -100,9 +100,9 @@ impl Overlay { /// App::run(w).with_size(Size::new(200., 200.)); /// ``` pub fn new_with_handle( - mut builder: impl FnMut(OverlayCloseHandle) -> Widget<'static> + 'static, + builder: impl FnMut(OverlayCloseHandle) -> Widget<'static> + 'static, ) -> Self { - Self::inner_new(Box::new(move |ctrl, _| builder(ctrl))) + Self::inner_new(Box::new(builder)) } /// Overlay will show with the given style, if the overlay have not been set @@ -115,10 +115,10 @@ impl Overlay { if self.is_show() { return; } - let ctx = BuildCtx::new(None, &wnd.widget_tree); + let mut inner = self.0.borrow_mut(); let handle = inner.state.close_handle(); - let w = (inner.builder)(handle, &ctx); + let w = (inner.builder)(handle); let style = inner.style.clone(); inner.state.show(w, style, wnd); } @@ -168,10 +168,9 @@ impl Overlay { return; } - let ctx = BuildCtx::new(None, &wnd.widget_tree); let mut inner = self.0.borrow_mut(); let close_handle = inner.state.close_handle(); - let overlay = (inner.builder)(close_handle.clone(), &ctx); + let overlay = (inner.builder)(close_handle.clone()); let overlay = f(overlay, close_handle); let style = inner.style.clone(); inner diff --git a/core/src/widget.rs b/core/src/widget.rs index 35ea6c567..c27b3539a 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; #[doc(hidden)] pub use std::{ any::{Any, TypeId}, @@ -5,6 +6,7 @@ pub use std::{ ops::Deref, }; +use ribir_algo::Sc; use widget_id::{new_node, RenderQueryable}; pub(crate) use crate::widget_tree::*; @@ -82,7 +84,8 @@ impl<'w> LazyWidget<'w> { /// A boxed function widget that can be called multiple times to regenerate /// widget. -pub struct GenWidget(Box Widget<'static>>); +pub struct GenWidget(InnerGenWidget); +type InnerGenWidget = Sc Widget<'static>>>>; // The widget type marker. pub const COMPOSE: usize = 1; @@ -147,7 +150,7 @@ where impl IntoWidgetStrict<'static, FN> for GenWidget { #[inline] - fn into_widget_strict(self) -> Widget<'static> { self.0.into_widget_strict() } + fn into_widget_strict(self) -> Widget<'static> { self.gen_widget() } } impl<'a> Widget<'a> { @@ -180,10 +183,15 @@ impl<'a> Widget<'a> { } impl GenWidget { #[inline] - pub fn new(f: impl FnMut(&BuildCtx) -> Widget<'static> + 'static) -> Self { Self(Box::new(f)) } + pub fn new(f: impl FnMut(&BuildCtx) -> Widget<'static> + 'static) -> Self { + Self(Sc::new(RefCell::new(Box::new(f)))) + } #[inline] - pub fn gen_widget(&mut self, ctx: &BuildCtx) -> Widget<'static> { (self.0)(ctx) } + pub fn gen_widget(&self) -> Widget<'static> { + let f = self.0.clone(); + fn_widget! { f.borrow_mut()(ctx!()) }.into_widget() + } } impl Widget<'static> + 'static> From for GenWidget { diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 31c490f5d..f3355d730 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -72,7 +72,8 @@ pub fn lerp_derive(input: TokenStream) -> TokenStream { /// `declare!` to build the `XXX` widget. /// - for every field of `XXXBuilder` /// - implement method with same name of the field and use to init the field. -/// [declare]: ../ribir/declare/index.html +/// +/// [declare]: ../ribir/declare/index.html #[proc_macro_derive(Declare, attributes(declare))] pub fn declare_trait_macro_derive(input: TokenStream) -> TokenStream { let mut input = parse_macro_input!(input as DeriveInput); diff --git a/widgets/src/tabs.rs b/widgets/src/tabs.rs index af488ceb8..586449d39 100644 --- a/widgets/src/tabs.rs +++ b/widgets/src/tabs.rs @@ -319,7 +319,7 @@ impl ComposeChild<'static> for Tabs { }, @ { header } @Expanded { - @ { pipe!($this.cur_idx).map(move |idx| panes[idx].gen_widget(ctx!())) } + @ { pipe!($this.cur_idx).map(move |idx| panes[idx].gen_widget()) } } } }