use std::fmt::Debug; use super::Space; use crate::styles::{ComponentDefinition, ContextFreeComponent}; use crate::value::{Destination, Dynamic}; use crate::widget::{MakeWidget, WidgetRef, WrapperWidget}; /// A widget that provides access to a [`ComponentDefinition`]'s value through a /// [`Dynamic`]. /// /// This widget enables access to runtime values provided by the theme without /// creating a custom widget. After creating a probe, [`value()`](Self::value) /// can be used to observe and use the value. /// /// The theme information retrieved will be the effective theme at the location /// the probe is inserted in the widget hierarchy. #[derive(Debug)] pub struct ComponentProbe where Component: ComponentDefinition, { component: Component, probed: Dynamic, child: WidgetRef, } impl ComponentProbe where Component: ComponentDefinition, { /// Returns a new probe that provides access to the runtime value of /// `Component`. /// /// The initial contents of the dynamic will be `initial_value`. pub fn new(component: Component, initial_value: Component::ComponentType) -> Self { Self::new_wrapping(component, initial_value, Space::clear()) } /// Returns a new probe wrapping `child` that provides access to the runtime /// value of this component. /// /// The initial contents of the dynamic will be `initial_value`. pub fn new_wrapping( component: Component, initial_value: Component::ComponentType, child: impl MakeWidget, ) -> Self { Self { component, probed: Dynamic::new(initial_value), child: WidgetRef::new(child), } } /// Returns a new probe that provides access to the runtime value of /// `Component`. pub fn default_for(component: Component) -> Self where Component: ContextFreeComponent, { let default = component.default(); Self::new(component, default) } /// Returns a new probe wrapping `child` that provides access to the runtime /// value of this component. pub fn default_wrapping(component: Component, child: impl MakeWidget) -> Self where Component: ContextFreeComponent, { let default = component.default(); Self::new_wrapping(component, default, child) } /// Returns the dynamic that contains the component's current value. /// /// This dynamic's contents will be updated whenever this probe is /// invalidated. pub const fn value(&self) -> &Dynamic { &self.probed } } impl WrapperWidget for ComponentProbe where Component: ComponentDefinition + Debug + Send + 'static, Component::ComponentType: PartialEq + Debug + Send + 'static, { fn child_mut(&mut self) -> &mut crate::widget::WidgetRef { &mut self.child } fn redraw_foreground(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>) { self.probed.set(context.get(&self.component)); } }