diff options
Diffstat (limited to 'examples/pure/component')
| -rw-r--r-- | examples/pure/component/Cargo.toml | 11 | ||||
| -rw-r--r-- | examples/pure/component/src/main.rs | 168 | 
2 files changed, 179 insertions, 0 deletions
| diff --git a/examples/pure/component/Cargo.toml b/examples/pure/component/Cargo.toml new file mode 100644 index 00000000..a15f134f --- /dev/null +++ b/examples/pure/component/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "pure_component" +version = "0.1.0" +authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] +edition = "2021" +publish = false + +[dependencies] +iced = { path = "../../..", features = ["debug", "pure"] } +iced_native = { path = "../../../native" } +iced_lazy = { path = "../../../lazy", features = ["pure"] } diff --git a/examples/pure/component/src/main.rs b/examples/pure/component/src/main.rs new file mode 100644 index 00000000..0de7bdd9 --- /dev/null +++ b/examples/pure/component/src/main.rs @@ -0,0 +1,168 @@ +use iced::pure::widget::container; +use iced::pure::{Element, Sandbox}; +use iced::{Length, Settings}; + +use numeric_input::numeric_input; + +pub fn main() -> iced::Result { +    Component::run(Settings::default()) +} + +#[derive(Default)] +struct Component { +    value: Option<u32>, +} + +#[derive(Debug, Clone, Copy)] +enum Message { +    NumericInputChanged(Option<u32>), +} + +impl Sandbox for Component { +    type Message = Message; + +    fn new() -> Self { +        Self::default() +    } + +    fn title(&self) -> String { +        String::from("Component - Iced") +    } + +    fn update(&mut self, message: Message) { +        match message { +            Message::NumericInputChanged(value) => { +                self.value = value; +            } +        } +    } + +    fn view(&self) -> Element<Message> { +        container(numeric_input(self.value, Message::NumericInputChanged)) +            .padding(20) +            .height(Length::Fill) +            .center_y() +            .into() +    } +} + +mod numeric_input { +    use iced::pure::widget::Element; +    use iced::pure::widget::{row, text, text_input}; +    use iced_lazy::pure::component::{self, Component}; +    use iced_native::alignment::{self, Alignment}; +    use iced_native::text; +    use iced_native::Length; + +    pub struct NumericInput<Message> { +        value: Option<u32>, +        on_change: Box<dyn Fn(Option<u32>) -> Message>, +    } + +    pub fn numeric_input<Message>( +        value: Option<u32>, +        on_change: impl Fn(Option<u32>) -> Message + 'static, +    ) -> NumericInput<Message> { +        NumericInput::new(value, on_change) +    } + +    #[derive(Debug, Clone)] +    pub enum Event { +        InputChanged(String), +        IncrementPressed, +        DecrementPressed, +    } + +    impl<Message> NumericInput<Message> { +        pub fn new( +            value: Option<u32>, +            on_change: impl Fn(Option<u32>) -> Message + 'static, +        ) -> Self { +            Self { +                value, +                on_change: Box::new(on_change), +            } +        } +    } + +    impl<Message, Renderer> Component<Message, Renderer> for NumericInput<Message> +    where +        Renderer: text::Renderer + 'static, +    { +        type State = (); +        type Event = Event; + +        fn update( +            &mut self, +            _state: &mut Self::State, +            event: Event, +        ) -> Option<Message> { +            match event { +                Event::IncrementPressed => Some((self.on_change)(Some( +                    self.value.unwrap_or_default().saturating_add(1), +                ))), +                Event::DecrementPressed => Some((self.on_change)(Some( +                    self.value.unwrap_or_default().saturating_sub(1), +                ))), +                Event::InputChanged(value) => { +                    if value.is_empty() { +                        Some((self.on_change)(None)) +                    } else { +                        value +                            .parse() +                            .ok() +                            .map(Some) +                            .map(self.on_change.as_ref()) +                    } +                } +            } +        } + +        fn view(&self, _state: &Self::State) -> Element<Event, Renderer> { +            let button = |label, on_press| { +                use iced::pure::widget::button; + +                button( +                    text(label) +                        .width(Length::Fill) +                        .height(Length::Fill) +                        .horizontal_alignment(alignment::Horizontal::Center) +                        .vertical_alignment(alignment::Vertical::Center), +                ) +                .width(Length::Units(50)) +                .on_press(on_press) +            }; + +            row() +                .push(button("-", Event::DecrementPressed)) +                .push( +                    text_input( +                        "Type a number", +                        self.value +                            .as_ref() +                            .map(u32::to_string) +                            .as_ref() +                            .map(String::as_str) +                            .unwrap_or(""), +                        Event::InputChanged, +                    ) +                    .padding(10), +                ) +                .push(button("+", Event::IncrementPressed)) +                .align_items(Alignment::Fill) +                .spacing(10) +                .into() +        } +    } + +    impl<'a, Message, Renderer> From<NumericInput<Message>> +        for Element<'a, Message, Renderer> +    where +        Message: 'a, +        Renderer: 'static + text::Renderer, +    { +        fn from(numeric_input: NumericInput<Message>) -> Self { +            component::view(numeric_input) +        } +    } +} | 
