diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 30b5bb4a..799c1f34 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -20,7 +20,7 @@ //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs //! [WebGPU API]: https://gpuweb.github.io/gpuweb/ //! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph -//#![deny(missing_docs)] +#![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] #![forbid(unsafe_code)] diff --git a/wgpu/src/widget/canvas.rs b/wgpu/src/widget/canvas.rs index a5834330..05306e67 100644 --- a/wgpu/src/widget/canvas.rs +++ b/wgpu/src/widget/canvas.rs @@ -48,12 +48,15 @@ pub use text::Text; /// /// - [`clock`], an application that uses the [`Canvas`] widget to draw a clock /// and its hands to display the current time. +/// - [`game_of_life`], an interactive version of the Game of Life, invented by +/// John Conway. /// - [`solar_system`], an animated solar system drawn using the [`Canvas`] widget /// and showcasing how to compose different transforms. /// -/// [examples]: https://github.com/hecrj/iced/tree/0.1/examples -/// [`clock`]: https://github.com/hecrj/iced/tree/0.1/examples/clock -/// [`solar_system`]: https://github.com/hecrj/iced/tree/0.1/examples/solar_system +/// [examples]: https://github.com/hecrj/iced/tree/master/examples +/// [`clock`]: https://github.com/hecrj/iced/tree/master/examples/clock +/// [`game_of_life`]: https://github.com/hecrj/iced/tree/master/examples/game_of_life +/// [`solar_system`]: https://github.com/hecrj/iced/tree/master/examples/solar_system /// /// ## Drawing a simple circle /// If you want to get a quick overview, here's how we can draw a simple circle: @@ -89,7 +92,7 @@ pub use text::Text; /// } /// } /// -/// // Finally, we simply use our `Cache` to create the `Canvas`! +/// // Finally, we simply use our `Circle` to create the `Canvas`! /// let canvas = Canvas::new(Circle { radius: 50.0 }); /// ``` #[derive(Debug)] diff --git a/wgpu/src/widget/canvas/cache.rs b/wgpu/src/widget/canvas/cache.rs index 03643f74..4b28d164 100644 --- a/wgpu/src/widget/canvas/cache.rs +++ b/wgpu/src/widget/canvas/cache.rs @@ -19,13 +19,14 @@ impl Default for State { State::Empty } } -/// A simple cache that stores generated geometry to avoid recomputation. +/// A simple cache that stores generated [`Geometry`] to avoid recomputation. /// /// A [`Cache`] will not redraw its geometry unless the dimensions of its layer /// change or it is explicitly cleared. /// /// [`Layer`]: ../trait.Layer.html /// [`Cache`]: struct.Cache.html +/// [`Geometry`]: struct.Geometry.html #[derive(Debug, Default)] pub struct Cache { state: RefCell, @@ -41,30 +42,41 @@ impl Cache { } } - /// Clears the cache, forcing a redraw the next time it is used. + /// Clears the [`Cache`], forcing a redraw the next time it is used. /// - /// [`Cached`]: struct.Cached.html + /// [`Cache`]: struct.Cache.html pub fn clear(&mut self) { *self.state.borrow_mut() = State::Empty; } - pub fn draw( - &self, - new_bounds: Size, - draw_fn: impl Fn(&mut Frame), - ) -> Geometry { + /// Draws [`Geometry`] using the provided closure and stores it in the + /// [`Cache`]. + /// + /// The closure will only be called when + /// - the bounds have changed since the previous draw call. + /// - the [`Cache`] is empty or has been explicitly cleared. + /// + /// Otherwise, the previously stored [`Geometry`] will be returned. The + /// [`Cache`] is not cleared in this case. In other words, it will keep + /// returning the stored [`Geometry`] if needed. + /// + /// [`Cache`]: struct.Cache.html + pub fn draw(&self, bounds: Size, draw_fn: impl Fn(&mut Frame)) -> Geometry { use std::ops::Deref; - if let State::Filled { bounds, primitive } = self.state.borrow().deref() + if let State::Filled { + bounds: cached_bounds, + primitive, + } = self.state.borrow().deref() { - if *bounds == new_bounds { + if *cached_bounds == bounds { return Geometry::from_primitive(Primitive::Cached { cache: primitive.clone(), }); } } - let mut frame = Frame::new(new_bounds); + let mut frame = Frame::new(bounds); draw_fn(&mut frame); let primitive = { @@ -74,7 +86,7 @@ impl Cache { }; *self.state.borrow_mut() = State::Filled { - bounds: new_bounds, + bounds, primitive: primitive.clone(), }; diff --git a/wgpu/src/widget/canvas/cursor.rs b/wgpu/src/widget/canvas/cursor.rs index 7ab58b87..456760ea 100644 --- a/wgpu/src/widget/canvas/cursor.rs +++ b/wgpu/src/widget/canvas/cursor.rs @@ -1,8 +1,12 @@ use iced_native::{Point, Rectangle}; +/// The mouse cursor state. #[derive(Debug, Clone, Copy, PartialEq)] pub enum Cursor { + /// The cursor has a defined position. Available(Point), + + /// The cursor is currently unavailable (i.e. out of bounds or busy). Unavailable, } @@ -17,6 +21,9 @@ impl Cursor { } } + /// Returns the absolute position of the [`Cursor`], if available. + /// + /// [`Cursor`]: enum.Cursor.html pub fn position(&self) -> Option { match self { Cursor::Available(position) => Some(*position), @@ -24,6 +31,13 @@ impl Cursor { } } + /// Returns the relative position of the [`Cursor`] inside the given bounds, + /// if available. + /// + /// If the [`Cursor`] is not over the provided bounds, this method will + /// return `None`. + /// + /// [`Cursor`]: enum.Cursor.html pub fn position_in(&self, bounds: &Rectangle) -> Option { if self.is_over(bounds) { self.position_from(bounds.position()) @@ -32,6 +46,10 @@ impl Cursor { } } + /// Returns the relative position of the [`Cursor`] from the given origin, + /// if available. + /// + /// [`Cursor`]: enum.Cursor.html pub fn position_from(&self, origin: Point) -> Option { match self { Cursor::Available(position) => { @@ -41,6 +59,10 @@ impl Cursor { } } + /// Returns whether the [`Cursor`] is currently over the provided bounds + /// or not. + /// + /// [`Cursor`]: enum.Cursor.html pub fn is_over(&self, bounds: &Rectangle) -> bool { match self { Cursor::Available(position) => bounds.contains(*position), diff --git a/wgpu/src/widget/canvas/event.rs b/wgpu/src/widget/canvas/event.rs index 4e7c1869..ad11f51e 100644 --- a/wgpu/src/widget/canvas/event.rs +++ b/wgpu/src/widget/canvas/event.rs @@ -1,6 +1,10 @@ use iced_native::mouse; +/// A [`Canvas`] event. +/// +/// [`Canvas`]: struct.Event.html #[derive(Debug, Clone, Copy, PartialEq)] pub enum Event { + /// A mouse event. Mouse(mouse::Event), } diff --git a/wgpu/src/widget/canvas/geometry.rs b/wgpu/src/widget/canvas/geometry.rs index 12ef828f..4cadee39 100644 --- a/wgpu/src/widget/canvas/geometry.rs +++ b/wgpu/src/widget/canvas/geometry.rs @@ -1,5 +1,13 @@ use crate::Primitive; +/// A bunch of shapes that can be drawn. +/// +/// [`Geometry`] can be easily generated with a [`Frame`] or stored in a +/// [`Cache`]. +/// +/// [`Geometry`]: struct.Geometry.html +/// [`Frame`]: struct.Frame.html +/// [`Cache`]: struct.Cache.html #[derive(Debug, Clone)] pub struct Geometry(Primitive); @@ -8,6 +16,12 @@ impl Geometry { Self(primitive) } + /// Turns the [`Geometry`] into a [`Primitive`]. + /// + /// This can be useful if you are building a custom widget. + /// + /// [`Geometry`]: struct.Geometry.html + /// [`Primitive`]: ../enum.Primitive.html pub fn into_primitive(self) -> Primitive { self.0 } diff --git a/wgpu/src/widget/canvas/program.rs b/wgpu/src/widget/canvas/program.rs index f8e54514..5b995bfa 100644 --- a/wgpu/src/widget/canvas/program.rs +++ b/wgpu/src/widget/canvas/program.rs @@ -1,7 +1,27 @@ use crate::canvas::{Cursor, Event, Geometry}; use iced_native::{MouseCursor, Rectangle}; +/// The state and logic of a [`Canvas`]. +/// +/// A [`Program`] can mutate internal state and produce messages for an +/// application. +/// +/// [`Canvas`]: struct.Canvas.html +/// [`Program`]: trait.Program.html pub trait Program { + /// Updates the state of the [`Program`]. + /// + /// When a [`Program`] is used in a [`Canvas`], the runtime will call this + /// method for each [`Event`]. + /// + /// This method can optionally return a `Message` to notify an application + /// of any meaningful interactions. + /// + /// By default, this method does and returns nothing. + /// + /// [`Program`]: trait.Program.html + /// [`Canvas`]: struct.Canvas.html + /// [`Event`]: enum.Event.html fn update( &mut self, _event: Event, @@ -11,8 +31,24 @@ pub trait Program { None } + /// Draws the state of the [`Program`], producing a bunch of [`Geometry`]. + /// + /// [`Geometry`] can be easily generated with a [`Frame`] or stored in a + /// [`Cache`]. + /// + /// [`Program`]: trait.Program.html + /// [`Geometry`]: struct.Geometry.html + /// [`Frame`]: struct.Frame.html + /// [`Cache`]: struct.Cache.html fn draw(&self, bounds: Rectangle, cursor: Cursor) -> Vec; + /// Returns the mouse cursor state of the [`Program`]. + /// + /// The mouse cursor returned will be in effect even if the cursor position + /// is out of bounds of the program's [`Canvas`]. + /// + /// [`Program`]: trait.Program.html + /// [`Canvas`]: struct.Canvas.html fn mouse_cursor(&self, _bounds: Rectangle, _cursor: Cursor) -> MouseCursor { MouseCursor::default() } diff --git a/wgpu/src/widget/canvas/stroke.rs b/wgpu/src/widget/canvas/stroke.rs index e20379cd..5b6fc56a 100644 --- a/wgpu/src/widget/canvas/stroke.rs +++ b/wgpu/src/widget/canvas/stroke.rs @@ -15,18 +15,32 @@ pub struct Stroke { } impl Stroke { + /// Sets the color of the [`Stroke`]. + /// + /// [`Stroke`]: struct.Stroke.html pub fn with_color(self, color: Color) -> Stroke { Stroke { color, ..self } } + /// Sets the width of the [`Stroke`]. + /// + /// [`Stroke`]: struct.Stroke.html pub fn with_width(self, width: f32) -> Stroke { Stroke { width, ..self } } + /// Sets the [`LineCap`] of the [`Stroke`]. + /// + /// [`LineCap`]: enum.LineCap.html + /// [`Stroke`]: struct.Stroke.html pub fn with_line_cap(self, line_cap: LineCap) -> Stroke { Stroke { line_cap, ..self } } + /// Sets the [`LineJoin`] of the [`Stroke`]. + /// + /// [`LineJoin`]: enum.LineJoin.html + /// [`Stroke`]: struct.Stroke.html pub fn with_line_join(self, line_join: LineJoin) -> Stroke { Stroke { line_join, ..self } }