diff options
Diffstat (limited to 'native/src/widget/container.rs')
-rw-r--r-- | native/src/widget/container.rs | 106 |
1 files changed, 66 insertions, 40 deletions
diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs index 0e86ab62..596af7fd 100644 --- a/native/src/widget/container.rs +++ b/native/src/widget/container.rs @@ -4,19 +4,23 @@ use std::hash::Hash; use crate::alignment::{self, Alignment}; use crate::event::{self, Event}; use crate::layout; +use crate::mouse; use crate::overlay; +use crate::renderer; use crate::{ - Clipboard, Element, Hasher, Layout, Length, Padding, Point, Rectangle, - Widget, + Background, Clipboard, Color, Element, Hasher, Layout, Length, Padding, + Point, Rectangle, Widget, }; use std::u32; +pub use iced_style::container::{Style, StyleSheet}; + /// An element decorating some content. /// /// It is normally used for alignment purposes. #[allow(missing_debug_implementations)] -pub struct Container<'a, Message, Renderer: self::Renderer> { +pub struct Container<'a, Message, Renderer> { padding: Padding, width: Length, height: Length, @@ -24,13 +28,13 @@ pub struct Container<'a, Message, Renderer: self::Renderer> { max_height: u32, horizontal_alignment: alignment::Horizontal, vertical_alignment: alignment::Vertical, - style: Renderer::Style, + style_sheet: Box<dyn StyleSheet + 'a>, content: Element<'a, Message, Renderer>, } impl<'a, Message, Renderer> Container<'a, Message, Renderer> where - Renderer: self::Renderer, + Renderer: crate::Renderer, { /// Creates an empty [`Container`]. pub fn new<T>(content: T) -> Self @@ -45,7 +49,7 @@ where max_height: u32::MAX, horizontal_alignment: alignment::Horizontal::Left, vertical_alignment: alignment::Vertical::Top, - style: Renderer::Style::default(), + style_sheet: Default::default(), content: content.into(), } } @@ -105,8 +109,11 @@ where } /// Sets the style of the [`Container`]. - pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self { - self.style = style.into(); + pub fn style( + mut self, + style_sheet: impl Into<Box<dyn StyleSheet + 'a>>, + ) -> Self { + self.style_sheet = style_sheet.into(); self } } @@ -114,7 +121,7 @@ where impl<'a, Message, Renderer> Widget<Message, Renderer> for Container<'a, Message, Renderer> where - Renderer: self::Renderer, + Renderer: crate::Renderer, { fn width(&self) -> Length { self.width @@ -172,23 +179,42 @@ where ) } + fn mouse_interaction( + &self, + layout: Layout<'_>, + cursor_position: Point, + viewport: &Rectangle, + ) -> mouse::Interaction { + self.content.widget.mouse_interaction( + layout.children().next().unwrap(), + cursor_position, + viewport, + ) + } + fn draw( &self, renderer: &mut Renderer, - defaults: &Renderer::Defaults, + renderer_style: &renderer::Style, layout: Layout<'_>, cursor_position: Point, viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw( - defaults, - layout.bounds(), + ) { + let style = self.style_sheet.style(); + + draw_background(renderer, &style, layout.bounds()); + + self.content.draw( + renderer, + &renderer::Style { + text_color: style + .text_color + .unwrap_or(renderer_style.text_color), + }, + layout.children().next().unwrap(), cursor_position, viewport, - &self.style, - &self.content, - layout.children().next().unwrap(), - ) + ); } fn hash_layout(&self, state: &mut Hasher) { @@ -212,33 +238,33 @@ where } } -/// The renderer of a [`Container`]. -/// -/// Your [renderer] will need to implement this trait before being -/// able to use a [`Container`] in your user interface. -/// -/// [renderer]: crate::renderer -pub trait Renderer: crate::Renderer { - /// The style supported by this renderer. - type Style: Default; - - /// Draws a [`Container`]. - fn draw<Message>( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - cursor_position: Point, - viewport: &Rectangle, - style: &Self::Style, - content: &Element<'_, Message, Self>, - content_layout: Layout<'_>, - ) -> Self::Output; +/// Draws the background of a [`Container`] given its [`Style`] and its `bounds`. +pub fn draw_background<Renderer>( + renderer: &mut Renderer, + style: &Style, + bounds: Rectangle, +) where + Renderer: crate::Renderer, +{ + if style.background.is_some() || style.border_width > 0.0 { + renderer.fill_quad( + renderer::Quad { + bounds, + border_radius: style.border_radius, + border_width: style.border_width, + border_color: style.border_color, + }, + style + .background + .unwrap_or(Background::Color(Color::TRANSPARENT)), + ); + } } impl<'a, Message, Renderer> From<Container<'a, Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + self::Renderer, + Renderer: 'a + crate::Renderer, Message: 'a, { fn from( |