//! This example showcases a simple native custom widget that draws a circle. mod circle { // 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::advanced::layout::{self, Layout}; use iced::advanced::renderer; use iced::advanced::widget::{self, Widget}; use iced::mouse; use iced::{Border, Color, Element, Length, Rectangle, Size}; pub struct Circle { radius: f32, } impl Circle { pub fn new(radius: f32) -> Self { Self { radius } } } pub fn circle(radius: f32) -> Circle { Circle::new(radius) } impl Widget for Circle where Renderer: renderer::Renderer, { fn size(&self) -> Size { Size { width: Length::Shrink, height: Length::Shrink, } } fn layout( &self, _tree: &mut widget::Tree, _renderer: &Renderer, _limits: &layout::Limits, ) -> layout::Node { layout::Node::new(Size::new(self.radius * 2.0, self.radius * 2.0)) } fn draw( &self, _state: &widget::Tree, renderer: &mut Renderer, _theme: &Theme, _style: &renderer::Style, layout: Layout<'_>, _cursor: mouse::Cursor, _viewport: &Rectangle, ) { renderer.fill_quad( renderer::Quad { bounds: layout.bounds(), border: Border::rounded(self.radius), ..renderer::Quad::default() }, Color::BLACK, ); } } impl<'a, Message, Theme, Renderer> From for Element<'a, Message, Theme, Renderer> where Renderer: renderer::Renderer, { fn from(circle: Circle) -> Self { Self::new(circle) } } } use circle::circle; use iced::widget::{center, column, slider, text}; use iced::{Center, Element}; pub fn main() -> iced::Result { iced::run("Custom Widget - Iced", Example::update, Example::view) } struct Example { radius: f32, } #[derive(Debug, Clone, Copy)] enum Message { RadiusChanged(f32), } impl Example { fn new() -> Self { Example { radius: 50.0 } } fn update(&mut self, message: Message) { match message { Message::RadiusChanged(radius) => { self.radius = radius; } } } fn view(&self) -> Element { let content = column![ circle(self.radius), text!("Radius: {:.2}", self.radius), slider(1.0..=100.0, self.radius, Message::RadiusChanged).step(0.01), ] .padding(20) .spacing(20) .max_width(500) .align_x(Center); center(content).into() } } impl Default for Example { fn default() -> Self { Self::new() } }