diff options
Diffstat (limited to '')
| -rw-r--r-- | graphics/src/widget.rs | 59 | ||||
| -rw-r--r-- | graphics/src/widget/button.rs (renamed from wgpu/src/renderer/widget/button.rs) | 26 | ||||
| -rw-r--r-- | graphics/src/widget/canvas.rs | 236 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/cache.rs (renamed from wgpu/src/widget/canvas/cache.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/cursor.rs (renamed from wgpu/src/widget/canvas/cursor.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/event.rs (renamed from wgpu/src/widget/canvas/event.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/fill.rs (renamed from wgpu/src/widget/canvas/fill.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/frame.rs (renamed from wgpu/src/widget/canvas/frame.rs) | 2 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/geometry.rs (renamed from wgpu/src/widget/canvas/geometry.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/path.rs (renamed from wgpu/src/widget/canvas/path.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/path/arc.rs (renamed from wgpu/src/widget/canvas/path/arc.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/path/builder.rs (renamed from wgpu/src/widget/canvas/path/builder.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/program.rs (renamed from wgpu/src/widget/canvas/program.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/stroke.rs (renamed from wgpu/src/widget/canvas/stroke.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/canvas/text.rs (renamed from wgpu/src/widget/canvas/text.rs) | 0 | ||||
| -rw-r--r-- | graphics/src/widget/checkbox.rs (renamed from wgpu/src/renderer/widget/checkbox.rs) | 27 | ||||
| -rw-r--r-- | graphics/src/widget/column.rs (renamed from wgpu/src/renderer/widget/row.rs) | 19 | ||||
| -rw-r--r-- | graphics/src/widget/container.rs (renamed from wgpu/src/renderer/widget/container.rs) | 19 | ||||
| -rw-r--r-- | graphics/src/widget/image.rs (renamed from wgpu/src/renderer/widget/image.rs) | 15 | ||||
| -rw-r--r-- | graphics/src/widget/pane_grid.rs (renamed from wgpu/src/renderer/widget/pane_grid.rs) | 37 | ||||
| -rw-r--r-- | graphics/src/widget/progress_bar.rs (renamed from wgpu/src/renderer/widget/progress_bar.rs) | 25 | ||||
| -rw-r--r-- | graphics/src/widget/radio.rs (renamed from wgpu/src/renderer/widget/radio.rs) | 21 | ||||
| -rw-r--r-- | graphics/src/widget/row.rs (renamed from wgpu/src/renderer/widget/column.rs) | 15 | ||||
| -rw-r--r-- | graphics/src/widget/scrollable.rs (renamed from wgpu/src/renderer/widget/scrollable.rs) | 23 | ||||
| -rw-r--r-- | graphics/src/widget/slider.rs (renamed from wgpu/src/renderer/widget/slider.rs) | 30 | ||||
| -rw-r--r-- | graphics/src/widget/space.rs | 15 | ||||
| -rw-r--r-- | graphics/src/widget/svg.rs (renamed from wgpu/src/renderer/widget/svg.rs) | 11 | ||||
| -rw-r--r-- | graphics/src/widget/text.rs (renamed from wgpu/src/renderer/widget/text.rs) | 19 | ||||
| -rw-r--r-- | graphics/src/widget/text_input.rs (renamed from wgpu/src/renderer/widget/text_input.rs) | 47 | 
29 files changed, 581 insertions, 65 deletions
| diff --git a/graphics/src/widget.rs b/graphics/src/widget.rs new file mode 100644 index 00000000..1f6d6559 --- /dev/null +++ b/graphics/src/widget.rs @@ -0,0 +1,59 @@ +//! Use the widgets supported out-of-the-box. +//! +//! # Re-exports +//! For convenience, the contents of this module are available at the root +//! module. Therefore, you can directly type: +//! +//! ``` +//! use iced_graphics::{button, Button}; +//! ``` +pub mod button; +pub mod checkbox; +pub mod container; +pub mod image; +pub mod pane_grid; +pub mod progress_bar; +pub mod radio; +pub mod scrollable; +pub mod slider; +pub mod svg; +pub mod text_input; + +mod column; +mod row; +mod space; +mod text; + +#[doc(no_inline)] +pub use button::Button; +#[doc(no_inline)] +pub use checkbox::Checkbox; +#[doc(no_inline)] +pub use container::Container; +#[doc(no_inline)] +pub use pane_grid::PaneGrid; +#[doc(no_inline)] +pub use progress_bar::ProgressBar; +#[doc(no_inline)] +pub use radio::Radio; +#[doc(no_inline)] +pub use scrollable::Scrollable; +#[doc(no_inline)] +pub use slider::Slider; +#[doc(no_inline)] +pub use text_input::TextInput; + +pub use column::Column; +pub use image::Image; +pub use row::Row; +pub use space::Space; +pub use svg::Svg; +pub use text::Text; + +#[cfg(feature = "canvas")] +#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))] +pub mod canvas; + +#[cfg(feature = "canvas")] +#[doc(no_inline)] +pub use canvas::Canvas; diff --git a/wgpu/src/renderer/widget/button.rs b/graphics/src/widget/button.rs index eb225038..aeb862d5 100644 --- a/wgpu/src/renderer/widget/button.rs +++ b/graphics/src/widget/button.rs @@ -1,9 +1,29 @@ -use crate::{button::StyleSheet, defaults, Defaults, Primitive, Renderer}; +//! Allow your users to perform actions by pressing a button. +//! +//! A [`Button`] has some local [`State`]. +//! +//! [`Button`]: type.Button.html +//! [`State`]: struct.State.html +use crate::defaults::{self, Defaults}; +use crate::{Backend, Primitive, Renderer}; +use iced_native::mouse;  use iced_native::{ -    mouse, Background, Color, Element, Layout, Point, Rectangle, Vector, +    Background, Color, Element, Layout, Point, Rectangle, Vector,  }; -impl iced_native::button::Renderer for Renderer { +pub use iced_native::button::State; +pub use iced_style::button::{Style, StyleSheet}; + +/// A widget that produces a message when clicked. +/// +/// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`. +pub type Button<'a, Message, Backend> = +    iced_native::Button<'a, Message, Renderer<Backend>>; + +impl<B> iced_native::button::Renderer for Renderer<B> +where +    B: Backend, +{      const DEFAULT_PADDING: u16 = 5;      type Style = Box<dyn StyleSheet>; diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs new file mode 100644 index 00000000..d393a5c5 --- /dev/null +++ b/graphics/src/widget/canvas.rs @@ -0,0 +1,236 @@ +//! 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! +//! +//! [`Canvas`]: struct.Canvas.html +//! [`Frame`]: struct.Frame.html +use crate::{Backend, Defaults, Primitive, Renderer}; +use iced_native::{ +    layout, mouse, Clipboard, Element, Hasher, Layout, Length, Point, Size, +    Vector, Widget, +}; +use std::hash::Hash; +use std::marker::PhantomData; + +pub mod path; + +mod cache; +mod cursor; +mod event; +mod fill; +mod frame; +mod geometry; +mod program; +mod stroke; +mod text; + +pub use cache::Cache; +pub use cursor::Cursor; +pub use event::Event; +pub use fill::Fill; +pub use frame::Frame; +pub use geometry::Geometry; +pub use path::Path; +pub use program::Program; +pub use stroke::{LineCap, LineJoin, Stroke}; +pub use text::Text; + +/// A widget capable of drawing 2D graphics. +/// +/// [`Canvas`]: struct.Canvas.html +/// +/// # Examples +/// The repository has a couple of [examples] showcasing how to use a +/// [`Canvas`]: +/// +/// - [`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/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: +/// +/// ```no_run +/// # mod iced { +/// #     pub use iced_graphics::canvas; +/// #     pub use iced_native::{Color, Rectangle}; +/// # } +/// use iced::canvas::{self, Canvas, Cursor, Fill, Frame, Geometry, Path, Program}; +/// use iced::{Color, Rectangle}; +/// +/// // First, we define the data we need for drawing +/// #[derive(Debug)] +/// struct Circle { +///     radius: f32, +/// } +/// +/// // Then, we implement the `Program` trait +/// impl Program<()> for Circle { +///     fn draw(&self, bounds: Rectangle, _cursor: Cursor) -> Vec<Geometry>{ +///         // We prepare a new `Frame` +///         let mut frame = Frame::new(bounds.size()); +/// +///         // We create a `Path` representing a simple circle +///         let circle = Path::circle(frame.center(), self.radius); +/// +///         // And fill it with some color +///         frame.fill(&circle, Fill::Color(Color::BLACK)); +/// +///         // Finally, we produce the geometry +///         vec![frame.into_geometry()] +///     } +/// } +/// +/// // Finally, we simply use our `Circle` to create the `Canvas`! +/// let canvas = Canvas::new(Circle { radius: 50.0 }); +/// ``` +#[derive(Debug)] +pub struct Canvas<Message, P: Program<Message>> { +    width: Length, +    height: Length, +    program: P, +    phantom: PhantomData<Message>, +} + +impl<Message, P: Program<Message>> Canvas<Message, P> { +    const DEFAULT_SIZE: u16 = 100; + +    /// Creates a new [`Canvas`]. +    /// +    /// [`Canvas`]: struct.Canvas.html +    pub fn new(program: P) -> Self { +        Canvas { +            width: Length::Units(Self::DEFAULT_SIZE), +            height: Length::Units(Self::DEFAULT_SIZE), +            program, +            phantom: PhantomData, +        } +    } + +    /// Sets the width of the [`Canvas`]. +    /// +    /// [`Canvas`]: struct.Canvas.html +    pub fn width(mut self, width: Length) -> Self { +        self.width = width; +        self +    } + +    /// Sets the height of the [`Canvas`]. +    /// +    /// [`Canvas`]: struct.Canvas.html +    pub fn height(mut self, height: Length) -> Self { +        self.height = height; +        self +    } +} + +impl<Message, P, B> Widget<Message, Renderer<B>> for Canvas<Message, P> +where +    P: Program<Message>, +    B: Backend, +{ +    fn width(&self) -> Length { +        self.width +    } + +    fn height(&self) -> Length { +        self.height +    } + +    fn layout( +        &self, +        _renderer: &Renderer<B>, +        limits: &layout::Limits, +    ) -> layout::Node { +        let limits = limits.width(self.width).height(self.height); +        let size = limits.resolve(Size::ZERO); + +        layout::Node::new(size) +    } + +    fn on_event( +        &mut self, +        event: iced_native::Event, +        layout: Layout<'_>, +        cursor_position: Point, +        messages: &mut Vec<Message>, +        _renderer: &Renderer<B>, +        _clipboard: Option<&dyn Clipboard>, +    ) { +        let bounds = layout.bounds(); + +        let canvas_event = match event { +            iced_native::Event::Mouse(mouse_event) => { +                Some(Event::Mouse(mouse_event)) +            } +            _ => None, +        }; + +        let cursor = Cursor::from_window_position(cursor_position); + +        if let Some(canvas_event) = canvas_event { +            if let Some(message) = +                self.program.update(canvas_event, bounds, cursor) +            { +                messages.push(message); +            } +        } +    } + +    fn draw( +        &self, +        _renderer: &mut Renderer<B>, +        _defaults: &Defaults, +        layout: Layout<'_>, +        cursor_position: Point, +    ) -> (Primitive, mouse::Interaction) { +        let bounds = layout.bounds(); +        let translation = Vector::new(bounds.x, bounds.y); +        let cursor = Cursor::from_window_position(cursor_position); + +        ( +            Primitive::Translate { +                translation, +                content: Box::new(Primitive::Group { +                    primitives: self +                        .program +                        .draw(bounds, cursor) +                        .into_iter() +                        .map(Geometry::into_primitive) +                        .collect(), +                }), +            }, +            self.program.mouse_interaction(bounds, cursor), +        ) +    } + +    fn hash_layout(&self, state: &mut Hasher) { +        struct Marker; +        std::any::TypeId::of::<Marker>().hash(state); + +        self.width.hash(state); +        self.height.hash(state); +    } +} + +impl<'a, Message, P, B> From<Canvas<Message, P>> +    for Element<'a, Message, Renderer<B>> +where +    Message: 'static, +    P: Program<Message> + 'a, +    B: Backend, +{ +    fn from(canvas: Canvas<Message, P>) -> Element<'a, Message, Renderer<B>> { +        Element::new(canvas) +    } +} diff --git a/wgpu/src/widget/canvas/cache.rs b/graphics/src/widget/canvas/cache.rs index 4b28d164..4b28d164 100644 --- a/wgpu/src/widget/canvas/cache.rs +++ b/graphics/src/widget/canvas/cache.rs diff --git a/wgpu/src/widget/canvas/cursor.rs b/graphics/src/widget/canvas/cursor.rs index 456760ea..456760ea 100644 --- a/wgpu/src/widget/canvas/cursor.rs +++ b/graphics/src/widget/canvas/cursor.rs diff --git a/wgpu/src/widget/canvas/event.rs b/graphics/src/widget/canvas/event.rs index ad11f51e..ad11f51e 100644 --- a/wgpu/src/widget/canvas/event.rs +++ b/graphics/src/widget/canvas/event.rs diff --git a/wgpu/src/widget/canvas/fill.rs b/graphics/src/widget/canvas/fill.rs index a2010e45..a2010e45 100644 --- a/wgpu/src/widget/canvas/fill.rs +++ b/graphics/src/widget/canvas/fill.rs diff --git a/wgpu/src/widget/canvas/frame.rs b/graphics/src/widget/canvas/frame.rs index 5262ab4e..48d28d95 100644 --- a/wgpu/src/widget/canvas/frame.rs +++ b/graphics/src/widget/canvas/frame.rs @@ -304,11 +304,11 @@ impl Frame {      pub fn into_geometry(mut self) -> Geometry {          if !self.buffers.indices.is_empty() {              self.primitives.push(Primitive::Mesh2D { -                size: self.size,                  buffers: triangle::Mesh2D {                      vertices: self.buffers.vertices,                      indices: self.buffers.indices,                  }, +                size: self.size,              });          } diff --git a/wgpu/src/widget/canvas/geometry.rs b/graphics/src/widget/canvas/geometry.rs index 4cadee39..4cadee39 100644 --- a/wgpu/src/widget/canvas/geometry.rs +++ b/graphics/src/widget/canvas/geometry.rs diff --git a/wgpu/src/widget/canvas/path.rs b/graphics/src/widget/canvas/path.rs index c26bf187..c26bf187 100644 --- a/wgpu/src/widget/canvas/path.rs +++ b/graphics/src/widget/canvas/path.rs diff --git a/wgpu/src/widget/canvas/path/arc.rs b/graphics/src/widget/canvas/path/arc.rs index 343191f1..343191f1 100644 --- a/wgpu/src/widget/canvas/path/arc.rs +++ b/graphics/src/widget/canvas/path/arc.rs diff --git a/wgpu/src/widget/canvas/path/builder.rs b/graphics/src/widget/canvas/path/builder.rs index 6511fa52..6511fa52 100644 --- a/wgpu/src/widget/canvas/path/builder.rs +++ b/graphics/src/widget/canvas/path/builder.rs diff --git a/wgpu/src/widget/canvas/program.rs b/graphics/src/widget/canvas/program.rs index 725d9d72..725d9d72 100644 --- a/wgpu/src/widget/canvas/program.rs +++ b/graphics/src/widget/canvas/program.rs diff --git a/wgpu/src/widget/canvas/stroke.rs b/graphics/src/widget/canvas/stroke.rs index 5b6fc56a..5b6fc56a 100644 --- a/wgpu/src/widget/canvas/stroke.rs +++ b/graphics/src/widget/canvas/stroke.rs diff --git a/wgpu/src/widget/canvas/text.rs b/graphics/src/widget/canvas/text.rs index c4cae30e..c4cae30e 100644 --- a/wgpu/src/widget/canvas/text.rs +++ b/graphics/src/widget/canvas/text.rs diff --git a/wgpu/src/renderer/widget/checkbox.rs b/graphics/src/widget/checkbox.rs index 0340bf62..cb7fd2cf 100644 --- a/wgpu/src/renderer/widget/checkbox.rs +++ b/graphics/src/widget/checkbox.rs @@ -1,9 +1,22 @@ -use crate::{checkbox::StyleSheet, Primitive, Renderer}; -use iced_native::{ -    checkbox, mouse, HorizontalAlignment, Rectangle, VerticalAlignment, -}; +//! Show toggle controls using checkboxes. +use crate::backend::{self, Backend}; +use crate::{Primitive, Renderer}; +use iced_native::checkbox; +use iced_native::mouse; +use iced_native::{HorizontalAlignment, Rectangle, VerticalAlignment}; -impl checkbox::Renderer for Renderer { +pub use iced_style::checkbox::{Style, StyleSheet}; + +/// A box that can be checked. +/// +/// This is an alias of an `iced_native` checkbox with an `iced_wgpu::Renderer`. +pub type Checkbox<Message, Backend> = +    iced_native::Checkbox<Message, Renderer<Backend>>; + +impl<B> checkbox::Renderer for Renderer<B> +where +    B: Backend + backend::Text, +{      type Style = Box<dyn StyleSheet>;      const DEFAULT_SIZE: u16 = 20; @@ -35,8 +48,8 @@ impl checkbox::Renderer for Renderer {              Primitive::Group {                  primitives: if is_checked {                      let check = Primitive::Text { -                        content: crate::text::CHECKMARK_ICON.to_string(), -                        font: crate::text::BUILTIN_ICONS, +                        content: B::CHECKMARK_ICON.to_string(), +                        font: B::ICON_FONT,                          size: bounds.height * 0.7,                          bounds: Rectangle {                              x: bounds.center_x(), diff --git a/wgpu/src/renderer/widget/row.rs b/graphics/src/widget/column.rs index d0b7ef09..6c7235c7 100644 --- a/wgpu/src/renderer/widget/row.rs +++ b/graphics/src/widget/column.rs @@ -1,11 +1,20 @@ -use crate::{Primitive, Renderer}; -use iced_native::{mouse, row, Element, Layout, Point}; +use crate::{Backend, Primitive, Renderer}; +use iced_native::column; +use iced_native::mouse; +use iced_native::{Element, Layout, Point}; -impl row::Renderer for Renderer { +/// A container that distributes its contents vertically. +pub type Column<'a, Message, Backend> = +    iced_native::Column<'a, Message, Renderer<Backend>>; + +impl<B> column::Renderer for Renderer<B> +where +    B: Backend, +{      fn draw<Message>(          &mut self,          defaults: &Self::Defaults, -        children: &[Element<'_, Message, Self>], +        content: &[Element<'_, Message, Self>],          layout: Layout<'_>,          cursor_position: Point,      ) -> Self::Output { @@ -13,7 +22,7 @@ impl row::Renderer for Renderer {          (              Primitive::Group { -                primitives: children +                primitives: content                      .iter()                      .zip(layout.children())                      .map(|(child, layout)| { diff --git a/wgpu/src/renderer/widget/container.rs b/graphics/src/widget/container.rs index 30cc3f07..070cb48b 100644 --- a/wgpu/src/renderer/widget/container.rs +++ b/graphics/src/widget/container.rs @@ -1,7 +1,22 @@ -use crate::{container, defaults, Defaults, Primitive, Renderer}; +//! Decorate content and apply alignment. +use crate::container; +use crate::defaults::{self, Defaults}; +use crate::{Backend, Primitive, Renderer};  use iced_native::{Background, Color, Element, Layout, Point, Rectangle}; -impl iced_native::container::Renderer for Renderer { +pub use iced_style::container::{Style, StyleSheet}; + +/// An element decorating some content. +/// +/// This is an alias of an `iced_native` container with a default +/// `Renderer`. +pub type Container<'a, Message, Backend> = +    iced_native::Container<'a, Message, Renderer<Backend>>; + +impl<B> iced_native::container::Renderer for Renderer<B> +where +    B: Backend, +{      type Style = Box<dyn container::StyleSheet>;      fn draw<Message>( diff --git a/wgpu/src/renderer/widget/image.rs b/graphics/src/widget/image.rs index c4c04984..30f446e8 100644 --- a/wgpu/src/renderer/widget/image.rs +++ b/graphics/src/widget/image.rs @@ -1,9 +1,18 @@ +//! Display images in your user interface. +use crate::backend::{self, Backend};  use crate::{Primitive, Renderer}; -use iced_native::{image, mouse, Layout}; +use iced_native::image; +use iced_native::mouse; +use iced_native::Layout; -impl image::Renderer for Renderer { +pub use iced_native::image::{Handle, Image}; + +impl<B> image::Renderer for Renderer<B> +where +    B: Backend + backend::Image, +{      fn dimensions(&self, handle: &image::Handle) -> (u32, u32) { -        self.image_pipeline.dimensions(handle) +        self.backend().dimensions(handle)      }      fn draw( diff --git a/wgpu/src/renderer/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs index 2253e4af..56af683d 100644 --- a/wgpu/src/renderer/widget/pane_grid.rs +++ b/graphics/src/widget/pane_grid.rs @@ -1,11 +1,36 @@ -use crate::{Primitive, Renderer}; -use iced_native::{ -    mouse, -    pane_grid::{self, Axis, Pane}, -    Element, Layout, Point, Rectangle, Vector, +//! Let your users split regions of your application and organize layout dynamically. +//! +//! [](https://gfycat.com/mixedflatjellyfish) +//! +//! # Example +//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing, +//! drag and drop, and hotkey support. +//! +//! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.1/examples/pane_grid +//! [`PaneGrid`]: type.PaneGrid.html +use crate::{Backend, Primitive, Renderer}; +use iced_native::mouse; +use iced_native::pane_grid; +use iced_native::{Element, Layout, Point, Rectangle, Vector}; + +pub use iced_native::pane_grid::{ +    Axis, Direction, DragEvent, Focus, KeyPressEvent, Pane, ResizeEvent, Split, +    State,  }; -impl pane_grid::Renderer for Renderer { +/// A collection of panes distributed using either vertical or horizontal splits +/// to completely fill the space available. +/// +/// [](https://gfycat.com/mixedflatjellyfish) +/// +/// This is an alias of an `iced_native` pane grid with an `iced_wgpu::Renderer`. +pub type PaneGrid<'a, Message, Backend> = +    iced_native::PaneGrid<'a, Message, Renderer<Backend>>; + +impl<B> pane_grid::Renderer for Renderer<B> +where +    B: Backend, +{      fn draw<Message>(          &mut self,          defaults: &Self::Defaults, diff --git a/wgpu/src/renderer/widget/progress_bar.rs b/graphics/src/widget/progress_bar.rs index 2baeeb14..48acb3c1 100644 --- a/wgpu/src/renderer/widget/progress_bar.rs +++ b/graphics/src/widget/progress_bar.rs @@ -1,7 +1,26 @@ -use crate::{progress_bar::StyleSheet, Primitive, Renderer}; -use iced_native::{mouse, progress_bar, Color, Rectangle}; +//! Allow your users to visually track the progress of a computation. +//! +//! A [`ProgressBar`] has a range of possible values and a current value, +//! as well as a length, height and style. +//! +//! [`ProgressBar`]: type.ProgressBar.html +use crate::{Backend, Primitive, Renderer}; +use iced_native::mouse; +use iced_native::progress_bar; +use iced_native::{Color, Rectangle}; -impl progress_bar::Renderer for Renderer { +pub use iced_style::progress_bar::{Style, StyleSheet}; + +/// A bar that displays progress. +/// +/// This is an alias of an `iced_native` progress bar with an +/// `iced_wgpu::Renderer`. +pub type ProgressBar<Backend> = iced_native::ProgressBar<Renderer<Backend>>; + +impl<B> progress_bar::Renderer for Renderer<B> +where +    B: Backend, +{      type Style = Box<dyn StyleSheet>;      const DEFAULT_HEIGHT: u16 = 30; diff --git a/wgpu/src/renderer/widget/radio.rs b/graphics/src/widget/radio.rs index cee0deb6..dd8b5f17 100644 --- a/wgpu/src/renderer/widget/radio.rs +++ b/graphics/src/widget/radio.rs @@ -1,10 +1,25 @@ -use crate::{radio::StyleSheet, Primitive, Renderer}; -use iced_native::{mouse, radio, Background, Color, Rectangle}; +//! Create choices using radio buttons. +use crate::{Backend, Primitive, Renderer}; +use iced_native::mouse; +use iced_native::radio; +use iced_native::{Background, Color, Rectangle}; + +pub use iced_style::radio::{Style, StyleSheet}; + +/// A circular button representing a choice. +/// +/// This is an alias of an `iced_native` radio button with an +/// `iced_wgpu::Renderer`. +pub type Radio<Message, Backend> = +    iced_native::Radio<Message, Renderer<Backend>>;  const SIZE: f32 = 28.0;  const DOT_SIZE: f32 = SIZE / 2.0; -impl radio::Renderer for Renderer { +impl<B> radio::Renderer for Renderer<B> +where +    B: Backend, +{      type Style = Box<dyn StyleSheet>;      const DEFAULT_SIZE: u16 = SIZE as u16; diff --git a/wgpu/src/renderer/widget/column.rs b/graphics/src/widget/row.rs index b853276d..4c1dbadc 100644 --- a/wgpu/src/renderer/widget/column.rs +++ b/graphics/src/widget/row.rs @@ -1,7 +1,16 @@ -use crate::{Primitive, Renderer}; -use iced_native::{column, mouse, Element, Layout, Point}; +use crate::{Backend, Primitive, Renderer}; +use iced_native::mouse; +use iced_native::row; +use iced_native::{Element, Layout, Point}; -impl column::Renderer for Renderer { +/// A container that distributes its contents horizontally. +pub type Row<'a, Message, Backend> = +    iced_native::Row<'a, Message, Renderer<Backend>>; + +impl<B> row::Renderer for Renderer<B> +where +    B: Backend, +{      fn draw<Message>(          &mut self,          defaults: &Self::Defaults, diff --git a/wgpu/src/renderer/widget/scrollable.rs b/graphics/src/widget/scrollable.rs index 8a400b82..b149db0a 100644 --- a/wgpu/src/renderer/widget/scrollable.rs +++ b/graphics/src/widget/scrollable.rs @@ -1,10 +1,27 @@ -use crate::{Primitive, Renderer}; -use iced_native::{mouse, scrollable, Background, Color, Rectangle, Vector}; +//! Navigate an endless amount of content with a scrollbar. +use crate::{Backend, Primitive, Renderer}; +use iced_native::mouse; +use iced_native::scrollable; +use iced_native::{Background, Color, Rectangle, Vector}; + +pub use iced_native::scrollable::State; +pub use iced_style::scrollable::{Scrollbar, Scroller, StyleSheet}; + +/// A widget that can vertically display an infinite amount of content +/// with a scrollbar. +/// +/// This is an alias of an `iced_native` scrollable with a default +/// `Renderer`. +pub type Scrollable<'a, Message, Backend> = +    iced_native::Scrollable<'a, Message, Renderer<Backend>>;  const SCROLLBAR_WIDTH: u16 = 10;  const SCROLLBAR_MARGIN: u16 = 2; -impl scrollable::Renderer for Renderer { +impl<B> scrollable::Renderer for Renderer<B> +where +    B: Backend, +{      type Style = Box<dyn iced_style::scrollable::StyleSheet>;      fn scrollbar( diff --git a/wgpu/src/renderer/widget/slider.rs b/graphics/src/widget/slider.rs index 220feace..b00cde9a 100644 --- a/wgpu/src/renderer/widget/slider.rs +++ b/graphics/src/widget/slider.rs @@ -1,12 +1,30 @@ -use crate::{ -    slider::{HandleShape, StyleSheet}, -    Primitive, Renderer, -}; -use iced_native::{mouse, slider, Background, Color, Point, Rectangle}; +//! Display an interactive selector of a single value from a range of values. +//! +//! A [`Slider`] has some local [`State`]. +//! +//! [`Slider`]: struct.Slider.html +//! [`State`]: struct.State.html +use crate::{Backend, Primitive, Renderer}; +use iced_native::mouse; +use iced_native::slider; +use iced_native::{Background, Color, Point, Rectangle}; + +pub use iced_native::slider::State; +pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet}; + +/// An horizontal bar and a handle that selects a single value from a range of +/// values. +/// +/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`. +pub type Slider<'a, Message, Backend> = +    iced_native::Slider<'a, Message, Renderer<Backend>>;  const HANDLE_HEIGHT: f32 = 22.0; -impl slider::Renderer for Renderer { +impl<B> slider::Renderer for Renderer<B> +where +    B: Backend, +{      type Style = Box<dyn StyleSheet>;      fn height(&self) -> u32 { diff --git a/graphics/src/widget/space.rs b/graphics/src/widget/space.rs new file mode 100644 index 00000000..1f31eabe --- /dev/null +++ b/graphics/src/widget/space.rs @@ -0,0 +1,15 @@ +use crate::{Backend, Primitive, Renderer}; +use iced_native::mouse; +use iced_native::space; +use iced_native::Rectangle; + +pub use iced_native::Space; + +impl<B> space::Renderer for Renderer<B> +where +    B: Backend, +{ +    fn draw(&mut self, _bounds: Rectangle) -> Self::Output { +        (Primitive::None, mouse::Interaction::default()) +    } +} diff --git a/wgpu/src/renderer/widget/svg.rs b/graphics/src/widget/svg.rs index f6d6d0ba..8b5ed66a 100644 --- a/wgpu/src/renderer/widget/svg.rs +++ b/graphics/src/widget/svg.rs @@ -1,9 +1,16 @@ +//! Display vector graphics in your application. +use crate::backend::{self, Backend};  use crate::{Primitive, Renderer};  use iced_native::{mouse, svg, Layout}; -impl svg::Renderer for Renderer { +pub use iced_native::svg::{Handle, Svg}; + +impl<B> svg::Renderer for Renderer<B> +where +    B: Backend + backend::Svg, +{      fn dimensions(&self, handle: &svg::Handle) -> (u32, u32) { -        self.image_pipeline.viewport_dimensions(handle) +        self.backend().viewport_dimensions(handle)      }      fn draw( diff --git a/wgpu/src/renderer/widget/text.rs b/graphics/src/widget/text.rs index 4605ed06..327f8e29 100644 --- a/wgpu/src/renderer/widget/text.rs +++ b/graphics/src/widget/text.rs @@ -1,12 +1,23 @@ +//! Write some text for your users to read. +use crate::backend::{self, Backend};  use crate::{Primitive, Renderer}; +use iced_native::mouse; +use iced_native::text;  use iced_native::{ -    mouse, text, Color, Font, HorizontalAlignment, Rectangle, Size, -    VerticalAlignment, +    Color, Font, HorizontalAlignment, Rectangle, Size, VerticalAlignment,  }; +/// A paragraph of text. +/// +/// This is an alias of an `iced_native` text with an `iced_wgpu::Renderer`. +pub type Text<Backend> = iced_native::Text<Renderer<Backend>>; +  use std::f32; -impl text::Renderer for Renderer { +impl<B> text::Renderer for Renderer<B> +where +    B: Backend + backend::Text, +{      type Font = Font;      const DEFAULT_SIZE: u16 = 20; @@ -18,7 +29,7 @@ impl text::Renderer for Renderer {          font: Font,          bounds: Size,      ) -> (f32, f32) { -        self.text_pipeline +        self.backend()              .measure(content, f32::from(size), font, bounds)      } diff --git a/wgpu/src/renderer/widget/text_input.rs b/graphics/src/widget/text_input.rs index 5799dba7..893197d1 100644 --- a/wgpu/src/renderer/widget/text_input.rs +++ b/graphics/src/widget/text_input.rs @@ -1,14 +1,32 @@ -use crate::{text_input::StyleSheet, Primitive, Renderer}; - +//! Display fields that can be filled with text. +//! +//! A [`TextInput`] has some local [`State`]. +//! +//! [`TextInput`]: struct.TextInput.html +//! [`State`]: struct.State.html +use crate::backend::{self, Backend}; +use crate::{Primitive, Renderer}; +use iced_native::mouse; +use iced_native::text_input::{self, cursor};  use iced_native::{ -    mouse, -    text_input::{self, cursor},      Background, Color, Font, HorizontalAlignment, Point, Rectangle, Size,      Vector, VerticalAlignment,  };  use std::f32; -impl text_input::Renderer for Renderer { +pub use iced_native::text_input::State; +pub use iced_style::text_input::{Style, StyleSheet}; + +/// A field that can be filled with text. +/// +/// This is an alias of an `iced_native` text input with an `iced_wgpu::Renderer`. +pub type TextInput<'a, Message, Backend> = +    iced_native::TextInput<'a, Message, Renderer<Backend>>; + +impl<B> text_input::Renderer for Renderer<B> +where +    B: Backend + backend::Text, +{      type Style = Box<dyn StyleSheet>;      fn default_size(&self) -> u16 { @@ -17,12 +35,10 @@ impl text_input::Renderer for Renderer {      }      fn measure_value(&self, value: &str, size: u16, font: Font) -> f32 { -        let (width, _) = self.text_pipeline.measure( -            value, -            f32::from(size), -            font, -            Size::INFINITY, -        ); +        let backend = self.backend(); + +        let (width, _) = +            backend.measure(value, f32::from(size), font, Size::INFINITY);          width      } @@ -234,14 +250,17 @@ impl text_input::Renderer for Renderer {      }  } -fn measure_cursor_and_scroll_offset( -    renderer: &Renderer, +fn measure_cursor_and_scroll_offset<B>( +    renderer: &Renderer<B>,      text_bounds: Rectangle,      value: &text_input::Value,      size: u16,      cursor_index: usize,      font: Font, -) -> (f32, f32) { +) -> (f32, f32) +where +    B: Backend + backend::Text, +{      use iced_native::text_input::Renderer;      let text_before_cursor = value.until(cursor_index).to_string(); | 
