From 0d620b7701f427ed0091f3640ab9ca0e116eb412 Mon Sep 17 00:00:00 2001 From: Artur Sapek Date: Wed, 1 Jan 2020 15:44:32 -0700 Subject: Implement Geometry2D primitive --- examples/geometry.rs | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 examples/geometry.rs (limited to 'examples') 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 Widget 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> 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 { + 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() + } +} -- cgit From d60f3b89a75f5b2ad8e6fb17827f5574a0a44bd1 Mon Sep 17 00:00:00 2001 From: Songtronix Date: Wed, 1 Jan 2020 17:27:14 +0100 Subject: add(widget): primitive progressbar widget --- examples/progressbar.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 examples/progressbar.rs (limited to 'examples') diff --git a/examples/progressbar.rs b/examples/progressbar.rs new file mode 100644 index 00000000..4663f8df --- /dev/null +++ b/examples/progressbar.rs @@ -0,0 +1,51 @@ +use iced::{slider, Column, Element, Sandbox, Settings, Slider}; +use iced_winit::Progressbar; + +pub fn main() { + Progress::run(Settings::default()) +} + +#[derive(Default)] +struct Progress { + value: f32, + progressbar_slider: slider::State, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + SliderChanged(f32), +} + +impl Sandbox for Progress { + type Message = Message; + + fn new() -> Self { + Self::default() + } + + fn title(&self) -> String { + String::from("A simple Progressbar") + } + + fn update(&mut self, message: Message) { + match message { + Message::SliderChanged(x) => { + self.value = x; + } + } + } + + fn view(&mut self) -> Element { + Column::new() + .padding(20) + .push(Progressbar::new(0.0..=100.0, self.value)) + .padding(20) + .push(Slider::new( + &mut self.progressbar_slider, + 0.0..=100.0, + self.value, + Message::SliderChanged, + )) + .into() + } +} -- cgit From bf8f83decc039494d310f6ecbb05cbab2c241cbf Mon Sep 17 00:00:00 2001 From: Songtronix Date: Thu, 2 Jan 2020 14:10:18 +0100 Subject: change(widget): custom coloring for progressbar --- examples/progressbar.rs | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'examples') diff --git a/examples/progressbar.rs b/examples/progressbar.rs index 4663f8df..c4ebf248 100644 --- a/examples/progressbar.rs +++ b/examples/progressbar.rs @@ -1,8 +1,17 @@ -use iced::{slider, Column, Element, Sandbox, Settings, Slider}; +use iced::{ + settings::Window, slider, Background, Color, Column, Element, Sandbox, + Settings, Slider, +}; use iced_winit::Progressbar; pub fn main() { - Progress::run(Settings::default()) + Progress::run(Settings { + window: Window { + size: (700, 300), + resizable: true, + decorations: true, + }, + }) } #[derive(Default)] @@ -29,17 +38,20 @@ impl Sandbox for Progress { fn update(&mut self, message: Message) { match message { - Message::SliderChanged(x) => { - self.value = x; - } + Message::SliderChanged(x) => self.value = x, } } fn view(&mut self) -> Element { Column::new() .padding(20) - .push(Progressbar::new(0.0..=100.0, self.value)) - .padding(20) + .push( + Progressbar::new(0.0..=100.0, self.value) + .background(Background::Color(Color::from_rgb( + 0.6, 0.6, 0.6, + ))) + .active_color(Color::from_rgb(0.0, 0.95, 0.0)), + ) .push(Slider::new( &mut self.progressbar_slider, 0.0..=100.0, -- cgit From 986f01237f227ad2eaabda982324fc26840cb12b Mon Sep 17 00:00:00 2001 From: Songtronix Date: Thu, 2 Jan 2020 18:07:00 +0100 Subject: change(widget): make height adjustable at widget level addtionally rename Progressbar to ProgressBar --- examples/progress_bar.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ examples/progressbar.rs | 63 ----------------------------------------------- 2 files changed, 64 insertions(+), 63 deletions(-) create mode 100644 examples/progress_bar.rs delete mode 100644 examples/progressbar.rs (limited to 'examples') diff --git a/examples/progress_bar.rs b/examples/progress_bar.rs new file mode 100644 index 00000000..56f54903 --- /dev/null +++ b/examples/progress_bar.rs @@ -0,0 +1,64 @@ +use iced::{ + settings::Window, slider, Background, Color, Column, Element, Length, + Sandbox, Settings, Slider, +}; +use iced_winit::ProgressBar; + +pub fn main() { + Progress::run(Settings { + window: Window { + size: (700, 300), + resizable: true, + decorations: true, + }, + }) +} + +#[derive(Default)] +struct Progress { + value: f32, + progress_bar_slider: slider::State, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + SliderChanged(f32), +} + +impl Sandbox for Progress { + type Message = Message; + + fn new() -> Self { + Self::default() + } + + fn title(&self) -> String { + String::from("A simple Progressbar") + } + + fn update(&mut self, message: Message) { + match message { + Message::SliderChanged(x) => self.value = x, + } + } + + fn view(&mut self) -> Element { + Column::new() + .padding(20) + .push( + ProgressBar::new(0.0..=100.0, self.value) + .background(Background::Color(Color::from_rgb( + 0.6, 0.6, 0.6, + ))) + .active_color(Color::from_rgb(0.0, 0.95, 0.0)) + .height(Length::Units(30)), + ) + .push(Slider::new( + &mut self.progress_bar_slider, + 0.0..=100.0, + self.value, + Message::SliderChanged, + )) + .into() + } +} diff --git a/examples/progressbar.rs b/examples/progressbar.rs deleted file mode 100644 index c4ebf248..00000000 --- a/examples/progressbar.rs +++ /dev/null @@ -1,63 +0,0 @@ -use iced::{ - settings::Window, slider, Background, Color, Column, Element, Sandbox, - Settings, Slider, -}; -use iced_winit::Progressbar; - -pub fn main() { - Progress::run(Settings { - window: Window { - size: (700, 300), - resizable: true, - decorations: true, - }, - }) -} - -#[derive(Default)] -struct Progress { - value: f32, - progressbar_slider: slider::State, -} - -#[derive(Debug, Clone, Copy)] -enum Message { - SliderChanged(f32), -} - -impl Sandbox for Progress { - type Message = Message; - - fn new() -> Self { - Self::default() - } - - fn title(&self) -> String { - String::from("A simple Progressbar") - } - - fn update(&mut self, message: Message) { - match message { - Message::SliderChanged(x) => self.value = x, - } - } - - fn view(&mut self) -> Element { - Column::new() - .padding(20) - .push( - Progressbar::new(0.0..=100.0, self.value) - .background(Background::Color(Color::from_rgb( - 0.6, 0.6, 0.6, - ))) - .active_color(Color::from_rgb(0.0, 0.95, 0.0)), - ) - .push(Slider::new( - &mut self.progressbar_slider, - 0.0..=100.0, - self.value, - Message::SliderChanged, - )) - .into() - } -} -- cgit From 5ca98b113e49bfb2372b245a985f957611a0a1ac Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 2 Jan 2020 19:25:00 +0100 Subject: Rename `Geometry2D` to `Mesh2D` and move it to `iced_wgpu` --- examples/geometry.rs | 194 +++++++++++++++++++++++---------------------------- 1 file changed, 88 insertions(+), 106 deletions(-) (limited to 'examples') diff --git a/examples/geometry.rs b/examples/geometry.rs index feb7684e..ae6c9ca0 100644 --- a/examples/geometry.rs +++ b/examples/geometry.rs @@ -11,24 +11,25 @@ mod rainbow { // 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, + layout, Element, Hasher, Layout, Length, MouseCursor, Point, Size, + Widget, + }; + use iced_wgpu::{ + triangle::{Mesh2D, Vertex2D}, + Primitive, Renderer, }; - use iced_wgpu::{Primitive, Renderer}; - pub struct Rainbow { - dimen: u16, - } + pub struct Rainbow; impl Rainbow { - pub fn new(dimen: u16) -> Self { - Self { dimen } + pub fn new() -> Self { + Self } } impl Widget for Rainbow { fn width(&self) -> Length { - Length::Shrink + Length::Fill } fn height(&self) -> Length { @@ -38,20 +39,15 @@ mod rainbow { fn layout( &self, _renderer: &Renderer, - _limits: &layout::Limits, + 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; + let size = limits.width(Length::Fill).resolve(Size::ZERO); - self.dimen.hash(state); + layout::Node::new(Size::new(size.width, size.width)) } + fn hash_layout(&self, _state: &mut Hasher) {} + fn draw( &self, _renderer: &mut Renderer, @@ -88,58 +84,56 @@ mod rainbow { 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 - ], - }, - }, + Primitive::Mesh2D(std::sync::Arc::new(Mesh2D { + 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, ) } @@ -153,35 +147,24 @@ mod rainbow { } use iced::{ - scrollable, settings::Window, Align, Column, Container, Element, - Length, Sandbox, Scrollable, Settings, Text, + scrollable, 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, - }, - }) + Example::run(Settings::default()) } struct Example { - dimen: u16, scroll: scrollable::State, } -#[derive(Debug, Clone, Copy)] -enum Message {} - impl Sandbox for Example { - type Message = Message; + type Message = (); fn new() -> Self { Example { - dimen: 500, scroll: scrollable::State::new(), } } @@ -190,37 +173,36 @@ impl Sandbox for Example { String::from("Custom 2D geometry - Iced") } - fn update(&mut self, _: Message) {} + fn update(&mut self, _: ()) {} - fn view(&mut self) -> Element { + fn view(&mut self) -> Element<()> { 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), - ); + .push(Rainbow::new()) + .push(Text::new( + "In this example we draw a custom widget Rainbow, using \ + the Mesh2D primitive. This primitive supplies a list of \ + triangles, expressed as vertices and indices.", + )) + .push(Text::new( + "Move your cursor over it, and see the center vertex \ + follow you!", + )) + .push(Text::new( + "Every Vertex2D defines its own color. You could use the \ + Mesh2D primitive to render virtually any two-dimensional \ + geometry for your widget.", + )); - let scrollable = - Scrollable::new(&mut self.scroll).push(Container::new(content)); + let scrollable = Scrollable::new(&mut self.scroll) + .push(Container::new(content).width(Length::Fill).center_x()); Container::new(scrollable) .width(Length::Fill) .height(Length::Fill) - .center_x() .center_y() .into() } -- cgit From 43de28ae1515ace34758656f228444898459d85b Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 4 Jan 2020 14:14:28 +0100 Subject: Expose `ProgressBar` in `iced` crate --- examples/progress_bar.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/progress_bar.rs b/examples/progress_bar.rs index 56f54903..525019b4 100644 --- a/examples/progress_bar.rs +++ b/examples/progress_bar.rs @@ -1,8 +1,7 @@ use iced::{ settings::Window, slider, Background, Color, Column, Element, Length, - Sandbox, Settings, Slider, + ProgressBar, Sandbox, Settings, Slider, }; -use iced_winit::ProgressBar; pub fn main() { Progress::run(Settings { -- cgit