diff options
| author | 2020-01-01 15:44:32 -0700 | |
|---|---|---|
| committer | 2020-01-01 22:45:29 -0700 | |
| commit | 0d620b7701f427ed0091f3640ab9ca0e116eb412 (patch) | |
| tree | 6bd8a4cdd03643e4eca4dfe777a5e819643b1cec /examples/geometry | |
| parent | 26de688e68347e1f6e388d01014eac89cea71afa (diff) | |
| download | iced-0d620b7701f427ed0091f3640ab9ca0e116eb412.tar.gz iced-0d620b7701f427ed0091f3640ab9ca0e116eb412.tar.bz2 iced-0d620b7701f427ed0091f3640ab9ca0e116eb412.zip | |
Implement Geometry2D primitive
Diffstat (limited to '')
| -rw-r--r-- | examples/geometry.rs | 227 | 
1 files changed, 227 insertions, 0 deletions
| diff --git a/examples/geometry.rs b/examples/geometry.rs new file mode 100644 index 00000000..feb7684e --- /dev/null +++ b/examples/geometry.rs @@ -0,0 +1,227 @@ +//! This example showcases a simple native custom widget that renders using +//! arbitrary low-level geometry. +mod rainbow { +    // For now, to implement a custom native widget you will need to add +    // `iced_native` and `iced_wgpu` to your dependencies. +    // +    // Then, you simply need to define your widget type and implement the +    // `iced_native::Widget` trait with the `iced_wgpu::Renderer`. +    // +    // Of course, you can choose to make the implementation renderer-agnostic, +    // if you wish to, by creating your own `Renderer` trait, which could be +    // implemented by `iced_wgpu` and other renderers. +    use iced_native::{ +        layout,  Element, Geometry2D, Hasher, Layout, Length, +        MouseCursor, Point, Size, Vertex2D, Widget, +    }; +    use iced_wgpu::{Primitive, Renderer}; + +    pub struct Rainbow { +        dimen: u16, +    } + +    impl Rainbow { +        pub fn new(dimen: u16) -> Self { +            Self { dimen } +        } +    } + +    impl<Message> Widget<Message, Renderer> for Rainbow { +        fn width(&self) -> Length { +            Length::Shrink +        } + +        fn height(&self) -> Length { +            Length::Shrink +        } + +        fn layout( +            &self, +            _renderer: &Renderer, +            _limits: &layout::Limits, +        ) -> layout::Node { +            layout::Node::new(Size::new( +                f32::from(self.dimen), +                f32::from(self.dimen), +            )) +        } + +        fn hash_layout(&self, state: &mut Hasher) { +            use std::hash::Hash; + +            self.dimen.hash(state); +        } + +        fn draw( +            &self, +            _renderer: &mut Renderer, +            layout: Layout<'_>, +            cursor_position: Point, +        ) -> (Primitive, MouseCursor) { +            let b = layout.bounds(); + +            // R O Y G B I V +            let color_r = [1.0, 0.0, 0.0, 1.0]; +            let color_o = [1.0, 0.5, 0.0, 1.0]; +            let color_y = [1.0, 1.0, 0.0, 1.0]; +            let color_g = [0.0, 1.0, 0.0, 1.0]; +            let color_gb = [0.0, 1.0, 0.5, 1.0]; +            let color_b = [0.0, 0.2, 1.0, 1.0]; +            let color_i = [0.5, 0.0, 1.0, 1.0]; +            let color_v = [0.75, 0.0, 0.5, 1.0]; + +            let posn_center = { +                if b.contains(cursor_position) { +                    [cursor_position.x, cursor_position.y] +                } else { +                    [b.x + (b.width / 2.0), b.y + (b.height / 2.0)] +                } +            }; + +            let posn_tl = [b.x, b.y]; +            let posn_t = [b.x + (b.width / 2.0), b.y]; +            let posn_tr = [b.x + b.width, b.y]; +            let posn_r = [b.x + b.width, b.y + (b.height / 2.0)]; +            let posn_br = [b.x + b.width, b.y + b.height]; +            let posn_b = [b.x + (b.width / 2.0), b.y + b.height]; +            let posn_bl = [b.x, b.y + b.height]; +            let posn_l = [b.x, b.y + (b.height / 2.0)]; + +            ( +                Primitive::Geometry2D { +                    geometry: Geometry2D { +                        vertices: vec![ +                            Vertex2D { +                                position: posn_center, +                                color: [1.0, 1.0, 1.0, 1.0], +                            }, +                            Vertex2D { +                                position: posn_tl, +                                color: color_r, +                            }, +                            Vertex2D { +                                position: posn_t, +                                color: color_o, +                            }, +                            Vertex2D { +                                position: posn_tr, +                                color: color_y, +                            }, +                            Vertex2D { +                                position: posn_r, +                                color: color_g, +                            }, +                            Vertex2D { +                                position: posn_br, +                                color: color_gb, +                            }, +                            Vertex2D { +                                position: posn_b, +                                color: color_b, +                            }, +                            Vertex2D { +                                position: posn_bl, +                                color: color_i, +                            }, +                            Vertex2D { +                                position: posn_l, +                                color: color_v, +                            }, +                        ], +                        indices: vec![ +                            0, 1, 2, // TL +                            0, 2, 3, // T +                            0, 3, 4, // TR +                            0, 4, 5, // R +                            0, 5, 6, // BR +                            0, 6, 7, // B +                            0, 7, 8, // BL +                            0, 8, 1, // L +                        ], +                    }, +                }, +                MouseCursor::OutOfBounds, +            ) +        } +    } + +    impl<'a, Message> Into<Element<'a, Message, Renderer>> for Rainbow { +        fn into(self) -> Element<'a, Message, Renderer> { +            Element::new(self) +        } +    } +} + +use iced::{ +    scrollable, settings::Window,  Align, Column, Container, Element, +    Length, Sandbox, Scrollable, Settings,  Text, +}; +use rainbow::Rainbow; + +pub fn main() { +    Example::run(Settings { +        window: Window { +            size: (660, 660), +            resizable: true, +            decorations: true, +        }, +    }) +} + +struct Example { +    dimen: u16, +    scroll: scrollable::State, +} + +#[derive(Debug, Clone, Copy)] +enum Message {} + +impl Sandbox for Example { +    type Message = Message; + +    fn new() -> Self { +        Example { +            dimen: 500, +            scroll: scrollable::State::new(), +        } +    } + +    fn title(&self) -> String { +        String::from("Custom 2D geometry - Iced") +    } + +    fn update(&mut self, _: Message) {} + +    fn view(&mut self) -> Element<Message> { +        let content = Column::new() +            .padding(20) +            .spacing(20) +            .max_width(500) +            .align_items(Align::Start) +            .push(Rainbow::new(self.dimen)) +            .push( +                Text::new(String::from("In this example we draw a custom widget Rainbow, using the \ +                Geometry2D primitive. This primitive supplies a list of triangles, expressed as vertices and indices.")) +                    .width(Length::Shrink), +            ) +            .push( +                Text::new(String::from("Move your cursor over it, and see the center vertex follow you!")) +                    .width(Length::Shrink), +            ) +            .push( +                Text::new(String::from("Every Vertex2D defines its own color. You could use the \ +                Geometry2D primitive to render virtually any two-dimensional geometry for your widget.")) +                    .width(Length::Shrink), +            ); + +        let scrollable = +            Scrollable::new(&mut self.scroll).push(Container::new(content)); + +        Container::new(scrollable) +            .width(Length::Fill) +            .height(Length::Fill) +            .center_x() +            .center_y() +            .into() +    } +} | 
