From 568f72efca2c2f233d2932e4cc165acbe15203f6 Mon Sep 17 00:00:00 2001 From: Adoo Date: Sun, 12 Jan 2025 21:00:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=F0=9F=8E=B8=20added=20`Variant`?= =?UTF-8?q?=20to=20support=20building=20widgets=20with=20variables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + core/src/builtin_widgets.rs | 28 +-- core/src/builtin_widgets/providers.rs | 20 +-- core/src/builtin_widgets/theme.rs | 12 ++ core/src/builtin_widgets/theme/palette.rs | 14 ++ core/src/context.rs | 2 + core/src/context/build_ctx.rs | 13 +- core/src/context/build_variant.rs | 163 ++++++++++++++++++ examples/wordle_game/src/ui.rs | 94 +++++----- painter/src/color.rs | 9 +- painter/src/style.rs | 7 +- .../wordle_game_with_material_by_wgpu.png | Bin 46353 -> 47029 bytes themes/material/src/classes/buttons_cls.rs | 12 +- themes/material/src/classes/checkbox_cls.rs | 17 +- themes/material/src/classes/progress_cls.rs | 69 ++++---- themes/material/src/classes/radio_cls.rs | 11 +- themes/material/src/classes/scrollbar_cls.rs | 10 +- themes/material/src/classes/slider_cls.rs | 4 +- themes/material/src/md.rs | 5 +- widgets/src/path.rs | 11 +- 20 files changed, 349 insertions(+), 153 deletions(-) create mode 100644 core/src/context/build_variant.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a1404ba5..5753c5f77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he - **core**: The `Render::dirty_phase` method has been added to allow widgets to mark only the paint phase as dirty when it is modified. (#689 @M-Adoo) - **core**: Supports `Provider` to dirty the tree if it's a state writer. (#689 @M-Adoo) - **core**: Added the built-in field `providers` to provide data to its descendants. (#pr @M-Adoo) +- **core**: Added `Variant` to support building widgets with variables across `Providers`. (#pr @M-Adoo) - **macros**: Added the `part_reader!` macro to generate a partial reader from a reference of a reader. (#688 @M-Adoo) - **macros**: The `simple_declare` now supports the `stateless` meta attribute, `#[simple_declare(stateless)]`. (#688 @M-Adoo) diff --git a/core/src/builtin_widgets.rs b/core/src/builtin_widgets.rs index cc333e588..40f2d58d5 100644 --- a/core/src/builtin_widgets.rs +++ b/core/src/builtin_widgets.rs @@ -986,19 +986,23 @@ impl<'a> FatObj> { )* }; } - let mut host = self.host; - if let Some(painting_style) = self.painting_style { - self - .providers - .get_or_insert_default() - .push(PaintingStyleWidget::into_provider(painting_style)); - } - if let Some(text_style) = self.text_style { - self - .providers - .get_or_insert_default() - .push(TextStyleWidget::into_provider(text_style)); + macro_rules! consume_providers_widget { + ($host: ident, + [$($field: ident: $w_ty: ty),*]) => { + $( + if let Some($field) = self.$field { + self + .providers + .get_or_insert_default() + .push(<$w_ty>::into_provider($field)); + } + )* + }; } + let mut host = self.host; + consume_providers_widget!(host, + [ + painting_style: PaintingStyleWidget, + text_style: TextStyleWidget + ]); compose_builtin_widgets!( host diff --git a/core/src/builtin_widgets/providers.rs b/core/src/builtin_widgets/providers.rs index abb918628..3cfefcf1a 100644 --- a/core/src/builtin_widgets/providers.rs +++ b/core/src/builtin_widgets/providers.rs @@ -129,7 +129,6 @@ use std::{cell::RefCell, convert::Infallible}; use ops::box_it::CloneableBoxOp; -use ribir_painter::Color; use smallvec::SmallVec; use widget_id::RenderQueryable; @@ -184,11 +183,6 @@ pub trait ProviderRestore { fn restore(self: Box, ctx: &mut ProviderCtx) -> Box; } -/// A type for providing the container color of the widget. -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct ContainerColor(pub Color); - /// The context used to store the providers. #[derive(Default)] pub struct ProviderCtx { @@ -422,10 +416,6 @@ impl Providers { } } -impl ContainerColor { - pub fn provider(color: Color) -> Provider { Provider::new(ContainerColor(color)) } -} - impl ProviderCtx { pub(crate) fn collect_from(id: WidgetId, tree: &WidgetTree) -> ProviderCtx { let ancestors = id @@ -779,10 +769,10 @@ mod tests { @Providers { providers: smallvec![Provider::new(Color::RED)], @ { - assert_eq!(BuildCtx::color(), Color::RED); + assert_eq!(BuildCtx::color().clone_value(), Color::RED); @MockMulti { @fn_widget!{ - assert_eq!(BuildCtx::color(), Color::RED); + assert_eq!(BuildCtx::color().clone_value(), Color::RED); Void } } @@ -790,7 +780,7 @@ mod tests { } @ { let color = BuildCtx::color(); - assert_eq!(color, Palette::of(BuildCtx::get()).primary()); + assert_eq!(color.clone_value(), Palette::of(BuildCtx::get()).primary()); Void } }); @@ -807,9 +797,9 @@ mod tests { providers: smallvec![ContainerColor::provider(Color::GREEN)], @ { let container_color = BuildCtx::container_color(); - assert_eq!(container_color, Color::GREEN); + assert_eq!(container_color.clone_value(), Color::GREEN); let color = BuildCtx::color(); - assert_eq!(color, Color::RED); + assert_eq!(color.clone_value(), Color::RED); Void } } diff --git a/core/src/builtin_widgets/theme.rs b/core/src/builtin_widgets/theme.rs index 66c9cc0b8..a76312f28 100644 --- a/core/src/builtin_widgets/theme.rs +++ b/core/src/builtin_widgets/theme.rs @@ -106,9 +106,21 @@ pub struct Theme { pub icon_font: IconFont, } +/// A type for providing the icon font of the widget. #[derive(Clone, Debug, Default)] pub struct IconFont(pub FontFace); +/// A container color of the theme providing for the widgets that should +/// consider as their default container brush. The user can provide another +/// `ContainerColor` to customize use the widget. +#[derive(Clone)] +#[repr(transparent)] +pub struct ContainerColor(pub Color); + +impl ContainerColor { + pub fn provider(color: Color) -> Provider { Provider::new(ContainerColor(color)) } +} + impl Theme { pub fn of(ctx: &impl AsRef) -> QueryRef { Provider::of(ctx).unwrap() } diff --git a/core/src/builtin_widgets/theme/palette.rs b/core/src/builtin_widgets/theme/palette.rs index bc1ebcbe7..81af53b9d 100644 --- a/core/src/builtin_widgets/theme/palette.rs +++ b/core/src/builtin_widgets/theme/palette.rs @@ -253,6 +253,13 @@ impl Palette { .with_lightness(self.lightness_cfg().surface_container) } + #[inline] + pub fn on_surface_container(&self) -> Color { + self + .neutral + .with_lightness(self.lightness_cfg().color_group.on_container) + } + #[inline] pub fn surface_container_high(&self) -> Color { self @@ -345,6 +352,13 @@ impl Palette { color.with_lightness(self.lightness_cfg().color_group.on_container) } + pub fn lightness_group(&self) -> &LightnessGroup { + match self.brightness { + Brightness::Dark => &self.dark.color_group, + Brightness::Light => &self.light.color_group, + } + } + #[inline] fn lightness_cfg(&self) -> &LightnessCfg { match self.brightness { diff --git a/core/src/context.rs b/core/src/context.rs index c3620895a..85fde691b 100644 --- a/core/src/context.rs +++ b/core/src/context.rs @@ -10,3 +10,5 @@ pub mod app_ctx; #[cfg(feature = "tokio-async")] pub use app_ctx::tokio_async::*; pub use app_ctx::*; +mod build_variant; +pub use build_variant::*; diff --git a/core/src/context/build_ctx.rs b/core/src/context/build_ctx.rs index a28084305..7cd29b489 100644 --- a/core/src/context/build_ctx.rs +++ b/core/src/context/build_ctx.rs @@ -18,14 +18,15 @@ impl BuildCtx { /// Return the window of this context is created from. pub fn window(&self) -> Sc { self.tree().window() } - /// Return the `Color` provide in the current build context. - pub fn color() -> Color { *Provider::of::(BuildCtx::get()).unwrap() } + /// Return the variant of `Color` provided in the current build context. + pub fn color() -> Variant { Variant::new(BuildCtx::get()).unwrap() } - /// Return the `ContainerColor` provide in the current build context. - pub fn container_color() -> Color { - Provider::of::(BuildCtx::get()) - .map(|v| v.0) + /// Return the variant of the `ContainerColor` provide in the current build + /// context and unwrap it as a `Color`. + pub fn container_color() -> VariantMap Color> { + Variant::new(BuildCtx::get()) .unwrap() + .map(|c: ContainerColor| c.0) } pub(crate) fn tree(&self) -> &WidgetTree { diff --git a/core/src/context/build_variant.rs b/core/src/context/build_variant.rs new file mode 100644 index 000000000..efb7a3348 --- /dev/null +++ b/core/src/context/build_variant.rs @@ -0,0 +1,163 @@ +use crate::prelude::*; +/// `Variant` is an enum designed to help you store a clone of a provider. It +/// serves as a shortcut for `Provider::state_of` and `Provider::of`. +/// +/// Initially, it checks for the existence of a stateful provider; if not +/// found, it proceeds to check the value provider. +/// +/// It supports conversion to `DeclareInit` for initialization of a declare +/// object, enabling the object to track changes in the provider value if it's a +/// stateful provider. +/// +/// ## Example +/// +/// ``` +/// use ribir_core::prelude::*; +/// +/// let _ = fn_widget! { +/// let color = Variant::::new(BuildCtx::get()).unwrap(); +/// @Container { +/// size: Size::new(100., 100.), +/// background: color, +/// } +/// }; +/// ``` +/// +/// Here, we create a 100x100 rectangle with a background using the `Color` +/// Provider. If an ancestor provides a `Stateful`, this rectangle will +/// reflect changes in color. +pub enum Variant { + Stateful(Stateful), + Value(V), +} + +/// `VariantMap` is a Variant that maps a value to another value using a +/// function. +#[derive(Clone)] +pub struct VariantMap { + variant: Variant, + map: F, +} + +impl Variant { + /// Creates a new `Variant` from a provider context. + pub fn new(ctx: &impl AsRef) -> Option { + if let Some(value) = Provider::state_of::>(ctx) { + Some(Variant::Stateful(value.clone_writer())) + } else { + Provider::of::(ctx).map(|v| Variant::Value(v.clone())) + } + } + + /// Maps a value to another value using a function. + pub fn map(self, map: F) -> VariantMap + where + F: Fn(V) -> U, + { + VariantMap { variant: self, map } + } + + /// Clones the value of the variant. + pub fn clone_value(&self) -> V { + match self { + Variant::Value(v) => v.clone(), + Variant::Stateful(v) => v.read().clone(), + } + } +} + +impl Variant { + /// Convert a color variant to another color variant with its base lightness + /// tone. + pub fn into_base_color( + self, ctx: &impl AsRef, + ) -> VariantMap Color> { + let p = Palette::of(ctx); + let lightness = p.lightness_group().base; + self.map(move |c| c.with_lightness(lightness)) + } + + /// Converts a color variant to another color variant with its container + /// lightness tone. + pub fn into_container_color( + self, ctx: &impl AsRef, + ) -> VariantMap Color> { + let p = Palette::of(ctx); + let lightness = p.lightness_group().container; + self.map(move |c| c.with_lightness(lightness)) + } + + /// Converts a color variant to another color variant that its lightness tone + /// is suitable display on its base color. + pub fn on_this_color( + self, ctx: &impl AsRef, + ) -> VariantMap Color> { + let p = Palette::of(ctx); + let lightness = p.lightness_group().on; + self.map(move |c| c.with_lightness(lightness)) + } + + /// Converts a color variant to another color variant that its lightness tone + /// is suitable display on its container color. + pub fn on_this_container_color( + self, ctx: &impl AsRef, + ) -> VariantMap Color> { + let p = Palette::of(ctx); + let lightness = p.lightness_group().on_container; + self.map(move |c| c.with_lightness(lightness)) + } +} + +impl VariantMap { + /// Maps a value to another value using a function. + pub fn map(self, map: F2) -> VariantMap U2> + where + F: Fn(V) -> U1, + F2: Fn(U1) -> U2, + { + VariantMap { variant: self.variant, map: move |v| map((self.map)(v)) } + } + + /// Clones the value of the variant. + pub fn clone_value(&self) -> U + where + F: Fn(V) -> U, + V: Clone, + { + (self.map)(self.variant.clone_value()) + } +} + +impl DeclareFrom, 0> for DeclareInit +where + U: From + 'static, +{ + fn declare_from(value: Variant) -> Self { + match value { + Variant::Stateful(value) => pipe!($value.clone()).declare_into(), + Variant::Value(value) => DeclareInit::Value(value.into()), + } + } +} + +impl DeclareFrom, 0> for DeclareInit

+where + F: Fn(V) -> U + 'static, + P: From + 'static, +{ + fn declare_from(value: VariantMap) -> Self { + match value.variant { + Variant::Stateful(s) => pipe!(P::from((value.map)($s.clone()))).declare_into(), + Variant::Value(v) => DeclareInit::Value((value.map)(v).into()), + } + } +} + +impl Clone for Variant { + fn clone(&self) -> Self { + match self { + Variant::Stateful(value) => Variant::Stateful(value.clone_writer()), + Variant::Value(value) => Variant::Value(value.clone()), + } + } +} diff --git a/examples/wordle_game/src/ui.rs b/examples/wordle_game/src/ui.rs index ae2dd31e1..09e9deceb 100644 --- a/examples/wordle_game/src/ui.rs +++ b/examples/wordle_game/src/ui.rs @@ -15,54 +15,70 @@ trait WordleExtraWidgets: StateWriter + Sized + 'static { fn char_key(self, key: char) -> Widget<'static> { let this = self.clone_writer(); - fn_widget! { - @FilledButton { - on_tap: move |_| $this.write().guessing.enter_char(key), - // todo: color: pipe!{ hint_color($this.key_hint(key)) }, - @ { key.to_string() } - } + let color = Stateful::new(Color::TRANSPARENT); + let color2 = color.clone_writer(); + + let palette = Palette::of(BuildCtx::get()); + let base = palette.base_of(&palette.surface_variant()); + let success = palette.success(); + let warning = palette.warning(); + let error = palette.error(); + watch! { $this.key_hint(key).map_or( + base, + |s| match s { + CharHint::Correct => success, + CharHint::WrongPosition => warning, + CharHint::Wrong => error, + }) + } + .subscribe(move |c| *color2.write() = c); + + filled_button! { + providers: [Provider::value_of_writer(color, None)], + on_tap: move |_| $this.write().guessing.enter_char(key), + @ { key.to_string() } } .into_widget() } fn keyboard(self, state_bar: impl StateWriter + 'static) -> Widget<'static> { let this: ::Writer = self.clone_writer(); - fn_widget! { - @Column { + let palette = Palette::of(BuildCtx::get()); + let gray = palette.base_of(&palette.surface_variant()); + self::column! { + item_gap: 5., + align_items: Align::Center, + justify_content: JustifyContent::Center, + @Row { item_gap: 5., align_items: Align::Center, justify_content: JustifyContent::Center, - @Row { - item_gap: 5., - align_items: Align::Center, - justify_content: JustifyContent::Center, - @ { this.clone_writer().chars_key(['Q', 'W', 'E', 'R','T', 'Y', 'U', 'I','O', 'P']) } - } - @Row { - item_gap: 5., - align_items: Align::Center, - justify_content: JustifyContent::Center, - @ { this.clone_writer().chars_key(['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L' ]) } + @ { this.clone_writer().chars_key(['Q', 'W', 'E', 'R','T', 'Y', 'U', 'I','O', 'P']) } + } + @Row { + item_gap: 5., + align_items: Align::Center, + justify_content: JustifyContent::Center, + @ { this.clone_writer().chars_key(['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L' ]) } + } + @Row { + item_gap: 5., + align_items: Align::Center, + justify_content: JustifyContent::Center, + @FilledButton { + providers: [Provider::new(gray)], + on_tap: move |_| $this.write().guessing.delete_back_char(), + @ { "Del" } } - @Row { - item_gap: 5., - align_items: Align::Center, - justify_content: JustifyContent::Center, - @FilledButton { - on_tap: move |_| $this.write().guessing.delete_back_char(), - // todo: color: palette.surface_variant(), - @ { "Del" } - } - @ { self.chars_key(['Z', 'X', 'C', 'V', 'B', 'N', 'M' ]) } - - @FilledButton { - on_tap: move |_| match $this.write().guess() { - Ok(status) => state_bar.write().text = status.state_message().into(), - Err(e) => state_bar.write().text = e.message().into(), - }, - // todo: color: palette.surface_variant(), - @ { "Enter" } - } + @ { self.chars_key(['Z', 'X', 'C', 'V', 'B', 'N', 'M' ]) } + + @FilledButton { + providers: [Provider::new(gray)], + on_tap: move |_| match $this.write().guess() { + Ok(status) => state_bar.write().text = status.state_message().into(), + Err(e) => state_bar.write().text = e.message().into(), + }, + @ { "Enter" } } } } @@ -101,7 +117,7 @@ impl + 'static> WordleExtraWidgets for T {} fn hint_color(hint: Option) -> Color { let palette = Palette::of(BuildCtx::get()); hint.map_or_else( - || palette.surface_variant(), + || palette.base_of(&palette.surface_variant()), |s| match s { CharHint::Correct => palette.success(), CharHint::WrongPosition => palette.warning(), diff --git a/painter/src/color.rs b/painter/src/color.rs index 96f8ca64c..ac47f7d0d 100644 --- a/painter/src/color.rs +++ b/painter/src/color.rs @@ -49,6 +49,9 @@ pub struct LightnessTone(f32); impl LightnessTone { #[inline] pub fn new(tone: f32) -> Self { Self(tone.clamp(0., 1.0)) } + + #[inline] + pub fn value(self) -> f32 { self.0 } } impl Color { @@ -96,7 +99,6 @@ impl Color { self } - #[inline] pub fn with_lightness(self, l: LightnessTone) -> Self { let mut hct = htc::Hct::from_int([self.alpha, self.red, self.green, self.blue]); hct.set_tone((l.0 * 100.).clamp(0., 100.) as f64); @@ -104,6 +106,11 @@ impl Color { Self { red: argb[1], green: argb[2], blue: argb[3], alpha: argb[0] } } + pub fn lightness(self) -> LightnessTone { + let hct = htc::Hct::from_int([self.alpha, self.red, self.green, self.blue]); + LightnessTone::new(hct.tone() as f32 / 100.) + } + #[inline] pub fn into_components(self) -> [u8; 4] { let Self { red, green, blue, alpha } = self; diff --git a/painter/src/style.rs b/painter/src/style.rs index bd7042255..8e9f023ec 100644 --- a/painter/src/style.rs +++ b/painter/src/style.rs @@ -17,10 +17,11 @@ pub enum Brush { } impl Brush { - pub fn only_convert_color(&self, f: impl FnOnce(&Color) -> Color) -> Brush { + /// Returns the color of the brush, or `None` if the brush is not a color. + pub fn get_color(&self) -> Option { match self { - Brush::Color(color) => f(color).into(), - _ => panic!("Need Color!"), + Brush::Color(c) => Some(*c), + _ => None, } } diff --git a/test_cases/wordle_game/tests/wordle_game_with_material_by_wgpu.png b/test_cases/wordle_game/tests/wordle_game_with_material_by_wgpu.png index 706ea5c123c0b3000cabf5bee5a807aa67da2f7a..e41811dacb9671c4faf2191eb46e0f16e5d228c9 100644 GIT binary patch literal 47029 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

?3LHNy_4WN?~@4 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 diff --git a/themes/material/src/classes/buttons_cls.rs b/themes/material/src/classes/buttons_cls.rs index b6194bbfd..0eea37867 100644 --- a/themes/material/src/classes/buttons_cls.rs +++ b/themes/material/src/classes/buttons_cls.rs @@ -57,9 +57,8 @@ fn filled_button_init(classes: &mut Classes) { .clamp(BTN_40_CLAMP) .into_widget(); - let on_color = Palette::of(BuildCtx::get()).on_of(&color); FatObj::new(base_interactive(w, md::RADIUS_20)) - .foreground(on_color) + .foreground(BuildCtx::color().on_this_color(BuildCtx::get())) .into_widget() } @@ -97,14 +96,17 @@ fn button_init(classes: &mut Classes) { fn fab_common_interactive(w: Widget, radius: Radius, btn_clamp: BoxClamp) -> Widget { let color = BuildCtx::color(); - let p = Palette::of(BuildCtx::get()); let w = FatObj::new(w) - .background(p.container_of(&color)) + .background( + color + .clone() + .into_container_color(BuildCtx::get()), + ) .clamp(btn_clamp) .border_radius(radius); FatObj::new(base_interactive(w.into_widget(), radius)) - .foreground(p.on_container_of(&color)) + .foreground(color.on_this_container_color(BuildCtx::get())) .into_widget() } diff --git a/themes/material/src/classes/checkbox_cls.rs b/themes/material/src/classes/checkbox_cls.rs index 38bb6187d..d5fb56a2a 100644 --- a/themes/material/src/classes/checkbox_cls.rs +++ b/themes/material/src/classes/checkbox_cls.rs @@ -19,7 +19,9 @@ pub(super) fn init(classes: &mut Classes) { .into_widget() }); - fn icon_with_ripple<'w>(icon: Widget<'w>, ripple: Widget<'w>, foreground: Color) -> Widget<'w> { + fn icon_with_ripple<'w>( + icon: Widget<'w>, ripple: Widget<'w>, foreground: Variant, + ) -> Widget<'w> { stack! { margin: md::EDGES_4, foreground, @@ -39,14 +41,13 @@ pub(super) fn init(classes: &mut Classes) { }; fn check_icon_with_ripple<'w>(icon: Widget<'w>, ripple: Widget<'w>) -> Widget<'w> { - let ripple_color = BuildCtx::color(); let icon = container! { size: md::SIZE_18, - background: ripple_color, + background: BuildCtx::color(), border_radius: md::RADIUS_2, @ { icon } }; - icon_with_ripple(icon.into_widget(), ripple, ripple_color) + icon_with_ripple(icon.into_widget(), ripple, BuildCtx::color()) } classes.insert(CHECKBOX_CHECKED, |w| { @@ -71,7 +72,7 @@ pub(super) fn init(classes: &mut Classes) { }; @FatObj { on_mounted: move |_| enter.run(), - foreground: Palette::of(BuildCtx::get()).on_of(&BuildCtx::color()), + foreground: BuildCtx::color().on_this_color(BuildCtx::get()), painting_style: PaintingStyle::Stroke(StrokeOptions { width: 2., ..Default::default() @@ -89,7 +90,7 @@ pub(super) fn init(classes: &mut Classes) { size: Size::new(12., 2.), h_align: HAlign::Center, v_align: VAlign::Center, - background: Palette::of(BuildCtx::get()).on_of(&BuildCtx::color()), + background: BuildCtx::color().on_this_color(BuildCtx::get()), }; let enter = @Animate { state: part_writer!(&mut icon.size), @@ -102,7 +103,6 @@ pub(super) fn init(classes: &mut Classes) { }); classes.insert(CHECKBOX_UNCHECKED, |w| { - let foreground = Palette::of(BuildCtx::get()).on_surface_variant(); let icon = container! { size: md::SIZE_18, border: md::border_2_surface_color(), @@ -111,6 +111,7 @@ pub(super) fn init(classes: &mut Classes) { } .into_widget(); - icon_with_ripple(icon, w, foreground) + let foreground = Palette::of(BuildCtx::get()).on_surface_variant(); + icon_with_ripple(icon, w, Variant::Value(foreground)) }); } diff --git a/themes/material/src/classes/progress_cls.rs b/themes/material/src/classes/progress_cls.rs index c627cd145..10170d9cb 100644 --- a/themes/material/src/classes/progress_cls.rs +++ b/themes/material/src/classes/progress_cls.rs @@ -15,38 +15,30 @@ fn indeterminate_trans() -> Box { .box_it() } -class_names! { - MD_BASE_LINEAR_INDICATOR, - MD_BASE_SPINNER, - MD_BASE_SPINNER_INDICATOR, - MD_BASE_SPINNER_TRACK +fn md_base_spinner(w: Widget, foreground: DeclareInit) -> Widget { + fat_obj! { + foreground, + clamp: BoxClamp::fixed_size(md::SIZE_48), + painting_style: PaintingStyle::Stroke(StrokeOptions { + width: md::THICKNESS_4, + line_cap: LineCap::Round, + ..Default::default() + }), + @ { w } + } + .into_widget() } +named_style_class! { md_base_linear_indicator => { + background: BuildCtx::color(), + border_radius: md::RADIUS_2, +}} + fn lerp_angle(from: &Angle, to: &Angle, rate: f32) -> Angle { let radians = from.radians.lerp(&to.radians, rate); Angle::radians(radians) } pub(super) fn init(classes: &mut Classes) { - classes.insert(MD_BASE_LINEAR_INDICATOR, style_class! { - background: BuildCtx::color(), - border_radius: md::RADIUS_2, - }); - classes.insert(MD_BASE_SPINNER, style_class! { - clamp: BoxClamp::fixed_size(md::SIZE_48), - painting_style: PaintingStyle::Stroke(StrokeOptions { - width: md::THICKNESS_4, - line_cap: LineCap::Round, - ..Default::default() - }), - }); - classes.insert(MD_BASE_SPINNER_INDICATOR, style_class! { - class: MD_BASE_SPINNER, - foreground: BuildCtx::color(), - }); - classes.insert(MD_BASE_SPINNER_TRACK, style_class! { - class: MD_BASE_SPINNER, - foreground: BuildCtx::container_color(), - }); classes.insert(LINEAR_INDETERMINATE_TRACK, style_class! { background: BuildCtx::container_color(), border_radius: md::RADIUS_2, @@ -64,18 +56,18 @@ pub(super) fn init(classes: &mut Classes) { // introduced for the progress. @Container { h_align: HAlign::Right, - class: MD_BASE_LINEAR_INDICATOR, + background: BuildCtx::color(), + border_radius: md::RADIUS_2, size: Size::new(md::THICKNESS_4, md::THICKNESS_4), } } .into_widget() }); classes.insert(LINEAR_DETERMINATE_INDICATOR, move |host| { - let host = FatObj::new(host); smooth_width! { transition: DETERMINATE_TRANS, init_value: 0., - @ $host { class: MD_BASE_LINEAR_INDICATOR } + @md_base_linear_indicator(host) } .into_widget() }); @@ -84,7 +76,6 @@ pub(super) fn init(classes: &mut Classes) { // thus transforming the entire progress into `Row[Indicator, Track, // Indicator, Track]`, adjusting the size of the four children to simulate // the repeated motion. - let host = FatObj::new(host); fn_widget! { let indicator1 = @Expanded { flex: 0.}; let track1 = @Expanded { flex: 0., }; @@ -114,15 +105,16 @@ pub(super) fn init(classes: &mut Classes) { @ $total_fraction { @Row { - @ $indicator1 { @ $host { class: MD_BASE_LINEAR_INDICATOR } } + @ $indicator1 { @md_base_linear_indicator(host) } @ $track1 { @FractionallyWidthBox { class: LINEAR_INDETERMINATE_TRACK } } @ $indicator2 { - @FractionallyWidthBox { - margin: EdgeInsets::only_left(4.), - class: MD_BASE_LINEAR_INDICATOR - } + @md_base_linear_indicator( + @FractionallyWidthBox { + margin: EdgeInsets::only_left(4.), + }.into_widget() + ) } } } @@ -131,7 +123,6 @@ pub(super) fn init(classes: &mut Classes) { }); classes.insert(SPINNER_DETERMINATE, move |w| { - let w = FatObj::new(w); let margin_angle: Angle = Angle::degrees(16.); fn_widget! { let indicator = Provider::of::>(BuildCtx::get()).unwrap(); @@ -158,8 +149,8 @@ pub(super) fn init(classes: &mut Classes) { transform: Transform::translation(-center.width, -center.height) .then_rotate(margin_angle / 2.) .then_translate(center.to_vector()), - @ $track { class: MD_BASE_SPINNER_TRACK } - @ $w { class: MD_BASE_SPINNER_INDICATOR } + @md_base_spinner(track.into_widget(), BuildCtx::container_color().declare_into()) + @md_base_spinner(w, BuildCtx::color().declare_into()) } } @@ -167,7 +158,6 @@ pub(super) fn init(classes: &mut Classes) { }); classes.insert(SPINNER_INDETERMINATE, move |w| { - let w = FatObj::new(w); fn_widget! { let indicator = Provider::of::>(BuildCtx::get()).unwrap(); let pi = Angle::pi(); @@ -186,8 +176,7 @@ pub(super) fn init(classes: &mut Classes) { transition: indeterminate_trans(), from: (Angle::zero(), pi * 0.1), }.run(); - - @ $w { class: MD_BASE_SPINNER_INDICATOR } + @md_base_spinner(w, BuildCtx::color().declare_into()) } .into_widget() }); diff --git a/themes/material/src/classes/radio_cls.rs b/themes/material/src/classes/radio_cls.rs index a7ac99a79..c61404b8b 100644 --- a/themes/material/src/classes/radio_cls.rs +++ b/themes/material/src/classes/radio_cls.rs @@ -18,7 +18,9 @@ pub(super) fn init(classes: &mut Classes) { .into_widget() }); - fn icon_with_ripple<'w>(icon: Widget<'w>, ripple: Widget<'w>, foreground: Color) -> Widget<'w> { + fn icon_with_ripple<'w>( + icon: Widget<'w>, ripple: Widget<'w>, foreground: DeclareInit, + ) -> Widget<'w> { stack! { margin: md::EDGES_4, foreground, @@ -33,11 +35,10 @@ pub(super) fn init(classes: &mut Classes) { } classes.insert(RADIO_SELECTED, |ripple| { - let color = BuildCtx::color(); let icon = rdl! { let w = @Container { size: md::SIZE_10, - background: color, + background: BuildCtx::color(), border_radius: md::RADIUS_5, h_align: HAlign::Center, v_align: VAlign::Center, @@ -59,7 +60,7 @@ pub(super) fn init(classes: &mut Classes) { } }; - icon_with_ripple(icon.into_widget(), ripple, color) + icon_with_ripple(icon.into_widget(), ripple, BuildCtx::color().declare_into()) }); classes.insert(RADIO_UNSELECTED, |ripple| { let foreground = Palette::of(BuildCtx::get()).on_surface_variant(); @@ -68,6 +69,6 @@ pub(super) fn init(classes: &mut Classes) { border: md::border_2_surface_color(), border_radius: md::RADIUS_10, }; - icon_with_ripple(icon.into_widget(), ripple, foreground) + icon_with_ripple(icon.into_widget(), ripple, foreground.declare_into()) }); } diff --git a/themes/material/src/classes/scrollbar_cls.rs b/themes/material/src/classes/scrollbar_cls.rs index c8f9e4ce1..22ce8b61a 100644 --- a/themes/material/src/classes/scrollbar_cls.rs +++ b/themes/material/src/classes/scrollbar_cls.rs @@ -31,6 +31,8 @@ pub(super) fn init(classes: &mut Classes) { classes.insert(V_SCROLL_TRACK, |w| style_track(w, false)); } +fn track_color(w: Color, hovering: bool) -> Color { if hovering { w } else { w.with_alpha(0.) } } + fn style_track(w: Widget, is_hor: bool) -> Widget { rdl! { let mut w = FatObj::new(w); @@ -42,10 +44,10 @@ fn style_track(w: Widget, is_hor: bool) -> Widget { let mut w = @ $w { opacity: 0., visible: false, - background: { - let color = BuildCtx::container_color(); - pipe!(if $w.is_hover() { color } else { color.with_alpha(0.)}) - }, + background: match Variant::::new(BuildCtx::get()).unwrap() { + Variant::Value(c) => pipe!(track_color(c.0, $w.is_hover())).declare_into(), + Variant::Stateful(c) => pipe!(track_color($c.0, $w.is_hover())).declare_into() + } }; let trans = EasingTransition { diff --git a/themes/material/src/classes/slider_cls.rs b/themes/material/src/classes/slider_cls.rs index c82bb37f6..411c8d282 100644 --- a/themes/material/src/classes/slider_cls.rs +++ b/themes/material/src/classes/slider_cls.rs @@ -65,10 +65,10 @@ pub(super) fn init(classes: &mut Classes) { }); classes.insert(STOP_INDICATOR_ACTIVE, stop_indicator_class! { - background: Palette::of(BuildCtx::get()).on_of(&BuildCtx::color()) + background: BuildCtx::color().on_this_color(BuildCtx::get()) }); classes.insert(STOP_INDICATOR_INACTIVE, stop_indicator_class! { - background: Palette::of(BuildCtx::get()).on_container_of(&BuildCtx::color()) + background: BuildCtx::color().on_this_container_color(BuildCtx::get()) }); } diff --git a/themes/material/src/md.rs b/themes/material/src/md.rs index 6212e1f84..923d9859b 100644 --- a/themes/material/src/md.rs +++ b/themes/material/src/md.rs @@ -107,9 +107,8 @@ pub const EDGES_HOR_36: EdgeInsets = EdgeInsets::horizontal(36.); pub const EDGES_HOR_48: EdgeInsets = EdgeInsets::horizontal(48.); // Borders -pub fn border_2() -> Border { - let color = BuildCtx::color(); - Border::all(BorderSide::new(2., color.into())) +pub fn border_2() -> VariantMap Border> { + BuildCtx::color().map(|color| Border::all(BorderSide::new(2., color.into()))) } pub fn border_2_surface_color() -> Border { let surface_variant = Palette::of(BuildCtx::get()).on_surface_variant(); diff --git a/widgets/src/path.rs b/widgets/src/path.rs index 9bfd9bb4d..16eab5bf7 100644 --- a/widgets/src/path.rs +++ b/widgets/src/path.rs @@ -14,16 +14,7 @@ impl Render for PathPaintKit { #[inline] fn only_sized_by_parent(&self) -> bool { true } - fn paint(&self, ctx: &mut PaintingCtx) { - let path = PaintPath::Share(self.path.clone()); - let style = Provider::of::(ctx).map(|p| p.clone()); - let painter = ctx.painter(); - if let Some(PaintingStyle::Stroke(options)) = style { - painter.set_strokes(options).stroke_path(path); - } else { - painter.fill_path(path); - } - } + fn paint(&self, ctx: &mut PaintingCtx) { self.path.paint(ctx); } fn hit_test(&self, _ctx: &mut HitTestCtx, _: Point) -> HitTest { HitTest { hit: false, can_hit_child: false }