diff options
Diffstat (limited to '')
-rw-r--r-- | native/Cargo.toml | 6 | ||||
-rw-r--r-- | native/src/lib.rs | 4 | ||||
-rw-r--r-- | native/src/widget.rs | 16 | ||||
-rw-r--r-- | native/src/widget/canvas.rs (renamed from graphics/src/widget/canvas.rs) | 101 | ||||
-rw-r--r-- | native/src/widget/canvas/cursor.rs (renamed from graphics/src/widget/canvas/cursor.rs) | 2 | ||||
-rw-r--r-- | native/src/widget/canvas/event.rs (renamed from graphics/src/widget/canvas/event.rs) | 8 | ||||
-rw-r--r-- | native/src/widget/canvas/fill.rs (renamed from graphics/src/widget/canvas/fill.rs) | 18 | ||||
-rw-r--r-- | native/src/widget/canvas/path.rs (renamed from graphics/src/widget/canvas/path.rs) | 52 | ||||
-rw-r--r-- | native/src/widget/canvas/path/arc.rs (renamed from graphics/src/widget/canvas/path/arc.rs) | 2 | ||||
-rw-r--r-- | native/src/widget/canvas/path/builder.rs (renamed from graphics/src/widget/canvas/path/builder.rs) | 24 | ||||
-rw-r--r-- | native/src/widget/canvas/program.rs (renamed from graphics/src/widget/canvas/program.rs) | 24 | ||||
-rw-r--r-- | native/src/widget/canvas/stroke.rs (renamed from graphics/src/widget/canvas/stroke.rs) | 22 | ||||
-rw-r--r-- | native/src/widget/canvas/style.rs (renamed from graphics/src/widget/canvas/style.rs) | 3 | ||||
-rw-r--r-- | native/src/widget/canvas/text.rs (renamed from graphics/src/widget/canvas/text.rs) | 0 |
14 files changed, 114 insertions, 168 deletions
diff --git a/native/Cargo.toml b/native/Cargo.toml index 3f92783e..23533e33 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -8,12 +8,14 @@ license = "MIT" repository = "https://github.com/iced-rs/iced" [features] +canvas = ["lyon_path"] debug = [] [dependencies] twox-hash = { version = "1.5", default-features = false } unicode-segmentation = "1.6" num-traits = "0.2" +thiserror = "1" [dependencies.iced_core] version = "0.8" @@ -27,3 +29,7 @@ features = ["thread-pool"] [dependencies.iced_style] version = "0.7" path = "../style" + +[dependencies.lyon_path] +version = "1" +optional = true diff --git a/native/src/lib.rs b/native/src/lib.rs index 27b6fc0d..c98827e7 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -33,7 +33,7 @@ )] #![deny( missing_debug_implementations, - missing_docs, + //missing_docs, unused_results, clippy::extra_unused_lifetimes, clippy::from_over_into, @@ -79,6 +79,7 @@ mod debug; mod debug; pub use iced_core::alignment; +pub use iced_core::gradient; pub use iced_core::time; pub use iced_core::{ color, Alignment, Background, Color, ContentFit, Length, Padding, Pixels, @@ -97,6 +98,7 @@ pub use debug::Debug; pub use element::Element; pub use event::Event; pub use font::Font; +pub use gradient::Gradient; pub use hasher::Hasher; pub use layout::Layout; pub use overlay::Overlay; diff --git a/native/src/widget.rs b/native/src/widget.rs index 2b3ca7be..27330894 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -83,6 +83,22 @@ pub use tree::Tree; #[doc(no_inline)] pub use vertical_slider::VerticalSlider; +#[cfg(feature = "canvas")] +#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))] +pub mod canvas; + +#[cfg(feature = "canvas")] +#[doc(no_inline)] +pub use canvas::Canvas; + +#[cfg(feature = "qr_code")] +#[cfg_attr(docsrs, doc(cfg(feature = "qr_code")))] +pub mod qr_code; + +#[cfg(feature = "qr_code")] +#[doc(no_inline)] +pub use qr_code::QRCode; + pub use action::Action; pub use id::Id; pub use operation::Operation; diff --git a/graphics/src/widget/canvas.rs b/native/src/widget/canvas.rs index a8d050f5..8a9addd2 100644 --- a/graphics/src/widget/canvas.rs +++ b/native/src/widget/canvas.rs @@ -8,34 +8,26 @@ 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 fill::Fill; 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}; - -use iced_native::layout::{self, Layout}; -use iced_native::mouse; -use iced_native::renderer; -use iced_native::widget::tree::{self, Tree}; -use iced_native::{ +use crate::layout::{self, Layout}; +use crate::mouse; +use crate::renderer; +use crate::widget::tree::{self, Tree}; +use crate::{ Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector, Widget, }; @@ -85,20 +77,22 @@ use std::marker::PhantomData; /// let canvas = Canvas::new(Circle { radius: 50.0 }); /// ``` #[derive(Debug)] -pub struct Canvas<Message, Theme, P> +pub struct Canvas<Message, Renderer, P> where - P: Program<Message, Theme>, + Renderer: self::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<Message, Renderer, P> Canvas<Message, Renderer, P> where - P: Program<Message, Theme>, + Renderer: self::Renderer, + P: Program<Message, Renderer>, { const DEFAULT_SIZE: f32 = 100.0; @@ -126,10 +120,11 @@ where } } -impl<Message, P, B, T> Widget<Message, Renderer<B, T>> for Canvas<Message, T, P> +impl<Message, Renderer, P> Widget<Message, Renderer> + for Canvas<Message, Renderer, P> where - P: Program<Message, T>, - B: Backend, + Renderer: self::Renderer, + P: Program<Message, Renderer>, { fn tag(&self) -> tree::Tag { struct Tag<T>(T); @@ -150,7 +145,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,23 +157,19 @@ where fn on_event( &mut self, tree: &mut Tree, - event: iced_native::Event, + event: crate::Event, layout: Layout<'_>, cursor_position: Point, - _renderer: &Renderer<B, T>, + _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) => { + crate::Event::Mouse(mouse_event) => Some(Event::Mouse(mouse_event)), + crate::Event::Touch(touch_event) => Some(Event::Touch(touch_event)), + crate::Event::Keyboard(keyboard_event) => { Some(Event::Keyboard(keyboard_event)) } _ => None, @@ -208,7 +199,7 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - _renderer: &Renderer<B, T>, + _renderer: &Renderer, ) -> mouse::Interaction { let bounds = layout.bounds(); let cursor = Cursor::from_window_position(cursor_position); @@ -220,49 +211,49 @@ 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, _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, Message, Renderer, P> From<Canvas<Message, Renderer, P>> + for Element<'a, Message, Renderer> where Message: 'a, - P: Program<Message, T> + 'a, - B: Backend, - T: 'a, + Renderer: 'a + self::Renderer, + P: Program<Message, Renderer> + 'a, { fn from( - canvas: Canvas<Message, T, P>, - ) -> Element<'a, Message, Renderer<B, T>> { + canvas: Canvas<Message, Renderer, P>, + ) -> Element<'a, Message, Renderer> { Element::new(canvas) } } + +pub trait Renderer: crate::Renderer { + type Geometry; + + fn draw(&mut self, geometry: Vec<Self::Geometry>); +} diff --git a/graphics/src/widget/canvas/cursor.rs b/native/src/widget/canvas/cursor.rs index 9588d129..ef6a7771 100644 --- a/graphics/src/widget/canvas/cursor.rs +++ b/native/src/widget/canvas/cursor.rs @@ -1,4 +1,4 @@ -use iced_native::{Point, Rectangle}; +use crate::{Point, Rectangle}; /// The mouse cursor state. #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/graphics/src/widget/canvas/event.rs b/native/src/widget/canvas/event.rs index 7c733a4d..1d726577 100644 --- a/graphics/src/widget/canvas/event.rs +++ b/native/src/widget/canvas/event.rs @@ -1,9 +1,9 @@ //! Handle events of a canvas. -use iced_native::keyboard; -use iced_native::mouse; -use iced_native::touch; +use crate::keyboard; +use crate::mouse; +use crate::touch; -pub use iced_native::event::Status; +pub use crate::event::Status; /// A [`Canvas`] event. /// diff --git a/graphics/src/widget/canvas/fill.rs b/native/src/widget/canvas/fill.rs index e954ebb5..92b1e47e 100644 --- a/graphics/src/widget/canvas/fill.rs +++ b/native/src/widget/canvas/fill.rs @@ -1,5 +1,6 @@ //! Fill [crate::widget::canvas::Geometry] with a certain style. -use crate::{Color, Gradient}; +use crate::widget::canvas::Gradient; +use crate::Color; pub use crate::widget::canvas::Style; @@ -19,14 +20,14 @@ pub struct Fill { /// By default, it is set to `NonZero`. /// /// [1]: https://www.w3.org/TR/SVG/painting.html#FillRuleProperty - pub rule: FillRule, + pub rule: Rule, } impl Default for Fill { fn default() -> Self { Self { style: Style::Solid(Color::BLACK), - rule: FillRule::NonZero, + rule: Rule::NonZero, } } } @@ -57,16 +58,7 @@ impl From<Gradient> for Fill { /// [1]: https://www.w3.org/TR/SVG/painting.html#FillRuleProperty #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[allow(missing_docs)] -pub enum FillRule { +pub enum Rule { NonZero, EvenOdd, } - -impl From<FillRule> for lyon::tessellation::FillRule { - fn from(rule: FillRule) -> lyon::tessellation::FillRule { - match rule { - FillRule::NonZero => lyon::tessellation::FillRule::NonZero, - FillRule::EvenOdd => lyon::tessellation::FillRule::EvenOdd, - } - } -} diff --git a/graphics/src/widget/canvas/path.rs b/native/src/widget/canvas/path.rs index aeb2589e..30c387c5 100644 --- a/graphics/src/widget/canvas/path.rs +++ b/native/src/widget/canvas/path.rs @@ -7,18 +7,16 @@ mod builder; pub use arc::Arc; pub use builder::Builder; -use crate::widget::canvas::LineDash; +pub use lyon_path; -use iced_native::{Point, Size}; -use lyon::algorithms::walk::{walk_along_path, RepeatedPattern, WalkerEvent}; -use lyon::path::iterator::PathIterator; +use crate::{Point, Size}; /// An immutable set of points that may or may not be connected. /// /// A single [`Path`] can represent different kinds of 2D shapes! #[derive(Debug, Clone)] pub struct Path { - raw: lyon::path::Path, + raw: lyon_path::Path, } impl Path { @@ -56,54 +54,14 @@ impl Path { } #[inline] - pub(crate) fn raw(&self) -> &lyon::path::Path { + pub fn raw(&self) -> &lyon_path::Path { &self.raw } #[inline] - pub(crate) fn transformed( - &self, - transform: &lyon::math::Transform, - ) -> Path { + pub fn transform(&self, transform: &lyon_path::math::Transform) -> Path { Path { raw: self.raw.clone().transformed(transform), } } } - -pub(super) fn dashed(path: &Path, line_dash: LineDash<'_>) -> Path { - Path::new(|builder| { - let segments_odd = (line_dash.segments.len() % 2 == 1) - .then(|| [line_dash.segments, line_dash.segments].concat()); - - let mut draw_line = false; - - walk_along_path( - path.raw().iter().flattened(0.01), - 0.0, - lyon::tessellation::StrokeOptions::DEFAULT_TOLERANCE, - &mut RepeatedPattern { - callback: |event: WalkerEvent<'_>| { - let point = Point { - x: event.position.x, - y: event.position.y, - }; - - if draw_line { - builder.line_to(point); - } else { - builder.move_to(point); - } - - draw_line = !draw_line; - - true - }, - index: line_dash.offset, - intervals: segments_odd - .as_deref() - .unwrap_or(line_dash.segments), - }, - ); - }) -} diff --git a/graphics/src/widget/canvas/path/arc.rs b/native/src/widget/canvas/path/arc.rs index b8e72daf..e0747d3e 100644 --- a/graphics/src/widget/canvas/path/arc.rs +++ b/native/src/widget/canvas/path/arc.rs @@ -1,5 +1,5 @@ //! Build and draw curves. -use iced_native::{Point, Vector}; +use crate::{Point, Vector}; /// A segment of a differentiable curve. #[derive(Debug, Clone, Copy)] diff --git a/graphics/src/widget/canvas/path/builder.rs b/native/src/widget/canvas/path/builder.rs index 5121aa68..84fda052 100644 --- a/graphics/src/widget/canvas/path/builder.rs +++ b/native/src/widget/canvas/path/builder.rs @@ -1,35 +1,37 @@ use crate::widget::canvas::path::{arc, Arc, Path}; +use crate::{Point, Size}; -use iced_native::{Point, Size}; -use lyon::path::builder::SvgPathBuilder; +use lyon_path::builder::{self, SvgPathBuilder}; +use lyon_path::geom; +use lyon_path::math; /// A [`Path`] builder. /// /// Once a [`Path`] is built, it can no longer be mutated. #[allow(missing_debug_implementations)] pub struct Builder { - raw: lyon::path::builder::WithSvg<lyon::path::path::BuilderImpl>, + raw: builder::WithSvg<lyon_path::path::BuilderImpl>, } impl Builder { /// Creates a new [`Builder`]. pub fn new() -> Builder { Builder { - raw: lyon::path::Path::builder().with_svg(), + raw: lyon_path::Path::builder().with_svg(), } } /// Moves the starting point of a new sub-path to the given `Point`. #[inline] pub fn move_to(&mut self, point: Point) { - let _ = self.raw.move_to(lyon::math::Point::new(point.x, point.y)); + let _ = self.raw.move_to(math::Point::new(point.x, point.y)); } /// Connects the last point in the [`Path`] to the given `Point` with a /// straight line. #[inline] pub fn line_to(&mut self, point: Point) { - let _ = self.raw.line_to(lyon::math::Point::new(point.x, point.y)); + let _ = self.raw.line_to(math::Point::new(point.x, point.y)); } /// Adds an [`Arc`] to the [`Path`] from `start_angle` to `end_angle` in @@ -53,8 +55,6 @@ impl Builder { /// See [the HTML5 specification of `arcTo`](https://html.spec.whatwg.org/multipage/canvas.html#building-paths:dom-context-2d-arcto) /// for more details and examples. pub fn arc_to(&mut self, a: Point, b: Point, radius: f32) { - use lyon::{math, path}; - let start = self.raw.current_position(); let mid = math::Point::new(a.x, a.y); let end = math::Point::new(b.x, b.y); @@ -92,7 +92,7 @@ impl Builder { self.raw.arc_to( math::Vector::new(radius, radius), math::Angle::radians(0.0), - path::ArcFlags { + lyon_path::ArcFlags { large_arc: false, sweep, }, @@ -102,8 +102,6 @@ impl Builder { /// Adds an ellipse to the [`Path`] using a clockwise direction. pub fn ellipse(&mut self, arc: arc::Elliptical) { - use lyon::{geom, math}; - let arc = geom::Arc { center: math::Point::new(arc.center.x, arc.center.y), radii: math::Vector::new(arc.radii.x, arc.radii.y), @@ -128,8 +126,6 @@ impl Builder { control_b: Point, to: Point, ) { - use lyon::math; - let _ = self.raw.cubic_bezier_to( math::Point::new(control_a.x, control_a.y), math::Point::new(control_b.x, control_b.y), @@ -141,8 +137,6 @@ impl Builder { /// and its end point. #[inline] pub fn quadratic_curve_to(&mut self, control: Point, to: Point) { - use lyon::math; - let _ = self.raw.quadratic_bezier_to( math::Point::new(control.x, control.y), math::Point::new(to.x, to.y), diff --git a/graphics/src/widget/canvas/program.rs b/native/src/widget/canvas/program.rs index 656dbfa6..17a5a137 100644 --- a/graphics/src/widget/canvas/program.rs +++ b/native/src/widget/canvas/program.rs @@ -1,6 +1,6 @@ use crate::widget::canvas::event::{self, Event}; use crate::widget::canvas::mouse; -use crate::widget::canvas::{Cursor, Geometry}; +use crate::widget::canvas::{Cursor, Renderer}; use crate::Rectangle; /// The state and logic of a [`Canvas`]. @@ -9,7 +9,10 @@ use crate::Rectangle; /// application. /// /// [`Canvas`]: crate::widget::Canvas -pub trait Program<Message, Theme = iced_native::Theme> { +pub trait Program<Message, Renderer> +where + Renderer: self::Renderer, +{ /// The internal state mutated by the [`Program`]. type State: Default + 'static; @@ -44,10 +47,11 @@ pub trait Program<Message, Theme = iced_native::Theme> { fn draw( &self, state: &Self::State, - theme: &Theme, + renderer: &Renderer, + theme: &Renderer::Theme, bounds: Rectangle, cursor: Cursor, - ) -> Vec<Geometry>; + ) -> Vec<Renderer::Geometry>; /// Returns the current mouse interaction of the [`Program`]. /// @@ -65,9 +69,10 @@ pub trait Program<Message, Theme = iced_native::Theme> { } } -impl<Message, Theme, T> Program<Message, Theme> for &T +impl<Message, Renderer, T> Program<Message, Renderer> for &T where - T: Program<Message, Theme>, + Renderer: self::Renderer, + T: Program<Message, Renderer>, { type State = T::State; @@ -84,11 +89,12 @@ where fn draw( &self, state: &Self::State, - theme: &Theme, + renderer: &Renderer, + theme: &Renderer::Theme, bounds: Rectangle, cursor: Cursor, - ) -> Vec<Geometry> { - T::draw(self, state, theme, bounds, cursor) + ) -> Vec<Renderer::Geometry> { + T::draw(self, state, renderer, theme, bounds, cursor) } fn mouse_interaction( diff --git a/graphics/src/widget/canvas/stroke.rs b/native/src/widget/canvas/stroke.rs index 4c19251d..ab4727b2 100644 --- a/graphics/src/widget/canvas/stroke.rs +++ b/native/src/widget/canvas/stroke.rs @@ -1,7 +1,7 @@ //! Create lines from a [crate::widget::canvas::Path] and assigns them various attributes/styles. pub use crate::widget::canvas::Style; -use iced_native::Color; +use crate::Color; /// The style of a stroke. #[derive(Debug, Clone)] @@ -77,16 +77,6 @@ impl Default for LineCap { } } -impl From<LineCap> for lyon::tessellation::LineCap { - fn from(line_cap: LineCap) -> lyon::tessellation::LineCap { - match line_cap { - LineCap::Butt => lyon::tessellation::LineCap::Butt, - LineCap::Square => lyon::tessellation::LineCap::Square, - LineCap::Round => lyon::tessellation::LineCap::Round, - } - } -} - /// The shape used at the corners of paths or basic shapes when they are /// stroked. #[derive(Debug, Clone, Copy)] @@ -105,16 +95,6 @@ impl Default for LineJoin { } } -impl From<LineJoin> for lyon::tessellation::LineJoin { - fn from(line_join: LineJoin) -> lyon::tessellation::LineJoin { - match line_join { - LineJoin::Miter => lyon::tessellation::LineJoin::Miter, - LineJoin::Round => lyon::tessellation::LineJoin::Round, - LineJoin::Bevel => lyon::tessellation::LineJoin::Bevel, - } - } -} - /// The dash pattern used when stroking the line. #[derive(Debug, Clone, Copy, Default)] pub struct LineDash<'a> { diff --git a/graphics/src/widget/canvas/style.rs b/native/src/widget/canvas/style.rs index 6794f2e7..2642fdb8 100644 --- a/graphics/src/widget/canvas/style.rs +++ b/native/src/widget/canvas/style.rs @@ -1,4 +1,5 @@ -use crate::{Color, Gradient}; +use crate::widget::canvas::Gradient; +use crate::Color; /// The coloring style of some drawing. #[derive(Debug, Clone, PartialEq)] diff --git a/graphics/src/widget/canvas/text.rs b/native/src/widget/canvas/text.rs index 8c0b2dfb..8c0b2dfb 100644 --- a/graphics/src/widget/canvas/text.rs +++ b/native/src/widget/canvas/text.rs |