mirror of
https://seed.radicle.dev/rad:z39mP9rQAaGmERfUMPULfPUi473tY.git
synced 2026-11-03 18:30:41 +08:00
lib: Improve update callback prorperties
This commit is contained in:
+35
-22
@@ -32,7 +32,7 @@ pub trait View<S, A> {
|
||||
Self: Sized;
|
||||
|
||||
/// Should set the optional custom event handler.
|
||||
fn on_change(self, callback: EventCallback<A>) -> Self
|
||||
fn on_event(self, callback: EventCallback<A>) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
@@ -51,12 +51,20 @@ pub trait View<S, A> {
|
||||
|
||||
/// Should handle key events and call `handle_key_event` on all children.
|
||||
///
|
||||
/// After key events have been handled, the custom event handler `on_change` should
|
||||
/// After key events have been handled, the custom event handler `on_event` should
|
||||
/// be called
|
||||
fn handle_key_event(&mut self, key: Key);
|
||||
|
||||
/// Should update internal props by calling the custom update handler `on_update`
|
||||
/// and call `update` on all children.
|
||||
/// Should update the internal props of this and all children.
|
||||
///
|
||||
/// Applications are usually defined by app-specific widgets that do know
|
||||
/// the type of `state`. These can use widgets from the library that do not know the
|
||||
/// type of `state`.
|
||||
///
|
||||
/// If `on_update` is set, implementators of this function should call it to
|
||||
/// construct and update the internal props. If it is not set, app widgets can construct
|
||||
/// prosp directly via their state converters, whereas library widgets can just fallback
|
||||
/// to their current props.
|
||||
fn update(&mut self, state: &S);
|
||||
}
|
||||
|
||||
@@ -93,6 +101,15 @@ pub trait Properties {
|
||||
{
|
||||
any.downcast_ref::<Self>().cloned()
|
||||
}
|
||||
|
||||
fn from_callback<S>(callback: Option<UpdateCallback<S>>, state: &S) -> Option<Self>
|
||||
where
|
||||
Self: Sized + Clone + 'static,
|
||||
{
|
||||
callback
|
||||
.map(|callback| (callback)(state))
|
||||
.and_then(|props| Self::from_boxed_any(props))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -135,7 +152,7 @@ pub struct Shortcuts<S, A> {
|
||||
/// Custom update handler
|
||||
on_update: Option<UpdateCallback<S>>,
|
||||
/// Additional custom event handler
|
||||
on_change: Option<EventCallback<A>>,
|
||||
on_event: Option<EventCallback<A>>,
|
||||
}
|
||||
|
||||
impl<S, A> Shortcuts<S, A> {
|
||||
@@ -161,12 +178,12 @@ impl<S, A> View<S, A> for Shortcuts<S, A> {
|
||||
_action_tx: action_tx.clone(),
|
||||
props: ShortcutsProps::default(),
|
||||
on_update: None,
|
||||
on_change: None,
|
||||
on_event: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn on_change(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_change = Some(callback);
|
||||
fn on_event(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_event = Some(callback);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -178,10 +195,8 @@ impl<S, A> View<S, A> for Shortcuts<S, A> {
|
||||
fn handle_key_event(&mut self, _key: Key) {}
|
||||
|
||||
fn update(&mut self, state: &S) {
|
||||
self.props = self
|
||||
.on_update
|
||||
.and_then(|on_update| ShortcutsProps::from_boxed_any((on_update)(state)))
|
||||
.unwrap_or(self.props.clone())
|
||||
self.props =
|
||||
ShortcutsProps::from_callback(self.on_update, state).unwrap_or(self.props.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,7 +350,7 @@ where
|
||||
/// Custom update handler
|
||||
on_update: Option<UpdateCallback<S>>,
|
||||
/// Additional custom event handler
|
||||
on_change: Option<EventCallback<A>>,
|
||||
on_event: Option<EventCallback<A>>,
|
||||
/// Internal selection and offset state
|
||||
state: TableState,
|
||||
}
|
||||
@@ -405,7 +420,7 @@ where
|
||||
props: TableProps::default(),
|
||||
state: TableState::default().with_selected(Some(0)),
|
||||
on_update: None,
|
||||
on_change: None,
|
||||
on_event: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,16 +429,14 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
fn on_change(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_change = Some(callback);
|
||||
fn on_event(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_event = Some(callback);
|
||||
self
|
||||
}
|
||||
|
||||
fn update(&mut self, state: &S) {
|
||||
self.props = self
|
||||
.on_update
|
||||
.and_then(|on_update| TableProps::<'_, R>::from_boxed_any((on_update)(state)))
|
||||
.unwrap_or(self.props.clone());
|
||||
self.props =
|
||||
TableProps::<'_, R>::from_callback(self.on_update, state).unwrap_or(self.props.clone());
|
||||
|
||||
// TODO: Move to state reducer
|
||||
if let Some(selected) = self.state.selected() {
|
||||
@@ -458,8 +471,8 @@ where
|
||||
|
||||
self.props.selected = self.state.selected();
|
||||
|
||||
if let Some(on_change) = self.on_change {
|
||||
(on_change)(&self.state, self.action_tx.clone());
|
||||
if let Some(on_event) = self.on_event {
|
||||
(on_event)(&self.state, self.action_tx.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-20
@@ -60,7 +60,7 @@ pub struct Header<'a, S, A> {
|
||||
/// Custom update handler
|
||||
on_update: Option<UpdateCallback<S>>,
|
||||
/// Additional custom event handler
|
||||
on_change: Option<EventCallback<A>>,
|
||||
on_event: Option<EventCallback<A>>,
|
||||
}
|
||||
|
||||
impl<'a, S, A> Header<'a, S, A> {
|
||||
@@ -87,7 +87,7 @@ impl<'a: 'static, S, A> View<S, A> for Header<'a, S, A> {
|
||||
action_tx: action_tx.clone(),
|
||||
props: HeaderProps::default(),
|
||||
on_update: None,
|
||||
on_change: None,
|
||||
on_event: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ impl<'a: 'static, S, A> View<S, A> for Header<'a, S, A> {
|
||||
self
|
||||
}
|
||||
|
||||
fn on_change(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_change = Some(callback);
|
||||
fn on_event(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_event = Some(callback);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -109,8 +109,8 @@ impl<'a: 'static, S, A> View<S, A> for Header<'a, S, A> {
|
||||
}
|
||||
|
||||
fn handle_key_event(&mut self, _key: Key) {
|
||||
if let Some(on_change) = self.on_change {
|
||||
(on_change)(&self.props, self.action_tx.clone());
|
||||
if let Some(on_event) = self.on_event {
|
||||
(on_event)(&self.props, self.action_tx.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,7 +224,7 @@ pub struct Footer<'a, S, A> {
|
||||
/// Custom update handler
|
||||
on_update: Option<UpdateCallback<S>>,
|
||||
/// Additional custom event handler
|
||||
on_change: Option<EventCallback<A>>,
|
||||
on_event: Option<EventCallback<A>>,
|
||||
}
|
||||
|
||||
impl<'a, S, A> Footer<'a, S, A> {
|
||||
@@ -251,7 +251,7 @@ impl<'a: 'static, S, A> View<S, A> for Footer<'a, S, A> {
|
||||
action_tx: action_tx.clone(),
|
||||
props: FooterProps::default(),
|
||||
on_update: None,
|
||||
on_change: None,
|
||||
on_event: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,8 +260,8 @@ impl<'a: 'static, S, A> View<S, A> for Footer<'a, S, A> {
|
||||
self
|
||||
}
|
||||
|
||||
fn on_change(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_change = Some(callback);
|
||||
fn on_event(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_event = Some(callback);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -273,8 +273,8 @@ impl<'a: 'static, S, A> View<S, A> for Footer<'a, S, A> {
|
||||
}
|
||||
|
||||
fn handle_key_event(&mut self, _key: Key) {
|
||||
if let Some(on_change) = self.on_change {
|
||||
(on_change)(&self.props, self.action_tx.clone());
|
||||
if let Some(on_event) = self.on_event {
|
||||
(on_event)(&self.props, self.action_tx.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,7 +375,7 @@ where
|
||||
/// Custom update handler
|
||||
on_update: Option<UpdateCallback<S>>,
|
||||
/// Additional custom event handler
|
||||
on_change: Option<EventCallback<A>>,
|
||||
on_event: Option<EventCallback<A>>,
|
||||
/// Container header
|
||||
header: Option<BoxedWidget<B, S, A>>,
|
||||
/// Content widget
|
||||
@@ -419,7 +419,7 @@ where
|
||||
content: None,
|
||||
footer: None,
|
||||
on_update: None,
|
||||
on_change: None,
|
||||
on_event: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,16 +428,14 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
fn on_change(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_change = Some(callback);
|
||||
fn on_event(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_event = Some(callback);
|
||||
self
|
||||
}
|
||||
|
||||
fn update(&mut self, state: &S) {
|
||||
self.props = self
|
||||
.on_update
|
||||
.and_then(|on_update| ContainerProps::from_boxed_any((on_update)(state)))
|
||||
.unwrap_or(self.props.clone());
|
||||
self.props =
|
||||
ContainerProps::from_callback(self.on_update, state).unwrap_or(self.props.clone());
|
||||
|
||||
if let Some(header) = &mut self.header {
|
||||
header.update(state);
|
||||
|
||||
@@ -63,7 +63,7 @@ pub struct TextField<S, A> {
|
||||
/// Custom update handler
|
||||
on_update: Option<UpdateCallback<S>>,
|
||||
/// Additional custom event handler
|
||||
on_change: Option<EventCallback<A>>,
|
||||
on_event: Option<EventCallback<A>>,
|
||||
/// Internal state
|
||||
state: TextFieldState,
|
||||
}
|
||||
@@ -136,7 +136,7 @@ impl<S, A> View<S, A> for TextField<S, A> {
|
||||
action_tx,
|
||||
props: TextFieldProps::default(),
|
||||
on_update: None,
|
||||
on_change: None,
|
||||
on_event: None,
|
||||
state: TextFieldState {
|
||||
text: None,
|
||||
cursor_position: 0,
|
||||
@@ -149,8 +149,8 @@ impl<S, A> View<S, A> for TextField<S, A> {
|
||||
self
|
||||
}
|
||||
|
||||
fn on_change(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_change = Some(callback);
|
||||
fn on_event(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_event = Some(callback);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -188,8 +188,8 @@ impl<S, A> View<S, A> for TextField<S, A> {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(on_change) = self.on_change {
|
||||
(on_change)(&self.state, self.action_tx.clone());
|
||||
if let Some(on_event) = self.on_event {
|
||||
(on_event)(&self.state, self.action_tx.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -67,7 +67,7 @@ pub struct Paragraph<'a, S, A> {
|
||||
/// Custom update handler
|
||||
on_update: Option<UpdateCallback<S>>,
|
||||
/// Additional custom event handler
|
||||
on_change: Option<EventCallback<A>>,
|
||||
on_event: Option<EventCallback<A>>,
|
||||
/// Internal state
|
||||
state: ParagraphState,
|
||||
}
|
||||
@@ -155,7 +155,7 @@ impl<'a: 'static, S, A> View<S, A> for Paragraph<'a, S, A> {
|
||||
action_tx: action_tx.clone(),
|
||||
props: ParagraphProps::default(),
|
||||
on_update: None,
|
||||
on_change: None,
|
||||
on_event: None,
|
||||
state: ParagraphState {
|
||||
offset: 0,
|
||||
progress: 0,
|
||||
@@ -163,8 +163,8 @@ impl<'a: 'static, S, A> View<S, A> for Paragraph<'a, S, A> {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_change(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_change = Some(callback);
|
||||
fn on_event(mut self, callback: EventCallback<A>) -> Self {
|
||||
self.on_event = Some(callback);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -174,10 +174,8 @@ impl<'a: 'static, S, A> View<S, A> for Paragraph<'a, S, A> {
|
||||
}
|
||||
|
||||
fn update(&mut self, state: &S) {
|
||||
self.props = self
|
||||
.on_update
|
||||
.and_then(|on_update| ParagraphProps::from_boxed_any((on_update)(state)))
|
||||
.unwrap_or(self.props.clone());
|
||||
self.props =
|
||||
ParagraphProps::from_callback(self.on_update, state).unwrap_or(self.props.clone());
|
||||
}
|
||||
|
||||
fn handle_key_event(&mut self, key: Key) {
|
||||
@@ -206,8 +204,8 @@ impl<'a: 'static, S, A> View<S, A> for Paragraph<'a, S, A> {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(on_change) = self.on_change {
|
||||
(on_change)(&self.state, self.action_tx.clone());
|
||||
if let Some(on_event) = self.on_event {
|
||||
(on_event)(&self.state, self.action_tx.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user