diff options
| author | 2021-11-07 15:15:33 +0700 | |
|---|---|---|
| committer | 2021-11-07 15:15:33 +0700 | |
| commit | eafad00af2a9bae9f3ed8124e2a6f6e59ee5d253 (patch) | |
| tree | 76413948c9c9723075189d51d4c2e02c0f8fdd23 /graphics | |
| parent | 61c747b53589d98f477fea95f85d2ea5349666d3 (diff) | |
| parent | 07b5097bc92ced376d09115d787ff1d2ebe00836 (diff) | |
| download | iced-eafad00af2a9bae9f3ed8124e2a6f6e59ee5d253.tar.gz iced-eafad00af2a9bae9f3ed8124e2a6f6e59ee5d253.tar.bz2 iced-eafad00af2a9bae9f3ed8124e2a6f6e59ee5d253.zip | |
Merge pull request #1110 from iced-rs/remove-renderer-traits
Reduce the surface of the `Renderer` APIs
Diffstat (limited to 'graphics')
30 files changed, 247 insertions, 2174 deletions
| diff --git a/graphics/src/defaults.rs b/graphics/src/defaults.rs deleted file mode 100644 index 11718a87..00000000 --- a/graphics/src/defaults.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Use default styling attributes to inherit styles. -use iced_native::Color; - -/// Some default styling attributes. -#[derive(Debug, Clone, Copy)] -pub struct Defaults { -    /// Text styling -    pub text: Text, -} - -impl Default for Defaults { -    fn default() -> Defaults { -        Defaults { -            text: Text::default(), -        } -    } -} - -/// Some default text styling attributes. -#[derive(Debug, Clone, Copy)] -pub struct Text { -    /// The default color of text -    pub color: Color, -} - -impl Default for Text { -    fn default() -> Text { -        Text { -            color: Color::BLACK, -        } -    } -} diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index 9653a2e4..7a32c850 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -74,7 +74,7 @@ impl<'a> Layer<'a> {      /// Distributes the given [`Primitive`] and generates a list of layers based      /// on its contents.      pub fn generate( -        primitive: &'a Primitive, +        primitives: &'a [Primitive],          viewport: &Viewport,      ) -> Vec<Self> {          let first_layer = @@ -82,12 +82,14 @@ impl<'a> Layer<'a> {          let mut layers = vec![first_layer]; -        Self::process_primitive( -            &mut layers, -            Vector::new(0.0, 0.0), -            primitive, -            0, -        ); +        for primitive in primitives { +            Self::process_primitive( +                &mut layers, +                Vector::new(0.0, 0.0), +                primitive, +                0, +            ); +        }          layers      } @@ -173,11 +175,7 @@ impl<'a> Layer<'a> {                      });                  }              } -            Primitive::Clip { -                bounds, -                offset, -                content, -            } => { +            Primitive::Clip { bounds, content } => {                  let layer = &mut layers[current_layer];                  let translated_bounds = *bounds + translation; @@ -190,8 +188,7 @@ impl<'a> Layer<'a> {                      Self::process_primitive(                          layers, -                        translation -                            - Vector::new(offset.x as f32, offset.y as f32), +                        translation,                          content,                          layers.len() - 1,                      ); diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index 54cdcb77..5b8defc5 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -13,15 +13,14 @@  mod antialiasing;  mod error;  mod primitive; -mod renderer;  mod transformation;  mod viewport;  pub mod backend; -pub mod defaults;  pub mod font;  pub mod layer;  pub mod overlay; +pub mod renderer;  pub mod triangle;  pub mod widget;  pub mod window; @@ -31,7 +30,6 @@ pub use widget::*;  pub use antialiasing::Antialiasing;  pub use backend::Backend; -pub use defaults::Defaults;  pub use error::Error;  pub use layer::Layer;  pub use primitive::Primitive; diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs index 53f47984..c5ff093d 100644 --- a/graphics/src/overlay/menu.rs +++ b/graphics/src/overlay/menu.rs @@ -1,116 +1,3 @@  //! Build and show dropdown menus. -use crate::alignment; -use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; - -use iced_native::{mouse, overlay, Color, Font, Padding, Point, Rectangle};  pub use iced_style::menu::Style; - -impl<B> overlay::menu::Renderer for Renderer<B> -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/primitive.rs b/graphics/src/primitive.rs index 32f8383d..5f7a344d 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -1,6 +1,6 @@ -use iced_native::{ -    image, svg, Background, Color, Font, Rectangle, Size, Vector, -}; +use iced_native::image; +use iced_native::svg; +use iced_native::{Background, Color, Font, Rectangle, Size, Vector};  use crate::alignment;  use crate::triangle; @@ -66,8 +66,6 @@ pub enum Primitive {      Clip {          /// The bounds of the clip          bounds: Rectangle, -        /// The offset transformation of the clip -        offset: Vector<u32>,          /// The content of the clip          content: Box<Primitive>,      }, diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 8f234f1f..c32eb471 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -1,30 +1,43 @@ -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, -}; +//! Create a renderer from a [`Backend`]. +use crate::backend::{self, Backend}; +use crate::{Primitive, Vector}; +use iced_native::layout; +use iced_native::renderer; +use iced_native::text::{self, Text}; +use iced_native::{Background, Element, Font, Point, Rectangle, Size}; + +pub use iced_native::renderer::Style;  /// A backend-agnostic renderer that supports all the built-in widgets.  #[derive(Debug)]  pub struct Renderer<B: Backend> {      backend: B, +    primitives: Vec<Primitive>,  }  impl<B: Backend> Renderer<B> {      /// Creates a new [`Renderer`] from the given [`Backend`].      pub fn new(backend: B) -> Self { -        Self { backend } +        Self { +            backend, +            primitives: Vec::new(), +        }      } -    /// Returns a reference to the [`Backend`] of the [`Renderer`]. +    /// Returns 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 +    /// Enqueues the given [`Primitive`] in the [`Renderer`] for drawing. +    pub fn draw_primitive(&mut self, primitive: Primitive) { +        self.primitives.push(primitive); +    } + +    /// Runs the given closure with the [`Backend`] and the recorded primitives +    /// of the [`Renderer`]. +    pub fn with_primitives(&mut self, f: impl FnOnce(&mut B, &[Primitive])) { +        f(&mut self.backend, &self.primitives);      }  } @@ -32,9 +45,6 @@ impl<B> iced_native::Renderer for Renderer<B>  where      B: Backend,  { -    type Output = (Primitive, mouse::Interaction); -    type Defaults = Defaults; -      fn layout<'a, Message>(          &mut self,          element: &Element<'a, Message, Self>, @@ -47,75 +57,114 @@ where          layout      } -    fn overlay( +    fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) { +        let current_primitives = std::mem::take(&mut self.primitives); + +        f(self); + +        let layer_primitives = +            std::mem::replace(&mut self.primitives, current_primitives); + +        self.primitives.push(Primitive::Clip { +            bounds, +            content: Box::new(Primitive::Group { +                primitives: layer_primitives, +            }), +        }); +    } + +    fn with_translation(          &mut self, -        (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 -            }, -        ) +        translation: Vector, +        f: impl FnOnce(&mut Self), +    ) { +        let current_primitives = std::mem::take(&mut self.primitives); + +        f(self); + +        let layer_primitives = +            std::mem::replace(&mut self.primitives, current_primitives); + +        self.primitives.push(Primitive::Translate { +            translation, +            content: Box::new(Primitive::Group { +                primitives: layer_primitives, +            }), +        }); +    } + +    fn fill_quad( +        &mut self, +        quad: renderer::Quad, +        background: impl Into<Background>, +    ) { +        self.primitives.push(Primitive::Quad { +            bounds: quad.bounds, +            background: background.into(), +            border_radius: quad.border_radius, +            border_width: quad.border_width, +            border_color: quad.border_color, +        }); +    } + +    fn clear(&mut self) { +        self.primitives.clear();      }  } -impl<B> layout::Debugger for Renderer<B> +impl<B> text::Renderer for Renderer<B>  where -    B: Backend, +    B: Backend + backend::Text,  { -    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) +    type Font = Font; + +    const ICON_FONT: Font = B::ICON_FONT; +    const CHECKMARK_ICON: char = B::CHECKMARK_ICON; +    const ARROW_DOWN_ICON: char = B::ARROW_DOWN_ICON; + +    fn default_size(&self) -> u16 { +        self.backend().default_size() +    } + +    fn measure( +        &self, +        content: &str, +        size: u16, +        font: Font, +        bounds: Size, +    ) -> (f32, f32) { +        self.backend() +            .measure(content, f32::from(size), font, bounds) +    } + +    fn hit_test( +        &self, +        content: &str, +        size: f32, +        font: Font, +        bounds: Size, +        point: Point, +        nearest_only: bool, +    ) -> Option<text::Hit> { +        self.backend().hit_test( +            content, +            size, +            font, +            bounds, +            point, +            nearest_only, +        )      } -} -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: color, -    }); - -    for child in layout.children() { -        explain_layout(child, color, primitives); +    fn fill_text(&mut self, text: Text<'_, Self::Font>) { +        self.primitives.push(Primitive::Text { +            content: text.content.to_string(), +            bounds: text.bounds, +            size: text.size, +            color: text.color, +            font: text.font, +            horizontal_alignment: text.horizontal_alignment, +            vertical_alignment: text.vertical_alignment, +        });      }  } diff --git a/graphics/src/widget/button.rs b/graphics/src/widget/button.rs index 60400ed8..7b40c47b 100644 --- a/graphics/src/widget/button.rs +++ b/graphics/src/widget/button.rs @@ -1,111 +1,12 @@  //! 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::Renderer; -pub use iced_native::button::State; -pub use iced_style::button::{Style, StyleSheet}; +pub use iced_native::widget::button::{State, Style, StyleSheet};  /// A widget that produces a message when clicked.  ///  /// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`.  pub type Button<'a, Message, Backend> = -    iced_native::Button<'a, Message, Renderer<Backend>>; - -impl<B> iced_native::button::Renderer for Renderer<B> -where -    B: Backend, -{ -    const DEFAULT_PADDING: 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() -            }, -        ) -    } -} +    iced_native::widget::Button<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs index 7897c8ec..639c2a9b 100644 --- a/graphics/src/widget/canvas.rs +++ b/graphics/src/widget/canvas.rs @@ -3,7 +3,9 @@  //! 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::renderer::{self, Renderer}; +use crate::{Backend, Primitive}; +  use iced_native::layout;  use iced_native::mouse;  use iced_native::{ @@ -186,32 +188,42 @@ where          event::Status::Ignored      } +    fn mouse_interaction( +        &self, +        layout: Layout<'_>, +        cursor_position: Point, +        _viewport: &Rectangle, +    ) -> mouse::Interaction { +        let bounds = layout.bounds(); +        let cursor = Cursor::from_window_position(cursor_position); + +        self.program.mouse_interaction(bounds, cursor) +    } +      fn draw(          &self, -        _renderer: &mut Renderer<B>, -        _defaults: &Defaults, +        renderer: &mut Renderer<B>, +        _style: &renderer::Style,          layout: Layout<'_>,          cursor_position: Point,          _viewport: &Rectangle, -    ) -> (Primitive, mouse::Interaction) { +    ) { +        use iced_native::Renderer as _; +          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), -        ) +        renderer.with_translation(translation, |renderer| { +            renderer.draw_primitive(Primitive::Group { +                primitives: self +                    .program +                    .draw(bounds, cursor) +                    .into_iter() +                    .map(Geometry::into_primitive) +                    .collect(), +            }); +        });      }      fn hash_layout(&self, state: &mut Hasher) { diff --git a/graphics/src/widget/checkbox.rs b/graphics/src/widget/checkbox.rs index 620bfc9e..0d2e93f9 100644 --- a/graphics/src/widget/checkbox.rs +++ b/graphics/src/widget/checkbox.rs @@ -1,77 +1,10 @@  //! Show toggle controls using checkboxes. -use crate::alignment; -use crate::backend::{self, Backend}; -use crate::{Primitive, Rectangle, Renderer}; - -use iced_native::checkbox; -use iced_native::mouse; +use crate::Renderer;  pub use iced_style::checkbox::{Style, StyleSheet};  /// A box that can be checked.  ///  /// This is an alias of an `iced_native` checkbox with an `iced_wgpu::Renderer`. -pub type Checkbox<Message, Backend> = -    iced_native::Checkbox<Message, Renderer<Backend>>; - -impl<B> checkbox::Renderer for Renderer<B> -where -    B: Backend + backend::Text, -{ -    type Style = Box<dyn StyleSheet>; - -    const DEFAULT_SIZE: u16 = 20; -    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() -            }, -        ) -    } -} +pub type Checkbox<'a, Message, Backend> = +    iced_native::widget::Checkbox<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/column.rs b/graphics/src/widget/column.rs index 0cf56842..561681d5 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, -        ) -    } -} +    iced_native::widget::Column<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/container.rs b/graphics/src/widget/container.rs index aae3e1d8..99996f3b 100644 --- a/graphics/src/widget/container.rs +++ b/graphics/src/widget/container.rs @@ -1,8 +1,5 @@  //! 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::Renderer;  pub use iced_style::container::{Style, StyleSheet}; @@ -11,68 +8,4 @@ pub use iced_style::container::{Style, StyleSheet};  /// This is an alias of an `iced_native` container with a default  /// `Renderer`.  pub type Container<'a, Message, Backend> = -    iced_native::Container<'a, Message, Renderer<Backend>>; - -impl<B> iced_native::container::Renderer for Renderer<B> -where -    B: Backend, -{ -    type Style = Box<dyn container::StyleSheet>; - -    fn draw<Message>( -        &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 -    } -} +    iced_native::widget::Container<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/image.rs b/graphics/src/widget/image.rs index bdf03de3..ad8159de 100644 --- a/graphics/src/widget/image.rs +++ b/graphics/src/widget/image.rs @@ -2,13 +2,12 @@  pub mod viewer;  use crate::backend::{self, Backend}; +use crate::{Primitive, Rectangle, Renderer}; -use crate::{Primitive, Renderer};  use iced_native::image; -use iced_native::mouse; -use iced_native::Layout; -pub use iced_native::image::{Handle, Image, Viewer}; +pub use iced_native::widget::image::{Image, Viewer}; +pub use image::Handle;  impl<B> image::Renderer for Renderer<B>  where @@ -18,17 +17,7 @@ where          self.backend().dimensions(handle)      } -    fn draw( -        &mut self, -        handle: image::Handle, -        layout: Layout<'_>, -    ) -> Self::Output { -        ( -            Primitive::Image { -                handle, -                bounds: layout.bounds(), -            }, -            mouse::Interaction::default(), -        ) +    fn draw(&mut self, handle: image::Handle, bounds: Rectangle) { +        self.draw_primitive(Primitive::Image { handle, bounds })      }  } diff --git a/graphics/src/widget/image/viewer.rs b/graphics/src/widget/image/viewer.rs index 28dffc4f..9260990a 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::widget::image::Viewer; diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs index 92cdbb77..95189920 100644 --- a/graphics/src/widget/pane_grid.rs +++ b/graphics/src/widget/pane_grid.rs @@ -7,14 +7,9 @@  //! 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 iced_native::pane_grid; -use iced_native::{Element, Layout, Point, Rectangle, Vector}; +use crate::Renderer; -pub use iced_native::pane_grid::{ +pub use iced_native::widget::pane_grid::{      Axis, Configuration, Content, Direction, DragEvent, Node, Pane,      ResizeEvent, Split, State, TitleBar,  }; @@ -28,277 +23,4 @@ pub use iced_style::pane_grid::{Line, StyleSheet};  ///  /// This is an alias of an `iced_native` pane grid with an `iced_wgpu::Renderer`.  pub type PaneGrid<'a, Message, Backend> = -    iced_native::PaneGrid<'a, Message, Renderer<Backend>>; - -impl<B> pane_grid::Renderer for Renderer<B> -where -    B: Backend, -{ -    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, -            ) -        } -    } -} +    iced_native::widget::PaneGrid<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/pick_list.rs b/graphics/src/widget/pick_list.rs index 532840b8..f3ac12b8 100644 --- a/graphics/src/widget/pick_list.rs +++ b/graphics/src/widget/pick_list.rs @@ -1,103 +1,9 @@  //! 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_style::menu; - -pub use iced_native::pick_list::State; +pub use iced_native::widget::pick_list::State;  pub use iced_style::pick_list::{Style, StyleSheet};  /// A widget allowing the selection of a single value from a list of options.  pub type PickList<'a, T, Message, Backend> = -    iced_native::PickList<'a, T, Message, Renderer<Backend>>; - -impl<B> iced_native::pick_list::Renderer for Renderer<B> -where -    B: Backend + backend::Text, -{ -    type Style = Box<dyn StyleSheet>; - -    const DEFAULT_PADDING: Padding = Padding::new(5); - -    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() -            }, -        ) -    } -} +    iced_native::widget::PickList<'a, T, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/progress_bar.rs b/graphics/src/widget/progress_bar.rs index 32ee42c6..3666ecfd 100644 --- a/graphics/src/widget/progress_bar.rs +++ b/graphics/src/widget/progress_bar.rs @@ -2,73 +2,4 @@  //!  //! 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 iced_native::progress_bar; -use iced_native::{Color, Rectangle}; - -pub use iced_style::progress_bar::{Style, StyleSheet}; - -/// A bar that displays progress. -/// -/// This is an alias of an `iced_native` progress bar with an -/// `iced_wgpu::Renderer`. -pub type ProgressBar<Backend> = iced_native::ProgressBar<Renderer<Backend>>; - -impl<B> progress_bar::Renderer for Renderer<B> -where -    B: Backend, -{ -    type Style = Box<dyn StyleSheet>; - -    const DEFAULT_HEIGHT: u16 = 30; - -    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(), -        ) -    } -} +pub use iced_native::widget::progress_bar::*; diff --git a/graphics/src/widget/qr_code.rs b/graphics/src/widget/qr_code.rs index b3a01dd7..285b8622 100644 --- a/graphics/src/widget/qr_code.rs +++ b/graphics/src/widget/qr_code.rs @@ -1,10 +1,12 @@  //! Encode and display information in a QR code.  use crate::canvas; -use crate::{Backend, Defaults, Primitive, Renderer, Vector}; +use crate::renderer::{self, Renderer}; +use crate::Backend; +use iced_native::layout;  use iced_native::{ -    layout, mouse, Color, Element, Hasher, Layout, Length, Point, Rectangle, -    Size, Widget, +    Color, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector, +    Widget,  };  use thiserror::Error; @@ -80,12 +82,14 @@ where      fn draw(          &self, -        _renderer: &mut Renderer<B>, -        _defaults: &Defaults, +        renderer: &mut Renderer<B>, +        _style: &renderer::Style,          layout: Layout<'_>,          _cursor_position: Point,          _viewport: &Rectangle, -    ) -> (Primitive, mouse::Interaction) { +    ) { +        use iced_native::Renderer as _; +          let bounds = layout.bounds();          let side_length = self.state.width + 2 * QUIET_ZONE; @@ -122,13 +126,11 @@ where                  });          }); -        ( -            Primitive::Translate { -                translation: Vector::new(bounds.x, bounds.y), -                content: Box::new(geometry.into_primitive()), -            }, -            mouse::Interaction::default(), -        ) +        let translation = Vector::new(bounds.x, bounds.y); + +        renderer.with_translation(translation, |renderer| { +            renderer.draw_primitive(geometry.into_primitive()); +        });      }  } diff --git a/graphics/src/widget/radio.rs b/graphics/src/widget/radio.rs index fd3d8145..20d72747 100644 --- a/graphics/src/widget/radio.rs +++ b/graphics/src/widget/radio.rs @@ -1,8 +1,5 @@  //! Create choices using radio buttons. -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; -use iced_native::radio; -use iced_native::{Background, Color, Rectangle}; +use crate::Renderer;  pub use iced_style::radio::{Style, StyleSheet}; @@ -10,69 +7,5 @@ pub use iced_style::radio::{Style, StyleSheet};  ///  /// This is an alias of an `iced_native` radio button with an  /// `iced_wgpu::Renderer`. -pub type Radio<Message, Backend> = -    iced_native::Radio<Message, Renderer<Backend>>; - -impl<B> radio::Renderer for Renderer<B> -where -    B: Backend, -{ -    type Style = Box<dyn StyleSheet>; - -    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() -            }, -        ) -    } -} +pub type Radio<'a, Message, Backend> = +    iced_native::widget::Radio<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/row.rs b/graphics/src/widget/row.rs index 397d80bf..5bee3fd5 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, -        ) -    } -} +    iced_native::widget::Row<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/rule.rs b/graphics/src/widget/rule.rs index 835ebed8..b96924fa 100644 --- a/graphics/src/widget/rule.rs +++ b/graphics/src/widget/rule.rs @@ -1,73 +1,3 @@  //! Display a horizontal or vertical rule for dividing content. -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; -use iced_native::rule; -use iced_native::{Background, Color, Rectangle}; - -pub use iced_style::rule::{FillMode, Style, StyleSheet}; - -/// Display a horizontal or vertical rule for dividing content. -/// -/// This is an alias of an `iced_native` rule with an `iced_graphics::Renderer`. -pub type Rule<Backend> = iced_native::Rule<Renderer<Backend>>; - -impl<B> rule::Renderer for Renderer<B> -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()) -    } -} +pub use iced_native::widget::rule::*; diff --git a/graphics/src/widget/scrollable.rs b/graphics/src/widget/scrollable.rs index 2220e4b8..3fdaf668 100644 --- a/graphics/src/widget/scrollable.rs +++ b/graphics/src/widget/scrollable.rs @@ -1,10 +1,7 @@  //! Navigate an endless amount of content with a scrollbar. -use crate::{Backend, Primitive, Renderer}; -use iced_native::mouse; -use iced_native::scrollable; -use iced_native::{Background, Color, Rectangle, Vector}; +use crate::Renderer; -pub use iced_native::scrollable::State; +pub use iced_native::widget::scrollable::State;  pub use iced_style::scrollable::{Scrollbar, Scroller, StyleSheet};  /// A widget that can vertically display an infinite amount of content @@ -13,146 +10,4 @@ pub use iced_style::scrollable::{Scrollbar, Scroller, StyleSheet};  /// This is an alias of an `iced_native` scrollable with a default  /// `Renderer`.  pub type Scrollable<'a, Message, Backend> = -    iced_native::Scrollable<'a, Message, Renderer<Backend>>; - -impl<B> scrollable::Renderer for Renderer<B> -where -    B: Backend, -{ -    type Style = Box<dyn iced_style::scrollable::StyleSheet>; - -    fn scrollbar( -        &self, -        bounds: Rectangle, -        content_bounds: Rectangle, -        offset: u32, -        scrollbar_width: u16, -        scrollbar_margin: u16, -        scroller_width: u16, -    ) -> Option<scrollable::Scrollbar> { -        if content_bounds.height > bounds.height { -            let outer_width = -                scrollbar_width.max(scroller_width) + 2 * scrollbar_margin; - -            let outer_bounds = Rectangle { -                x: bounds.x + bounds.width - outer_width as f32, -                y: bounds.y, -                width: outer_width as f32, -                height: bounds.height, -            }; - -            let scrollbar_bounds = Rectangle { -                x: bounds.x + bounds.width -                    - f32::from(outer_width / 2 + scrollbar_width / 2), -                y: bounds.y, -                width: scrollbar_width as f32, -                height: bounds.height, -            }; - -            let ratio = bounds.height / content_bounds.height; -            let scroller_height = bounds.height * ratio; -            let y_offset = offset as f32 * ratio; - -            let scroller_bounds = Rectangle { -                x: bounds.x + bounds.width -                    - f32::from(outer_width / 2 + scroller_width / 2), -                y: scrollbar_bounds.y + y_offset, -                width: scroller_width as f32, -                height: scroller_height, -            }; - -            Some(scrollable::Scrollbar { -                outer_bounds, -                bounds: scrollbar_bounds, -                margin: scrollbar_margin, -                scroller: scrollable::Scroller { -                    bounds: scroller_bounds, -                }, -            }) -        } else { -            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 -            }, -        ) -    } -} +    iced_native::widget::Scrollable<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/slider.rs b/graphics/src/widget/slider.rs index aeceec3f..96dc6ec4 100644 --- a/graphics/src/widget/slider.rs +++ b/graphics/src/widget/slider.rs @@ -1,123 +1,5 @@  //! 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 iced_native::slider; -use iced_native::{Background, Color, Point, Rectangle}; - -pub use iced_native::slider::State; +pub use iced_native::widget::slider::{Slider, State};  pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet}; - -/// An horizontal bar and a handle that selects a single value from a range of -/// values. -/// -/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`. -pub type Slider<'a, T, Message, Backend> = -    iced_native::Slider<'a, T, Message, Renderer<Backend>>; - -impl<B> slider::Renderer for Renderer<B> -where -    B: Backend, -{ -    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..77e93dbb 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()) -    } -} +pub use iced_native::widget::Space; diff --git a/graphics/src/widget/svg.rs b/graphics/src/widget/svg.rs index 8b5ed66a..5817a552 100644 --- a/graphics/src/widget/svg.rs +++ b/graphics/src/widget/svg.rs @@ -1,9 +1,10 @@  //! Display vector graphics in your application.  use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; -use iced_native::{mouse, svg, Layout}; +use crate::{Primitive, Rectangle, Renderer}; +use iced_native::svg; -pub use iced_native::svg::{Handle, Svg}; +pub use iced_native::widget::svg::Svg; +pub use svg::Handle;  impl<B> svg::Renderer for Renderer<B>  where @@ -13,17 +14,7 @@ where          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(), -        ) +    fn draw(&mut self, handle: svg::Handle, bounds: Rectangle) { +        self.draw_primitive(Primitive::Svg { handle, bounds })      }  } diff --git a/graphics/src/widget/text.rs b/graphics/src/widget/text.rs index d6d446d3..43516fca 100644 --- a/graphics/src/widget/text.rs +++ b/graphics/src/widget/text.rs @@ -1,92 +1,7 @@  //! 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 iced_native::text; -use iced_native::{Color, Font, Point, Rectangle, Size}; +use crate::Renderer;  /// A paragraph of text.  ///  /// This is an alias of an `iced_native` text with an `iced_wgpu::Renderer`. -pub type Text<Backend> = iced_native::Text<Renderer<Backend>>; - -use std::f32; - -impl<B> text::Renderer for Renderer<B> -where -    B: Backend + backend::Text, -{ -    type Font = Font; - -    fn default_size(&self) -> u16 { -        self.backend().default_size() -    } - -    fn measure( -        &self, -        content: &str, -        size: u16, -        font: Font, -        bounds: Size, -    ) -> (f32, f32) { -        self.backend() -            .measure(content, f32::from(size), font, bounds) -    } - -    fn hit_test( -        &self, -        content: &str, -        size: f32, -        font: Font, -        bounds: Size, -        point: Point, -        nearest_only: bool, -    ) -> Option<text::Hit> { -        self.backend().hit_test( -            content, -            size, -            font, -            bounds, -            point, -            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(), -        ) -    } -} +pub type Text<Backend> = iced_native::widget::Text<Renderer<Backend>>; diff --git a/graphics/src/widget/text_input.rs b/graphics/src/widget/text_input.rs index 1516b007..87384d7e 100644 --- a/graphics/src/widget/text_input.rs +++ b/graphics/src/widget/text_input.rs @@ -1,266 +1,13 @@  //! 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::Renderer; -use iced_native::mouse; -use iced_native::text_input::{self, cursor}; -use std::f32; - -pub use iced_native::text_input::State; +pub use iced_native::widget::text_input::State;  pub use iced_style::text_input::{Style, StyleSheet};  /// A field that can be filled with text.  ///  /// This is an alias of an `iced_native` text input with an `iced_wgpu::Renderer`.  pub type TextInput<'a, Message, Backend> = -    iced_native::TextInput<'a, Message, Renderer<Backend>>; - -impl<B> text_input::Renderer for Renderer<B> -where -    B: Backend + backend::Text, -{ -    type Style = Box<dyn StyleSheet>; - -    fn measure_value(&self, value: &str, size: u16, font: Font) -> f32 { -        let backend = self.backend(); - -        let (width, _) = -            backend.measure(value, f32::from(size), font, Size::INFINITY); - -        width -    } - -    fn offset( -        &self, -        text_bounds: Rectangle, -        font: Font, -        size: u16, -        value: &text_input::Value, -        state: &text_input::State, -    ) -> f32 { -        if state.is_focused() { -            let cursor = state.cursor(); - -            let focus_position = match cursor.state(value) { -                cursor::State::Index(i) => i, -                cursor::State::Selection { end, .. } => end, -            }; - -            let (_, offset) = measure_cursor_and_scroll_offset( -                self, -                text_bounds, -                value, -                size, -                focus_position, -                font, -            ); - -            offset -        } else { -            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>( -    renderer: &Renderer<B>, -    text_bounds: Rectangle, -    value: &text_input::Value, -    size: u16, -    cursor_index: usize, -    font: Font, -) -> (f32, f32) -where -    B: Backend + backend::Text, -{ -    use iced_native::text_input::Renderer; - -    let text_before_cursor = value.until(cursor_index).to_string(); - -    let text_value_width = -        renderer.measure_value(&text_before_cursor, size, font); -    let offset = ((text_value_width + 5.0) - text_bounds.width).max(0.0); - -    (text_value_width, offset) -} +    iced_native::widget::TextInput<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/toggler.rs b/graphics/src/widget/toggler.rs index 852d18ee..9053e6ed 100644 --- a/graphics/src/widget/toggler.rs +++ b/graphics/src/widget/toggler.rs @@ -1,99 +1,10 @@  //! Show toggle controls using togglers. -use crate::backend::{self, Backend}; -use crate::{Primitive, Renderer}; -use iced_native::mouse; -use iced_native::toggler; -use iced_native::Rectangle; +use crate::Renderer;  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`. -pub type Toggler<Message, Backend> = -    iced_native::Toggler<Message, Renderer<Backend>>; - -impl<B> toggler::Renderer for Renderer<B> -where -    B: Backend + backend::Text, -{ -    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() -            }, -        ) -    } -} +pub type Toggler<'a, Message, Backend> = +    iced_native::widget::Toggler<'a, Message, Renderer<Backend>>; diff --git a/graphics/src/widget/tooltip.rs b/graphics/src/widget/tooltip.rs index 493a6389..7dc12ed4 100644 --- a/graphics/src/widget/tooltip.rs +++ b/graphics/src/widget/tooltip.rs @@ -1,168 +1,11 @@  //! 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.  ///  /// This is an alias of an `iced_native` tooltip with a default  /// `Renderer`.  pub type Tooltip<'a, Message, Backend> = -    iced_native::Tooltip<'a, Message, Renderer<Backend>>; - -pub use iced_native::tooltip::Position; - -impl<B> iced_native::tooltip::Renderer for Renderer<B> -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, -            ); +    iced_native::widget::Tooltip<'a, Message, Renderer<Backend>>; -            ( -                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) -        } -    } -} +pub use iced_native::widget::tooltip::Position; 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; +    );  } | 
