From 03b34931383e701c39c653a7662a616fe21a0947 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 14 Oct 2021 16:07:22 +0700 Subject: Remove trait-specific draw logic in `iced_native` --- graphics/src/renderer.rs | 92 ++++++------------------------------------------ 1 file changed, 10 insertions(+), 82 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index fa63991b..cedffe7e 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -1,30 +1,29 @@ use crate::{Backend, Defaults, Primitive}; -use iced_native::layout::{self, Layout}; -use iced_native::mouse; -use iced_native::{ - Background, Color, Element, Point, Rectangle, Vector, Widget, -}; +use iced_native::layout; +use iced_native::{Element, Rectangle}; /// A backend-agnostic renderer that supports all the built-in widgets. #[derive(Debug)] pub struct Renderer { backend: B, + primitive: Primitive, } impl Renderer { /// Creates a new [`Renderer`] from the given [`Backend`]. pub fn new(backend: B) -> Self { - Self { backend } + Self { + backend, + primitive: Primitive::None, + } } - /// Returns a reference to the [`Backend`] of the [`Renderer`]. pub fn backend(&self) -> &B { &self.backend } - /// Returns a mutable reference to the [`Backend`] of the [`Renderer`]. - pub fn backend_mut(&mut self) -> &mut B { - &mut self.backend + pub fn present(&mut self, f: impl FnOnce(&mut B, &Primitive)) { + f(&mut self.backend, &self.primitive); } } @@ -32,7 +31,6 @@ impl iced_native::Renderer for Renderer where B: Backend, { - type Output = (Primitive, mouse::Interaction); type Defaults = Defaults; fn layout<'a, Message>( @@ -47,75 +45,5 @@ where layout } - fn overlay( - &mut self, - (base_primitive, base_cursor): (Primitive, mouse::Interaction), - (overlay_primitives, overlay_cursor): (Primitive, mouse::Interaction), - overlay_bounds: Rectangle, - ) -> (Primitive, mouse::Interaction) { - ( - Primitive::Group { - primitives: vec![ - base_primitive, - Primitive::Clip { - bounds: Rectangle { - width: overlay_bounds.width + 0.5, - height: overlay_bounds.height + 0.5, - ..overlay_bounds - }, - offset: Vector::new(0, 0), - content: Box::new(overlay_primitives), - }, - ], - }, - if base_cursor > overlay_cursor { - base_cursor - } else { - overlay_cursor - }, - ) - } -} - -impl layout::Debugger for Renderer -where - B: Backend, -{ - fn explain( - &mut self, - defaults: &Defaults, - widget: &dyn Widget, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - color: Color, - ) -> Self::Output { - let (primitive, cursor) = - widget.draw(self, defaults, layout, cursor_position, viewport); - - let mut primitives = Vec::new(); - - explain_layout(layout, color, &mut primitives); - primitives.push(primitive); - - (Primitive::Group { primitives }, cursor) - } -} - -fn explain_layout( - layout: Layout<'_>, - color: Color, - primitives: &mut Vec, -) { - primitives.push(Primitive::Quad { - bounds: layout.bounds(), - background: Background::Color(Color::TRANSPARENT), - border_radius: 0.0, - border_width: 1.0, - border_color: [0.6, 0.6, 0.6, 0.5].into(), - }); - - for child in layout.children() { - explain_layout(child, color, primitives); - } + fn with_layer(&mut self, _bounds: Rectangle, _f: impl FnOnce(&mut Self)) {} } -- cgit From 3a0c503db99eb3d45ac971132904df419ee566b6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 14 Oct 2021 16:59:19 +0700 Subject: Implement `Widget::draw` for `Text` --- graphics/src/renderer.rs | 55 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index cedffe7e..a708cb67 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -1,12 +1,14 @@ -use crate::{Backend, Defaults, Primitive}; +use crate::backend::{self, Backend}; +use crate::{Defaults, Primitive, Vector}; use iced_native::layout; -use iced_native::{Element, Rectangle}; +use iced_native::renderer; +use iced_native::{Color, Element, Font, Rectangle}; /// A backend-agnostic renderer that supports all the built-in widgets. #[derive(Debug)] pub struct Renderer { backend: B, - primitive: Primitive, + primitives: Vec, } impl Renderer { @@ -14,7 +16,7 @@ impl Renderer { pub fn new(backend: B) -> Self { Self { backend, - primitive: Primitive::None, + primitives: Vec::new(), } } @@ -22,8 +24,8 @@ impl Renderer { &self.backend } - pub fn present(&mut self, f: impl FnOnce(&mut B, &Primitive)) { - f(&mut self.backend, &self.primitive); + pub fn present(&mut self, f: impl FnOnce(&mut B, &[Primitive])) { + f(&mut self.backend, &self.primitives); } } @@ -45,5 +47,44 @@ where layout } - fn with_layer(&mut self, _bounds: Rectangle, _f: impl FnOnce(&mut Self)) {} + fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) { + let current_primitives = + std::mem::replace(&mut self.primitives, Vec::new()); + + f(self); + + let layer_primitives = + std::mem::replace(&mut self.primitives, current_primitives); + + self.primitives.push(Primitive::Clip { + bounds, + offset: Vector::new(0, 0), + content: Box::new(Primitive::Group { + primitives: layer_primitives, + }), + }); + } + + fn clear(&mut self) { + self.primitives.clear(); + } +} + +impl renderer::Text for Renderer +where + B: Backend + backend::Text, +{ + type Font = Font; + + fn fill_text(&mut self, text: renderer::text::Section<'_, Self::Font>) { + self.primitives.push(Primitive::Text { + content: text.content.to_string(), + bounds: text.bounds, + size: text.size.unwrap_or(f32::from(self.backend.default_size())), + color: text.color.unwrap_or(Color::BLACK), + font: text.font, + horizontal_alignment: text.horizontal_alignment, + vertical_alignment: text.vertical_alignment, + }); + } } -- cgit From dfceee99aad9462f09ca61081e68e1decb2fed92 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 14 Oct 2021 17:15:29 +0700 Subject: Implement `Widget::draw` for `Scrollable` Rendering the scroller is still WIP --- graphics/src/renderer.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index a708cb67..91f6b550 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -47,7 +47,12 @@ where layout } - fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) { + fn with_layer( + &mut self, + bounds: Rectangle, + offset: Vector, + f: impl FnOnce(&mut Self), + ) { let current_primitives = std::mem::replace(&mut self.primitives, Vec::new()); @@ -58,7 +63,7 @@ where self.primitives.push(Primitive::Clip { bounds, - offset: Vector::new(0, 0), + offset, content: Box::new(Primitive::Group { primitives: layer_primitives, }), @@ -77,6 +82,8 @@ where type Font = Font; fn fill_text(&mut self, text: renderer::text::Section<'_, Self::Font>) { + dbg!(text); + self.primitives.push(Primitive::Text { content: text.content.to_string(), bounds: text.bounds, -- cgit From a4f4d831615899046d36c96e6a580d5386aa25bf Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 18 Oct 2021 14:47:49 +0700 Subject: Introduce `fill_rectangle` to `Renderer` trait --- graphics/src/renderer.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 91f6b550..7ed06151 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -70,6 +70,16 @@ where }); } + fn fill_rectangle(&mut self, quad: renderer::Quad) { + self.primitives.push(Primitive::Quad { + bounds: quad.bounds, + background: quad.background, + border_radius: quad.border_radius, + border_width: quad.border_width, + border_color: quad.border_color, + }); + } + fn clear(&mut self) { self.primitives.clear(); } -- cgit From edea093350e1b576e2b7db50c525e7fa5c3bea9f Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 18 Oct 2021 15:19:04 +0700 Subject: Move `Defaults` from `iced_graphics` to `iced_native` --- graphics/src/renderer.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 7ed06151..8d623868 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -1,8 +1,10 @@ use crate::backend::{self, Backend}; -use crate::{Defaults, Primitive, Vector}; +use crate::{Primitive, Vector}; use iced_native::layout; use iced_native::renderer; -use iced_native::{Color, Element, Font, Rectangle}; +use iced_native::{Element, Font, Rectangle}; + +pub use iced_native::renderer::Style; /// A backend-agnostic renderer that supports all the built-in widgets. #[derive(Debug)] @@ -33,8 +35,6 @@ impl iced_native::Renderer for Renderer where B: Backend, { - type Defaults = Defaults; - fn layout<'a, Message>( &mut self, element: &Element<'a, Message, Self>, @@ -97,8 +97,8 @@ where self.primitives.push(Primitive::Text { content: text.content.to_string(), bounds: text.bounds, - size: text.size.unwrap_or(f32::from(self.backend.default_size())), - color: text.color.unwrap_or(Color::BLACK), + size: text.size, + color: text.color, font: text.font, horizontal_alignment: text.horizontal_alignment, vertical_alignment: text.vertical_alignment, -- cgit From e00a2e9b2d97147be5912a97362d1bf1705b7c4e Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 18 Oct 2021 16:59:59 +0700 Subject: Remove `dbg!` leftover in `Renderer::fill_text` --- graphics/src/renderer.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 8d623868..0dca685f 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -92,8 +92,6 @@ where type Font = Font; fn fill_text(&mut self, text: renderer::text::Section<'_, Self::Font>) { - dbg!(text); - self.primitives.push(Primitive::Text { content: text.content.to_string(), bounds: text.bounds, -- cgit From e914888f57394e4b67b40e42f1ad9df4ae8147e6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 20 Oct 2021 18:40:39 +0700 Subject: Implement `Widget::draw` for `TextInput` --- graphics/src/renderer.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 0dca685f..f8c67047 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -2,7 +2,7 @@ use crate::backend::{self, Backend}; use crate::{Primitive, Vector}; use iced_native::layout; use iced_native::renderer; -use iced_native::{Element, Font, Rectangle}; +use iced_native::{Element, Font, Point, Rectangle, Size}; pub use iced_native::renderer::Style; @@ -91,6 +91,40 @@ where { type Font = Font; + fn default_size(&self) -> u16 { + self.backend().default_size() + } + + fn measure( + &self, + content: &str, + size: u16, + font: Font, + bounds: Size, + ) -> (f32, f32) { + self.backend() + .measure(content, f32::from(size), font, bounds) + } + + fn hit_test( + &self, + content: &str, + size: f32, + font: Font, + bounds: Size, + point: Point, + nearest_only: bool, + ) -> Option { + self.backend().hit_test( + content, + size, + font, + bounds, + point, + nearest_only, + ) + } + fn fill_text(&mut self, text: renderer::text::Section<'_, Self::Font>) { self.primitives.push(Primitive::Text { content: text.content.to_string(), -- cgit From 1397be38ca2caaf5c49ca51e164a28b63f9e461b Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 21 Oct 2021 19:06:22 +0700 Subject: Implement `Widget::draw` for `Checkbox` --- graphics/src/renderer.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index f8c67047..5e74019f 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -91,6 +91,10 @@ where { type Font = Font; + const ICON_FONT: Font = B::ICON_FONT; + const CHECKMARK_ICON: char = B::CHECKMARK_ICON; + const ARROW_DOWN_ICON: char = B::ARROW_DOWN_ICON; + fn default_size(&self) -> u16 { self.backend().default_size() } -- cgit From 1afbc98544327b5454b862bec938dc76c4d38fa0 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 25 Oct 2021 15:03:57 +0700 Subject: Implement `Widget::draw` for `Image` --- graphics/src/renderer.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 5e74019f..d90a3f1e 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -26,6 +26,10 @@ impl Renderer { &self.backend } + pub fn draw_primitive(&mut self, primitive: Primitive) { + self.primitives.push(primitive); + } + pub fn present(&mut self, f: impl FnOnce(&mut B, &[Primitive])) { f(&mut self.backend, &self.primitives); } -- cgit From 4a11cbd99445338619dfaf1f327dbc25b2983cb7 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 25 Oct 2021 16:16:35 +0700 Subject: Implement `Widget::mouse_interaction` for `PaneGrid` ... and fix rendering of drag interaction in `PaneGrid` by introducing an explicit `with_translation` method to `Renderer` and simplifying the `with_layer` and `Clip` primitive. --- graphics/src/renderer.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index d90a3f1e..8b6c2217 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -51,10 +51,26 @@ where layout } - fn with_layer( + fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) { + let current_primitives = + std::mem::replace(&mut self.primitives, Vec::new()); + + f(self); + + let layer_primitives = + std::mem::replace(&mut self.primitives, current_primitives); + + self.primitives.push(Primitive::Clip { + bounds, + content: Box::new(Primitive::Group { + primitives: layer_primitives, + }), + }); + } + + fn with_translation( &mut self, - bounds: Rectangle, - offset: Vector, + translation: Vector, f: impl FnOnce(&mut Self), ) { let current_primitives = @@ -65,9 +81,8 @@ where let layer_primitives = std::mem::replace(&mut self.primitives, current_primitives); - self.primitives.push(Primitive::Clip { - bounds, - offset, + self.primitives.push(Primitive::Translate { + translation, content: Box::new(Primitive::Group { primitives: layer_primitives, }), -- cgit From b3a01973c6c726e6539be959659f4306ef3234c6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 31 Oct 2021 16:13:03 +0700 Subject: Introduce first-class `text` module in `iced_native` --- graphics/src/renderer.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 8b6c2217..125962ba 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -2,6 +2,7 @@ use crate::backend::{self, Backend}; use crate::{Primitive, Vector}; use iced_native::layout; use iced_native::renderer; +use iced_native::text::{self, Text}; use iced_native::{Element, Font, Point, Rectangle, Size}; pub use iced_native::renderer::Style; @@ -104,7 +105,7 @@ where } } -impl renderer::Text for Renderer +impl text::Renderer for Renderer where B: Backend + backend::Text, { @@ -137,7 +138,7 @@ where bounds: Size, point: Point, nearest_only: bool, - ) -> Option { + ) -> Option { self.backend().hit_test( content, size, @@ -148,7 +149,7 @@ where ) } - fn fill_text(&mut self, text: renderer::text::Section<'_, Self::Font>) { + fn fill_text(&mut self, text: Text<'_, Self::Font>) { self.primitives.push(Primitive::Text { content: text.content.to_string(), bounds: text.bounds, -- cgit From ef5a731e4bd17f763b1697c7f0ac595928e91e58 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 4 Nov 2021 18:23:18 +0700 Subject: Use `mem::take` instead of `mem::replace` in `iced_graphics::Renderer` Thanks to @tarkah for pointing this out! --- graphics/src/renderer.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 125962ba..df9f1ac0 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -53,8 +53,7 @@ where } fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) { - let current_primitives = - std::mem::replace(&mut self.primitives, Vec::new()); + let current_primitives = std::mem::take(&mut self.primitives); f(self); @@ -74,8 +73,7 @@ where translation: Vector, f: impl FnOnce(&mut Self), ) { - let current_primitives = - std::mem::replace(&mut self.primitives, Vec::new()); + let current_primitives = std::mem::take(&mut self.primitives); f(self); -- cgit From 023aded2772f0cd6abd716fe5c8624d5d22e21fa Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 4 Nov 2021 19:22:29 +0700 Subject: Rename `fill_rectangle` to `fill_quad` in `Renderer` --- graphics/src/renderer.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index df9f1ac0..30f9d40e 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -3,7 +3,7 @@ use crate::{Primitive, Vector}; use iced_native::layout; use iced_native::renderer; use iced_native::text::{self, Text}; -use iced_native::{Element, Font, Point, Rectangle, Size}; +use iced_native::{Background, Element, Font, Point, Rectangle, Size}; pub use iced_native::renderer::Style; @@ -88,10 +88,14 @@ where }); } - fn fill_rectangle(&mut self, quad: renderer::Quad) { + fn fill_quad( + &mut self, + quad: renderer::Quad, + background: impl Into, + ) { self.primitives.push(Primitive::Quad { bounds: quad.bounds, - background: quad.background, + background: background.into(), border_radius: quad.border_radius, border_width: quad.border_width, border_color: quad.border_color, -- cgit From 9fe65ed729c75a8401765cf373345aaba93352ca Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 5 Nov 2021 15:38:27 +0700 Subject: Rename `Renderer::present` to `with_primitives` --- graphics/src/renderer.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 30f9d40e..69ed8775 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -31,7 +31,9 @@ impl Renderer { self.primitives.push(primitive); } - pub fn present(&mut self, f: impl FnOnce(&mut B, &[Primitive])) { + /// Runs the given closure with the [`Backend`] and the recorded primitives + /// of the [`Renderer`]. + pub fn with_primitives(&mut self, f: impl FnOnce(&mut B, &[Primitive])) { f(&mut self.backend, &self.primitives); } } -- cgit From b64e8752056e526b95ad3c0ff2385000c1213698 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 5 Nov 2021 15:38:40 +0700 Subject: Write missing documentation in `iced_graphics` --- graphics/src/renderer.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'graphics/src/renderer.rs') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 69ed8775..c32eb471 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -1,3 +1,4 @@ +//! Create a renderer from a [`Backend`]. use crate::backend::{self, Backend}; use crate::{Primitive, Vector}; use iced_native::layout; @@ -23,10 +24,12 @@ impl Renderer { } } + /// Returns the [`Backend`] of the [`Renderer`]. pub fn backend(&self) -> &B { &self.backend } + /// Enqueues the given [`Primitive`] in the [`Renderer`] for drawing. pub fn draw_primitive(&mut self, primitive: Primitive) { self.primitives.push(primitive); } -- cgit