diff options
Diffstat (limited to '')
-rw-r--r-- | widget/src/canvas.rs (renamed from graphics/src/widget/canvas.rs) | 145 |
1 files changed, 55 insertions, 90 deletions
diff --git a/graphics/src/widget/canvas.rs b/widget/src/canvas.rs index a8d050f5..96062038 100644 --- a/graphics/src/widget/canvas.rs +++ b/widget/src/canvas.rs @@ -1,43 +1,22 @@ //! Draw 2D graphics for your users. -//! -//! A [`Canvas`] widget can be used to draw different kinds of 2D shapes in a -//! [`Frame`]. It can be used for animation, data visualization, game graphics, -//! and more! pub mod event; -pub mod fill; -pub mod path; -pub mod stroke; -mod cache; -mod cursor; -mod frame; -mod geometry; mod program; -mod style; -mod text; -pub use crate::gradient::{self, Gradient}; -pub use cache::Cache; -pub use cursor::Cursor; pub use event::Event; -pub use fill::{Fill, FillRule}; -pub use frame::Frame; -pub use geometry::Geometry; -pub use path::Path; pub use program::Program; -pub use stroke::{LineCap, LineDash, LineJoin, Stroke}; -pub use style::Style; -pub use text::Text; -use crate::{Backend, Primitive, Renderer}; +pub use crate::graphics::geometry::*; +pub use crate::renderer::geometry::*; -use iced_native::layout::{self, Layout}; -use iced_native::mouse; -use iced_native::renderer; -use iced_native::widget::tree::{self, Tree}; -use iced_native::{ - Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector, Widget, -}; +use crate::core; +use crate::core::layout::{self, Layout}; +use crate::core::mouse; +use crate::core::renderer; +use crate::core::widget::tree::{self, Tree}; +use crate::core::{Clipboard, Element, Shell, Widget}; +use crate::core::{Length, Rectangle, Size, Vector}; +use crate::graphics::geometry; use std::marker::PhantomData; @@ -47,15 +26,12 @@ use std::marker::PhantomData; /// If you want to get a quick overview, here's how we can draw a simple circle: /// /// ```no_run -/// # mod iced { -/// # pub mod widget { -/// # pub use iced_graphics::widget::canvas; -/// # } -/// # pub use iced_native::{Color, Rectangle, Theme}; -/// # } -/// use iced::widget::canvas::{self, Canvas, Cursor, Fill, Frame, Geometry, Path, Program}; -/// use iced::{Color, Rectangle, Theme}; -/// +/// # use iced_widget::canvas::{self, Canvas, Fill, Frame, Geometry, Path, Program}; +/// # use iced_widget::core::{Color, Rectangle}; +/// # use iced_widget::core::mouse; +/// # use iced_widget::style::Theme; +/// # +/// # pub type Renderer = iced_widget::renderer::Renderer<Theme>; /// // First, we define the data we need for drawing /// #[derive(Debug)] /// struct Circle { @@ -66,9 +42,9 @@ use std::marker::PhantomData; /// impl Program<()> for Circle { /// type State = (); /// -/// fn draw(&self, _state: &(), _theme: &Theme, bounds: Rectangle, _cursor: Cursor) -> Vec<Geometry>{ +/// fn draw(&self, _state: &(), renderer: &Renderer, _theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor) -> Vec<Geometry>{ /// // We prepare a new `Frame` -/// let mut frame = Frame::new(bounds.size()); +/// let mut frame = Frame::new(renderer, bounds.size()); /// /// // We create a `Path` representing a simple circle /// let circle = Path::circle(frame.center(), self.radius); @@ -85,20 +61,22 @@ use std::marker::PhantomData; /// let canvas = Canvas::new(Circle { radius: 50.0 }); /// ``` #[derive(Debug)] -pub struct Canvas<Message, Theme, P> +pub struct Canvas<P, Message, Renderer = crate::Renderer> where - P: Program<Message, Theme>, + Renderer: geometry::Renderer, + P: Program<Message, Renderer>, { width: Length, height: Length, program: P, message_: PhantomData<Message>, - theme_: PhantomData<Theme>, + theme_: PhantomData<Renderer>, } -impl<Message, Theme, P> Canvas<Message, Theme, P> +impl<P, Message, Renderer> Canvas<P, Message, Renderer> where - P: Program<Message, Theme>, + Renderer: geometry::Renderer, + P: Program<Message, Renderer>, { const DEFAULT_SIZE: f32 = 100.0; @@ -126,10 +104,11 @@ where } } -impl<Message, P, B, T> Widget<Message, Renderer<B, T>> for Canvas<Message, T, P> +impl<P, Message, Renderer> Widget<Message, Renderer> + for Canvas<P, Message, Renderer> where - P: Program<Message, T>, - B: Backend, + Renderer: geometry::Renderer, + P: Program<Message, Renderer>, { fn tag(&self) -> tree::Tag { struct Tag<T>(T); @@ -150,7 +129,7 @@ where fn layout( &self, - _renderer: &Renderer<B, T>, + _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { let limits = limits.width(self.width).height(self.height); @@ -162,30 +141,24 @@ where fn on_event( &mut self, tree: &mut Tree, - event: iced_native::Event, + event: core::Event, layout: Layout<'_>, - cursor_position: Point, - _renderer: &Renderer<B, T>, + cursor: mouse::Cursor, + _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, ) -> event::Status { let bounds = layout.bounds(); let canvas_event = match event { - iced_native::Event::Mouse(mouse_event) => { - Some(Event::Mouse(mouse_event)) - } - iced_native::Event::Touch(touch_event) => { - Some(Event::Touch(touch_event)) - } - iced_native::Event::Keyboard(keyboard_event) => { + core::Event::Mouse(mouse_event) => Some(Event::Mouse(mouse_event)), + core::Event::Touch(touch_event) => Some(Event::Touch(touch_event)), + core::Event::Keyboard(keyboard_event) => { Some(Event::Keyboard(keyboard_event)) } _ => None, }; - let cursor = Cursor::from_window_position(cursor_position); - if let Some(canvas_event) = canvas_event { let state = tree.state.downcast_mut::<P::State>(); @@ -206,12 +179,11 @@ where &self, tree: &Tree, layout: Layout<'_>, - cursor_position: Point, + cursor: mouse::Cursor, _viewport: &Rectangle, - _renderer: &Renderer<B, T>, + _renderer: &Renderer, ) -> mouse::Interaction { let bounds = layout.bounds(); - let cursor = Cursor::from_window_position(cursor_position); let state = tree.state.downcast_ref::<P::State>(); self.program.mouse_interaction(state, bounds, cursor) @@ -220,49 +192,42 @@ where fn draw( &self, tree: &Tree, - renderer: &mut Renderer<B, T>, - theme: &T, + renderer: &mut Renderer, + theme: &Renderer::Theme, _style: &renderer::Style, layout: Layout<'_>, - cursor_position: Point, + cursor: mouse::Cursor, _viewport: &Rectangle, ) { - use iced_native::Renderer as _; - let bounds = layout.bounds(); if bounds.width < 1.0 || bounds.height < 1.0 { return; } - let translation = Vector::new(bounds.x, bounds.y); - let cursor = Cursor::from_window_position(cursor_position); let state = tree.state.downcast_ref::<P::State>(); - renderer.with_translation(translation, |renderer| { - renderer.draw_primitive(Primitive::Group { - primitives: self - .program - .draw(state, theme, bounds, cursor) - .into_iter() - .map(Geometry::into_primitive) - .collect(), - }); - }); + renderer.with_translation( + Vector::new(bounds.x, bounds.y), + |renderer| { + renderer.draw( + self.program.draw(state, renderer, theme, bounds, cursor), + ); + }, + ); } } -impl<'a, Message, P, B, T> From<Canvas<Message, T, P>> - for Element<'a, Message, Renderer<B, T>> +impl<'a, P, Message, Renderer> From<Canvas<P, Message, Renderer>> + for Element<'a, Message, Renderer> where Message: 'a, - P: Program<Message, T> + 'a, - B: Backend, - T: 'a, + Renderer: 'a + geometry::Renderer, + P: Program<Message, Renderer> + 'a, { fn from( - canvas: Canvas<Message, T, P>, - ) -> Element<'a, Message, Renderer<B, T>> { + canvas: Canvas<P, Message, Renderer>, + ) -> Element<'a, Message, Renderer> { Element::new(canvas) } } |