From ea7ab5e4f1d47d67dc28124daa0ec084b3913993 Mon Sep 17 00:00:00 2001 From: edouard Date: Fri, 25 Nov 2022 19:06:33 +0100 Subject: [PATCH] Reintroduce ui component: collapse --- gui/src/ui/component/collapse.rs | 92 ++++++++++++++++++++++++++++++++ gui/src/ui/component/mod.rs | 1 + 2 files changed, 93 insertions(+) create mode 100644 gui/src/ui/component/collapse.rs diff --git a/gui/src/ui/component/collapse.rs b/gui/src/ui/component/collapse.rs new file mode 100644 index 00000000..480e6c38 --- /dev/null +++ b/gui/src/ui/component/collapse.rs @@ -0,0 +1,92 @@ +use iced::{ + widget::{Button, Column}, + Element, +}; +use iced_lazy::{self, Component}; +use std::marker::PhantomData; + +use super::button::Style; + +pub fn collapse< + 'a, + Message: 'a, + T: Into + Clone + 'a, + H: Fn() -> Element<'a, T> + 'a, + C: Fn() -> Element<'a, T> + 'a, +>( + header: H, + content: C, +) -> impl Into> { + Collapse { + header, + content, + phantom: PhantomData, + } +} + +struct Collapse<'a, H, C> { + header: H, + content: C, + phantom: PhantomData<&'a H>, +} + +#[derive(Debug, Clone, Copy)] +enum Event { + Internal(T), + Collapse(bool), +} + +impl<'a, Message, T, H, C> Component for Collapse<'a, H, C> +where + T: Into + Clone + 'a, + H: Fn() -> Element<'a, T>, + C: Fn() -> Element<'a, T>, +{ + type State = bool; + type Event = Event; + + fn update(&mut self, state: &mut Self::State, event: Event) -> Option { + match event { + Event::Internal(e) => Some(e.into()), + Event::Collapse(s) => { + *state = s; + None + } + } + } + + fn view(&self, state: &Self::State) -> Element { + if *state { + Column::new() + .push( + Button::new((self.header)().map(Event::Internal)) + .style(Style::TransparentBorder.into()) + .padding(10) + .on_press(Event::Collapse(false)), + ) + .push((self.content)().map(Event::Internal)) + .into() + } else { + Column::new() + .push( + Button::new((self.header)().map(Event::Internal)) + .style(Style::TransparentBorder.into()) + .padding(10) + .on_press(Event::Collapse(true)), + ) + .into() + } + } +} + +impl<'a, Message, T, H: 'a, C: 'a> From> for Element<'a, Message> +where + Message: 'a, + T: Into + Clone + 'a, + H: Fn() -> Element<'a, T, iced::Renderer>, + C: Fn() -> Element<'a, T, iced::Renderer>, +{ + fn from(c: Collapse<'a, H, C>) -> Self { + iced_lazy::component(c) + } +} diff --git a/gui/src/ui/component/mod.rs b/gui/src/ui/component/mod.rs index ac7abdfb..381f6563 100644 --- a/gui/src/ui/component/mod.rs +++ b/gui/src/ui/component/mod.rs @@ -1,6 +1,7 @@ pub mod badge; pub mod button; pub mod card; +pub mod collapse; pub mod container; pub mod form; pub mod notification;