diff options
-rw-r--r-- | graphics/src/image/storage.rs | 2 | ||||
-rw-r--r-- | lazy/src/component.rs | 35 | ||||
-rw-r--r-- | native/src/widget/helpers.rs | 2 | ||||
-rw-r--r-- | native/src/widget/toggler.rs | 18 |
4 files changed, 46 insertions, 11 deletions
diff --git a/graphics/src/image/storage.rs b/graphics/src/image/storage.rs index 2098c7b2..1b5b5c35 100644 --- a/graphics/src/image/storage.rs +++ b/graphics/src/image/storage.rs @@ -20,7 +20,7 @@ pub trait Storage { state: &mut Self::State<'_>, ) -> Option<Self::Entry>; - /// Romve a [`Self::Entry`] from the [`Storage`]. + /// Remove a [`Self::Entry`] from the [`Storage`]. fn remove(&mut self, entry: &Self::Entry, state: &mut Self::State<'_>); } diff --git a/lazy/src/component.rs b/lazy/src/component.rs index ad15d69d..d8f21f8a 100644 --- a/lazy/src/component.rs +++ b/lazy/src/component.rs @@ -46,6 +46,16 @@ pub trait Component<Message, Renderer> { /// Produces the widgets of the [`Component`], which may trigger an [`Event`](Component::Event) /// on user interaction. fn view(&self, state: &Self::State) -> Element<'_, Self::Event, Renderer>; + + /// Update the [`Component`] state based on the provided [`Operation`](widget::Operation) + /// + /// By default, it does nothing. + fn operate( + &self, + _state: &mut Self::State, + _operation: &mut dyn widget::Operation<Message>, + ) { + } } /// Turns an implementor of [`Component`] into an [`Element`] that can be @@ -106,6 +116,26 @@ where ); } + fn rebuild_element_with_operation( + &self, + state: &mut S, + operation: &mut dyn widget::Operation<Message>, + ) { + let heads = self.state.borrow_mut().take().unwrap().into_heads(); + + heads.component.operate(state, operation); + + *self.state.borrow_mut() = Some( + StateBuilder { + component: heads.component, + message: PhantomData, + state: PhantomData, + element_builder: |component| Some(component.view(state)), + } + .build(), + ); + } + fn with_element<T>( &self, f: impl FnOnce(&Element<'_, Event, Renderer>) -> T, @@ -237,6 +267,11 @@ where renderer: &Renderer, operation: &mut dyn widget::Operation<Message>, ) { + self.rebuild_element_with_operation( + tree.state.downcast_mut(), + operation, + ); + struct MapOperation<'a, B> { operation: &'a mut dyn widget::Operation<B>, } diff --git a/native/src/widget/helpers.rs b/native/src/widget/helpers.rs index 8cc1ae82..5b241f83 100644 --- a/native/src/widget/helpers.rs +++ b/native/src/widget/helpers.rs @@ -162,7 +162,7 @@ where Renderer: crate::text::Renderer, Renderer::Theme: widget::toggler::StyleSheet, { - widget::Toggler::new(is_checked, label, f) + widget::Toggler::new(label, is_checked, f) } /// Creates a new [`TextInput`]. diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index 1ae65ba6..f0a944a3 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -24,9 +24,9 @@ pub use iced_style::toggler::{Appearance, StyleSheet}; /// TogglerToggled(bool), /// } /// -/// let is_active = true; +/// let is_toggled = true; /// -/// Toggler::new(is_active, String::from("Toggle me!"), |b| Message::TogglerToggled(b)); +/// Toggler::new(String::from("Toggle me!"), is_toggled, |b| Message::TogglerToggled(b)); /// ``` #[allow(missing_debug_implementations)] pub struct Toggler<'a, Message, Renderer> @@ -34,7 +34,7 @@ where Renderer: text::Renderer, Renderer::Theme: StyleSheet, { - is_active: bool, + is_toggled: bool, on_toggle: Box<dyn Fn(bool) -> Message + 'a>, label: Option<String>, width: Length, @@ -63,15 +63,15 @@ where /// will receive the new state of the [`Toggler`] and must produce a /// `Message`. pub fn new<F>( - is_active: bool, label: impl Into<Option<String>>, + is_toggled: bool, f: F, ) -> Self where F: 'a + Fn(bool) -> Message, { Toggler { - is_active, + is_toggled, on_toggle: Box::new(f), label: label.into(), width: Length::Fill, @@ -193,7 +193,7 @@ where let mouse_over = layout.bounds().contains(cursor_position); if mouse_over { - shell.publish((self.on_toggle)(!self.is_active)); + shell.publish((self.on_toggle)(!self.is_toggled)); event::Status::Captured } else { @@ -260,9 +260,9 @@ where let is_mouse_over = bounds.contains(cursor_position); let style = if is_mouse_over { - theme.hovered(&self.style, self.is_active) + theme.hovered(&self.style, self.is_toggled) } else { - theme.active(&self.style, self.is_active) + theme.active(&self.style, self.is_toggled) }; let border_radius = bounds.height / BORDER_RADIUS_RATIO; @@ -289,7 +289,7 @@ where let toggler_foreground_bounds = Rectangle { x: bounds.x - + if self.is_active { + + if self.is_toggled { bounds.width - 2.0 * space - (bounds.height - (4.0 * space)) } else { 2.0 * space |