diff options
Diffstat (limited to 'web/src/widget')
| -rw-r--r-- | web/src/widget/button.rs | 45 | ||||
| -rw-r--r-- | web/src/widget/checkbox.rs | 48 | ||||
| -rw-r--r-- | web/src/widget/column.rs | 36 | ||||
| -rw-r--r-- | web/src/widget/image.rs | 42 | ||||
| -rw-r--r-- | web/src/widget/radio.rs | 49 | ||||
| -rw-r--r-- | web/src/widget/row.rs | 36 | ||||
| -rw-r--r-- | web/src/widget/slider.rs | 62 | ||||
| -rw-r--r-- | web/src/widget/text.rs | 29 | 
8 files changed, 347 insertions, 0 deletions
| diff --git a/web/src/widget/button.rs b/web/src/widget/button.rs new file mode 100644 index 00000000..23a4165a --- /dev/null +++ b/web/src/widget/button.rs @@ -0,0 +1,45 @@ +use crate::{Bus, Element, Widget}; + +use dodrio::bumpalo; + +pub use iced_core::button::*; + +impl<'a, Message> Widget<Message> for Button<'a, Message> +where +    Message: 'static + Copy, +{ +    fn node<'b>( +        &self, +        bump: &'b bumpalo::Bump, +        bus: &Bus<Message>, +    ) -> dodrio::Node<'b> { +        use dodrio::builder::*; + +        let label = bumpalo::format!(in bump, "{}", self.label); + +        let mut node = button(bump).children(vec![text(label.into_bump_str())]); + +        if let Some(on_press) = self.on_press { +            let event_bus = bus.clone(); + +            node = node.on("click", move |root, vdom, _event| { +                event_bus.publish(on_press, root); + +                vdom.schedule_render(); +            }); +        } + +        // TODO: Complete styling + +        node.finish() +    } +} + +impl<'a, Message> From<Button<'a, Message>> for Element<'a, Message> +where +    Message: 'static + Copy, +{ +    fn from(button: Button<'a, Message>) -> Element<'a, Message> { +        Element::new(button) +    } +} diff --git a/web/src/widget/checkbox.rs b/web/src/widget/checkbox.rs new file mode 100644 index 00000000..72f0a2aa --- /dev/null +++ b/web/src/widget/checkbox.rs @@ -0,0 +1,48 @@ +use crate::{Bus, Element, Widget}; + +use dodrio::bumpalo; + +pub use iced_core::Checkbox; + +impl<Message> Widget<Message> for Checkbox<Message> +where +    Message: 'static + Copy, +{ +    fn node<'b>( +        &self, +        bump: &'b bumpalo::Bump, +        bus: &Bus<Message>, +    ) -> dodrio::Node<'b> { +        use dodrio::builder::*; + +        let checkbox_label = bumpalo::format!(in bump, "{}", self.label); + +        let event_bus = bus.clone(); +        let msg = (self.on_toggle)(!self.is_checked); + +        // TODO: Complete styling +        label(bump) +            .children(vec![ +                input(bump) +                    .attr("type", "checkbox") +                    .bool_attr("checked", self.is_checked) +                    .on("click", move |root, vdom, _event| { +                        event_bus.publish(msg, root); + +                        vdom.schedule_render(); +                    }) +                    .finish(), +                text(checkbox_label.into_bump_str()), +            ]) +            .finish() +    } +} + +impl<'a, Message> From<Checkbox<Message>> for Element<'a, Message> +where +    Message: 'static + Copy, +{ +    fn from(checkbox: Checkbox<Message>) -> Element<'a, Message> { +        Element::new(checkbox) +    } +} diff --git a/web/src/widget/column.rs b/web/src/widget/column.rs new file mode 100644 index 00000000..becd6bc6 --- /dev/null +++ b/web/src/widget/column.rs @@ -0,0 +1,36 @@ +use crate::{Bus, Element, Widget}; + +use dodrio::bumpalo; + +pub type Column<'a, Message> = iced_core::Column<Element<'a, Message>>; + +impl<'a, Message> Widget<Message> for Column<'a, Message> { +    fn node<'b>( +        &self, +        bump: &'b bumpalo::Bump, +        publish: &Bus<Message>, +    ) -> dodrio::Node<'b> { +        use dodrio::builder::*; + +        let children: Vec<_> = self +            .children +            .iter() +            .map(|element| element.widget.node(bump, publish)) +            .collect(); + +        // TODO: Complete styling +        div(bump) +            .attr("style", "display: flex; flex-direction: column") +            .children(children) +            .finish() +    } +} + +impl<'a, Message> From<Column<'a, Message>> for Element<'a, Message> +where +    Message: 'static, +{ +    fn from(column: Column<'a, Message>) -> Element<'a, Message> { +        Element::new(column) +    } +} diff --git a/web/src/widget/image.rs b/web/src/widget/image.rs new file mode 100644 index 00000000..fd4ff0df --- /dev/null +++ b/web/src/widget/image.rs @@ -0,0 +1,42 @@ +use crate::{Bus, Element, Length, Widget}; + +use dodrio::bumpalo; + +pub type Image<'a> = iced_core::Image<&'a str>; + +impl<'a, Message> Widget<Message> for Image<'a> { +    fn node<'b>( +        &self, +        bump: &'b bumpalo::Bump, +        _bus: &Bus<Message>, +    ) -> dodrio::Node<'b> { +        use dodrio::builder::*; + +        let src = bumpalo::format!(in bump, "{}", self.handle); + +        let mut image = img(bump).attr("src", src.into_bump_str()); + +        match self.width { +            Length::Shrink => {} +            Length::Fill => { +                image = image.attr("width", "100%"); +            } +            Length::Units(px) => { +                image = image.attr( +                    "width", +                    bumpalo::format!(in bump, "{}px", px).into_bump_str(), +                ); +            } +        } + +        // TODO: Complete styling + +        image.finish() +    } +} + +impl<'a, Message> From<Image<'a>> for Element<'a, Message> { +    fn from(image: Image<'a>) -> Element<'a, Message> { +        Element::new(image) +    } +} diff --git a/web/src/widget/radio.rs b/web/src/widget/radio.rs new file mode 100644 index 00000000..d249ad26 --- /dev/null +++ b/web/src/widget/radio.rs @@ -0,0 +1,49 @@ +use crate::{Bus, Element, Widget}; + +use dodrio::bumpalo; + +pub use iced_core::Radio; + +impl<Message> Widget<Message> for Radio<Message> +where +    Message: 'static + Copy, +{ +    fn node<'b>( +        &self, +        bump: &'b bumpalo::Bump, +        bus: &Bus<Message>, +    ) -> dodrio::Node<'b> { +        use dodrio::builder::*; + +        let radio_label = bumpalo::format!(in bump, "{}", self.label); + +        let event_bus = bus.clone(); +        let on_click = self.on_click; + +        // TODO: Complete styling +        label(bump) +            .attr("style", "display: block") +            .children(vec![ +                input(bump) +                    .attr("type", "radio") +                    .bool_attr("checked", self.is_selected) +                    .on("click", move |root, vdom, _event| { +                        event_bus.publish(on_click, root); + +                        vdom.schedule_render(); +                    }) +                    .finish(), +                text(radio_label.into_bump_str()), +            ]) +            .finish() +    } +} + +impl<'a, Message> From<Radio<Message>> for Element<'a, Message> +where +    Message: 'static + Copy, +{ +    fn from(radio: Radio<Message>) -> Element<'a, Message> { +        Element::new(radio) +    } +} diff --git a/web/src/widget/row.rs b/web/src/widget/row.rs new file mode 100644 index 00000000..cf6ae594 --- /dev/null +++ b/web/src/widget/row.rs @@ -0,0 +1,36 @@ +use crate::{Bus, Element, Widget}; + +use dodrio::bumpalo; + +pub type Row<'a, Message> = iced_core::Row<Element<'a, Message>>; + +impl<'a, Message> Widget<Message> for Row<'a, Message> { +    fn node<'b>( +        &self, +        bump: &'b bumpalo::Bump, +        publish: &Bus<Message>, +    ) -> dodrio::Node<'b> { +        use dodrio::builder::*; + +        let children: Vec<_> = self +            .children +            .iter() +            .map(|element| element.widget.node(bump, publish)) +            .collect(); + +        // TODO: Complete styling +        div(bump) +            .attr("style", "display: flex; flex-direction: row") +            .children(children) +            .finish() +    } +} + +impl<'a, Message> From<Row<'a, Message>> for Element<'a, Message> +where +    Message: 'static, +{ +    fn from(column: Row<'a, Message>) -> Element<'a, Message> { +        Element::new(column) +    } +} diff --git a/web/src/widget/slider.rs b/web/src/widget/slider.rs new file mode 100644 index 00000000..54b2fdf6 --- /dev/null +++ b/web/src/widget/slider.rs @@ -0,0 +1,62 @@ +use crate::{Bus, Element, Widget}; + +use dodrio::bumpalo; + +pub use iced_core::slider::*; + +impl<'a, Message> Widget<Message> for Slider<'a, Message> +where +    Message: 'static + Copy, +{ +    fn node<'b>( +        &self, +        bump: &'b bumpalo::Bump, +        bus: &Bus<Message>, +    ) -> dodrio::Node<'b> { +        use dodrio::builder::*; +        use wasm_bindgen::JsCast; + +        let (start, end) = self.range.clone().into_inner(); + +        let min = bumpalo::format!(in bump, "{}", start); +        let max = bumpalo::format!(in bump, "{}", end); +        let value = bumpalo::format!(in bump, "{}", self.value); + +        let on_change = self.on_change.clone(); +        let event_bus = bus.clone(); + +        // TODO: Make `step` configurable +        // TODO: Complete styling +        label(bump) +            .children(vec![input(bump) +                .attr("type", "range") +                .attr("step", "0.01") +                .attr("min", min.into_bump_str()) +                .attr("max", max.into_bump_str()) +                .attr("value", value.into_bump_str()) +                .on("input", move |root, vdom, event| { +                    let slider = match event.target().and_then(|t| { +                        t.dyn_into::<web_sys::HtmlInputElement>().ok() +                    }) { +                        None => return, +                        Some(slider) => slider, +                    }; + +                    if let Ok(value) = slider.value().parse::<f32>() { +                        event_bus.publish(on_change(value), root); +                        vdom.schedule_render(); +                    } +                }) +                .finish()]) +            .finish() +    } +} + +impl<'a, Message> From<Slider<'a, Message>> for Element<'a, Message> +where +    Message: 'static + Copy, +{ +    fn from(slider: Slider<'a, Message>) -> Element<'a, Message> { +        Element::new(slider) +    } +} diff --git a/web/src/widget/text.rs b/web/src/widget/text.rs new file mode 100644 index 00000000..41ccd6fc --- /dev/null +++ b/web/src/widget/text.rs @@ -0,0 +1,29 @@ +use crate::{Bus, Element, Widget}; +use dodrio::bumpalo; + +pub use iced_core::text::*; + +impl<'a, Message> Widget<Message> for Text { +    fn node<'b>( +        &self, +        bump: &'b bumpalo::Bump, +        _publish: &Bus<Message>, +    ) -> dodrio::Node<'b> { +        use dodrio::builder::*; + +        let content = bumpalo::format!(in bump, "{}", self.content); +        let size = bumpalo::format!(in bump, "font-size: {}px", self.size.unwrap_or(20)); + +        // TODO: Complete styling +        p(bump) +            .attr("style", size.into_bump_str()) +            .children(vec![text(content.into_bump_str())]) +            .finish() +    } +} + +impl<'a, Message> From<Text> for Element<'a, Message> { +    fn from(text: Text) -> Element<'a, Message> { +        Element::new(text) +    } +} | 
