summaryrefslogtreecommitdiffstats
path: root/wgpu/src/renderer
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-05-29 02:00:28 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-05-29 02:00:28 +0200
commit0cde20b3550ede81bc7ddef628b91eec225aa8af (patch)
tree56920437979012cceb49718f2dd4ce27d5ba5d40 /wgpu/src/renderer
parent67b6f044e870df41be92cdc79f571682b97a5d0d (diff)
parente11b5c614f5bf73c137b8b4f24f56047617527eb (diff)
downloadiced-0cde20b3550ede81bc7ddef628b91eec225aa8af.tar.gz
iced-0cde20b3550ede81bc7ddef628b91eec225aa8af.tar.bz2
iced-0cde20b3550ede81bc7ddef628b91eec225aa8af.zip
Merge branch 'master' into improvement/update-wgpu_glyph
Diffstat (limited to '')
-rw-r--r--graphics/src/widget/button.rs (renamed from wgpu/src/renderer/widget/button.rs)26
-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/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
-rw-r--r--wgpu/src/renderer.rs524
-rw-r--r--wgpu/src/renderer/widget.rs19
-rw-r--r--wgpu/src/renderer/widget/space.rs8
17 files changed, 270 insertions, 615 deletions
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/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.
+//!
+//! [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](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.
+///
+/// [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](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/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();
diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs
deleted file mode 100644
index f3a7c288..00000000
--- a/wgpu/src/renderer.rs
+++ /dev/null
@@ -1,524 +0,0 @@
-use crate::{
- quad, text, triangle, Defaults, Primitive, Quad, Settings, Target,
- Transformation,
-};
-
-#[cfg(any(feature = "image", feature = "svg"))]
-use crate::image::{self, Image};
-
-use iced_native::{
- layout, mouse, Background, Color, Font, HorizontalAlignment, Layout, Point,
- Rectangle, Size, Vector, VerticalAlignment, Widget,
-};
-
-mod widget;
-
-/// A [`wgpu`] renderer.
-///
-/// [`wgpu`]: https://github.com/gfx-rs/wgpu-rs
-#[derive(Debug)]
-pub struct Renderer {
- quad_pipeline: quad::Pipeline,
- text_pipeline: text::Pipeline,
- triangle_pipeline: triangle::Pipeline,
-
- #[cfg(any(feature = "image", feature = "svg"))]
- image_pipeline: image::Pipeline,
-}
-
-struct Layer<'a> {
- bounds: Rectangle<u32>,
- quads: Vec<Quad>,
- meshes: Vec<(Vector, Rectangle<u32>, &'a triangle::Mesh2D)>,
- text: Vec<Text<'a>>,
-
- #[cfg(any(feature = "image", feature = "svg"))]
- images: Vec<Image>,
-}
-
-#[derive(Debug, Clone, Copy)]
-pub struct Text<'a> {
- pub content: &'a str,
- pub bounds: Rectangle,
- pub color: [f32; 4],
- pub size: f32,
- pub font: Font,
- pub horizontal_alignment: HorizontalAlignment,
- pub vertical_alignment: VerticalAlignment,
-}
-
-impl<'a> Layer<'a> {
- pub fn new(bounds: Rectangle<u32>) -> Self {
- Self {
- bounds,
- quads: Vec::new(),
- text: Vec::new(),
- meshes: Vec::new(),
-
- #[cfg(any(feature = "image", feature = "svg"))]
- images: Vec::new(),
- }
- }
-
- pub fn intersection(&self, rectangle: Rectangle) -> Option<Rectangle<u32>> {
- let layer_bounds: Rectangle<f32> = self.bounds.into();
-
- layer_bounds.intersection(&rectangle).map(Into::into)
- }
-}
-
-impl Renderer {
- /// Creates a new [`Renderer`].
- ///
- /// [`Renderer`]: struct.Renderer.html
- pub fn new(device: &wgpu::Device, settings: Settings) -> Self {
- let text_pipeline =
- text::Pipeline::new(device, settings.format, settings.default_font);
- let quad_pipeline = quad::Pipeline::new(device, settings.format);
- let triangle_pipeline = triangle::Pipeline::new(
- device,
- settings.format,
- settings.antialiasing,
- );
-
- #[cfg(any(feature = "image", feature = "svg"))]
- let image_pipeline = image::Pipeline::new(device, settings.format);
-
- Self {
- quad_pipeline,
- text_pipeline,
- triangle_pipeline,
-
- #[cfg(any(feature = "image", feature = "svg"))]
- image_pipeline,
- }
- }
-
- /// Draws the provided primitives in the given [`Target`].
- ///
- /// The text provided as overlay will be renderer on top of the primitives.
- /// This is useful for rendering debug information.
- ///
- /// [`Target`]: struct.Target.html
- pub fn draw<T: AsRef<str>>(
- &mut self,
- device: &wgpu::Device,
- encoder: &mut wgpu::CommandEncoder,
- target: Target<'_>,
- (primitive, mouse_interaction): &(Primitive, mouse::Interaction),
- scale_factor: f64,
- overlay: &[T],
- ) -> mouse::Interaction {
- log::debug!("Drawing");
-
- let (width, height) = target.viewport.dimensions();
- let scale_factor = scale_factor as f32;
- let transformation = target.viewport.transformation();
-
- let mut layers = Vec::new();
-
- layers.push(Layer::new(Rectangle {
- x: 0,
- y: 0,
- width,
- height,
- }));
-
- self.draw_primitive(Vector::new(0.0, 0.0), primitive, &mut layers);
- self.draw_overlay(overlay, &mut layers);
-
- for layer in layers {
- self.flush(
- device,
- scale_factor,
- transformation,
- &layer,
- encoder,
- target.texture,
- width,
- height,
- );
- }
-
- #[cfg(any(feature = "image", feature = "svg"))]
- self.image_pipeline.trim_cache();
-
- *mouse_interaction
- }
-
- fn draw_primitive<'a>(
- &mut self,
- translation: Vector,
- primitive: &'a Primitive,
- layers: &mut Vec<Layer<'a>>,
- ) {
- match primitive {
- Primitive::None => {}
- Primitive::Group { primitives } => {
- // TODO: Inspect a bit and regroup (?)
- for primitive in primitives {
- self.draw_primitive(translation, primitive, layers)
- }
- }
- Primitive::Text {
- content,
- bounds,
- size,
- color,
- font,
- horizontal_alignment,
- vertical_alignment,
- } => {
- let layer = layers.last_mut().unwrap();
-
- layer.text.push(Text {
- content,
- bounds: *bounds + translation,
- size: *size,
- color: color.into_linear(),
- font: *font,
- horizontal_alignment: *horizontal_alignment,
- vertical_alignment: *vertical_alignment,
- });
- }
- Primitive::Quad {
- bounds,
- background,
- border_radius,
- border_width,
- border_color,
- } => {
- let layer = layers.last_mut().unwrap();
-
- // TODO: Move some of these computations to the GPU (?)
- layer.quads.push(Quad {
- position: [
- bounds.x + translation.x,
- bounds.y + translation.y,
- ],
- scale: [bounds.width, bounds.height],
- color: match background {
- Background::Color(color) => color.into_linear(),
- },
- border_radius: *border_radius as f32,
- border_width: *border_width as f32,
- border_color: border_color.into_linear(),
- });
- }
- Primitive::Mesh2D { size, buffers } => {
- let layer = layers.last_mut().unwrap();
-
- // Only draw visible content
- if let Some(clip_bounds) = layer.intersection(Rectangle::new(
- Point::new(translation.x, translation.y),
- *size,
- )) {
- layer.meshes.push((
- translation,
- clip_bounds.into(),
- buffers,
- ));
- }
- }
- Primitive::Clip {
- bounds,
- offset,
- content,
- } => {
- let layer = layers.last_mut().unwrap();
-
- // Only draw visible content
- if let Some(clip_bounds) =
- layer.intersection(*bounds + translation)
- {
- let clip_layer = Layer::new(clip_bounds.into());
- let new_layer = Layer::new(layer.bounds);
-
- layers.push(clip_layer);
- self.draw_primitive(
- translation
- - Vector::new(offset.x as f32, offset.y as f32),
- content,
- layers,
- );
- layers.push(new_layer);
- }
- }
- Primitive::Translate {
- translation: new_translation,
- content,
- } => {
- self.draw_primitive(
- translation + *new_translation,
- &content,
- layers,
- );
- }
-
- Primitive::Cached { cache } => {
- self.draw_primitive(translation, &cache, layers);
- }
-
- #[cfg(feature = "image")]
- Primitive::Image { handle, bounds } => {
- let layer = layers.last_mut().unwrap();
-
- layer.images.push(Image {
- handle: image::Handle::Raster(handle.clone()),
- position: [
- bounds.x + translation.x,
- bounds.y + translation.y,
- ],
- size: [bounds.width, bounds.height],
- });
- }
- #[cfg(not(feature = "image"))]
- Primitive::Image { .. } => {}
-
- #[cfg(feature = "svg")]
- Primitive::Svg { handle, bounds } => {
- let layer = layers.last_mut().unwrap();
-
- layer.images.push(Image {
- handle: image::Handle::Vector(handle.clone()),
- position: [
- bounds.x + translation.x,
- bounds.y + translation.y,
- ],
- size: [bounds.width, bounds.height],
- });
- }
- #[cfg(not(feature = "svg"))]
- Primitive::Svg { .. } => {}
- }
- }
-
- fn draw_overlay<'a, T: AsRef<str>>(
- &mut self,
- lines: &'a [T],
- layers: &mut Vec<Layer<'a>>,
- ) {
- let first = layers.first().unwrap();
- let mut overlay = Layer::new(first.bounds);
-
- for (i, line) in lines.iter().enumerate() {
- let text = Text {
- content: line.as_ref(),
- bounds: Rectangle::new(
- Point::new(11.0, 11.0 + 25.0 * i as f32),
- Size::INFINITY,
- ),
- color: [0.9, 0.9, 0.9, 1.0],
- size: 20.0,
- font: Font::Default,
- horizontal_alignment: HorizontalAlignment::Left,
- vertical_alignment: VerticalAlignment::Top,
- };
-
- overlay.text.push(text);
-
- overlay.text.push(Text {
- bounds: text.bounds + Vector::new(-1.0, -1.0),
- color: [0.0, 0.0, 0.0, 1.0],
- ..text
- });
- }
-
- layers.push(overlay);
- }
-
- fn flush(
- &mut self,
- device: &wgpu::Device,
- scale_factor: f32,
- transformation: Transformation,
- layer: &Layer<'_>,
- encoder: &mut wgpu::CommandEncoder,
- target: &wgpu::TextureView,
- target_width: u32,
- target_height: u32,
- ) {
- let bounds = layer.bounds * scale_factor;
-
- if !layer.quads.is_empty() {
- self.quad_pipeline.draw(
- device,
- encoder,
- &layer.quads,
- transformation,
- scale_factor,
- bounds,
- target,
- );
- }
-
- if !layer.meshes.is_empty() {
- let scaled = transformation
- * Transformation::scale(scale_factor, scale_factor);
-
- self.triangle_pipeline.draw(
- device,
- encoder,
- target,
- target_width,
- target_height,
- scaled,
- scale_factor,
- &layer.meshes,
- );
- }
-
- #[cfg(any(feature = "image", feature = "svg"))]
- {
- if !layer.images.is_empty() {
- let scaled = transformation
- * Transformation::scale(scale_factor, scale_factor);
-
- self.image_pipeline.draw(
- device,
- encoder,
- &layer.images,
- scaled,
- bounds,
- target,
- scale_factor,
- );
- }
- }
-
- if !layer.text.is_empty() {
- for text in layer.text.iter() {
- // Target physical coordinates directly to avoid blurry text
- let text = wgpu_glyph::Section {
- // TODO: We `round` here to avoid rerasterizing text when
- // its position changes slightly. This can make text feel a
- // bit "jumpy". We may be able to do better once we improve
- // our text rendering/caching pipeline.
- screen_position: (
- (text.bounds.x * scale_factor).round(),
- (text.bounds.y * scale_factor).round(),
- ),
- // TODO: Fix precision issues with some scale factors.
- //
- // The `ceil` here can cause some words to render on the
- // same line when they should not.
- //
- // Ideally, `wgpu_glyph` should be able to compute layout
- // using logical positions, and then apply the proper
- // scaling when rendering. This would ensure that both
- // measuring and rendering follow the same layout rules.
- bounds: (
- (text.bounds.width * scale_factor).ceil(),
- (text.bounds.height * scale_factor).ceil(),
- ),
- text: vec![wgpu_glyph::Text {
- text: text.content,
- scale: wgpu_glyph::ab_glyph::PxScale {
- x: text.size * scale_factor,
- y: text.size * scale_factor,
- },
- font_id: self.text_pipeline.find_font(text.font),
- extra: wgpu_glyph::Extra {
- color: text.color,
- z: 0.0,
- },
- }],
- layout: wgpu_glyph::Layout::default()
- .h_align(match text.horizontal_alignment {
- HorizontalAlignment::Left => {
- wgpu_glyph::HorizontalAlign::Left
- }
- HorizontalAlignment::Center => {
- wgpu_glyph::HorizontalAlign::Center
- }
- HorizontalAlignment::Right => {
- wgpu_glyph::HorizontalAlign::Right
- }
- })
- .v_align(match text.vertical_alignment {
- VerticalAlignment::Top => {
- wgpu_glyph::VerticalAlign::Top
- }
- VerticalAlignment::Center => {
- wgpu_glyph::VerticalAlign::Center
- }
- VerticalAlignment::Bottom => {
- wgpu_glyph::VerticalAlign::Bottom
- }
- }),
- ..Default::default()
- };
-
- self.text_pipeline.queue(text);
- }
-
- self.text_pipeline.draw_queued(
- device,
- encoder,
- target,
- transformation,
- wgpu_glyph::Region {
- x: bounds.x,
- y: bounds.y,
- width: bounds.width,
- height: bounds.height,
- },
- );
- }
- }
-}
-
-impl iced_native::Renderer for Renderer {
- type Output = (Primitive, mouse::Interaction);
- type Defaults = Defaults;
-
- fn layout<'a, Message>(
- &mut self,
- element: &iced_native::Element<'a, Message, Self>,
- limits: &iced_native::layout::Limits,
- ) -> iced_native::layout::Node {
- let node = element.layout(self, limits);
-
- self.text_pipeline.clear_measurement_cache();
-
- node
- }
-}
-
-impl layout::Debugger for Renderer {
- fn explain<Message>(
- &mut self,
- defaults: &Defaults,
- widget: &dyn Widget<Message, Self>,
- layout: Layout<'_>,
- cursor_position: Point,
- color: Color,
- ) -> Self::Output {
- let mut primitives = Vec::new();
- let (primitive, cursor) =
- widget.draw(self, defaults, layout, cursor_position);
-
- explain_layout(layout, color, &mut primitives);
- primitives.push(primitive);
-
- (Primitive::Group { primitives }, cursor)
- }
-}
-
-fn explain_layout(
- layout: Layout<'_>,
- color: Color,
- primitives: &mut Vec<Primitive>,
-) {
- primitives.push(Primitive::Quad {
- bounds: layout.bounds(),
- background: Background::Color(Color::TRANSPARENT),
- border_radius: 0,
- border_width: 1,
- border_color: [0.6, 0.6, 0.6, 0.5].into(),
- });
-
- for child in layout.children() {
- explain_layout(child, color, primitives);
- }
-}
diff --git a/wgpu/src/renderer/widget.rs b/wgpu/src/renderer/widget.rs
deleted file mode 100644
index 37421fbe..00000000
--- a/wgpu/src/renderer/widget.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-mod button;
-mod checkbox;
-mod column;
-mod container;
-mod pane_grid;
-mod progress_bar;
-mod radio;
-mod row;
-mod scrollable;
-mod slider;
-mod space;
-mod text;
-mod text_input;
-
-#[cfg(feature = "svg")]
-mod svg;
-
-#[cfg(feature = "image")]
-mod image;
diff --git a/wgpu/src/renderer/widget/space.rs b/wgpu/src/renderer/widget/space.rs
deleted file mode 100644
index 225f7e6c..00000000
--- a/wgpu/src/renderer/widget/space.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-use crate::{Primitive, Renderer};
-use iced_native::{mouse, space, Rectangle};
-
-impl space::Renderer for Renderer {
- fn draw(&mut self, _bounds: Rectangle) -> Self::Output {
- (Primitive::None, mouse::Interaction::default())
- }
-}