-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add value_container for provide on_update to checkbox (#290)
Co-authored-by: Dongdong Zhou <[email protected]> Co-authored-by: pieterdd <[email protected]>
- Loading branch information
1 parent
ac05875
commit b8ee84c
Showing
6 changed files
with
154 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use std::any::Any; | ||
|
||
use floem_reactive::{create_effect, create_rw_signal, create_updater, RwSignal}; | ||
|
||
use crate::{ | ||
context::UpdateCx, | ||
id::Id, | ||
view::{View, ViewData}, | ||
}; | ||
|
||
/// A wrapper around another View that has value updates. See [`value_container`] | ||
pub struct ValueContainer<T> { | ||
data: ViewData, | ||
child: Box<dyn View>, | ||
on_update: Option<Box<dyn Fn(T)>>, | ||
} | ||
|
||
/// Creates two signals: | ||
/// - The outbound signal enables a widget's internal input event handlers | ||
/// to publish state changes via `ValueContainer::on_update`. | ||
/// - The inbound signal propagates value changes in the producer function | ||
/// into a widget's internals. | ||
pub fn create_value_container_signals<T>( | ||
producer: impl Fn() -> T + 'static, | ||
) -> (RwSignal<T>, RwSignal<T>) | ||
where | ||
T: Copy + 'static, | ||
{ | ||
let initial_value = producer(); | ||
|
||
let inbound_signal = create_rw_signal(initial_value); | ||
create_effect(move |_| { | ||
let checked = producer(); | ||
inbound_signal.set(checked); | ||
}); | ||
|
||
let outbound_signal = create_rw_signal(initial_value); | ||
create_effect(move |_| { | ||
let checked = outbound_signal.get(); | ||
inbound_signal.set(checked); | ||
}); | ||
|
||
(inbound_signal, outbound_signal) | ||
} | ||
|
||
/// A wrapper around another View that has value updates. | ||
/// | ||
/// A [`ValueContainer`] is useful for wrapping another [View](crate::view::View). | ||
/// This is to provide the `on_update` method which can notify when the view's | ||
/// internal value was get changed | ||
pub fn value_container<T: 'static, V: View + 'static>( | ||
child: V, | ||
value_update: impl Fn() -> T + 'static, | ||
) -> ValueContainer<T> { | ||
let id = Id::next(); | ||
create_updater(value_update, move |new_value| id.update_state(new_value)); | ||
ValueContainer { | ||
data: ViewData::new(id), | ||
child: Box::new(child), | ||
on_update: None, | ||
} | ||
} | ||
|
||
impl<T> ValueContainer<T> { | ||
pub fn on_update(mut self, action: impl Fn(T) + 'static) -> Self { | ||
self.on_update = Some(Box::new(action)); | ||
self | ||
} | ||
} | ||
|
||
impl<T: 'static> View for ValueContainer<T> { | ||
fn view_data(&self) -> &ViewData { | ||
&self.data | ||
} | ||
|
||
fn view_data_mut(&mut self) -> &mut ViewData { | ||
&mut self.data | ||
} | ||
|
||
fn update(&mut self, _cx: &mut UpdateCx, state: Box<dyn Any>) { | ||
if let Ok(state) = state.downcast::<T>() { | ||
if let Some(on_update) = self.on_update.as_ref() { | ||
on_update(*state); | ||
} | ||
} | ||
} | ||
|
||
fn for_each_child<'a>(&'a self, for_each: &mut dyn FnMut(&'a dyn View) -> bool) { | ||
for_each(&self.child); | ||
} | ||
|
||
fn for_each_child_mut<'a>(&'a mut self, for_each: &mut dyn FnMut(&'a mut dyn View) -> bool) { | ||
for_each(&mut self.child); | ||
} | ||
|
||
fn for_each_child_rev_mut<'a>( | ||
&'a mut self, | ||
for_each: &mut dyn FnMut(&'a mut dyn View) -> bool, | ||
) { | ||
for_each(&mut self.child); | ||
} | ||
|
||
fn debug_name(&self) -> std::borrow::Cow<'static, str> { | ||
"ValueContainer".into() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters