From ff3e700b92a01a1541e5e702979469704c00918a Mon Sep 17 00:00:00 2001 From: Adoo Date: Sat, 2 Nov 2024 17:32:32 +0800 Subject: [PATCH] =?UTF-8?q?refactor(core):=20=F0=9F=92=A1=20`KeyWidget`=20?= =?UTF-8?q?and=20`Expanded`=20are=20not=20declared=20as=20`FatObj`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ core/src/builtin_widgets/key.rs | 18 ++++++++++++------ core/src/builtin_widgets/provider.rs | 8 -------- core/src/widget.rs | 2 +- macros/src/declare_derive.rs | 6 +----- macros/src/simple_declare_attr.rs | 15 +++++++++++++-- widgets/src/layout/expanded.rs | 22 ++++++---------------- widgets/src/tabs.rs | 21 ++++++++++----------- 8 files changed, 47 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78f4ff4d2..1fbb4aa54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,10 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he - **core**: The `Provider` might be missing in a pipe class. (#648 @M-Adoo) - **core**: The child generated by the class may not be mounted. (#648 @M-Adoo) +### Breaking + +- **core**: `Expanded` and `KeyWidget` are not declared with `FatObj`, so they do not currently support built-in widgets. (#pr @M-Adoo) + ## [0.4.0-alpha.14] - 2024-10-30 ### Features diff --git a/core/src/builtin_widgets/key.rs b/core/src/builtin_widgets/key.rs index e5945f174..48f0c42e5 100644 --- a/core/src/builtin_widgets/key.rs +++ b/core/src/builtin_widgets/key.rs @@ -69,15 +69,21 @@ impl Default for KeyChange { /// // generate `KeyWidget`, because the root of generated widget is `Margin`. /// fn_widget!{ /// @ { -/// pipe!($trigger;).map(move |_| @KeyWidget { +/// pipe!($trigger;).map(move |_| +/// @Margin { /// margin: EdgeInsets::all(10.), -/// key: "key", -/// value: (), -/// @Void {} -/// }) +/// @KeyWidget { +/// key: "key", +/// value: (), +/// @Void {} +/// }}) /// } /// }; -#[derive(Declare)] +// `KeyWidget` should not support `FatObj`, as this may cause the `KeyWidget` to be invisible to its +// parent. `@KeyWidget { margin: EdgeInsets::all(10.) }` actually expands as `@Margin { @KeyWidget { +// .. } }`. +#[simple_declare] + pub struct KeyWidget { pub key: Key, #[declare(strict)] diff --git a/core/src/builtin_widgets/provider.rs b/core/src/builtin_widgets/provider.rs index 62a0ea8c0..54fa5e611 100644 --- a/core/src/builtin_widgets/provider.rs +++ b/core/src/builtin_widgets/provider.rs @@ -69,7 +69,6 @@ use crate::prelude::*; /// ``` #[simple_declare] pub struct Provider { - #[declare(custom)] pub provider: Box, } @@ -107,13 +106,6 @@ impl Provider { } } -impl ProviderDeclarer { - pub fn provider(mut self, p: impl Query) -> Self { - self.provider = Some(Box::new(p)); - self - } -} - impl<'c> ComposeChild<'c> for Provider { type Child = FnWidget<'c>; fn compose_child(this: impl StateWriter, child: Self::Child) -> Widget<'c> { diff --git a/core/src/widget.rs b/core/src/widget.rs index 79fb2c86b..cd0ac4fdc 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -222,7 +222,7 @@ impl<'w> Widget<'w> { /// Attach a state to a widget and try to unwrap it before attaching. /// /// User can query the state or its value type. - pub(crate) fn try_unwrap_state_and_attach( + pub fn try_unwrap_state_and_attach( self, data: impl StateWriter + 'static, ) -> Self { let data: Box = match data.try_into_value() { diff --git a/macros/src/declare_derive.rs b/macros/src/declare_derive.rs index 652409164..ccf9c2eb5 100644 --- a/macros/src/declare_derive.rs +++ b/macros/src/declare_derive.rs @@ -553,11 +553,7 @@ fn declarer_set_methods<'a>( .filter(|f| f.need_set_method()) .map(move |f| { let field_name = f.field.ident.as_ref().unwrap(); - let doc = f - .field - .attrs - .iter() - .find(|attr| matches!(&attr.meta, syn::Meta::NameValue(nv) if nv.path.is_ident("doc"))); + let doc = f.doc_attr(); let ty = &f.field.ty; let set_method = f.set_method_name(); if f diff --git a/macros/src/simple_declare_attr.rs b/macros/src/simple_declare_attr.rs index 03f3e55fe..1fde3b597 100644 --- a/macros/src/simple_declare_attr.rs +++ b/macros/src/simple_declare_attr.rs @@ -1,7 +1,7 @@ use proc_macro2::TokenStream; use quote::{ToTokens, quote, quote_spanned}; use syn::{ - Fields, Ident, Result, Visibility, + Attribute, Fields, Ident, Result, Visibility, parse::{Parse, discouraged::Speculative}, spanned::Spanned, }; @@ -191,6 +191,14 @@ impl<'a> DeclareField<'a> { .as_ref() .map_or(true, |attr| attr.custom.is_none() && attr.skip.is_none()) } + + pub fn doc_attr(&self) -> Option<&Attribute> { + self + .field + .attrs + .iter() + .find(|attr| matches!(&attr.meta, syn::Meta::NameValue(nv) if nv.path.is_ident("doc"))) + } } impl Parse for DeclareAttr { @@ -253,7 +261,7 @@ impl Parse for DefaultMeta { } } -fn declarer_set_methods<'a>( +pub fn declarer_set_methods<'a>( fields: &'a [DeclareField], vis: &'a Visibility, ) -> impl Iterator + 'a { fields @@ -261,11 +269,13 @@ fn declarer_set_methods<'a>( .filter(|f| f.need_set_method()) .map(move |f| { let field_name = f.field.ident.as_ref().unwrap(); + let doc_attr = f.doc_attr(); let ty = &f.field.ty; let set_method = f.set_method_name(); if f.is_strict() { quote! { #[inline] + #doc_attr #vis fn #set_method(mut self, v: #ty) -> Self { self.#field_name = Some(v); self @@ -274,6 +284,7 @@ fn declarer_set_methods<'a>( } else { quote! { #[inline] + #doc_attr #vis fn #set_method(mut self, v: impl Into<#ty>) -> Self { self.#field_name = Some(v.into()); diff --git a/widgets/src/layout/expanded.rs b/widgets/src/layout/expanded.rs index 5dc3a8be3..92bf92a5c 100644 --- a/widgets/src/layout/expanded.rs +++ b/widgets/src/layout/expanded.rs @@ -3,7 +3,11 @@ use ribir_core::prelude::*; /// A widget that expanded a child of `Flex`, so that the child fills the /// available space. If multiple children are expanded, the available space is /// divided among them according to the flex factor. -#[derive(Clone, PartialEq, Declare)] +#[derive(Clone, PartialEq)] +// `Expand` should not support `FatObj`, as this may cause the `Expanded` to be invisible to its +// parent. `@Expanded { margin: EdgeInsets::all(10.) }` actually expands as `@Margin { @Expanded { +// .. } }`. +#[simple_declare] pub struct Expanded { #[declare(default = 1.)] pub flex: f32, @@ -13,21 +17,7 @@ impl<'c> ComposeChild<'c> for Expanded { type Child = Widget<'c>; #[inline] fn compose_child(this: impl StateWriter, child: Self::Child) -> Widget<'c> { - let data: Box = match this.try_into_value() { - Ok(data) => Box::new(Queryable(data)), - Err(data) => Box::new(data), - }; - Provider::new(data) - .with_child(fn_widget! { - @ConstrainedBox { - clamp: BoxClamp { - min: Size::new(0., 0.), - max: Size::new(f32::INFINITY, f32::INFINITY) - }, - @{ child } - } - }) - .into_widget() + child.try_unwrap_state_and_attach(this) } } diff --git a/widgets/src/tabs.rs b/widgets/src/tabs.rs index ee33ea0c0..2bd94fb5b 100644 --- a/widgets/src/tabs.rs +++ b/widgets/src/tabs.rs @@ -184,27 +184,26 @@ impl Tabs { } }); @ { - let mut tab_header = @Expanded { + let mut tab_header = @Flex { + align_items: Align::Center, + justify_content: JustifyContent::Center, + direction: match icon_pos { + Position::Left | Position::Right => Direction::Horizontal, + Position::Top | Position::Bottom => Direction::Vertical, + }, + reverse: matches!(icon_pos, Position::Right | Position::Bottom), on_tap: move |_| if $tabs.cur_idx != idx { $tabs.write().cur_idx = idx; }, }; - let u = watch!(($tabs.cur_idx == idx, $tab_header.layout_rect())) .filter_map(|(active, rect)| active.then_some(rect)) .subscribe(move |v| $indicator.write().rect = v); @TabDecorator { on_disposed: move |_| { u.unsubscribe(); }, - @$tab_header { - @Flex { - align_items: Align::Center, - justify_content: JustifyContent::Center, - direction: match icon_pos { - Position::Left | Position::Right => Direction::Horizontal, - Position::Top | Position::Bottom => Direction::Vertical, - }, - reverse: matches!(icon_pos, Position::Right | Position::Bottom), + @Expanded { + @$tab_header { @ { icon_widget } @ { label_widget } }