diff options
Diffstat (limited to 'graphics')
| -rw-r--r-- | graphics/src/widget/container.rs | 33 | ||||
| -rw-r--r-- | graphics/src/widget/pane_grid.rs | 157 | 
2 files changed, 164 insertions, 26 deletions
| diff --git a/graphics/src/widget/container.rs b/graphics/src/widget/container.rs index 070cb48b..576062d4 100644 --- a/graphics/src/widget/container.rs +++ b/graphics/src/widget/container.rs @@ -39,20 +39,10 @@ where          let (content, mouse_interaction) =              content.draw(self, &defaults, content_layout, cursor_position); -        if style.background.is_some() || style.border_width > 0 { -            let quad = 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, -            }; - +        if let Some(background) = background(bounds, &style) {              (                  Primitive::Group { -                    primitives: vec![quad, content], +                    primitives: vec![background, content],                  },                  mouse_interaction,              ) @@ -61,3 +51,22 @@ where          }      }  } + +pub(crate) fn background( +    bounds: Rectangle, +    style: &container::Style, +) -> Option<Primitive> { +    if style.background.is_none() && style.border_width > 0 { +        return None; +    } + +    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, +    }) +} diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs index 56af683d..ec607c47 100644 --- a/graphics/src/widget/pane_grid.rs +++ b/graphics/src/widget/pane_grid.rs @@ -8,14 +8,19 @@  //!  //! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.1/examples/pane_grid  //! [`PaneGrid`]: type.PaneGrid.html -use crate::{Backend, Primitive, Renderer}; +use crate::backend::{self, Backend}; +use crate::{Primitive, Renderer};  use iced_native::mouse;  use iced_native::pane_grid; -use iced_native::{Element, Layout, Point, Rectangle, Vector}; +use iced_native::text; +use iced_native::{ +    Element, HorizontalAlignment, Layout, Point, Rectangle, Vector, +    VerticalAlignment, +};  pub use iced_native::pane_grid::{ -    Axis, Direction, DragEvent, Focus, KeyPressEvent, Pane, ResizeEvent, Split, -    State, +    Axis, Configuration, Content, Direction, DragEvent, Focus, KeyPressEvent, +    Pane, ResizeEvent, Split, State, TitleBar,  };  /// A collection of panes distributed using either vertical or horizontal splits @@ -29,13 +34,13 @@ pub type PaneGrid<'a, Message, Backend> =  impl<B> pane_grid::Renderer for Renderer<B>  where -    B: Backend, +    B: Backend + backend::Text,  {      fn draw<Message>(          &mut self,          defaults: &Self::Defaults, -        content: &[(Pane, Element<'_, Message, Self>)], -        dragging: Option<Pane>, +        content: &[(Pane, Content<'_, Message, Self>)], +        dragging: Option<(Pane, Point)>,          resizing: Option<Axis>,          layout: Layout<'_>,          cursor_position: Point, @@ -63,32 +68,40 @@ where                      mouse_interaction = new_mouse_interaction;                  } -                if Some(*id) == dragging { -                    dragged_pane = Some((i, layout)); +                if let Some((dragging, origin)) = dragging { +                    if *id == dragging { +                        dragged_pane = Some((i, layout, origin)); +                    }                  }                  primitive              })              .collect(); -        let primitives = if let Some((index, layout)) = dragged_pane { +        let primitives = if let Some((index, layout, origin)) = dragged_pane {              let pane = panes.remove(index);              let bounds = layout.bounds(); +            if let Primitive::Group { primitives } = &pane { +                panes.push( +                    primitives.first().cloned().unwrap_or(Primitive::None), +                ); +            } +              // 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 - bounds.width / 2.0, -                    y: cursor_position.y - bounds.height / 2.0, +                    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 - bounds.width / 2.0, -                        cursor_position.y - bounds.y - bounds.height / 2.0, +                        cursor_position.x - bounds.x - origin.x, +                        cursor_position.y - bounds.y - origin.y,                      ),                      content: Box::new(pane),                  }), @@ -115,4 +128,120 @@ where              },          )      } + +    fn draw_pane<Message>( +        &mut self, +        defaults: &Self::Defaults, +        bounds: Rectangle, +        style_sheet: &Self::Style, +        title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>, +        body: (&Element<'_, Message, Self>, Layout<'_>), +        cursor_position: Point, +    ) -> 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); + +        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_draggable = +                title_bar.is_over_draggable(title_bar_layout, cursor_position); + +            let (title_bar_primitive, title_bar_interaction) = title_bar.draw( +                self, +                defaults, +                title_bar_layout, +                cursor_position, +                show_controls, +            ); + +            ( +                Primitive::Group { +                    primitives: vec![ +                        background.unwrap_or(Primitive::None), +                        title_bar_primitive, +                        body_primitive, +                    ], +                }, +                if is_over_draggable { +                    mouse::Interaction::Grab +                } else if title_bar_interaction > body_interaction { +                    title_bar_interaction +                } 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::Style, +        title: &str, +        title_size: u16, +        title_font: Self::Font, +        title_bounds: Rectangle, +        controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, +        cursor_position: Point, +    ) -> Self::Output { +        let style = style_sheet.style(); + +        let background = crate::widget::container::background(bounds, &style); + +        let (title_primitive, _) = text::Renderer::draw( +            self, +            defaults, +            title_bounds, +            title, +            title_size, +            title_font, +            None, +            HorizontalAlignment::Left, +            VerticalAlignment::Top, +        ); + +        if let Some((controls, controls_layout)) = controls { +            let (controls_primitive, controls_interaction) = +                controls.draw(self, defaults, controls_layout, cursor_position); + +            ( +                Primitive::Group { +                    primitives: vec![ +                        background.unwrap_or(Primitive::None), +                        title_primitive, +                        controls_primitive, +                    ], +                }, +                controls_interaction, +            ) +        } else { +            ( +                if let Some(background) = background { +                    Primitive::Group { +                        primitives: vec![background, title_primitive], +                    } +                } else { +                    title_primitive +                }, +                mouse::Interaction::default(), +            ) +        } +    }  } | 
