Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
lib: Improve update callback prorperties
Erik Kundt committed 2 years ago
commit ec63bc50f6f2e760199b4fc887fdad93de7e5fa1
parent 7e1237eb3285c492ce70b1306ba8b4ee4402000a
4 files changed +67 -58
modified src/ui/widget.rs
@@ -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());
        }
    }
}
modified src/ui/widget/container.rs
@@ -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);
modified src/ui/widget/input.rs
@@ -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());
        }
    }
}
modified src/ui/widget/text.rs
@@ -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());
        }
    }
}