diff options
71 files changed, 681 insertions, 3166 deletions
diff --git a/examples/custom_widget/src/main.rs b/examples/custom_widget/src/main.rs index c9ad1905..648e7295 100644 --- a/examples/custom_widget/src/main.rs +++ b/examples/custom_widget/src/main.rs @@ -11,8 +11,7 @@ mod circle { // implemented by `iced_wgpu` and other renderers. use iced_graphics::{Backend, Defaults, Primitive, Renderer}; use iced_native::{ - layout, mouse, Background, Color, Element, Hasher, Layout, Length, - Point, Rectangle, Size, Widget, + layout, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; pub struct Circle { @@ -55,20 +54,20 @@ mod circle { &self, _renderer: &mut Renderer<B>, _defaults: &Defaults, - layout: Layout<'_>, + _layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> (Primitive, mouse::Interaction) { - ( - Primitive::Quad { - bounds: layout.bounds(), - background: Background::Color(Color::BLACK), - border_radius: self.radius, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }, - mouse::Interaction::default(), - ) + ) { + // ( + // Primitive::Quad { + // bounds: layout.bounds(), + // background: Background::Color(Color::BLACK), + // border_radius: self.radius, + // border_width: 0.0, + // border_color: Color::TRANSPARENT, + // }, + // mouse::Interaction::default(), + // ) } } diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs index e5115493..0745739a 100644 --- a/examples/geometry/src/main.rs +++ b/examples/geometry/src/main.rs @@ -55,98 +55,99 @@ mod rainbow { &self, _renderer: &mut Renderer<B>, _defaults: &Defaults, - layout: Layout<'_>, - cursor_position: Point, + _layout: Layout<'_>, + _cursor_position: Point, _viewport: &Rectangle, - ) -> (Primitive, mouse::Interaction) { - let b = layout.bounds(); - - // R O Y G B I V - let color_r = [1.0, 0.0, 0.0, 1.0]; - let color_o = [1.0, 0.5, 0.0, 1.0]; - let color_y = [1.0, 1.0, 0.0, 1.0]; - let color_g = [0.0, 1.0, 0.0, 1.0]; - let color_gb = [0.0, 1.0, 0.5, 1.0]; - let color_b = [0.0, 0.2, 1.0, 1.0]; - let color_i = [0.5, 0.0, 1.0, 1.0]; - let color_v = [0.75, 0.0, 0.5, 1.0]; - - let posn_center = { - if b.contains(cursor_position) { - [cursor_position.x - b.x, cursor_position.y - b.y] - } else { - [b.width / 2.0, b.height / 2.0] - } - }; - - let posn_tl = [0.0, 0.0]; - let posn_t = [b.width / 2.0, 0.0]; - let posn_tr = [b.width, 0.0]; - let posn_r = [b.width, b.height / 2.0]; - let posn_br = [b.width, b.height]; - let posn_b = [(b.width / 2.0), b.height]; - let posn_bl = [0.0, b.height]; - let posn_l = [0.0, b.height / 2.0]; - - ( - Primitive::Translate { - translation: Vector::new(b.x, b.y), - content: Box::new(Primitive::Mesh2D { - size: b.size(), - buffers: Mesh2D { - vertices: vec![ - Vertex2D { - position: posn_center, - color: [1.0, 1.0, 1.0, 1.0], - }, - Vertex2D { - position: posn_tl, - color: color_r, - }, - Vertex2D { - position: posn_t, - color: color_o, - }, - Vertex2D { - position: posn_tr, - color: color_y, - }, - Vertex2D { - position: posn_r, - color: color_g, - }, - Vertex2D { - position: posn_br, - color: color_gb, - }, - Vertex2D { - position: posn_b, - color: color_b, - }, - Vertex2D { - position: posn_bl, - color: color_i, - }, - Vertex2D { - position: posn_l, - color: color_v, - }, - ], - indices: vec![ - 0, 1, 2, // TL - 0, 2, 3, // T - 0, 3, 4, // TR - 0, 4, 5, // R - 0, 5, 6, // BR - 0, 6, 7, // B - 0, 7, 8, // BL - 0, 8, 1, // L - ], - }, - }), - }, - mouse::Interaction::default(), - ) + ) { + // let b = layout.bounds(); + + // // R O Y G B I V + // let color_r = [1.0, 0.0, 0.0, 1.0]; + // let color_o = [1.0, 0.5, 0.0, 1.0]; + // let color_y = [1.0, 1.0, 0.0, 1.0]; + // let color_g = [0.0, 1.0, 0.0, 1.0]; + // let color_gb = [0.0, 1.0, 0.5, 1.0]; + // let color_b = [0.0, 0.2, 1.0, 1.0]; + // let color_i = [0.5, 0.0, 1.0, 1.0]; + // let color_v = [0.75, 0.0, 0.5, 1.0]; + + // let posn_center = { + // if b.contains(cursor_position) { + // [cursor_position.x - b.x, cursor_position.y - b.y] + // } else { + // [b.width / 2.0, b.height / 2.0] + // } + // }; + + // let posn_tl = [0.0, 0.0]; + // let posn_t = [b.width / 2.0, 0.0]; + // let posn_tr = [b.width, 0.0]; + // let posn_r = [b.width, b.height / 2.0]; + // let posn_br = [b.width, b.height]; + // let posn_b = [(b.width / 2.0), b.height]; + // let posn_bl = [0.0, b.height]; + // let posn_l = [0.0, b.height / 2.0]; + + // ( + // Primitive::Translate { + // translation: Vector::new(b.x, b.y), + // content: Box::new(Primitive::Mesh2D { + // size: b.size(), + // buffers: Mesh2D { + // vertices: vec![ + // Vertex2D { + // position: posn_center, + // color: [1.0, 1.0, 1.0, 1.0], + // }, + // Vertex2D { + // position: posn_tl, + // color: color_r, + // }, + // Vertex2D { + // position: posn_t, + // color: color_o, + // }, + // Vertex2D { + // position: posn_tr, + // color: color_y, + // }, + // Vertex2D { + // position: posn_r, + // color: color_g, + // }, + // Vertex2D { + // position: posn_br, + // color: color_gb, + // }, + // Vertex2D { + // position: posn_b, + // color: color_b, + // }, + // Vertex2D { + // position: posn_bl, + // color: color_i, + // }, + // Vertex2D { + // position: posn_l, + // color: color_v, + // }, + // ], + // indices: vec![ + // 0, 1, 2, // TL + // 0, 2, 3, // T + // 0, 3, 4, // TR + // 0, 4, 5, // R + // 0, 5, 6, // BR + // 0, 6, 7, // B + // 0, 7, 8, // BL + // 0, 8, 1, // L + // ], + // }, + // }), + // }, + // mouse::Interaction::default(), + // ) + // TODO } } diff --git a/examples/integration_opengl/src/main.rs b/examples/integration_opengl/src/main.rs index f80915d2..bab6331e 100644 --- a/examples/integration_opengl/src/main.rs +++ b/examples/integration_opengl/src/main.rs @@ -160,18 +160,22 @@ pub fn main() { } // And then iced on top - let mouse_interaction = renderer.backend_mut().draw( - &gl, - &viewport, - state.primitive(), - &debug.overlay(), - ); + renderer.present(|backend, primitive| { + backend.present( + &gl, + primitive, + &viewport, + &debug.overlay(), + ); + }); + // Update the mouse cursor - windowed_context.window().set_cursor_icon( - iced_winit::conversion::mouse_interaction( - mouse_interaction, - ), - ); + // TODO + // windowed_context.window().set_cursor_icon( + // iced_winit::conversion::mouse_interaction( + // mouse_interaction, + // ), + // ); windowed_context.swap_buffers().unwrap(); } diff --git a/examples/integration_wgpu/src/main.rs b/examples/integration_wgpu/src/main.rs index 7ef148bc..9980acc2 100644 --- a/examples/integration_wgpu/src/main.rs +++ b/examples/integration_wgpu/src/main.rs @@ -195,26 +195,28 @@ pub fn main() { } // And then iced on top - let mouse_interaction = renderer.backend_mut().draw( - &mut device, - &mut staging_belt, - &mut encoder, - &view, - &viewport, - state.primitive(), - &debug.overlay(), - ); + renderer.present(|backend, primitive| { + backend.present( + &mut device, + &mut staging_belt, + &mut encoder, + &view, + primitive, + &viewport, + &debug.overlay(), + ); + }); // Then we submit the work staging_belt.finish(); queue.submit(Some(encoder.finish())); // Update the mouse cursor - window.set_cursor_icon( - iced_winit::conversion::mouse_interaction( - mouse_interaction, - ), - ); + // window.set_cursor_icon( + // iced_winit::conversion::mouse_interaction( + // mouse_interaction, + // ), + // ); // And recall staging buffers local_pool diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 9a9457cf..b8e4bd4b 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -5,10 +5,8 @@ use crate::{Settings, Transformation, Viewport}; use iced_graphics::backend; use iced_graphics::font; -use iced_graphics::Layer; -use iced_graphics::Primitive; +use iced_graphics::{Layer, Primitive}; use iced_native::alignment; -use iced_native::mouse; use iced_native::{Font, Size}; /// A [`glow`] graphics backend for [`iced`]. @@ -47,13 +45,13 @@ impl Backend { /// /// The text provided as overlay will be rendered on top of the primitives. /// This is useful for rendering debug information. - pub fn draw<T: AsRef<str>>( + pub fn present<T: AsRef<str>>( &mut self, gl: &glow::Context, + primitive: &Primitive, viewport: &Viewport, - (primitive, mouse_interaction): &(Primitive, mouse::Interaction), overlay_text: &[T], - ) -> mouse::Interaction { + ) { let viewport_size = viewport.physical_size(); let scale_factor = viewport.scale_factor() as f32; let projection = viewport.projection(); @@ -70,8 +68,6 @@ impl Backend { viewport_size.height, ); } - - *mouse_interaction } fn flush( diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs index b8157f78..36e591cd 100644 --- a/glow/src/window/compositor.rs +++ b/glow/src/window/compositor.rs @@ -3,7 +3,6 @@ use crate::{Backend, Color, Error, Renderer, Settings, Viewport}; use core::ffi::c_void; use glow::HasContext; use iced_graphics::{Antialiasing, Size}; -use iced_native::mouse; /// A window graphics backend for iced powered by `glow`. #[allow(missing_debug_implementations)] @@ -59,14 +58,13 @@ impl iced_graphics::window::GLCompositor for Compositor { } } - fn draw<T: AsRef<str>>( + fn present<T: AsRef<str>>( &mut self, renderer: &mut Self::Renderer, viewport: &Viewport, color: Color, - output: &<Self::Renderer as iced_native::Renderer>::Output, overlay: &[T], - ) -> mouse::Interaction { + ) { let gl = &self.gl; let [r, g, b, a] = color.into_linear(); @@ -76,6 +74,8 @@ impl iced_graphics::window::GLCompositor for Compositor { gl.clear(glow::COLOR_BUFFER_BIT); } - renderer.backend_mut().draw(gl, viewport, output, overlay) + renderer.present(|backend, primitive| { + backend.present(gl, primitive, viewport, overlay); + }); } } diff --git a/glutin/src/application.rs b/glutin/src/application.rs index fa2192d8..508dfe04 100644 --- a/glutin/src/application.rs +++ b/glutin/src/application.rs @@ -1,5 +1,5 @@ //! Create interactive, native cross-platform applications. -use crate::{mouse, Error, Executor, Runtime}; +use crate::{Error, Executor, Runtime}; pub use iced_winit::Application; @@ -179,9 +179,8 @@ async fn run_instance<A, E, C>( &mut debug, )); - let mut primitive = - user_interface.draw(&mut renderer, state.cursor_position()); - let mut mouse_interaction = mouse::Interaction::default(); + // TODO + // let mut mouse_interaction = mouse::Interaction::default(); let mut events = Vec::new(); let mut messages = Vec::new(); @@ -246,8 +245,7 @@ async fn run_instance<A, E, C>( } debug.draw_started(); - primitive = - user_interface.draw(&mut renderer, state.cursor_position()); + user_interface.draw(&mut renderer, state.cursor_position()); debug.draw_finished(); context.window().request_redraw(); @@ -291,8 +289,7 @@ async fn run_instance<A, E, C>( debug.layout_finished(); debug.draw_started(); - primitive = user_interface - .draw(&mut renderer, state.cursor_position()); + user_interface.draw(&mut renderer, state.cursor_position()); debug.draw_finished(); context.resize(glutin::dpi::PhysicalSize::new( @@ -305,11 +302,10 @@ async fn run_instance<A, E, C>( viewport_version = current_viewport_version; } - let new_mouse_interaction = compositor.draw( + compositor.present( &mut renderer, state.viewport(), state.background_color(), - &primitive, &debug.overlay(), ); @@ -317,14 +313,6 @@ async fn run_instance<A, E, C>( debug.render_finished(); - if new_mouse_interaction != mouse_interaction { - context.window().set_cursor_icon( - conversion::mouse_interaction(new_mouse_interaction), - ); - - mouse_interaction = new_mouse_interaction; - } - // TODO: Handle animations! // Maybe we can use `ControlFlow::WaitUntil` for this. } diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index 54cdcb77..9c113da6 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -4,7 +4,7 @@ //!  //! //! [`iced`]: https://github.com/hecrj/iced -#![deny(missing_docs)] +//#![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] #![deny(unsafe_code)] diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs index 53f47984..7dfb48b9 100644 --- a/graphics/src/overlay/menu.rs +++ b/graphics/src/overlay/menu.rs @@ -1,9 +1,8 @@ //! Build and show dropdown menus. -use crate::alignment; use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; +use crate::Renderer; -use iced_native::{mouse, overlay, Color, Font, Padding, Point, Rectangle}; +use iced_native::overlay; pub use iced_style::menu::Style; @@ -12,105 +11,4 @@ where B: Backend + backend::Text, { type Style = Style; - - fn decorate( - &mut self, - bounds: Rectangle, - _cursor_position: Point, - style: &Style, - (primitives, mouse_cursor): Self::Output, - ) -> Self::Output { - ( - Primitive::Group { - primitives: vec![ - Primitive::Quad { - bounds, - background: style.background, - border_color: style.border_color, - border_width: style.border_width, - border_radius: 0.0, - }, - primitives, - ], - }, - mouse_cursor, - ) - } - - fn draw<T: ToString>( - &mut self, - bounds: Rectangle, - cursor_position: Point, - viewport: &Rectangle, - options: &[T], - hovered_option: Option<usize>, - padding: Padding, - text_size: u16, - font: Font, - style: &Style, - ) -> Self::Output { - use std::f32; - - let is_mouse_over = bounds.contains(cursor_position); - let option_height = (text_size + padding.vertical()) as usize; - - let mut primitives = Vec::new(); - - let offset = viewport.y - bounds.y; - let start = (offset / option_height as f32) as usize; - let end = - ((offset + viewport.height) / option_height as f32).ceil() as usize; - - let visible_options = &options[start..end.min(options.len())]; - - for (i, option) in visible_options.iter().enumerate() { - let i = start + i; - let is_selected = hovered_option == Some(i); - - let bounds = Rectangle { - x: bounds.x, - y: bounds.y + (option_height * i) as f32, - width: bounds.width, - height: f32::from(text_size + padding.vertical()), - }; - - if is_selected { - primitives.push(Primitive::Quad { - bounds, - background: style.selected_background, - border_color: Color::TRANSPARENT, - border_width: 0.0, - border_radius: 0.0, - }); - } - - primitives.push(Primitive::Text { - content: option.to_string(), - bounds: Rectangle { - x: bounds.x + padding.left as f32, - y: bounds.center_y(), - width: f32::INFINITY, - ..bounds - }, - size: f32::from(text_size), - font, - color: if is_selected { - style.selected_text_color - } else { - style.text_color - }, - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - }); - } - - ( - Primitive::Group { primitives }, - if is_mouse_over { - mouse::Interaction::Pointer - } else { - mouse::Interaction::default() - }, - ) - } } 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<B: Backend> { backend: B, + primitive: Primitive, } impl<B: Backend> Renderer<B> { /// 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<B> iced_native::Renderer for Renderer<B> 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<B> layout::Debugger for Renderer<B> -where - B: Backend, -{ - fn explain<Message>( - &mut self, - defaults: &Defaults, - widget: &dyn Widget<Message, Self>, - 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<Primitive>, -) { - 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)) {} } diff --git a/graphics/src/widget/button.rs b/graphics/src/widget/button.rs index 60400ed8..990aac9f 100644 --- a/graphics/src/widget/button.rs +++ b/graphics/src/widget/button.rs @@ -1,12 +1,8 @@ //! Allow your users to perform actions by pressing a button. //! //! A [`Button`] has some local [`State`]. -use crate::defaults::{self, Defaults}; -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; -use iced_native::{ - Background, Color, Element, Layout, Padding, Point, Rectangle, Vector, -}; +use crate::{Backend, Renderer}; +use iced_native::Padding; pub use iced_native::button::State; pub use iced_style::button::{Style, StyleSheet}; @@ -24,88 +20,4 @@ where const DEFAULT_PADDING: Padding = Padding::new(5); type Style = Box<dyn StyleSheet>; - - fn draw<Message>( - &mut self, - _defaults: &Defaults, - bounds: Rectangle, - cursor_position: Point, - is_disabled: bool, - is_pressed: bool, - style: &Box<dyn StyleSheet>, - content: &Element<'_, Message, Self>, - content_layout: Layout<'_>, - ) -> Self::Output { - let is_mouse_over = bounds.contains(cursor_position); - - let styling = if is_disabled { - style.disabled() - } else if is_mouse_over { - if is_pressed { - style.pressed() - } else { - style.hovered() - } - } else { - style.active() - }; - - let (content, _) = content.draw( - self, - &Defaults { - text: defaults::Text { - color: styling.text_color, - }, - }, - content_layout, - cursor_position, - &bounds, - ); - - ( - if styling.background.is_some() || styling.border_width > 0.0 { - let background = Primitive::Quad { - bounds, - background: styling - .background - .unwrap_or(Background::Color(Color::TRANSPARENT)), - border_radius: styling.border_radius, - border_width: styling.border_width, - border_color: styling.border_color, - }; - - if styling.shadow_offset == Vector::default() { - Primitive::Group { - primitives: vec![background, content], - } - } else { - // TODO: Implement proper shadow support - let shadow = Primitive::Quad { - bounds: Rectangle { - x: bounds.x + styling.shadow_offset.x, - y: bounds.y + styling.shadow_offset.y, - ..bounds - }, - background: Background::Color( - [0.0, 0.0, 0.0, 0.5].into(), - ), - border_radius: styling.border_radius, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }; - - Primitive::Group { - primitives: vec![shadow, background, content], - } - } - } else { - content - }, - if is_mouse_over && !is_disabled { - mouse::Interaction::Pointer - } else { - mouse::Interaction::default() - }, - ) - } } diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs index 7897c8ec..7bf00ca5 100644 --- a/graphics/src/widget/canvas.rs +++ b/graphics/src/widget/canvas.rs @@ -3,12 +3,10 @@ //! 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! -use crate::{Backend, Defaults, Primitive, Renderer}; +use crate::{Backend, Defaults, Renderer}; use iced_native::layout; -use iced_native::mouse; use iced_native::{ - Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector, - Widget, + Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; use std::hash::Hash; use std::marker::PhantomData; @@ -190,28 +188,29 @@ where &self, _renderer: &mut Renderer<B>, _defaults: &Defaults, - layout: Layout<'_>, - cursor_position: Point, + _layout: Layout<'_>, + _cursor_position: Point, _viewport: &Rectangle, - ) -> (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), - ) + ) { + // 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), + // ) + // TODO } fn hash_layout(&self, state: &mut Hasher) { diff --git a/graphics/src/widget/checkbox.rs b/graphics/src/widget/checkbox.rs index 620bfc9e..3b756525 100644 --- a/graphics/src/widget/checkbox.rs +++ b/graphics/src/widget/checkbox.rs @@ -1,10 +1,8 @@ //! Show toggle controls using checkboxes. -use crate::alignment; use crate::backend::{self, Backend}; -use crate::{Primitive, Rectangle, Renderer}; +use crate::Renderer; use iced_native::checkbox; -use iced_native::mouse; pub use iced_style::checkbox::{Style, StyleSheet}; @@ -22,56 +20,4 @@ where const DEFAULT_SIZE: u16 = 20; const DEFAULT_SPACING: u16 = 15; - - fn draw( - &mut self, - bounds: Rectangle, - is_checked: bool, - is_mouse_over: bool, - (label, _): Self::Output, - style_sheet: &Self::Style, - ) -> Self::Output { - let style = if is_mouse_over { - style_sheet.hovered(is_checked) - } else { - style_sheet.active(is_checked) - }; - - let checkbox = Primitive::Quad { - bounds, - background: style.background, - border_radius: style.border_radius, - border_width: style.border_width, - border_color: style.border_color, - }; - - ( - Primitive::Group { - primitives: if is_checked { - let check = Primitive::Text { - content: B::CHECKMARK_ICON.to_string(), - font: B::ICON_FONT, - size: bounds.height * 0.7, - bounds: Rectangle { - x: bounds.center_x(), - y: bounds.center_y(), - ..bounds - }, - color: style.checkmark_color, - horizontal_alignment: alignment::Horizontal::Center, - vertical_alignment: alignment::Vertical::Center, - }; - - vec![checkbox, check, label] - } else { - vec![checkbox, label] - }, - }, - if is_mouse_over { - mouse::Interaction::Pointer - } else { - mouse::Interaction::default() - }, - ) - } } diff --git a/graphics/src/widget/column.rs b/graphics/src/widget/column.rs index 0cf56842..567529e5 100644 --- a/graphics/src/widget/column.rs +++ b/graphics/src/widget/column.rs @@ -1,49 +1,5 @@ -use crate::{Backend, Primitive, Renderer}; -use iced_native::column; -use iced_native::mouse; -use iced_native::{Element, Layout, Point, Rectangle}; +use crate::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, - content: &[Element<'_, Message, Self>], - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output { - let mut mouse_interaction = mouse::Interaction::default(); - - ( - Primitive::Group { - primitives: content - .iter() - .zip(layout.children()) - .map(|(child, layout)| { - let (primitive, new_mouse_interaction) = child.draw( - self, - defaults, - layout, - cursor_position, - viewport, - ); - - if new_mouse_interaction > mouse_interaction { - mouse_interaction = new_mouse_interaction; - } - - primitive - }) - .collect(), - }, - mouse_interaction, - ) - } -} diff --git a/graphics/src/widget/container.rs b/graphics/src/widget/container.rs index aae3e1d8..811a0c7f 100644 --- a/graphics/src/widget/container.rs +++ b/graphics/src/widget/container.rs @@ -1,8 +1,6 @@ //! 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}; +use crate::{Backend, Renderer}; pub use iced_style::container::{Style, StyleSheet}; @@ -18,61 +16,4 @@ where B: Backend, { type Style = Box<dyn container::StyleSheet>; - - fn draw<Message>( - &mut self, - defaults: &Defaults, - bounds: Rectangle, - cursor_position: Point, - viewport: &Rectangle, - style_sheet: &Self::Style, - content: &Element<'_, Message, Self>, - content_layout: Layout<'_>, - ) -> Self::Output { - let style = style_sheet.style(); - - let defaults = Defaults { - text: defaults::Text { - color: style.text_color.unwrap_or(defaults.text.color), - }, - }; - - let (content, mouse_interaction) = content.draw( - self, - &defaults, - content_layout, - cursor_position, - viewport, - ); - - if let Some(background) = background(bounds, &style) { - ( - Primitive::Group { - primitives: vec![background, content], - }, - mouse_interaction, - ) - } else { - (content, mouse_interaction) - } - } -} - -pub(crate) fn background( - bounds: Rectangle, - style: &container::Style, -) -> Option<Primitive> { - if style.background.is_some() || style.border_width > 0.0 { - Some(Primitive::Quad { - bounds, - background: style - .background - .unwrap_or(Background::Color(Color::TRANSPARENT)), - border_radius: style.border_radius, - border_width: style.border_width, - border_color: style.border_color, - }) - } else { - None - } } diff --git a/graphics/src/widget/image.rs b/graphics/src/widget/image.rs index bdf03de3..b55ba32f 100644 --- a/graphics/src/widget/image.rs +++ b/graphics/src/widget/image.rs @@ -3,10 +3,8 @@ pub mod viewer; use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; +use crate::Renderer; use iced_native::image; -use iced_native::mouse; -use iced_native::Layout; pub use iced_native::image::{Handle, Image, Viewer}; @@ -17,18 +15,4 @@ where fn dimensions(&self, handle: &image::Handle) -> (u32, u32) { self.backend().dimensions(handle) } - - fn draw( - &mut self, - handle: image::Handle, - layout: Layout<'_>, - ) -> Self::Output { - ( - Primitive::Image { - handle, - bounds: layout.bounds(), - }, - mouse::Interaction::default(), - ) - } } diff --git a/graphics/src/widget/image/viewer.rs b/graphics/src/widget/image/viewer.rs index 28dffc4f..ea7d8591 100644 --- a/graphics/src/widget/image/viewer.rs +++ b/graphics/src/widget/image/viewer.rs @@ -1,55 +1,2 @@ //! Zoom and pan on an image. -use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; - -use iced_native::image; -use iced_native::image::viewer; -use iced_native::mouse; -use iced_native::{Rectangle, Size, Vector}; - -impl<B> viewer::Renderer for Renderer<B> -where - B: Backend + backend::Image, -{ - fn draw( - &mut self, - state: &viewer::State, - bounds: Rectangle, - image_size: Size, - translation: Vector, - handle: image::Handle, - is_mouse_over: bool, - ) -> Self::Output { - ( - { - Primitive::Clip { - bounds, - content: Box::new(Primitive::Translate { - translation, - content: Box::new(Primitive::Image { - handle, - bounds: Rectangle { - x: bounds.x, - y: bounds.y, - ..Rectangle::with_size(image_size) - }, - }), - }), - offset: Vector::new(0, 0), - } - }, - { - if state.is_cursor_grabbed() { - mouse::Interaction::Grabbing - } else if is_mouse_over - && (image_size.width > bounds.width - || image_size.height > bounds.height) - { - mouse::Interaction::Grab - } else { - mouse::Interaction::Idle - } - }, - ) - } -} +pub use iced_native::image::Viewer; diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs index 92cdbb77..8c6b0f82 100644 --- a/graphics/src/widget/pane_grid.rs +++ b/graphics/src/widget/pane_grid.rs @@ -7,12 +7,8 @@ //! drag and drop, and hotkey support. //! //! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.3/examples/pane_grid -use crate::defaults; -use crate::{Backend, Color, Primitive, Renderer}; -use iced_native::container; -use iced_native::mouse; +use crate::{Backend, Renderer}; use iced_native::pane_grid; -use iced_native::{Element, Layout, Point, Rectangle, Vector}; pub use iced_native::pane_grid::{ Axis, Configuration, Content, Direction, DragEvent, Node, Pane, @@ -35,270 +31,4 @@ where B: Backend, { type Style = Box<dyn StyleSheet>; - - fn draw<Message>( - &mut self, - defaults: &Self::Defaults, - content: &[(Pane, Content<'_, Message, Self>)], - dragging: Option<(Pane, Point)>, - resizing: Option<(Axis, Rectangle, bool)>, - layout: Layout<'_>, - style_sheet: &<Self as pane_grid::Renderer>::Style, - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output { - let pane_cursor_position = if dragging.is_some() { - // TODO: Remove once cursor availability is encoded in the type - // system - Point::new(-1.0, -1.0) - } else { - cursor_position - }; - - let mut mouse_interaction = mouse::Interaction::default(); - let mut dragged_pane = None; - - let mut panes: Vec<_> = content - .iter() - .zip(layout.children()) - .enumerate() - .map(|(i, ((id, pane), layout))| { - let (primitive, new_mouse_interaction) = pane.draw( - self, - defaults, - layout, - pane_cursor_position, - viewport, - ); - - if new_mouse_interaction > mouse_interaction { - mouse_interaction = new_mouse_interaction; - } - - if let Some((dragging, origin)) = dragging { - if *id == dragging { - dragged_pane = Some((i, layout, origin)); - } - } - - primitive - }) - .collect(); - - let mut primitives = if let Some((index, layout, origin)) = dragged_pane - { - let pane = panes.remove(index); - let bounds = layout.bounds(); - - // TODO: Fix once proper layering is implemented. - // This is a pretty hacky way to achieve layering. - let clip = Primitive::Clip { - bounds: Rectangle { - x: cursor_position.x - origin.x, - y: cursor_position.y - origin.y, - width: bounds.width + 0.5, - height: bounds.height + 0.5, - }, - offset: Vector::new(0, 0), - content: Box::new(Primitive::Translate { - translation: Vector::new( - cursor_position.x - bounds.x - origin.x, - cursor_position.y - bounds.y - origin.y, - ), - content: Box::new(pane), - }), - }; - - panes.push(clip); - - panes - } else { - panes - }; - - let (primitives, mouse_interaction) = - if let Some((axis, split_region, is_picked)) = resizing { - let highlight = if is_picked { - style_sheet.picked_split() - } else { - style_sheet.hovered_split() - }; - - if let Some(highlight) = highlight { - primitives.push(Primitive::Quad { - bounds: match axis { - Axis::Horizontal => Rectangle { - x: split_region.x, - y: (split_region.y - + (split_region.height - highlight.width) - / 2.0) - .round(), - width: split_region.width, - height: highlight.width, - }, - Axis::Vertical => Rectangle { - x: (split_region.x - + (split_region.width - highlight.width) - / 2.0) - .round(), - y: split_region.y, - width: highlight.width, - height: split_region.height, - }, - }, - background: highlight.color.into(), - border_radius: 0.0, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }); - } - - ( - primitives, - match axis { - Axis::Horizontal => { - mouse::Interaction::ResizingVertically - } - Axis::Vertical => { - mouse::Interaction::ResizingHorizontally - } - }, - ) - } else { - (primitives, mouse_interaction) - }; - - ( - Primitive::Group { primitives }, - if dragging.is_some() { - mouse::Interaction::Grabbing - } else { - mouse_interaction - }, - ) - } - - fn draw_pane<Message>( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - style_sheet: &<Self as container::Renderer>::Style, - title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>, - body: (&Element<'_, Message, Self>, Layout<'_>), - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output { - let style = style_sheet.style(); - let (body, body_layout) = body; - - let (body_primitive, body_interaction) = - body.draw(self, defaults, body_layout, cursor_position, viewport); - - let background = crate::widget::container::background(bounds, &style); - - if let Some((title_bar, title_bar_layout)) = title_bar { - let show_controls = bounds.contains(cursor_position); - let is_over_pick_area = - title_bar.is_over_pick_area(title_bar_layout, cursor_position); - - let (title_bar_primitive, title_bar_interaction) = title_bar.draw( - self, - defaults, - title_bar_layout, - cursor_position, - viewport, - show_controls, - ); - - ( - Primitive::Group { - primitives: vec![ - background.unwrap_or(Primitive::None), - title_bar_primitive, - body_primitive, - ], - }, - if title_bar_interaction > body_interaction { - title_bar_interaction - } else if is_over_pick_area { - mouse::Interaction::Grab - } else { - body_interaction - }, - ) - } else { - ( - if let Some(background) = background { - Primitive::Group { - primitives: vec![background, body_primitive], - } - } else { - body_primitive - }, - body_interaction, - ) - } - } - - fn draw_title_bar<Message>( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - style_sheet: &<Self as container::Renderer>::Style, - content: (&Element<'_, Message, Self>, Layout<'_>), - controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output { - let style = style_sheet.style(); - let (title_content, title_layout) = content; - - let defaults = Self::Defaults { - text: defaults::Text { - color: style.text_color.unwrap_or(defaults.text.color), - }, - }; - - let background = crate::widget::container::background(bounds, &style); - - let (title_primitive, title_interaction) = title_content.draw( - self, - &defaults, - title_layout, - cursor_position, - viewport, - ); - - if let Some((controls, controls_layout)) = controls { - let (controls_primitive, controls_interaction) = controls.draw( - self, - &defaults, - controls_layout, - cursor_position, - viewport, - ); - - ( - Primitive::Group { - primitives: vec![ - background.unwrap_or(Primitive::None), - title_primitive, - controls_primitive, - ], - }, - controls_interaction.max(title_interaction), - ) - } else { - ( - if let Some(background) = background { - Primitive::Group { - primitives: vec![background, title_primitive], - } - } else { - title_primitive - }, - title_interaction, - ) - } - } } diff --git a/graphics/src/widget/pick_list.rs b/graphics/src/widget/pick_list.rs index 532840b8..54f42cde 100644 --- a/graphics/src/widget/pick_list.rs +++ b/graphics/src/widget/pick_list.rs @@ -1,9 +1,8 @@ //! Display a dropdown list of selectable values. -use crate::alignment; use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; +use crate::Renderer; -use iced_native::{mouse, Font, Padding, Point, Rectangle}; +use iced_native::Padding; use iced_style::menu; pub use iced_native::pick_list::State; @@ -24,80 +23,4 @@ where fn menu_style(style: &Box<dyn StyleSheet>) -> menu::Style { style.menu() } - - fn draw( - &mut self, - bounds: Rectangle, - cursor_position: Point, - selected: Option<String>, - placeholder: Option<&str>, - padding: Padding, - text_size: u16, - font: Font, - style: &Box<dyn StyleSheet>, - ) -> Self::Output { - let is_mouse_over = bounds.contains(cursor_position); - let is_selected = selected.is_some(); - - let style = if is_mouse_over { - style.hovered() - } else { - style.active() - }; - - let background = Primitive::Quad { - bounds, - background: style.background, - border_color: style.border_color, - border_width: style.border_width, - border_radius: style.border_radius, - }; - - let arrow_down = Primitive::Text { - content: B::ARROW_DOWN_ICON.to_string(), - font: B::ICON_FONT, - size: bounds.height * style.icon_size, - bounds: Rectangle { - x: bounds.x + bounds.width - f32::from(padding.horizontal()), - y: bounds.center_y(), - ..bounds - }, - color: style.text_color, - horizontal_alignment: alignment::Horizontal::Right, - vertical_alignment: alignment::Vertical::Center, - }; - - ( - Primitive::Group { - primitives: if let Some(label) = - selected.or_else(|| placeholder.map(str::to_string)) - { - let label = Primitive::Text { - content: label, - size: f32::from(text_size), - font, - color: is_selected - .then(|| style.text_color) - .unwrap_or(style.placeholder_color), - bounds: Rectangle { - x: bounds.x + f32::from(padding.left), - y: bounds.center_y(), - ..bounds - }, - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - }; - - vec![background, label, arrow_down] - } else { - vec![background, arrow_down] - }, - }, - if is_mouse_over { - mouse::Interaction::Pointer - } else { - mouse::Interaction::default() - }, - ) - } } diff --git a/graphics/src/widget/progress_bar.rs b/graphics/src/widget/progress_bar.rs index 32ee42c6..3d21b7b9 100644 --- a/graphics/src/widget/progress_bar.rs +++ b/graphics/src/widget/progress_bar.rs @@ -2,10 +2,8 @@ //! //! A [`ProgressBar`] has a range of possible values and a current value, //! as well as a length, height and style. -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; +use crate::{Backend, Renderer}; use iced_native::progress_bar; -use iced_native::{Color, Rectangle}; pub use iced_style::progress_bar::{Style, StyleSheet}; @@ -22,53 +20,4 @@ where type Style = Box<dyn StyleSheet>; const DEFAULT_HEIGHT: u16 = 30; - - fn draw( - &self, - bounds: Rectangle, - range: std::ops::RangeInclusive<f32>, - value: f32, - style_sheet: &Self::Style, - ) -> Self::Output { - let style = style_sheet.style(); - let (range_start, range_end) = range.into_inner(); - - let active_progress_width = if range_start >= range_end { - 0.0 - } else { - bounds.width * (value - range_start) / (range_end - range_start) - }; - - let background = Primitive::Group { - primitives: vec![Primitive::Quad { - bounds: Rectangle { ..bounds }, - background: style.background, - border_radius: style.border_radius, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }], - }; - - ( - if active_progress_width > 0.0 { - let bar = Primitive::Quad { - bounds: Rectangle { - width: active_progress_width, - ..bounds - }, - background: style.bar, - border_radius: style.border_radius, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }; - - Primitive::Group { - primitives: vec![background, bar], - } - } else { - background - }, - mouse::Interaction::default(), - ) - } } diff --git a/graphics/src/widget/qr_code.rs b/graphics/src/widget/qr_code.rs index b3a01dd7..a809d99f 100644 --- a/graphics/src/widget/qr_code.rs +++ b/graphics/src/widget/qr_code.rs @@ -1,10 +1,10 @@ //! Encode and display information in a QR code. use crate::canvas; -use crate::{Backend, Defaults, Primitive, Renderer, Vector}; +use crate::{Backend, Defaults, Renderer}; use iced_native::{ - layout, mouse, Color, Element, Hasher, Layout, Length, Point, Rectangle, - Size, Widget, + layout, Color, Element, Hasher, Layout, Length, Point, Rectangle, Size, + Widget, }; use thiserror::Error; @@ -82,53 +82,54 @@ where &self, _renderer: &mut Renderer<B>, _defaults: &Defaults, - layout: Layout<'_>, + _layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> (Primitive, mouse::Interaction) { - let bounds = layout.bounds(); - let side_length = self.state.width + 2 * QUIET_ZONE; - - // Reuse cache if possible - let geometry = self.state.cache.draw(bounds.size(), |frame| { - // Scale units to cell size - frame.scale(f32::from(self.cell_size)); - - // Draw background - frame.fill_rectangle( - Point::ORIGIN, - Size::new(side_length as f32, side_length as f32), - self.light, - ); - - // Avoid drawing on the quiet zone - frame.translate(Vector::new(QUIET_ZONE as f32, QUIET_ZONE as f32)); - - // Draw contents - self.state - .contents - .iter() - .enumerate() - .filter(|(_, value)| **value == qrcode::Color::Dark) - .for_each(|(index, _)| { - let row = index / self.state.width; - let column = index % self.state.width; - - frame.fill_rectangle( - Point::new(column as f32, row as f32), - Size::UNIT, - self.dark, - ); - }); - }); - - ( - Primitive::Translate { - translation: Vector::new(bounds.x, bounds.y), - content: Box::new(geometry.into_primitive()), - }, - mouse::Interaction::default(), - ) + ) { + // let bounds = layout.bounds(); + // let side_length = self.state.width + 2 * QUIET_ZONE; + + // // Reuse cache if possible + // let geometry = self.state.cache.draw(bounds.size(), |frame| { + // // Scale units to cell size + // frame.scale(f32::from(self.cell_size)); + + // // Draw background + // frame.fill_rectangle( + // Point::ORIGIN, + // Size::new(side_length as f32, side_length as f32), + // self.light, + // ); + + // // Avoid drawing on the quiet zone + // frame.translate(Vector::new(QUIET_ZONE as f32, QUIET_ZONE as f32)); + + // // Draw contents + // self.state + // .contents + // .iter() + // .enumerate() + // .filter(|(_, value)| **value == qrcode::Color::Dark) + // .for_each(|(index, _)| { + // let row = index / self.state.width; + // let column = index % self.state.width; + + // frame.fill_rectangle( + // Point::new(column as f32, row as f32), + // Size::UNIT, + // self.dark, + // ); + // }); + // }); + + // ( + // Primitive::Translate { + // translation: Vector::new(bounds.x, bounds.y), + // content: Box::new(geometry.into_primitive()), + // }, + // mouse::Interaction::default(), + // ) + // TODO } } diff --git a/graphics/src/widget/radio.rs b/graphics/src/widget/radio.rs index fd3d8145..cd83f2ff 100644 --- a/graphics/src/widget/radio.rs +++ b/graphics/src/widget/radio.rs @@ -1,8 +1,6 @@ //! Create choices using radio buttons. -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; +use crate::{Backend, Renderer}; use iced_native::radio; -use iced_native::{Background, Color, Rectangle}; pub use iced_style::radio::{Style, StyleSheet}; @@ -21,58 +19,4 @@ where const DEFAULT_SIZE: u16 = 28; const DEFAULT_SPACING: u16 = 15; - - fn draw( - &mut self, - bounds: Rectangle, - is_selected: bool, - is_mouse_over: bool, - (label, _): Self::Output, - style_sheet: &Self::Style, - ) -> Self::Output { - let style = if is_mouse_over { - style_sheet.hovered() - } else { - style_sheet.active() - }; - - let size = bounds.width; - let dot_size = size / 2.0; - - let radio = Primitive::Quad { - bounds, - background: style.background, - border_radius: size / 2.0, - border_width: style.border_width, - border_color: style.border_color, - }; - - ( - Primitive::Group { - primitives: if is_selected { - let radio_circle = Primitive::Quad { - bounds: Rectangle { - x: bounds.x + dot_size / 2.0, - y: bounds.y + dot_size / 2.0, - width: bounds.width - dot_size, - height: bounds.height - dot_size, - }, - background: Background::Color(style.dot_color), - border_radius: dot_size / 2.0, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }; - - vec![radio, radio_circle, label] - } else { - vec![radio, label] - }, - }, - if is_mouse_over { - mouse::Interaction::Pointer - } else { - mouse::Interaction::default() - }, - ) - } } diff --git a/graphics/src/widget/row.rs b/graphics/src/widget/row.rs index 397d80bf..55960c04 100644 --- a/graphics/src/widget/row.rs +++ b/graphics/src/widget/row.rs @@ -1,49 +1,5 @@ -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; -use iced_native::row; -use iced_native::{Element, Layout, Point, Rectangle}; +use crate::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, - content: &[Element<'_, Message, Self>], - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output { - let mut mouse_interaction = mouse::Interaction::default(); - - ( - Primitive::Group { - primitives: content - .iter() - .zip(layout.children()) - .map(|(child, layout)| { - let (primitive, new_mouse_interaction) = child.draw( - self, - defaults, - layout, - cursor_position, - viewport, - ); - - if new_mouse_interaction > mouse_interaction { - mouse_interaction = new_mouse_interaction; - } - - primitive - }) - .collect(), - }, - mouse_interaction, - ) - } -} diff --git a/graphics/src/widget/rule.rs b/graphics/src/widget/rule.rs index 835ebed8..62766f82 100644 --- a/graphics/src/widget/rule.rs +++ b/graphics/src/widget/rule.rs @@ -1,9 +1,7 @@ //! Display a horizontal or vertical rule for dividing content. -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; +use crate::{Backend, Renderer}; use iced_native::rule; -use iced_native::{Background, Color, Rectangle}; pub use iced_style::rule::{FillMode, Style, StyleSheet}; @@ -17,57 +15,4 @@ where B: Backend, { type Style = Box<dyn StyleSheet>; - - fn draw( - &mut self, - bounds: Rectangle, - style_sheet: &Self::Style, - is_horizontal: bool, - ) -> Self::Output { - let style = style_sheet.style(); - - let line = if is_horizontal { - let line_y = (bounds.y + (bounds.height / 2.0) - - (style.width as f32 / 2.0)) - .round(); - - let (offset, line_width) = style.fill_mode.fill(bounds.width); - let line_x = bounds.x + offset; - - Primitive::Quad { - bounds: Rectangle { - x: line_x, - y: line_y, - width: line_width, - height: style.width as f32, - }, - background: Background::Color(style.color), - border_radius: style.radius, - border_width: 0.0, - border_color: Color::TRANSPARENT, - } - } else { - let line_x = (bounds.x + (bounds.width / 2.0) - - (style.width as f32 / 2.0)) - .round(); - - let (offset, line_height) = style.fill_mode.fill(bounds.height); - let line_y = bounds.y + offset; - - Primitive::Quad { - bounds: Rectangle { - x: line_x, - y: line_y, - width: style.width as f32, - height: line_height, - }, - background: Background::Color(style.color), - border_radius: style.radius, - border_width: 0.0, - border_color: Color::TRANSPARENT, - } - }; - - (line, mouse::Interaction::default()) - } } diff --git a/graphics/src/widget/scrollable.rs b/graphics/src/widget/scrollable.rs index 2220e4b8..f1fe0d2d 100644 --- a/graphics/src/widget/scrollable.rs +++ b/graphics/src/widget/scrollable.rs @@ -1,8 +1,7 @@ //! Navigate an endless amount of content with a scrollbar. -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; +use crate::{Backend, Renderer}; use iced_native::scrollable; -use iced_native::{Background, Color, Rectangle, Vector}; +use iced_native::Rectangle; pub use iced_native::scrollable::State; pub use iced_style::scrollable::{Scrollbar, Scroller, StyleSheet}; @@ -73,86 +72,4 @@ where None } } - - fn draw( - &mut self, - state: &scrollable::State, - bounds: Rectangle, - _content_bounds: Rectangle, - is_mouse_over: bool, - is_mouse_over_scrollbar: bool, - scrollbar: Option<scrollable::Scrollbar>, - offset: u32, - style_sheet: &Self::Style, - (content, mouse_interaction): Self::Output, - ) -> Self::Output { - ( - if let Some(scrollbar) = scrollbar { - let clip = Primitive::Clip { - bounds, - offset: Vector::new(0, offset), - content: Box::new(content), - }; - - let style = if state.is_scroller_grabbed() { - style_sheet.dragging() - } else if is_mouse_over_scrollbar { - style_sheet.hovered() - } else { - style_sheet.active() - }; - - let is_scrollbar_visible = - style.background.is_some() || style.border_width > 0.0; - - let scroller = if is_mouse_over - || state.is_scroller_grabbed() - || is_scrollbar_visible - { - Primitive::Quad { - bounds: scrollbar.scroller.bounds, - background: Background::Color(style.scroller.color), - border_radius: style.scroller.border_radius, - border_width: style.scroller.border_width, - border_color: style.scroller.border_color, - } - } else { - Primitive::None - }; - - let scrollbar = if is_scrollbar_visible { - Primitive::Quad { - bounds: scrollbar.bounds, - background: style - .background - .unwrap_or(Background::Color(Color::TRANSPARENT)), - border_radius: style.border_radius, - border_width: style.border_width, - border_color: style.border_color, - } - } else { - Primitive::None - }; - - let scroll = Primitive::Clip { - bounds, - offset: Vector::new(0, 0), - content: Box::new(Primitive::Group { - primitives: vec![scrollbar, scroller], - }), - }; - - Primitive::Group { - primitives: vec![clip, scroll], - } - } else { - content - }, - if is_mouse_over_scrollbar || state.is_scroller_grabbed() { - mouse::Interaction::Idle - } else { - mouse_interaction - }, - ) - } } diff --git a/graphics/src/widget/slider.rs b/graphics/src/widget/slider.rs index aeceec3f..5125d66c 100644 --- a/graphics/src/widget/slider.rs +++ b/graphics/src/widget/slider.rs @@ -1,10 +1,8 @@ //! Display an interactive selector of a single value from a range of values. //! //! A [`Slider`] has some local [`State`]. -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; +use crate::{Backend, Renderer}; 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}; @@ -23,101 +21,4 @@ where type Style = Box<dyn StyleSheet>; const DEFAULT_HEIGHT: u16 = 22; - - fn draw( - &mut self, - bounds: Rectangle, - cursor_position: Point, - range: std::ops::RangeInclusive<f32>, - value: f32, - is_dragging: bool, - style_sheet: &Self::Style, - ) -> Self::Output { - let is_mouse_over = bounds.contains(cursor_position); - - let style = if is_dragging { - style_sheet.dragging() - } else if is_mouse_over { - style_sheet.hovered() - } else { - style_sheet.active() - }; - - let rail_y = bounds.y + (bounds.height / 2.0).round(); - - let (rail_top, rail_bottom) = ( - Primitive::Quad { - bounds: Rectangle { - x: bounds.x, - y: rail_y, - width: bounds.width, - height: 2.0, - }, - background: Background::Color(style.rail_colors.0), - border_radius: 0.0, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }, - Primitive::Quad { - bounds: Rectangle { - x: bounds.x, - y: rail_y + 2.0, - width: bounds.width, - height: 2.0, - }, - background: Background::Color(style.rail_colors.1), - border_radius: 0.0, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }, - ); - - let (handle_width, handle_height, handle_border_radius) = match style - .handle - .shape - { - HandleShape::Circle { radius } => { - (radius * 2.0, radius * 2.0, radius) - } - HandleShape::Rectangle { - width, - border_radius, - } => (f32::from(width), f32::from(bounds.height), border_radius), - }; - - let (range_start, range_end) = range.into_inner(); - - let handle_offset = if range_start >= range_end { - 0.0 - } else { - (bounds.width - handle_width) * (value - range_start) - / (range_end - range_start) - }; - - let handle = Primitive::Quad { - bounds: Rectangle { - x: bounds.x + handle_offset.round(), - y: rail_y - handle_height / 2.0, - width: handle_width, - height: handle_height, - }, - background: Background::Color(style.handle.color), - border_radius: handle_border_radius, - border_width: style.handle.border_width, - border_color: style.handle.border_color, - }; - - ( - Primitive::Group { - primitives: vec![rail_top, rail_bottom, handle], - }, - if is_dragging { - mouse::Interaction::Grabbing - } else if is_mouse_over { - mouse::Interaction::Grab - } else { - mouse::Interaction::default() - }, - ) - } } diff --git a/graphics/src/widget/space.rs b/graphics/src/widget/space.rs index 1f31eabe..a4d60d4b 100644 --- a/graphics/src/widget/space.rs +++ b/graphics/src/widget/space.rs @@ -1,15 +1 @@ -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/graphics/src/widget/svg.rs b/graphics/src/widget/svg.rs index 8b5ed66a..b74a0abb 100644 --- a/graphics/src/widget/svg.rs +++ b/graphics/src/widget/svg.rs @@ -1,7 +1,7 @@ //! Display vector graphics in your application. use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; -use iced_native::{mouse, svg, Layout}; +use crate::Renderer; +use iced_native::svg; pub use iced_native::svg::{Handle, Svg}; @@ -12,18 +12,4 @@ where fn dimensions(&self, handle: &svg::Handle) -> (u32, u32) { self.backend().viewport_dimensions(handle) } - - fn draw( - &mut self, - handle: svg::Handle, - layout: Layout<'_>, - ) -> Self::Output { - ( - Primitive::Svg { - handle, - bounds: layout.bounds(), - }, - mouse::Interaction::default(), - ) - } } diff --git a/graphics/src/widget/text.rs b/graphics/src/widget/text.rs index d6d446d3..2ccd18a1 100644 --- a/graphics/src/widget/text.rs +++ b/graphics/src/widget/text.rs @@ -1,10 +1,8 @@ //! Write some text for your users to read. use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; -use iced_native::alignment; -use iced_native::mouse; +use crate::Renderer; use iced_native::text; -use iced_native::{Color, Font, Point, Rectangle, Size}; +use iced_native::{Font, Point, Size}; /// A paragraph of text. /// @@ -52,41 +50,4 @@ where nearest_only, ) } - - fn draw( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - content: &str, - size: u16, - font: Font, - color: Option<Color>, - horizontal_alignment: alignment::Horizontal, - vertical_alignment: alignment::Vertical, - ) -> Self::Output { - let x = match horizontal_alignment { - alignment::Horizontal::Left => bounds.x, - alignment::Horizontal::Center => bounds.center_x(), - alignment::Horizontal::Right => bounds.x + bounds.width, - }; - - let y = match vertical_alignment { - alignment::Vertical::Top => bounds.y, - alignment::Vertical::Center => bounds.center_y(), - alignment::Vertical::Bottom => bounds.y + bounds.height, - }; - - ( - Primitive::Text { - content: content.to_string(), - size: f32::from(size), - bounds: Rectangle { x, y, ..bounds }, - color: color.unwrap_or(defaults.text.color), - font, - horizontal_alignment, - vertical_alignment, - }, - mouse::Interaction::default(), - ) - } } diff --git a/graphics/src/widget/text_input.rs b/graphics/src/widget/text_input.rs index 1516b007..e9dbf056 100644 --- a/graphics/src/widget/text_input.rs +++ b/graphics/src/widget/text_input.rs @@ -1,14 +1,9 @@ //! Display fields that can be filled with text. //! //! A [`TextInput`] has some local [`State`]. -use crate::alignment; use crate::backend::{self, Backend}; -use crate::{ - Background, Color, Font, Point, Primitive, Rectangle, Renderer, Size, - Vector, -}; +use crate::{Font, Rectangle, Renderer, Size}; -use iced_native::mouse; use iced_native::text_input::{self, cursor}; use std::f32; @@ -66,181 +61,6 @@ where 0.0 } } - - fn draw( - &mut self, - bounds: Rectangle, - text_bounds: Rectangle, - cursor_position: Point, - font: Font, - size: u16, - placeholder: &str, - value: &text_input::Value, - state: &text_input::State, - style_sheet: &Self::Style, - ) -> Self::Output { - let is_mouse_over = bounds.contains(cursor_position); - - let style = if state.is_focused() { - style_sheet.focused() - } else if is_mouse_over { - style_sheet.hovered() - } else { - style_sheet.active() - }; - - let input = Primitive::Quad { - bounds, - background: style.background, - border_radius: style.border_radius, - border_width: style.border_width, - border_color: style.border_color, - }; - - let text = value.to_string(); - - let text_value = Primitive::Text { - content: if text.is_empty() { - placeholder.to_string() - } else { - text.clone() - }, - color: if text.is_empty() { - style_sheet.placeholder_color() - } else { - style_sheet.value_color() - }, - font, - bounds: Rectangle { - y: text_bounds.center_y(), - width: f32::INFINITY, - ..text_bounds - }, - size: f32::from(size), - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - }; - - let (contents_primitive, offset) = if state.is_focused() { - let cursor = state.cursor(); - - let (cursor_primitive, offset) = match cursor.state(value) { - cursor::State::Index(position) => { - let (text_value_width, offset) = - measure_cursor_and_scroll_offset( - self, - text_bounds, - value, - size, - position, - font, - ); - - ( - Primitive::Quad { - bounds: Rectangle { - x: text_bounds.x + text_value_width, - y: text_bounds.y, - width: 1.0, - height: text_bounds.height, - }, - background: Background::Color( - style_sheet.value_color(), - ), - border_radius: 0.0, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }, - offset, - ) - } - cursor::State::Selection { start, end } => { - let left = start.min(end); - let right = end.max(start); - - let (left_position, left_offset) = - measure_cursor_and_scroll_offset( - self, - text_bounds, - value, - size, - left, - font, - ); - - let (right_position, right_offset) = - measure_cursor_and_scroll_offset( - self, - text_bounds, - value, - size, - right, - font, - ); - - let width = right_position - left_position; - - ( - Primitive::Quad { - bounds: Rectangle { - x: text_bounds.x + left_position, - y: text_bounds.y, - width, - height: text_bounds.height, - }, - background: Background::Color( - style_sheet.selection_color(), - ), - border_radius: 0.0, - border_width: 0.0, - border_color: Color::TRANSPARENT, - }, - if end == right { - right_offset - } else { - left_offset - }, - ) - } - }; - - ( - Primitive::Group { - primitives: vec![cursor_primitive, text_value], - }, - Vector::new(offset as u32, 0), - ) - } else { - (text_value, Vector::new(0, 0)) - }; - - let text_width = self.measure_value( - if text.is_empty() { placeholder } else { &text }, - size, - font, - ); - - let contents = if text_width > text_bounds.width { - Primitive::Clip { - bounds: text_bounds, - offset, - content: Box::new(contents_primitive), - } - } else { - contents_primitive - }; - - ( - Primitive::Group { - primitives: vec![input, contents], - }, - if is_mouse_over { - mouse::Interaction::Text - } else { - mouse::Interaction::default() - }, - ) - } } fn measure_cursor_and_scroll_offset<B>( diff --git a/graphics/src/widget/toggler.rs b/graphics/src/widget/toggler.rs index 852d18ee..cd072f7c 100644 --- a/graphics/src/widget/toggler.rs +++ b/graphics/src/widget/toggler.rs @@ -1,19 +1,10 @@ //! Show toggle controls using togglers. use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; -use iced_native::mouse; +use crate::Renderer; use iced_native::toggler; -use iced_native::Rectangle; pub use iced_style::toggler::{Style, StyleSheet}; -/// Makes sure that the border radius of the toggler looks good at every size. -const BORDER_RADIUS_RATIO: f32 = 32.0 / 13.0; - -/// The space ratio between the background Quad and the Toggler bounds, and -/// between the background Quad and foreground Quad. -const SPACE_RATIO: f32 = 0.05; - /// A toggler that can be toggled. /// /// This is an alias of an `iced_native` toggler with an `iced_wgpu::Renderer`. @@ -27,73 +18,4 @@ where type Style = Box<dyn StyleSheet>; const DEFAULT_SIZE: u16 = 20; - - fn draw( - &mut self, - bounds: Rectangle, - is_active: bool, - is_mouse_over: bool, - label: Option<Self::Output>, - style_sheet: &Self::Style, - ) -> Self::Output { - let style = if is_mouse_over { - style_sheet.hovered(is_active) - } else { - style_sheet.active(is_active) - }; - - let border_radius = bounds.height as f32 / BORDER_RADIUS_RATIO; - let space = SPACE_RATIO * bounds.height as f32; - - let toggler_background_bounds = Rectangle { - x: bounds.x + space, - y: bounds.y + space, - width: bounds.width - (2.0 * space), - height: bounds.height - (2.0 * space), - }; - - let toggler_background = Primitive::Quad { - bounds: toggler_background_bounds, - background: style.background.into(), - border_radius, - border_width: 1.0, - border_color: style.background_border.unwrap_or(style.background), - }; - - let toggler_foreground_bounds = Rectangle { - x: bounds.x - + if is_active { - bounds.width - 2.0 * space - (bounds.height - (4.0 * space)) - } else { - 2.0 * space - }, - y: bounds.y + (2.0 * space), - width: bounds.height - (4.0 * space), - height: bounds.height - (4.0 * space), - }; - - let toggler_foreground = Primitive::Quad { - bounds: toggler_foreground_bounds, - background: style.foreground.into(), - border_radius, - border_width: 1.0, - border_color: style.foreground_border.unwrap_or(style.foreground), - }; - - ( - Primitive::Group { - primitives: match label { - Some((l, _)) => { - vec![l, toggler_background, toggler_foreground] - } - None => vec![toggler_background, toggler_foreground], - }, - }, - if is_mouse_over { - mouse::Interaction::Pointer - } else { - mouse::Interaction::default() - }, - ) - } } diff --git a/graphics/src/widget/tooltip.rs b/graphics/src/widget/tooltip.rs index 493a6389..d55d61b2 100644 --- a/graphics/src/widget/tooltip.rs +++ b/graphics/src/widget/tooltip.rs @@ -1,11 +1,6 @@ //! Decorate content and apply alignment. use crate::backend::{self, Backend}; -use crate::defaults::{self, Defaults}; -use crate::{Primitive, Renderer, Vector}; - -use iced_native::container; -use iced_native::layout::{self, Layout}; -use iced_native::{Element, Padding, Point, Rectangle, Size, Text}; +use crate::Renderer; /// An element decorating some content. /// @@ -21,148 +16,4 @@ where B: Backend + backend::Text, { const DEFAULT_PADDING: u16 = 5; - - fn draw<Message>( - &mut self, - defaults: &Defaults, - cursor_position: Point, - content_layout: Layout<'_>, - viewport: &Rectangle, - content: &Element<'_, Message, Self>, - tooltip: &Text<Self>, - position: Position, - style_sheet: &<Self as container::Renderer>::Style, - gap: u16, - padding: u16, - ) -> Self::Output { - let (content, mouse_interaction) = content.draw( - self, - &defaults, - content_layout, - cursor_position, - viewport, - ); - - let bounds = content_layout.bounds(); - - if bounds.contains(cursor_position) { - use iced_native::Widget; - - let gap = f32::from(gap); - let style = style_sheet.style(); - - let defaults = Defaults { - text: defaults::Text { - color: style.text_color.unwrap_or(defaults.text.color), - }, - }; - - let text_layout = Widget::<(), Self>::layout( - tooltip, - self, - &layout::Limits::new(Size::ZERO, viewport.size()) - .pad(Padding::new(padding)), - ); - - let padding = f32::from(padding); - let text_bounds = text_layout.bounds(); - let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0; - let y_center = - bounds.y + (bounds.height - text_bounds.height) / 2.0; - - let mut tooltip_bounds = { - let offset = match position { - Position::Top => Vector::new( - x_center, - bounds.y - text_bounds.height - gap - padding, - ), - Position::Bottom => Vector::new( - x_center, - bounds.y + bounds.height + gap + padding, - ), - Position::Left => Vector::new( - bounds.x - text_bounds.width - gap - padding, - y_center, - ), - Position::Right => Vector::new( - bounds.x + bounds.width + gap + padding, - y_center, - ), - Position::FollowCursor => Vector::new( - cursor_position.x, - cursor_position.y - text_bounds.height, - ), - }; - - Rectangle { - x: offset.x - padding, - y: offset.y - padding, - width: text_bounds.width + padding * 2.0, - height: text_bounds.height + padding * 2.0, - } - }; - - if tooltip_bounds.x < viewport.x { - tooltip_bounds.x = viewport.x; - } else if viewport.x + viewport.width - < tooltip_bounds.x + tooltip_bounds.width - { - tooltip_bounds.x = - viewport.x + viewport.width - tooltip_bounds.width; - } - - if tooltip_bounds.y < viewport.y { - tooltip_bounds.y = viewport.y; - } else if viewport.y + viewport.height - < tooltip_bounds.y + tooltip_bounds.height - { - tooltip_bounds.y = - viewport.y + viewport.height - tooltip_bounds.height; - } - - let (tooltip, _) = Widget::<(), Self>::draw( - tooltip, - self, - &defaults, - Layout::with_offset( - Vector::new( - tooltip_bounds.x + padding, - tooltip_bounds.y + padding, - ), - &text_layout, - ), - cursor_position, - viewport, - ); - - ( - Primitive::Group { - primitives: vec![ - content, - Primitive::Clip { - bounds: *viewport, - offset: Vector::new(0, 0), - content: Box::new( - if let Some(background) = - crate::container::background( - tooltip_bounds, - &style, - ) - { - Primitive::Group { - primitives: vec![background, tooltip], - } - } else { - tooltip - }, - ), - }, - ], - }, - mouse_interaction, - ) - } else { - (content, mouse_interaction) - } - } } diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs index 37edef1d..9ea040cd 100644 --- a/graphics/src/window/compositor.rs +++ b/graphics/src/window/compositor.rs @@ -1,7 +1,5 @@ use crate::{Color, Error, Viewport}; -use iced_native::mouse; - use raw_window_handle::HasRawWindowHandle; use thiserror::Error; @@ -30,9 +28,8 @@ pub trait Compositor: Sized { window: &W, ) -> Self::Surface; - /// Crates a new [`SwapChain`] for the given [`Surface`]. + /// Configures a new [`Surface`] with the given dimensions. /// - /// [`SwapChain`]: Self::SwapChain /// [`Surface`]: Self::Surface fn configure_surface( &mut self, @@ -41,18 +38,17 @@ pub trait Compositor: Sized { height: u32, ); - /// Draws the output primitives to the next frame of the given [`SwapChain`]. + /// Presents the [`Renderer`] primitives to the next frame of the given [`Surface`]. /// /// [`SwapChain`]: Self::SwapChain - fn draw<T: AsRef<str>>( + fn present<T: AsRef<str>>( &mut self, renderer: &mut Self::Renderer, surface: &mut Self::Surface, viewport: &Viewport, background_color: Color, - output: &<Self::Renderer as iced_native::Renderer>::Output, overlay: &[T], - ) -> Result<mouse::Interaction, SurfaceError>; + ) -> Result<(), SurfaceError>; } /// Result of an unsuccessful call to [`Compositor::draw`]. @@ -63,13 +59,13 @@ pub enum SurfaceError { "A timeout was encountered while trying to acquire the next frame" )] Timeout, - /// The underlying surface has changed, and therefore the swap chain must be updated. + /// The underlying surface has changed, and therefore the surface must be updated. #[error( - "The underlying surface has changed, and therefore the swap chain must be updated." + "The underlying surface has changed, and therefore the surface must be updated." )] Outdated, /// The swap chain has been lost and needs to be recreated. - #[error("The swap chain has been lost and needs to be recreated")] + #[error("The surface has been lost and needs to be recreated")] Lost, /// There is no more memory left to allocate a new frame. #[error("There is no more memory left to allocate a new frame")] diff --git a/graphics/src/window/gl_compositor.rs b/graphics/src/window/gl_compositor.rs index 34d70be3..b1b995f1 100644 --- a/graphics/src/window/gl_compositor.rs +++ b/graphics/src/window/gl_compositor.rs @@ -1,5 +1,4 @@ use crate::{Color, Error, Size, Viewport}; -use iced_native::mouse; use core::ffi::c_void; @@ -49,15 +48,15 @@ pub trait GLCompositor: Sized { /// Resizes the viewport of the [`GLCompositor`]. fn resize_viewport(&mut self, physical_size: Size<u32>); - /// Draws the provided output with the given [`Renderer`]. + /// Presents the primitives of the [`Renderer`] to the next frame of the + /// [`GLCompositor`]. /// /// [`Renderer`]: crate::Renderer - fn draw<T: AsRef<str>>( + fn present<T: AsRef<str>>( &mut self, renderer: &mut Self::Renderer, viewport: &Viewport, background_color: Color, - output: &<Self::Renderer as iced_native::Renderer>::Output, overlay: &[T], - ) -> mouse::Interaction; + ); } diff --git a/native/src/element.rs b/native/src/element.rs index 5c84a388..35e1b4f4 100644 --- a/native/src/element.rs +++ b/native/src/element.rs @@ -189,7 +189,7 @@ where ) -> Element<'a, Message, Renderer> where Message: 'static, - Renderer: 'a + layout::Debugger, + Renderer: 'a, { Element { widget: Box::new(Explain::new(self, color.into())), @@ -245,7 +245,7 @@ where layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output { + ) { self.widget .draw(renderer, defaults, layout, cursor_position, viewport) } @@ -340,7 +340,7 @@ where layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output { + ) { self.widget .draw(renderer, defaults, layout, cursor_position, viewport) } @@ -378,7 +378,7 @@ where impl<'a, Message, Renderer> Widget<Message, Renderer> for Explain<'a, Message, Renderer> where - Renderer: crate::Renderer + layout::Debugger, + Renderer: crate::Renderer, { fn width(&self) -> Length { self.element.widget.width() @@ -417,20 +417,12 @@ where fn draw( &self, - renderer: &mut Renderer, - defaults: &Renderer::Defaults, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Renderer::Output { - renderer.explain( - defaults, - self.element.widget.as_ref(), - layout, - cursor_position, - viewport, - self.color, - ) + _renderer: &mut Renderer, + _defaults: &Renderer::Defaults, + _layout: Layout<'_>, + _cursor_position: Point, + _viewport: &Rectangle, + ) { } fn hash_layout(&self, state: &mut Hasher) { diff --git a/native/src/layout.rs b/native/src/layout.rs index b4b4a021..04954fb9 100644 --- a/native/src/layout.rs +++ b/native/src/layout.rs @@ -1,11 +1,9 @@ //! Position your widgets properly. -mod debugger; mod limits; mod node; pub mod flex; -pub use debugger::Debugger; pub use limits::Limits; pub use node::Node; diff --git a/native/src/layout/debugger.rs b/native/src/layout/debugger.rs deleted file mode 100644 index 0759613f..00000000 --- a/native/src/layout/debugger.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::{Color, Layout, Point, Rectangle, Renderer, Widget}; - -/// A renderer able to graphically explain a [`Layout`]. -pub trait Debugger: Renderer { - /// Explains the [`Layout`] of an [`Element`] for debugging purposes. - /// - /// This will be called when [`Element::explain`] has been used. It should - /// _explain_ the given [`Layout`] graphically. - /// - /// A common approach consists in recursively rendering the bounds of the - /// [`Layout`] and its children. - /// - /// [`Element`]: crate::Element - /// [`Element::explain`]: crate::Element::explain - fn explain<Message>( - &mut self, - defaults: &Self::Defaults, - widget: &dyn Widget<Message, Self>, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - color: Color, - ) -> Self::Output; -} diff --git a/native/src/lib.rs b/native/src/lib.rs index 170a588b..55265fbf 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -28,7 +28,7 @@ //! [`druid`]: https://github.com/xi-editor/druid //! [`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle //! [renderer]: crate::renderer -#![deny(missing_docs)] +//#![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] #![forbid(unsafe_code)] diff --git a/native/src/overlay.rs b/native/src/overlay.rs index 84145e7f..7054ee69 100644 --- a/native/src/overlay.rs +++ b/native/src/overlay.rs @@ -35,7 +35,7 @@ where defaults: &Renderer::Defaults, layout: Layout<'_>, cursor_position: Point, - ) -> Renderer::Output; + ); /// Computes the _layout_ hash of the [`Overlay`]. /// diff --git a/native/src/overlay/element.rs b/native/src/overlay/element.rs index e4819037..081b62ce 100644 --- a/native/src/overlay/element.rs +++ b/native/src/overlay/element.rs @@ -74,7 +74,7 @@ where defaults: &Renderer::Defaults, layout: Layout<'_>, cursor_position: Point, - ) -> Renderer::Output { + ) { self.overlay .draw(renderer, defaults, layout, cursor_position) } @@ -145,7 +145,7 @@ where defaults: &Renderer::Defaults, layout: Layout<'_>, cursor_position: Point, - ) -> Renderer::Output { + ) { self.content .draw(renderer, defaults, layout, cursor_position) } diff --git a/native/src/overlay/menu.rs b/native/src/overlay/menu.rs index f62dcb46..f90a9f7b 100644 --- a/native/src/overlay/menu.rs +++ b/native/src/overlay/menu.rs @@ -239,21 +239,22 @@ where defaults: &Renderer::Defaults, layout: Layout<'_>, cursor_position: Point, - ) -> Renderer::Output { - let primitives = self.container.draw( - renderer, - defaults, - layout, - cursor_position, - &layout.bounds(), - ); - - renderer.decorate( - layout.bounds(), - cursor_position, - &self.style, - primitives, - ) + ) { + // TODO + // let primitives = self.container.draw( + // renderer, + // defaults, + // layout, + // cursor_position, + // &layout.bounds(), + // ); + + // renderer.decorate( + // layout.bounds(), + // cursor_position, + // &self.style, + // primitives, + // ) } } @@ -378,24 +379,13 @@ where fn draw( &self, - renderer: &mut Renderer, + _renderer: &mut Renderer, _defaults: &Renderer::Defaults, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Renderer::Output { - self::Renderer::draw( - renderer, - layout.bounds(), - cursor_position, - viewport, - self.options, - *self.hovered_option, - self.padding, - self.text_size.unwrap_or(renderer.default_size()), - self.font, - &self.style, - ) + _layout: Layout<'_>, + _cursor_position: Point, + _viewport: &Rectangle, + ) { + // TODO } } @@ -410,31 +400,6 @@ pub trait Renderer: { /// The [`Menu`] style supported by this renderer. type Style: Default + Clone; - - /// Decorates a the list of options of a [`Menu`]. - /// - /// This method can be used to draw a background for the [`Menu`]. - fn decorate( - &mut self, - bounds: Rectangle, - cursor_position: Point, - style: &<Self as Renderer>::Style, - primitive: Self::Output, - ) -> Self::Output; - - /// Draws the list of options of a [`Menu`]. - fn draw<T: ToString>( - &mut self, - bounds: Rectangle, - cursor_position: Point, - viewport: &Rectangle, - options: &[T], - hovered_option: Option<usize>, - padding: Padding, - text_size: u16, - font: Self::Font, - style: &<Self as Renderer>::Style, - ) -> Self::Output; } impl<'a, T, Message, Renderer> Into<Element<'a, Message, Renderer>> diff --git a/native/src/program/state.rs b/native/src/program/state.rs index 3f5f6069..55308a92 100644 --- a/native/src/program/state.rs +++ b/native/src/program/state.rs @@ -1,5 +1,5 @@ use crate::{ - Cache, Clipboard, Command, Debug, Event, Point, Program, Renderer, Size, + Cache, Clipboard, Command, Debug, Event, Point, Program, Size, UserInterface, }; @@ -12,7 +12,6 @@ where { program: P, cache: Option<Cache>, - primitive: <P::Renderer as Renderer>::Output, queued_events: Vec<Event>, queued_messages: Vec<P::Message>, } @@ -38,16 +37,11 @@ where debug, ); - debug.draw_started(); - let primitive = user_interface.draw(renderer, cursor_position); - debug.draw_finished(); - let cache = Some(user_interface.into_cache()); State { program, cache, - primitive, queued_events: Vec::new(), queued_messages: Vec::new(), } @@ -58,11 +52,6 @@ where &self.program } - /// Returns a reference to the current rendering primitive of the [`State`]. - pub fn primitive(&self) -> &<P::Renderer as Renderer>::Output { - &self.primitive - } - /// Queues an event in the [`State`] for processing during an [`update`]. /// /// [`update`]: Self::update @@ -120,7 +109,7 @@ where if messages.is_empty() { debug.draw_started(); - self.primitive = user_interface.draw(renderer, cursor_position); + user_interface.draw(renderer, cursor_position); debug.draw_finished(); self.cache = Some(user_interface.into_cache()); @@ -151,7 +140,7 @@ where ); debug.draw_started(); - self.primitive = user_interface.draw(renderer, cursor_position); + user_interface.draw(renderer, cursor_position); debug.draw_finished(); self.cache = Some(user_interface.into_cache()); diff --git a/native/src/renderer.rs b/native/src/renderer.rs index 39a6cff1..3784ff24 100644 --- a/native/src/renderer.rs +++ b/native/src/renderer.rs @@ -30,12 +30,6 @@ use crate::{layout, Element, Rectangle}; /// A component that can take the state of a user interface and produce an /// output for its users. pub trait Renderer: Sized { - /// The type of output of the [`Renderer`]. - /// - /// If you are implementing a graphical renderer, your output will most - /// likely be a tree of visual primitives. - type Output; - /// The default styling attributes of the [`Renderer`]. /// /// This type can be leveraged to implement style inheritance. @@ -53,12 +47,5 @@ pub trait Renderer: Sized { element.layout(self, limits) } - /// Overlays the `overlay` output with the given bounds on top of the `base` - /// output. - fn overlay( - &mut self, - base: Self::Output, - overlay: Self::Output, - overlay_bounds: Rectangle, - ) -> Self::Output; + fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)); } diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index b5921582..1ffca5c9 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -1,20 +1,15 @@ -use crate::alignment; use crate::button; use crate::checkbox; -use crate::column; use crate::container; use crate::pane_grid; use crate::progress_bar; use crate::radio; -use crate::row; use crate::scrollable; use crate::slider; use crate::text; use crate::text_input; use crate::toggler; -use crate::{ - Color, Element, Font, Layout, Padding, Point, Rectangle, Renderer, Size, -}; +use crate::{Font, Padding, Point, Rectangle, Renderer, Size}; /// A renderer that does nothing. /// @@ -30,35 +25,9 @@ impl Null { } impl Renderer for Null { - type Output = (); type Defaults = (); - fn overlay(&mut self, _base: (), _overlay: (), _overlay_bounds: Rectangle) { - } -} - -impl column::Renderer for Null { - fn draw<Message>( - &mut self, - _defaults: &Self::Defaults, - _content: &[Element<'_, Message, Self>], - _layout: Layout<'_>, - _cursor_position: Point, - _viewport: &Rectangle, - ) { - } -} - -impl row::Renderer for Null { - fn draw<Message>( - &mut self, - _defaults: &Self::Defaults, - _content: &[Element<'_, Message, Self>], - _layout: Layout<'_>, - _cursor_position: Point, - _viewport: &Rectangle, - ) { - } + fn with_layer(&mut self, _bounds: Rectangle, _f: impl FnOnce(&mut Self)) {} } impl text::Renderer for Null { @@ -89,19 +58,6 @@ impl text::Renderer for Null { ) -> Option<text::Hit> { None } - - fn draw( - &mut self, - _defaults: &Self::Defaults, - _bounds: Rectangle, - _content: &str, - _size: u16, - _font: Font, - _color: Option<Color>, - _horizontal_alignment: alignment::Horizontal, - _vertical_alignment: alignment::Vertical, - ) { - } } impl scrollable::Renderer for Null { @@ -118,20 +74,6 @@ impl scrollable::Renderer for Null { ) -> Option<scrollable::Scrollbar> { None } - - fn draw( - &mut self, - _scrollable: &scrollable::State, - _bounds: Rectangle, - _content_bounds: Rectangle, - _is_mouse_over: bool, - _is_mouse_over_scrollbar: bool, - _scrollbar: Option<scrollable::Scrollbar>, - _offset: u32, - _style: &Self::Style, - _content: Self::Output, - ) { - } } impl text_input::Renderer for Null { @@ -151,39 +93,12 @@ impl text_input::Renderer for Null { ) -> f32 { 0.0 } - - fn draw( - &mut self, - _bounds: Rectangle, - _text_bounds: Rectangle, - _cursor_position: Point, - _font: Font, - _size: u16, - _placeholder: &str, - _value: &text_input::Value, - _state: &text_input::State, - _style: &Self::Style, - ) -> Self::Output { - } } impl button::Renderer for Null { const DEFAULT_PADDING: Padding = Padding::ZERO; type Style = (); - - fn draw<Message>( - &mut self, - _defaults: &Self::Defaults, - _bounds: Rectangle, - _cursor_position: Point, - _is_disabled: bool, - _is_pressed: bool, - _style: &Self::Style, - _content: &Element<'_, Message, Self>, - _content_layout: Layout<'_>, - ) -> Self::Output { - } } impl radio::Renderer for Null { @@ -191,16 +106,6 @@ impl radio::Renderer for Null { const DEFAULT_SIZE: u16 = 20; const DEFAULT_SPACING: u16 = 15; - - fn draw( - &mut self, - _bounds: Rectangle, - _is_selected: bool, - _is_mouse_over: bool, - _label: Self::Output, - _style: &Self::Style, - ) { - } } impl checkbox::Renderer for Null { @@ -208,122 +113,30 @@ impl checkbox::Renderer for Null { const DEFAULT_SIZE: u16 = 20; const DEFAULT_SPACING: u16 = 15; - - fn draw( - &mut self, - _bounds: Rectangle, - _is_checked: bool, - _is_mouse_over: bool, - _label: Self::Output, - _style: &Self::Style, - ) { - } } impl slider::Renderer for Null { type Style = (); const DEFAULT_HEIGHT: u16 = 30; - - fn draw( - &mut self, - _bounds: Rectangle, - _cursor_position: Point, - _range: std::ops::RangeInclusive<f32>, - _value: f32, - _is_dragging: bool, - _style_sheet: &Self::Style, - ) { - } } impl progress_bar::Renderer for Null { type Style = (); const DEFAULT_HEIGHT: u16 = 30; - - fn draw( - &self, - _bounds: Rectangle, - _range: std::ops::RangeInclusive<f32>, - _value: f32, - _style: &Self::Style, - ) { - } } impl container::Renderer for Null { type Style = (); - - fn draw<Message>( - &mut self, - _defaults: &Self::Defaults, - _bounds: Rectangle, - _cursor_position: Point, - _viewport: &Rectangle, - _style: &Self::Style, - _content: &Element<'_, Message, Self>, - _content_layout: Layout<'_>, - ) { - } } impl pane_grid::Renderer for Null { type Style = (); - - fn draw<Message>( - &mut self, - _defaults: &Self::Defaults, - _content: &[(pane_grid::Pane, pane_grid::Content<'_, Message, Self>)], - _dragging: Option<(pane_grid::Pane, Point)>, - _resizing: Option<(pane_grid::Axis, Rectangle, bool)>, - _layout: Layout<'_>, - _style: &<Self as pane_grid::Renderer>::Style, - _cursor_position: Point, - _viewport: &Rectangle, - ) { - } - - fn draw_pane<Message>( - &mut self, - _defaults: &Self::Defaults, - _bounds: Rectangle, - _style: &<Self as container::Renderer>::Style, - _title_bar: Option<( - &pane_grid::TitleBar<'_, Message, Self>, - Layout<'_>, - )>, - _body: (&Element<'_, Message, Self>, Layout<'_>), - _cursor_position: Point, - _viewport: &Rectangle, - ) { - } - - fn draw_title_bar<Message>( - &mut self, - _defaults: &Self::Defaults, - _bounds: Rectangle, - _style: &<Self as container::Renderer>::Style, - _content: (&Element<'_, Message, Self>, Layout<'_>), - _controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, - _cursor_position: Point, - _viewport: &Rectangle, - ) { - } } impl toggler::Renderer for Null { type Style = (); const DEFAULT_SIZE: u16 = 20; - - fn draw( - &mut self, - _bounds: Rectangle, - _is_checked: bool, - _is_mouse_over: bool, - _label: Option<Self::Output>, - _style: &Self::Style, - ) { - } } diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index 8e0d7d1c..187c469a 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -329,11 +329,7 @@ where /// // Flush rendering operations... /// } /// ``` - pub fn draw( - &mut self, - renderer: &mut Renderer, - cursor_position: Point, - ) -> Renderer::Output { + pub fn draw(&mut self, renderer: &mut Renderer, cursor_position: Point) { let viewport = Rectangle::with_size(self.bounds); let overlay = if let Some(mut overlay) = @@ -348,40 +344,36 @@ where let overlay_bounds = layer.layout.bounds(); - let overlay_primitives = overlay.draw( - renderer, - &Renderer::Defaults::default(), - Layout::new(&layer.layout), - cursor_position, - ); + renderer.with_layer(overlay_bounds, |renderer| { + overlay.draw( + renderer, + &Renderer::Defaults::default(), + Layout::new(&layer.layout), + cursor_position, + ); + }); self.overlay = Some(layer); - Some((overlay_primitives, overlay_bounds)) + Some(overlay_bounds) } else { None }; - if let Some((overlay_primitives, overlay_bounds)) = overlay { + if let Some(overlay_bounds) = overlay { let base_cursor = if overlay_bounds.contains(cursor_position) { Point::new(-1.0, -1.0) } else { cursor_position }; - let base_primitives = self.root.widget.draw( + self.root.widget.draw( renderer, &Renderer::Defaults::default(), Layout::new(&self.base.layout), base_cursor, &viewport, ); - - renderer.overlay( - base_primitives, - overlay_primitives, - overlay_bounds, - ) } else { self.root.widget.draw( renderer, @@ -389,7 +381,7 @@ where Layout::new(&self.base.layout), cursor_position, &viewport, - ) + ); } } diff --git a/native/src/widget.rs b/native/src/widget.rs index 43c1b023..01c5bed3 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -135,7 +135,7 @@ where layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output; + ); /// Computes the _layout_ hash of the [`Widget`]. /// diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index c469a0e5..1c7f80ef 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -248,17 +248,7 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw( - defaults, - layout.bounds(), - cursor_position, - self.on_press.is_none(), - self.state.is_pressed, - &self.style, - &self.content, - layout.children().next().unwrap(), - ) + ) { } fn hash_layout(&self, state: &mut Hasher) { @@ -289,19 +279,6 @@ pub trait Renderer: crate::Renderer + Sized { /// The style supported by this renderer. type Style: Default; - - /// Draws a [`Button`]. - fn draw<Message>( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - cursor_position: Point, - is_disabled: bool, - is_pressed: bool, - style: &Self::Style, - content: &Element<'_, Message, Self>, - content_layout: Layout<'_>, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Button<'a, Message, Renderer>> diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index 8bdb6b78..579e4ee3 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -5,7 +5,6 @@ use crate::alignment::{self, Alignment}; use crate::event::{self, Event}; use crate::layout; use crate::mouse; -use crate::row; use crate::text; use crate::touch; use crate::{ @@ -121,7 +120,7 @@ impl<Message, Renderer: self::Renderer + text::Renderer> impl<Message, Renderer> Widget<Message, Renderer> for Checkbox<Message, Renderer> where - Renderer: self::Renderer + text::Renderer + row::Renderer, + Renderer: self::Renderer + text::Renderer, { fn width(&self) -> Length { self.width @@ -187,36 +186,29 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - let bounds = layout.bounds(); - let mut children = layout.children(); - - let checkbox_layout = children.next().unwrap(); - let label_layout = children.next().unwrap(); - let checkbox_bounds = checkbox_layout.bounds(); - - let label = text::Renderer::draw( - renderer, - defaults, - label_layout.bounds(), - &self.label, - self.text_size.unwrap_or(renderer.default_size()), - self.font, - self.text_color, - alignment::Horizontal::Left, - alignment::Vertical::Center, - ); - - let is_mouse_over = bounds.contains(cursor_position); - - self::Renderer::draw( - renderer, - checkbox_bounds, - self.is_checked, - is_mouse_over, - label, - &self.style, - ) + ) { + // let bounds = layout.bounds(); + // let mut children = layout.children(); + + // let checkbox_layout = children.next().unwrap(); + // let label_layout = children.next().unwrap(); + // let checkbox_bounds = checkbox_layout.bounds(); + + // let label = text::Renderer::draw( + // renderer, + // defaults, + // label_layout.bounds(), + // &self.label, + // self.text_size.unwrap_or(renderer.default_size()), + // self.font, + // self.text_color, + // alignment::Horizontal::Left, + // alignment::Vertical::Center, + // ); + + // let is_mouse_over = bounds.contains(cursor_position); + + // TODO } fn hash_layout(&self, state: &mut Hasher) { @@ -242,28 +234,12 @@ pub trait Renderer: crate::Renderer { /// The default spacing of a [`Checkbox`]. const DEFAULT_SPACING: u16; - - /// Draws a [`Checkbox`]. - /// - /// It receives: - /// * the bounds of the [`Checkbox`] - /// * whether the [`Checkbox`] is selected or not - /// * whether the mouse is over the [`Checkbox`] or not - /// * the drawn label of the [`Checkbox`] - fn draw( - &mut self, - bounds: Rectangle, - is_checked: bool, - is_mouse_over: bool, - label: Self::Output, - style: &Self::Style, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Checkbox<Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + self::Renderer + text::Renderer + row::Renderer, + Renderer: 'a + self::Renderer + text::Renderer, Message: 'a, { fn from( diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs index 30cf0781..61b2361f 100644 --- a/native/src/widget/column.rs +++ b/native/src/widget/column.rs @@ -105,7 +105,7 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> { impl<'a, Message, Renderer> Widget<Message, Renderer> for Column<'a, Message, Renderer> where - Renderer: self::Renderer, + Renderer: crate::Renderer, { fn width(&self) -> Length { self.width @@ -169,14 +169,8 @@ where layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw( - defaults, - &self.children, - layout, - cursor_position, - viewport, - ) + ) { + // TODO } fn hash_layout(&self, state: &mut Hasher) { @@ -208,33 +202,10 @@ where } } -/// The renderer of a [`Column`]. -/// -/// Your [renderer] will need to implement this trait before being -/// able to use a [`Column`] in your user interface. -/// -/// [renderer]: crate::renderer -pub trait Renderer: crate::Renderer + Sized { - /// Draws a [`Column`]. - /// - /// It receives: - /// - the children of the [`Column`] - /// - the [`Layout`] of the [`Column`] and its children - /// - the cursor position - fn draw<Message>( - &mut self, - defaults: &Self::Defaults, - content: &[Element<'_, Message, Self>], - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output; -} - impl<'a, Message, Renderer> From<Column<'a, Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + self::Renderer, + Renderer: 'a + crate::Renderer, Message: 'a, { fn from( diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs index 0e86ab62..f43de2a5 100644 --- a/native/src/widget/container.rs +++ b/native/src/widget/container.rs @@ -179,16 +179,8 @@ where layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw( - defaults, - layout.bounds(), - cursor_position, - viewport, - &self.style, - &self.content, - layout.children().next().unwrap(), - ) + ) { + // TODO } fn hash_layout(&self, state: &mut Hasher) { @@ -221,18 +213,6 @@ where pub trait Renderer: crate::Renderer { /// The style supported by this renderer. type Style: Default; - - /// Draws a [`Container`]. - fn draw<Message>( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - cursor_position: Point, - viewport: &Rectangle, - style: &Self::Style, - content: &Element<'_, Message, Self>, - content_layout: Layout<'_>, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Container<'a, Message, Renderer>> diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs index 4d8e0a3f..1607a596 100644 --- a/native/src/widget/image.rs +++ b/native/src/widget/image.rs @@ -96,8 +96,8 @@ where layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw(self.handle.clone(), layout) + ) { + // TODO } fn hash_layout(&self, state: &mut Hasher) { @@ -225,9 +225,6 @@ impl std::fmt::Debug for Data { pub trait Renderer: crate::Renderer { /// Returns the dimensions of an [`Image`] located on the given path. fn dimensions(&self, handle: &Handle) -> (u32, u32); - - /// Draws an [`Image`]. - fn draw(&mut self, handle: Handle, layout: Layout<'_>) -> Self::Output; } impl<'a, Message, Renderer> From<Image> for Element<'a, Message, Renderer> diff --git a/native/src/widget/image/viewer.rs b/native/src/widget/image/viewer.rs index 405daf00..d483ed61 100644 --- a/native/src/widget/image/viewer.rs +++ b/native/src/widget/image/viewer.rs @@ -88,7 +88,7 @@ impl<'a> Viewer<'a> { /// will be respected. fn image_size<Renderer>(&self, renderer: &Renderer, bounds: Size) -> Size where - Renderer: self::Renderer + image::Renderer, + Renderer: image::Renderer, { let (width, height) = renderer.dimensions(&self.handle); @@ -115,7 +115,7 @@ impl<'a> Viewer<'a> { impl<'a, Message, Renderer> Widget<Message, Renderer> for Viewer<'a> where - Renderer: self::Renderer + image::Renderer, + Renderer: image::Renderer, { fn width(&self) -> Length { self.width @@ -287,7 +287,7 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { + ) { let bounds = layout.bounds(); let image_size = self.image_size(renderer, bounds.size()); @@ -302,16 +302,6 @@ where }; let is_mouse_over = bounds.contains(cursor_position); - - self::Renderer::draw( - renderer, - &self.state, - bounds, - image_size, - translation, - self.handle.clone(), - is_mouse_over, - ) } fn hash_layout(&self, state: &mut Hasher) { @@ -373,38 +363,9 @@ impl State { } } -/// The renderer of an [`Viewer`]. -/// -/// Your [renderer] will need to implement this trait before being -/// able to use a [`Viewer`] in your user interface. -/// -/// [renderer]: crate::renderer -pub trait Renderer: crate::Renderer + Sized { - /// Draws the [`Viewer`]. - /// - /// It receives: - /// - the [`State`] of the [`Viewer`] - /// - the bounds of the [`Viewer`] widget - /// - the [`Size`] of the scaled [`Viewer`] image - /// - the translation of the clipped image - /// - the [`Handle`] to the underlying image - /// - whether the mouse is over the [`Viewer`] or not - /// - /// [`Handle`]: image::Handle - fn draw( - &mut self, - state: &State, - bounds: Rectangle, - image_size: Size, - translation: Vector, - handle: image::Handle, - is_mouse_over: bool, - ) -> Self::Output; -} - impl<'a, Message, Renderer> From<Viewer<'a>> for Element<'a, Message, Renderer> where - Renderer: 'a + self::Renderer + image::Renderer, + Renderer: 'a + image::Renderer, Message: 'a, { fn from(viewer: Viewer<'a>) -> Element<'a, Message, Renderer> { diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index 26a72409..b4a8cdb1 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -32,7 +32,6 @@ use crate::event::{self, Event}; use crate::layout; use crate::mouse; use crate::overlay; -use crate::row; use crate::touch; use crate::{ Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector, @@ -480,66 +479,56 @@ where layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output { - let picked_split = self - .state - .picked_split() - .and_then(|(split, axis)| { - let bounds = layout.bounds(); - - let splits = self - .state - .split_regions(f32::from(self.spacing), bounds.size()); - - let (_axis, region, ratio) = splits.get(&split)?; - - let region = axis.split_line_bounds( - *region, - *ratio, - f32::from(self.spacing), - ); - - Some((axis, region + Vector::new(bounds.x, bounds.y), true)) - }) - .or_else(|| match self.on_resize { - Some((leeway, _)) => { - let bounds = layout.bounds(); - - let relative_cursor = Point::new( - cursor_position.x - bounds.x, - cursor_position.y - bounds.y, - ); - - let splits = self - .state - .split_regions(f32::from(self.spacing), bounds.size()); - - let (_split, axis, region) = hovered_split( - splits.iter(), - f32::from(self.spacing + leeway), - relative_cursor, - )?; - - Some(( - axis, - region + Vector::new(bounds.x, bounds.y), - false, - )) - } - None => None, - }); - - self::Renderer::draw( - renderer, - defaults, - &self.elements, - self.state.picked_pane(), - picked_split, - layout, - &self.style, - cursor_position, - viewport, - ) + ) { + // let picked_split = self + // .state + // .picked_split() + // .and_then(|(split, axis)| { + // let bounds = layout.bounds(); + + // let splits = self + // .state + // .split_regions(f32::from(self.spacing), bounds.size()); + + // let (_axis, region, ratio) = splits.get(&split)?; + + // let region = axis.split_line_bounds( + // *region, + // *ratio, + // f32::from(self.spacing), + // ); + + // Some((axis, region + Vector::new(bounds.x, bounds.y), true)) + // }) + // .or_else(|| match self.on_resize { + // Some((leeway, _)) => { + // let bounds = layout.bounds(); + + // let relative_cursor = Point::new( + // cursor_position.x - bounds.x, + // cursor_position.y - bounds.y, + // ); + + // let splits = self + // .state + // .split_regions(f32::from(self.spacing), bounds.size()); + + // let (_split, axis, region) = hovered_split( + // splits.iter(), + // f32::from(self.spacing + leeway), + // relative_cursor, + // )?; + + // Some(( + // axis, + // region + Vector::new(bounds.x, bounds.y), + // false, + // )) + // } + // None => None, + // }); + + // TODO } fn hash_layout(&self, state: &mut Hasher) { @@ -578,69 +567,12 @@ where pub trait Renderer: crate::Renderer + container::Renderer + Sized { /// The style supported by this renderer. type Style: Default; - - /// Draws a [`PaneGrid`]. - /// - /// It receives: - /// - the elements of the [`PaneGrid`] - /// - the [`Pane`] that is currently being dragged - /// - the [`Axis`] that is currently being resized - /// - the [`Layout`] of the [`PaneGrid`] and its elements - /// - the cursor position - fn draw<Message>( - &mut self, - defaults: &Self::Defaults, - content: &[(Pane, Content<'_, Message, Self>)], - dragging: Option<(Pane, Point)>, - resizing: Option<(Axis, Rectangle, bool)>, - layout: Layout<'_>, - style: &<Self as self::Renderer>::Style, - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output; - - /// Draws a [`Pane`]. - /// - /// It receives: - /// - the [`TitleBar`] of the [`Pane`], if any - /// - the [`Content`] of the [`Pane`] - /// - the [`Layout`] of the [`Pane`] and its elements - /// - the cursor position - fn draw_pane<Message>( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - style: &<Self as container::Renderer>::Style, - title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>, - body: (&Element<'_, Message, Self>, Layout<'_>), - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output; - - /// Draws a [`TitleBar`]. - /// - /// It receives: - /// - the bounds, style of the [`TitleBar`] - /// - the style of the [`TitleBar`] - /// - the content of the [`TitleBar`] with its layout - /// - the controls of the [`TitleBar`] with their [`Layout`], if any - /// - the cursor position - fn draw_title_bar<Message>( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - style: &<Self as container::Renderer>::Style, - content: (&Element<'_, Message, Self>, Layout<'_>), - controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output; } impl<'a, Message, Renderer> From<PaneGrid<'a, Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + self::Renderer + row::Renderer, + Renderer: 'a + self::Renderer, Message: 'a, { fn from( diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index bac9fdd4..e94955f7 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -61,32 +61,33 @@ where layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output { - if let Some(title_bar) = &self.title_bar { - let mut children = layout.children(); - let title_bar_layout = children.next().unwrap(); - let body_layout = children.next().unwrap(); - - renderer.draw_pane( - defaults, - layout.bounds(), - &self.style, - Some((title_bar, title_bar_layout)), - (&self.body, body_layout), - cursor_position, - viewport, - ) - } else { - renderer.draw_pane( - defaults, - layout.bounds(), - &self.style, - None, - (&self.body, layout), - cursor_position, - viewport, - ) - } + ) { + // TODO + // if let Some(title_bar) = &self.title_bar { + // let mut children = layout.children(); + // let title_bar_layout = children.next().unwrap(); + // let body_layout = children.next().unwrap(); + + // renderer.draw_pane( + // defaults, + // layout.bounds(), + // &self.style, + // Some((title_bar, title_bar_layout)), + // (&self.body, body_layout), + // cursor_position, + // viewport, + // ) + // } else { + // renderer.draw_pane( + // defaults, + // layout.bounds(), + // &self.style, + // None, + // (&self.body, layout), + // cursor_position, + // viewport, + // ) + // } } /// Returns whether the [`Content`] with the given [`Layout`] can be picked diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index 070010f8..9b0b7c78 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -90,34 +90,34 @@ where cursor_position: Point, viewport: &Rectangle, show_controls: bool, - ) -> Renderer::Output { - let mut children = layout.children(); - let padded = children.next().unwrap(); - - let mut children = padded.children(); - let title_layout = children.next().unwrap(); - - let controls = if let Some(controls) = &self.controls { - let controls_layout = children.next().unwrap(); - - if show_controls || self.always_show_controls { - Some((controls, controls_layout)) - } else { - None - } - } else { - None - }; - - renderer.draw_title_bar( - defaults, - layout.bounds(), - &self.style, - (&self.content, title_layout), - controls, - cursor_position, - viewport, - ) + ) { + // let mut children = layout.children(); + // let padded = children.next().unwrap(); + + // let mut children = padded.children(); + // let title_layout = children.next().unwrap(); + + // let controls = if let Some(controls) = &self.controls { + // let controls_layout = children.next().unwrap(); + + // if show_controls || self.always_show_controls { + // Some((controls, controls_layout)) + // } else { + // None + // } + // } else { + // None + // }; + + // renderer.draw_title_bar( + // defaults, + // layout.bounds(), + // &self.style, + // (&self.content, title_layout), + // controls, + // cursor_position, + // viewport, + // ) } /// Returns whether the mouse cursor is over the pick area of the diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index d7792000..7154a572 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -327,18 +327,8 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - self::Renderer::draw( - renderer, - layout.bounds(), - cursor_position, - self.selected.as_ref().map(ToString::to_string), - self.placeholder.as_ref().map(String::as_str), - self.padding, - self.text_size.unwrap_or(renderer.default_size()), - self.font, - &self.style, - ) + ) { + // TODO } fn overlay( @@ -387,19 +377,6 @@ pub trait Renderer: text::Renderer + menu::Renderer { fn menu_style( style: &<Self as Renderer>::Style, ) -> <Self as menu::Renderer>::Style; - - /// Draws a [`PickList`]. - fn draw( - &mut self, - bounds: Rectangle, - cursor_position: Point, - selected: Option<String>, - placeholder: Option<&str>, - padding: Padding, - text_size: u16, - font: Self::Font, - style: &<Self as Renderer>::Style, - ) -> Self::Output; } impl<'a, T: 'a, Message, Renderer> Into<Element<'a, Message, Renderer>> diff --git a/native/src/widget/progress_bar.rs b/native/src/widget/progress_bar.rs index d294f198..d8cf5376 100644 --- a/native/src/widget/progress_bar.rs +++ b/native/src/widget/progress_bar.rs @@ -97,13 +97,8 @@ where layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw( - layout.bounds(), - self.range.clone(), - self.value, - &self.style, - ) + ) { + // TODO } fn hash_layout(&self, state: &mut Hasher) { @@ -127,22 +122,6 @@ pub trait Renderer: crate::Renderer { /// The default height of a [`ProgressBar`]. const DEFAULT_HEIGHT: u16; - - /// Draws a [`ProgressBar`]. - /// - /// It receives: - /// * the bounds of the [`ProgressBar`] - /// * the range of values of the [`ProgressBar`] - /// * the current value of the [`ProgressBar`] - /// * maybe a specific background of the [`ProgressBar`] - /// * maybe a specific active color of the [`ProgressBar`] - fn draw( - &self, - bounds: Rectangle, - range: RangeInclusive<f32>, - value: f32, - style: &Self::Style, - ) -> Self::Output; } impl<'a, Message, Renderer> From<ProgressBar<Renderer>> diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs index 513b2fce..c6955079 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -5,7 +5,6 @@ use crate::alignment::{self, Alignment}; use crate::event::{self, Event}; use crate::layout; use crate::mouse; -use crate::row; use crate::text; use crate::touch; use crate::{ @@ -136,7 +135,7 @@ where impl<Message, Renderer> Widget<Message, Renderer> for Radio<Message, Renderer> where Message: Clone, - Renderer: self::Renderer + text::Renderer + row::Renderer, + Renderer: self::Renderer + text::Renderer, { fn width(&self) -> Length { self.width @@ -199,36 +198,37 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - let bounds = layout.bounds(); - let mut children = layout.children(); + ) { + // TODO + // let bounds = layout.bounds(); + // let mut children = layout.children(); - let radio_layout = children.next().unwrap(); - let label_layout = children.next().unwrap(); - let radio_bounds = radio_layout.bounds(); + // let radio_layout = children.next().unwrap(); + // let label_layout = children.next().unwrap(); + // let radio_bounds = radio_layout.bounds(); - let label = text::Renderer::draw( - renderer, - defaults, - label_layout.bounds(), - &self.label, - self.text_size.unwrap_or(renderer.default_size()), - self.font, - self.text_color, - alignment::Horizontal::Left, - alignment::Vertical::Center, - ); + // let label = text::Renderer::draw( + // renderer, + // defaults, + // label_layout.bounds(), + // &self.label, + // self.text_size.unwrap_or(renderer.default_size()), + // self.font, + // self.text_color, + // alignment::Horizontal::Left, + // alignment::Vertical::Center, + // ); - let is_mouse_over = bounds.contains(cursor_position); + // let is_mouse_over = bounds.contains(cursor_position); - self::Renderer::draw( - renderer, - radio_bounds, - self.is_selected, - is_mouse_over, - label, - &self.style, - ) + // self::Renderer::draw( + // renderer, + // radio_bounds, + // self.is_selected, + // is_mouse_over, + // label, + // &self.style, + // ) } fn hash_layout(&self, state: &mut Hasher) { @@ -254,29 +254,13 @@ pub trait Renderer: crate::Renderer { /// The default spacing of a [`Radio`] button. const DEFAULT_SPACING: u16; - - /// Draws a [`Radio`] button. - /// - /// It receives: - /// * the bounds of the [`Radio`] - /// * whether the [`Radio`] is selected or not - /// * whether the mouse is over the [`Radio`] or not - /// * the drawn label of the [`Radio`] - fn draw( - &mut self, - bounds: Rectangle, - is_selected: bool, - is_mouse_over: bool, - label: Self::Output, - style: &Self::Style, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Radio<Message, Renderer>> for Element<'a, Message, Renderer> where Message: 'a + Clone, - Renderer: 'a + self::Renderer + row::Renderer + text::Renderer, + Renderer: 'a + self::Renderer + text::Renderer, { fn from(radio: Radio<Message, Renderer>) -> Element<'a, Message, Renderer> { Element::new(radio) diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs index 1923f213..04a1f864 100644 --- a/native/src/widget/row.rs +++ b/native/src/widget/row.rs @@ -104,7 +104,7 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> { impl<'a, Message, Renderer> Widget<Message, Renderer> for Row<'a, Message, Renderer> where - Renderer: self::Renderer, + Renderer: crate::Renderer, { fn width(&self) -> Length { self.width @@ -168,14 +168,15 @@ where layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw( - defaults, - &self.children, - layout, - cursor_position, - viewport, - ) + ) { + // TODO + // renderer.draw( + // defaults, + // &self.children, + // layout, + // cursor_position, + // viewport, + // ) } fn hash_layout(&self, state: &mut Hasher) { @@ -207,33 +208,10 @@ where } } -/// The renderer of a [`Row`]. -/// -/// Your [renderer] will need to implement this trait before being -/// able to use a [`Row`] in your user interface. -/// -/// [renderer]: crate::renderer -pub trait Renderer: crate::Renderer + Sized { - /// Draws a [`Row`]. - /// - /// It receives: - /// - the children of the [`Row`] - /// - the [`Layout`] of the [`Row`] and its children - /// - the cursor position - fn draw<Message>( - &mut self, - defaults: &Self::Defaults, - children: &[Element<'_, Message, Self>], - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Self::Output; -} - impl<'a, Message, Renderer> From<Row<'a, Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + self::Renderer, + Renderer: 'a + crate::Renderer, Message: 'a, { fn from(row: Row<'a, Message, Renderer>) -> Element<'a, Message, Renderer> { diff --git a/native/src/widget/rule.rs b/native/src/widget/rule.rs index 18c88658..1fab77bc 100644 --- a/native/src/widget/rule.rs +++ b/native/src/widget/rule.rs @@ -72,8 +72,9 @@ where layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw(layout.bounds(), &self.style, self.is_horizontal) + ) { + // TODO + // renderer.draw(layout.bounds(), &self.style, self.is_horizontal) } fn hash_layout(&self, state: &mut Hasher) { @@ -89,19 +90,6 @@ where pub trait Renderer: crate::Renderer { /// The style supported by this renderer. type Style: Default; - - /// Draws a [`Rule`]. - /// - /// It receives: - /// * the bounds of the [`Rule`] - /// * the style of the [`Rule`] - /// * whether the [`Rule`] is horizontal (true) or vertical (false) - fn draw( - &mut self, - bounds: Rectangle, - style: &Self::Style, - is_horizontal: bool, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Rule<Renderer>> diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index a8e467d3..1c897dc5 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -1,5 +1,4 @@ //! Navigate an endless amount of content with a scrollbar. -use crate::column; use crate::event::{self, Event}; use crate::layout; use crate::mouse; @@ -381,57 +380,45 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - let bounds = layout.bounds(); - let content_layout = layout.children().next().unwrap(); - let content_bounds = content_layout.bounds(); - let offset = self.state.offset(bounds, content_bounds); - let scrollbar = renderer.scrollbar( - bounds, - content_bounds, - offset, - self.scrollbar_width, - self.scrollbar_margin, - self.scroller_width, - ); - - let is_mouse_over = bounds.contains(cursor_position); - let is_mouse_over_scrollbar = scrollbar - .as_ref() - .map(|scrollbar| scrollbar.is_mouse_over(cursor_position)) - .unwrap_or(false); - - let content = { - let cursor_position = if is_mouse_over && !is_mouse_over_scrollbar { - Point::new(cursor_position.x, cursor_position.y + offset as f32) - } else { - Point::new(cursor_position.x, -1.0) - }; - - self.content.draw( - renderer, - defaults, - content_layout, - cursor_position, - &Rectangle { - y: bounds.y + offset as f32, - ..bounds - }, - ) - }; - - self::Renderer::draw( - renderer, - &self.state, - bounds, - content_layout.bounds(), - is_mouse_over, - is_mouse_over_scrollbar, - scrollbar, - offset, - &self.style, - content, - ) + ) { + // TODO + // let bounds = layout.bounds(); + // let content_layout = layout.children().next().unwrap(); + // let content_bounds = content_layout.bounds(); + // let offset = self.state.offset(bounds, content_bounds); + // let scrollbar = renderer.scrollbar( + // bounds, + // content_bounds, + // offset, + // self.scrollbar_width, + // self.scrollbar_margin, + // self.scroller_width, + // ); + + // let is_mouse_over = bounds.contains(cursor_position); + // let is_mouse_over_scrollbar = scrollbar + // .as_ref() + // .map(|scrollbar| scrollbar.is_mouse_over(cursor_position)) + // .unwrap_or(false); + + // let content = { + // let cursor_position = if is_mouse_over && !is_mouse_over_scrollbar { + // Point::new(cursor_position.x, cursor_position.y + offset as f32) + // } else { + // Point::new(cursor_position.x, -1.0) + // }; + + // self.content.draw( + // renderer, + // defaults, + // content_layout, + // cursor_position, + // &Rectangle { + // y: bounds.y + offset as f32, + // ..bounds + // }, + // ) + // }; } fn hash_layout(&self, state: &mut Hasher) { @@ -635,7 +622,7 @@ pub struct Scroller { /// able to use a [`Scrollable`] in your user interface. /// /// [renderer]: crate::renderer -pub trait Renderer: column::Renderer + Sized { +pub trait Renderer: crate::Renderer + Sized { /// The style supported by this renderer. type Style: Default; @@ -650,30 +637,6 @@ pub trait Renderer: column::Renderer + Sized { scrollbar_margin: u16, scroller_width: u16, ) -> Option<Scrollbar>; - - /// Draws the [`Scrollable`]. - /// - /// It receives: - /// - the [`State`] of the [`Scrollable`] - /// - the bounds of the [`Scrollable`] widget - /// - the bounds of the [`Scrollable`] content - /// - whether the mouse is over the [`Scrollable`] or not - /// - whether the mouse is over the [`Scrollbar`] or not - /// - a optional [`Scrollbar`] to be rendered - /// - the scrolling offset - /// - the drawn content - fn draw( - &mut self, - scrollable: &State, - bounds: Rectangle, - content_bounds: Rectangle, - is_mouse_over: bool, - is_mouse_over_scrollbar: bool, - scrollbar: Option<Scrollbar>, - offset: u32, - style: &Self::Style, - content: Self::Output, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Scrollable<'a, Message, Renderer>> diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index 2a74d5a3..bcf811fe 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -250,18 +250,19 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - let start = *self.range.start(); - let end = *self.range.end(); - - renderer.draw( - layout.bounds(), - cursor_position, - start.into() as f32..=end.into() as f32, - self.value.into() as f32, - self.state.is_dragging, - &self.style, - ) + ) { + // TODO + // let start = *self.range.start(); + // let end = *self.range.end(); + + // renderer.draw( + // layout.bounds(), + // cursor_position, + // start.into() as f32..=end.into() as f32, + // self.value.into() as f32, + // self.state.is_dragging, + // &self.style, + // ) } fn hash_layout(&self, state: &mut Hasher) { @@ -284,24 +285,6 @@ pub trait Renderer: crate::Renderer { /// The default height of a [`Slider`]. const DEFAULT_HEIGHT: u16; - - /// Draws a [`Slider`]. - /// - /// It receives: - /// * the current cursor position - /// * the bounds of the [`Slider`] - /// * the local state of the [`Slider`] - /// * the range of values of the [`Slider`] - /// * the current value of the [`Slider`] - fn draw( - &mut self, - bounds: Rectangle, - cursor_position: Point, - range: RangeInclusive<f32>, - value: f32, - is_dragging: bool, - style: &Self::Style, - ) -> Self::Output; } impl<'a, T, Message, Renderer> From<Slider<'a, T, Message, Renderer>> diff --git a/native/src/widget/space.rs b/native/src/widget/space.rs index 6b34ece8..9a70dab1 100644 --- a/native/src/widget/space.rs +++ b/native/src/widget/space.rs @@ -39,7 +39,7 @@ impl Space { impl<Message, Renderer> Widget<Message, Renderer> for Space where - Renderer: self::Renderer, + Renderer: crate::Renderer, { fn width(&self) -> Length { self.width @@ -66,8 +66,7 @@ where layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw(layout.bounds()) + ) { } fn hash_layout(&self, state: &mut Hasher) { @@ -78,17 +77,9 @@ where } } -/// The renderer of an amount of [`Space`]. -pub trait Renderer: crate::Renderer { - /// Draws an amount of empty [`Space`]. - /// - /// You should most likely return an empty primitive here. - fn draw(&mut self, bounds: Rectangle) -> Self::Output; -} - impl<'a, Message, Renderer> From<Space> for Element<'a, Message, Renderer> where - Renderer: self::Renderer, + Renderer: crate::Renderer, Message: 'a, { fn from(space: Space) -> Element<'a, Message, Renderer> { diff --git a/native/src/widget/svg.rs b/native/src/widget/svg.rs index 9cd61918..737dd8d4 100644 --- a/native/src/widget/svg.rs +++ b/native/src/widget/svg.rs @@ -94,8 +94,9 @@ where layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw(self.handle.clone(), layout) + ) { + // TODO + // renderer.draw(self.handle.clone(), layout) } fn hash_layout(&self, state: &mut Hasher) { @@ -187,9 +188,6 @@ impl std::fmt::Debug for Data { pub trait Renderer: crate::Renderer { /// Returns the default dimensions of an [`Svg`] for the given [`Handle`]. fn dimensions(&self, handle: &Handle) -> (u32, u32); - - /// Draws an [`Svg`]. - fn draw(&mut self, handle: Handle, layout: Layout<'_>) -> Self::Output; } impl<'a, Message, Renderer> From<Svg> for Element<'a, Message, Renderer> diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs index 168d49c2..9915a6e9 100644 --- a/native/src/widget/text.rs +++ b/native/src/widget/text.rs @@ -133,22 +133,13 @@ where fn draw( &self, - renderer: &mut Renderer, - defaults: &Renderer::Defaults, - layout: Layout<'_>, + _renderer: &mut Renderer, + _defaults: &Renderer::Defaults, + _layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw( - defaults, - layout.bounds(), - &self.content, - self.size.unwrap_or(renderer.default_size()), - self.font, - self.color, - self.horizontal_alignment, - self.vertical_alignment, - ) + ) { + // TODO } fn hash_layout(&self, state: &mut Hasher) { @@ -201,27 +192,6 @@ pub trait Renderer: crate::Renderer { point: Point, nearest_only: bool, ) -> Option<Hit>; - - /// Draws a [`Text`] fragment. - /// - /// It receives: - /// * the bounds of the [`Text`] - /// * the contents of the [`Text`] - /// * the size of the [`Text`] - /// * the color of the [`Text`] - /// * the [`HorizontalAlignment`] of the [`Text`] - /// * the [`VerticalAlignment`] of the [`Text`] - fn draw( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - content: &str, - size: u16, - font: Self::Font, - color: Option<Color>, - horizontal_alignment: alignment::Horizontal, - vertical_alignment: alignment::Vertical, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Text<Renderer>> diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 84d171be..fe95eb95 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -170,38 +170,39 @@ where layout: Layout<'_>, cursor_position: Point, value: Option<&Value>, - ) -> Renderer::Output { - let value = value.unwrap_or(&self.value); - let bounds = layout.bounds(); - let text_bounds = layout.children().next().unwrap().bounds(); - - if self.is_secure { - self::Renderer::draw( - renderer, - bounds, - text_bounds, - cursor_position, - self.font, - self.size.unwrap_or(renderer.default_size()), - &self.placeholder, - &value.secure(), - &self.state, - &self.style, - ) - } else { - self::Renderer::draw( - renderer, - bounds, - text_bounds, - cursor_position, - self.font, - self.size.unwrap_or(renderer.default_size()), - &self.placeholder, - value, - &self.state, - &self.style, - ) - } + ) { + // TODO + // let value = value.unwrap_or(&self.value); + // let bounds = layout.bounds(); + // let text_bounds = layout.children().next().unwrap().bounds(); + + // if self.is_secure { + // self::Renderer::draw( + // renderer, + // bounds, + // text_bounds, + // cursor_position, + // self.font, + // self.size.unwrap_or(renderer.default_size()), + // &self.placeholder, + // &value.secure(), + // &self.state, + // &self.style, + // ) + // } else { + // self::Renderer::draw( + // renderer, + // bounds, + // text_bounds, + // cursor_position, + // self.font, + // self.size.unwrap_or(renderer.default_size()), + // &self.placeholder, + // value, + // &self.state, + // &self.style, + // ) + // } } } @@ -630,7 +631,7 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { + ) { self.draw(renderer, layout, cursor_position, None) } @@ -673,28 +674,6 @@ pub trait Renderer: text::Renderer + Sized { state: &State, ) -> f32; - /// Draws a [`TextInput`]. - /// - /// It receives: - /// - the bounds of the [`TextInput`] - /// - the bounds of the text (i.e. the current value) - /// - the cursor position - /// - the placeholder to show when the value is empty - /// - the current [`Value`] - /// - the current [`State`] - fn draw( - &mut self, - bounds: Rectangle, - text_bounds: Rectangle, - cursor_position: Point, - font: Self::Font, - size: u16, - placeholder: &str, - value: &Value, - state: &State, - style: &Self::Style, - ) -> Self::Output; - /// Computes the position of the text cursor at the given X coordinate of /// a [`TextInput`]. fn find_cursor_position( diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index c624be4c..4a1f1f5d 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -5,7 +5,6 @@ use crate::alignment; use crate::event; use crate::layout; use crate::mouse; -use crate::row; use crate::text; use crate::{ Alignment, Clipboard, Element, Event, Hasher, Layout, Length, Point, @@ -119,7 +118,7 @@ impl<Message, Renderer: self::Renderer + text::Renderer> impl<Message, Renderer> Widget<Message, Renderer> for Toggler<Message, Renderer> where - Renderer: self::Renderer + text::Renderer + row::Renderer, + Renderer: self::Renderer + text::Renderer, { fn width(&self) -> Length { self.width @@ -190,43 +189,35 @@ where layout: Layout<'_>, cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - let bounds = layout.bounds(); - let mut children = layout.children(); - - let label = match &self.label { - Some(label) => { - let label_layout = children.next().unwrap(); - - Some(text::Renderer::draw( - renderer, - defaults, - label_layout.bounds(), - &label, - self.text_size.unwrap_or(renderer.default_size()), - self.font, - None, - self.text_alignment, - alignment::Vertical::Center, - )) - } - - None => None, - }; - - let toggler_layout = children.next().unwrap(); - let toggler_bounds = toggler_layout.bounds(); - - let is_mouse_over = bounds.contains(cursor_position); - - self::Renderer::draw( - renderer, - toggler_bounds, - self.is_active, - is_mouse_over, - label, - &self.style, - ) + ) { + // TODO + // let bounds = layout.bounds(); + // let mut children = layout.children(); + + // let label = match &self.label { + // Some(label) => { + // let label_layout = children.next().unwrap(); + + // Some(text::Renderer::draw( + // renderer, + // defaults, + // label_layout.bounds(), + // &label, + // self.text_size.unwrap_or(renderer.default_size()), + // self.font, + // None, + // self.text_alignment, + // alignment::Vertical::Center, + // )) + // } + + // None => None, + // }; + + // let toggler_layout = children.next().unwrap(); + // let toggler_bounds = toggler_layout.bounds(); + + // let is_mouse_over = bounds.contains(cursor_position); } fn hash_layout(&self, state: &mut Hasher) { @@ -249,29 +240,12 @@ pub trait Renderer: crate::Renderer { /// The default size of a [`Toggler`]. const DEFAULT_SIZE: u16; - - /// Draws a [`Toggler`]. - /// - /// It receives: - /// * the bounds of the [`Toggler`] - /// * whether the [`Toggler`] is activated or not - /// * whether the mouse is over the [`Toggler`] or not - /// * the drawn label of the [`Toggler`] - /// * the style of the [`Toggler`] - fn draw( - &mut self, - bounds: Rectangle, - is_active: bool, - is_mouse_over: bool, - label: Option<Self::Output>, - style: &Self::Style, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Toggler<Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + self::Renderer + text::Renderer + row::Renderer, + Renderer: 'a + self::Renderer + text::Renderer, Message: 'a, { fn from( diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs index 276afd41..83d04675 100644 --- a/native/src/widget/tooltip.rs +++ b/native/src/widget/tooltip.rs @@ -136,25 +136,13 @@ where fn draw( &self, - renderer: &mut Renderer, - defaults: &Renderer::Defaults, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) -> Renderer::Output { - self::Renderer::draw( - renderer, - defaults, - cursor_position, - layout, - viewport, - &self.content, - &self.tooltip, - self.position, - &self.style, - self.gap, - self.padding, - ) + _renderer: &mut Renderer, + _defaults: &Renderer::Defaults, + _layout: Layout<'_>, + _cursor_position: Point, + _viewport: &Rectangle, + ) { + // TODO } fn hash_layout(&self, state: &mut Hasher) { @@ -177,23 +165,6 @@ pub trait Renderer: { /// The default padding of a [`Tooltip`] drawn by this renderer. const DEFAULT_PADDING: u16; - - /// Draws a [`Tooltip`]. - /// - /// [`Tooltip`]: struct.Tooltip.html - fn draw<Message>( - &mut self, - defaults: &Self::Defaults, - cursor_position: Point, - content_layout: Layout<'_>, - viewport: &Rectangle, - content: &Element<'_, Message, Self>, - tooltip: &Text<Self>, - position: Position, - style: &<Self as container::Renderer>::Style, - gap: u16, - padding: u16, - ) -> Self::Output; } impl<'a, Message, Renderer> From<Tooltip<'a, Message, Renderer>> diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 73fa5c5f..56de553f 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -8,7 +8,6 @@ use iced_graphics::font; use iced_graphics::layer::Layer; use iced_graphics::{Primitive, Viewport}; use iced_native::alignment; -use iced_native::mouse; use iced_native::{Font, Size}; #[cfg(any(feature = "image_rs", feature = "svg"))] @@ -28,6 +27,7 @@ pub struct Backend { image_pipeline: image::Pipeline, default_text_size: u16, + primitive: Primitive, } impl Backend { @@ -60,6 +60,7 @@ impl Backend { image_pipeline, default_text_size: settings.default_text_size, + primitive: Primitive::None, } } @@ -67,16 +68,16 @@ impl Backend { /// /// The text provided as overlay will be rendered on top of the primitives. /// This is useful for rendering debug information. - pub fn draw<T: AsRef<str>>( + pub fn present<T: AsRef<str>>( &mut self, device: &wgpu::Device, staging_belt: &mut wgpu::util::StagingBelt, encoder: &mut wgpu::CommandEncoder, frame: &wgpu::TextureView, + primitive: &Primitive, viewport: &Viewport, - (primitive, mouse_interaction): &(Primitive, mouse::Interaction), overlay_text: &[T], - ) -> mouse::Interaction { + ) { log::debug!("Drawing"); let target_size = viewport.physical_size(); @@ -102,8 +103,6 @@ impl Backend { #[cfg(any(feature = "image_rs", feature = "svg"))] self.image_pipeline.trim_cache(); - - *mouse_interaction } fn flush( diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index eca54b6f..f29a50f5 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -1,7 +1,7 @@ use crate::{Backend, Color, Error, Renderer, Settings, Viewport}; use futures::task::SpawnExt; -use iced_native::{futures, mouse}; +use iced_native::futures; use raw_window_handle::HasRawWindowHandle; /// A window graphics backend for iced powered by `wgpu`. @@ -132,15 +132,14 @@ impl iced_graphics::window::Compositor for Compositor { ); } - fn draw<T: AsRef<str>>( + fn present<T: AsRef<str>>( &mut self, renderer: &mut Self::Renderer, surface: &mut Self::Surface, viewport: &Viewport, background_color: Color, - output: &<Self::Renderer as iced_native::Renderer>::Output, overlay: &[T], - ) -> Result<mouse::Interaction, iced_graphics::window::SurfaceError> { + ) -> Result<(), iced_graphics::window::SurfaceError> { match surface.get_current_frame() { Ok(frame) => { let mut encoder = self.device.create_command_encoder( @@ -180,15 +179,17 @@ impl iced_graphics::window::Compositor for Compositor { depth_stencil_attachment: None, }); - let mouse_interaction = renderer.backend_mut().draw( - &mut self.device, - &mut self.staging_belt, - &mut encoder, - view, - viewport, - output, - overlay, - ); + renderer.present(|backend, primitive| { + backend.present( + &mut self.device, + &mut self.staging_belt, + &mut encoder, + view, + primitive, + viewport, + overlay, + ); + }); // Submit work self.staging_belt.finish(); @@ -202,7 +203,7 @@ impl iced_graphics::window::Compositor for Compositor { self.local_pool.run_until_stalled(); - Ok(mouse_interaction) + Ok(()) } Err(error) => match error { wgpu::SurfaceError::Timeout => { diff --git a/winit/src/application.rs b/winit/src/application.rs index ab9a70a0..70562627 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -5,7 +5,6 @@ pub use state::State; use crate::clipboard::{self, Clipboard}; use crate::conversion; -use crate::mouse; use crate::{ Color, Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings, Size, Subscription, @@ -253,9 +252,8 @@ async fn run_instance<A, E, C>( &mut debug, )); - let mut primitive = - user_interface.draw(&mut renderer, state.cursor_position()); - let mut mouse_interaction = mouse::Interaction::default(); + // TODO + // let mut mouse_interaction = mouse::Interaction::default(); let mut events = Vec::new(); let mut messages = Vec::new(); @@ -319,8 +317,7 @@ async fn run_instance<A, E, C>( } debug.draw_started(); - primitive = - user_interface.draw(&mut renderer, state.cursor_position()); + user_interface.draw(&mut renderer, state.cursor_position()); debug.draw_finished(); window.request_redraw(); @@ -359,8 +356,7 @@ async fn run_instance<A, E, C>( debug.layout_finished(); debug.draw_started(); - primitive = user_interface - .draw(&mut renderer, state.cursor_position()); + user_interface.draw(&mut renderer, state.cursor_position()); debug.draw_finished(); compositor.configure_surface( @@ -372,27 +368,16 @@ async fn run_instance<A, E, C>( viewport_version = current_viewport_version; } - match compositor.draw( + match compositor.present( &mut renderer, &mut surface, state.viewport(), state.background_color(), - &primitive, &debug.overlay(), ) { - Ok(new_mouse_interaction) => { + Ok(()) => { debug.render_finished(); - if new_mouse_interaction != mouse_interaction { - window.set_cursor_icon( - conversion::mouse_interaction( - new_mouse_interaction, - ), - ); - - mouse_interaction = new_mouse_interaction; - } - // TODO: Handle animations! // Maybe we can use `ControlFlow::WaitUntil` for this. } |