diff options
Diffstat (limited to 'pure/src/widget/pane_grid')
-rw-r--r-- | pure/src/widget/pane_grid/content.rs | 345 | ||||
-rw-r--r-- | pure/src/widget/pane_grid/title_bar.rs | 388 |
2 files changed, 0 insertions, 733 deletions
diff --git a/pure/src/widget/pane_grid/content.rs b/pure/src/widget/pane_grid/content.rs deleted file mode 100644 index 9c2a0f4a..00000000 --- a/pure/src/widget/pane_grid/content.rs +++ /dev/null @@ -1,345 +0,0 @@ -use crate::widget::pane_grid::TitleBar; -use crate::widget::tree::Tree; -use crate::Element; - -use iced_native::event::{self, Event}; -use iced_native::layout; -use iced_native::mouse; -use iced_native::overlay; -use iced_native::renderer; -use iced_native::widget::container; -use iced_native::widget::pane_grid::Draggable; -use iced_native::{Clipboard, Layout, Point, Rectangle, Shell, Size}; - -/// The content of a [`Pane`]. -/// -/// [`Pane`]: crate::widget::pane_grid::Pane -#[allow(missing_debug_implementations)] -pub struct Content<'a, Message, Renderer> -where - Renderer: iced_native::Renderer, - Renderer::Theme: container::StyleSheet, -{ - title_bar: Option<TitleBar<'a, Message, Renderer>>, - body: Element<'a, Message, Renderer>, - style: <Renderer::Theme as container::StyleSheet>::Style, -} - -impl<'a, Message, Renderer> Content<'a, Message, Renderer> -where - Renderer: iced_native::Renderer, - Renderer::Theme: container::StyleSheet, -{ - /// Creates a new [`Content`] with the provided body. - pub fn new(body: impl Into<Element<'a, Message, Renderer>>) -> Self { - Self { - title_bar: None, - body: body.into(), - style: Default::default(), - } - } - - /// Sets the [`TitleBar`] of this [`Content`]. - pub fn title_bar( - mut self, - title_bar: TitleBar<'a, Message, Renderer>, - ) -> Self { - self.title_bar = Some(title_bar); - self - } - - /// Sets the style of the [`Content`]. - pub fn style( - mut self, - style: impl Into<<Renderer::Theme as container::StyleSheet>::Style>, - ) -> Self { - self.style = style.into(); - self - } -} - -impl<'a, Message, Renderer> Content<'a, Message, Renderer> -where - Renderer: iced_native::Renderer, - Renderer::Theme: container::StyleSheet, -{ - pub(super) fn state(&self) -> Tree { - let children = if let Some(title_bar) = self.title_bar.as_ref() { - vec![Tree::new(&self.body), title_bar.state()] - } else { - vec![Tree::new(&self.body), Tree::empty()] - }; - - Tree { - children, - ..Tree::empty() - } - } - - pub(super) fn diff(&self, tree: &mut Tree) { - if tree.children.len() == 2 { - if let Some(title_bar) = self.title_bar.as_ref() { - title_bar.diff(&mut tree.children[1]); - } - - tree.children[0].diff(&self.body); - } else { - *tree = self.state(); - } - } - - /// Draws the [`Content`] with the provided [`Renderer`] and [`Layout`]. - /// - /// [`Renderer`]: iced_native::Renderer - pub fn draw( - &self, - tree: &Tree, - renderer: &mut Renderer, - theme: &Renderer::Theme, - style: &renderer::Style, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) { - use container::StyleSheet; - - let bounds = layout.bounds(); - - { - let style = theme.appearance(self.style); - - container::draw_background(renderer, &style, bounds); - } - - if let Some(title_bar) = &self.title_bar { - let mut children = layout.children(); - let title_bar_layout = children.next().unwrap(); - let body_layout = children.next().unwrap(); - - let show_controls = bounds.contains(cursor_position); - - title_bar.draw( - &tree.children[1], - renderer, - theme, - style, - title_bar_layout, - cursor_position, - viewport, - show_controls, - ); - - self.body.as_widget().draw( - &tree.children[0], - renderer, - theme, - style, - body_layout, - cursor_position, - viewport, - ); - } else { - self.body.as_widget().draw( - &tree.children[0], - renderer, - theme, - style, - layout, - cursor_position, - viewport, - ); - } - } - - pub(crate) fn layout( - &self, - renderer: &Renderer, - limits: &layout::Limits, - ) -> layout::Node { - if let Some(title_bar) = &self.title_bar { - let max_size = limits.max(); - - let title_bar_layout = title_bar - .layout(renderer, &layout::Limits::new(Size::ZERO, max_size)); - - let title_bar_size = title_bar_layout.size(); - - let mut body_layout = self.body.as_widget().layout( - renderer, - &layout::Limits::new( - Size::ZERO, - Size::new( - max_size.width, - max_size.height - title_bar_size.height, - ), - ), - ); - - body_layout.move_to(Point::new(0.0, title_bar_size.height)); - - layout::Node::with_children( - max_size, - vec![title_bar_layout, body_layout], - ) - } else { - self.body.as_widget().layout(renderer, limits) - } - } - - pub(crate) fn on_event( - &mut self, - tree: &mut Tree, - event: Event, - layout: Layout<'_>, - cursor_position: Point, - renderer: &Renderer, - clipboard: &mut dyn Clipboard, - shell: &mut Shell<'_, Message>, - is_picked: bool, - ) -> event::Status { - let mut event_status = event::Status::Ignored; - - let body_layout = if let Some(title_bar) = &mut self.title_bar { - let mut children = layout.children(); - - event_status = title_bar.on_event( - &mut tree.children[1], - event.clone(), - children.next().unwrap(), - cursor_position, - renderer, - clipboard, - shell, - ); - - children.next().unwrap() - } else { - layout - }; - - let body_status = if is_picked { - event::Status::Ignored - } else { - self.body.as_widget_mut().on_event( - &mut tree.children[0], - event, - body_layout, - cursor_position, - renderer, - clipboard, - shell, - ) - }; - - event_status.merge(body_status) - } - - pub(crate) fn mouse_interaction( - &self, - tree: &Tree, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - renderer: &Renderer, - ) -> mouse::Interaction { - let (body_layout, title_bar_interaction) = - if let Some(title_bar) = &self.title_bar { - let mut children = layout.children(); - let title_bar_layout = children.next().unwrap(); - - let is_over_pick_area = title_bar - .is_over_pick_area(title_bar_layout, cursor_position); - - if is_over_pick_area { - return mouse::Interaction::Grab; - } - - let mouse_interaction = title_bar.mouse_interaction( - &tree.children[1], - title_bar_layout, - cursor_position, - viewport, - renderer, - ); - - (children.next().unwrap(), mouse_interaction) - } else { - (layout, mouse::Interaction::default()) - }; - - self.body - .as_widget() - .mouse_interaction( - &tree.children[0], - body_layout, - cursor_position, - viewport, - renderer, - ) - .max(title_bar_interaction) - } - - pub(crate) fn overlay<'b>( - &'b self, - tree: &'b mut Tree, - layout: Layout<'_>, - renderer: &Renderer, - ) -> Option<overlay::Element<'b, Message, Renderer>> { - if let Some(title_bar) = self.title_bar.as_ref() { - let mut children = layout.children(); - let title_bar_layout = children.next()?; - - let mut states = tree.children.iter_mut(); - let body_state = states.next().unwrap(); - let title_bar_state = states.next().unwrap(); - - match title_bar.overlay(title_bar_state, title_bar_layout, renderer) - { - Some(overlay) => Some(overlay), - None => self.body.as_widget().overlay( - body_state, - children.next()?, - renderer, - ), - } - } else { - self.body.as_widget().overlay( - &mut tree.children[0], - layout, - renderer, - ) - } - } -} - -impl<'a, Message, Renderer> Draggable for &Content<'a, Message, Renderer> -where - Renderer: iced_native::Renderer, - Renderer::Theme: container::StyleSheet, -{ - fn can_be_dragged_at( - &self, - layout: Layout<'_>, - cursor_position: Point, - ) -> bool { - if let Some(title_bar) = &self.title_bar { - let mut children = layout.children(); - let title_bar_layout = children.next().unwrap(); - - title_bar.is_over_pick_area(title_bar_layout, cursor_position) - } else { - false - } - } -} - -impl<'a, T, Message, Renderer> From<T> for Content<'a, Message, Renderer> -where - T: Into<Element<'a, Message, Renderer>>, - Renderer: iced_native::Renderer, - Renderer::Theme: container::StyleSheet, -{ - fn from(element: T) -> Self { - Self::new(element) - } -} diff --git a/pure/src/widget/pane_grid/title_bar.rs b/pure/src/widget/pane_grid/title_bar.rs deleted file mode 100644 index de9591a2..00000000 --- a/pure/src/widget/pane_grid/title_bar.rs +++ /dev/null @@ -1,388 +0,0 @@ -use crate::widget::Tree; -use crate::Element; - -use iced_native::event::{self, Event}; -use iced_native::layout; -use iced_native::mouse; -use iced_native::overlay; -use iced_native::renderer; -use iced_native::widget::container; -use iced_native::{Clipboard, Layout, Padding, Point, Rectangle, Shell, Size}; - -/// The title bar of a [`Pane`]. -/// -/// [`Pane`]: crate::widget::pane_grid::Pane -#[allow(missing_debug_implementations)] -pub struct TitleBar<'a, Message, Renderer> -where - Renderer: iced_native::Renderer, - Renderer::Theme: container::StyleSheet, -{ - content: Element<'a, Message, Renderer>, - controls: Option<Element<'a, Message, Renderer>>, - padding: Padding, - always_show_controls: bool, - style: <Renderer::Theme as container::StyleSheet>::Style, -} - -impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer> -where - Renderer: iced_native::Renderer, - Renderer::Theme: container::StyleSheet, -{ - /// Creates a new [`TitleBar`] with the given content. - pub fn new<E>(content: E) -> Self - where - E: Into<Element<'a, Message, Renderer>>, - { - Self { - content: content.into(), - controls: None, - padding: Padding::ZERO, - always_show_controls: false, - style: Default::default(), - } - } - - /// Sets the controls of the [`TitleBar`]. - pub fn controls( - mut self, - controls: impl Into<Element<'a, Message, Renderer>>, - ) -> Self { - self.controls = Some(controls.into()); - self - } - - /// Sets the [`Padding`] of the [`TitleBar`]. - pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self { - self.padding = padding.into(); - self - } - - /// Sets the style of the [`TitleBar`]. - pub fn style( - mut self, - style: impl Into<<Renderer::Theme as container::StyleSheet>::Style>, - ) -> Self { - self.style = style.into(); - self - } - - /// Sets whether or not the [`controls`] attached to this [`TitleBar`] are - /// always visible. - /// - /// By default, the controls are only visible when the [`Pane`] of this - /// [`TitleBar`] is hovered. - /// - /// [`controls`]: Self::controls - /// [`Pane`]: crate::widget::pane_grid::Pane - pub fn always_show_controls(mut self) -> Self { - self.always_show_controls = true; - self - } -} - -impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer> -where - Renderer: iced_native::Renderer, - Renderer::Theme: container::StyleSheet, -{ - pub(super) fn state(&self) -> Tree { - let children = if let Some(controls) = self.controls.as_ref() { - vec![Tree::new(&self.content), Tree::new(controls)] - } else { - vec![Tree::new(&self.content), Tree::empty()] - }; - - Tree { - children, - ..Tree::empty() - } - } - - pub(super) fn diff(&self, tree: &mut Tree) { - if tree.children.len() == 2 { - if let Some(controls) = self.controls.as_ref() { - tree.children[1].diff(controls); - } - - tree.children[0].diff(&self.content); - } else { - *tree = self.state(); - } - } - - /// Draws the [`TitleBar`] with the provided [`Renderer`] and [`Layout`]. - /// - /// [`Renderer`]: iced_native::Renderer - pub fn draw( - &self, - tree: &Tree, - renderer: &mut Renderer, - theme: &Renderer::Theme, - inherited_style: &renderer::Style, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - show_controls: bool, - ) { - use container::StyleSheet; - - let bounds = layout.bounds(); - let style = theme.appearance(self.style); - let inherited_style = renderer::Style { - text_color: style.text_color.unwrap_or(inherited_style.text_color), - }; - - container::draw_background(renderer, &style, bounds); - - let mut children = layout.children(); - let padded = children.next().unwrap(); - - let mut children = padded.children(); - let title_layout = children.next().unwrap(); - let mut show_title = true; - - if let Some(controls) = &self.controls { - let controls_layout = children.next().unwrap(); - if title_layout.bounds().width + controls_layout.bounds().width - > padded.bounds().width - { - show_title = false; - } - - if show_controls || self.always_show_controls { - controls.as_widget().draw( - &tree.children[1], - renderer, - theme, - &inherited_style, - controls_layout, - cursor_position, - viewport, - ); - } - } - - if show_title { - self.content.as_widget().draw( - &tree.children[0], - renderer, - theme, - &inherited_style, - title_layout, - cursor_position, - viewport, - ); - } - } - - /// Returns whether the mouse cursor is over the pick area of the - /// [`TitleBar`] or not. - /// - /// The whole [`TitleBar`] is a pick area, except its controls. - pub fn is_over_pick_area( - &self, - layout: Layout<'_>, - cursor_position: Point, - ) -> bool { - if layout.bounds().contains(cursor_position) { - let mut children = layout.children(); - let padded = children.next().unwrap(); - let mut children = padded.children(); - let title_layout = children.next().unwrap(); - - if self.controls.is_some() { - let controls_layout = children.next().unwrap(); - - !controls_layout.bounds().contains(cursor_position) - && !title_layout.bounds().contains(cursor_position) - } else { - !title_layout.bounds().contains(cursor_position) - } - } else { - false - } - } - - pub(crate) fn layout( - &self, - renderer: &Renderer, - limits: &layout::Limits, - ) -> layout::Node { - let limits = limits.pad(self.padding); - let max_size = limits.max(); - - let title_layout = self - .content - .as_widget() - .layout(renderer, &layout::Limits::new(Size::ZERO, max_size)); - - let title_size = title_layout.size(); - - let mut node = if let Some(controls) = &self.controls { - let mut controls_layout = controls - .as_widget() - .layout(renderer, &layout::Limits::new(Size::ZERO, max_size)); - - let controls_size = controls_layout.size(); - let space_before_controls = max_size.width - controls_size.width; - - let height = title_size.height.max(controls_size.height); - - controls_layout.move_to(Point::new(space_before_controls, 0.0)); - - layout::Node::with_children( - Size::new(max_size.width, height), - vec![title_layout, controls_layout], - ) - } else { - layout::Node::with_children( - Size::new(max_size.width, title_size.height), - vec![title_layout], - ) - }; - - node.move_to(Point::new( - self.padding.left.into(), - self.padding.top.into(), - )); - - layout::Node::with_children(node.size().pad(self.padding), vec![node]) - } - - pub(crate) fn on_event( - &mut self, - tree: &mut Tree, - event: Event, - layout: Layout<'_>, - cursor_position: Point, - renderer: &Renderer, - clipboard: &mut dyn Clipboard, - shell: &mut Shell<'_, Message>, - ) -> event::Status { - let mut children = layout.children(); - let padded = children.next().unwrap(); - - let mut children = padded.children(); - let title_layout = children.next().unwrap(); - let mut show_title = true; - - let control_status = if let Some(controls) = &mut self.controls { - let controls_layout = children.next().unwrap(); - if title_layout.bounds().width + controls_layout.bounds().width - > padded.bounds().width - { - show_title = false; - } - - controls.as_widget_mut().on_event( - &mut tree.children[1], - event.clone(), - controls_layout, - cursor_position, - renderer, - clipboard, - shell, - ) - } else { - event::Status::Ignored - }; - - let title_status = if show_title { - self.content.as_widget_mut().on_event( - &mut tree.children[0], - event, - title_layout, - cursor_position, - renderer, - clipboard, - shell, - ) - } else { - event::Status::Ignored - }; - - control_status.merge(title_status) - } - - pub(crate) fn mouse_interaction( - &self, - tree: &Tree, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - renderer: &Renderer, - ) -> mouse::Interaction { - let mut children = layout.children(); - let padded = children.next().unwrap(); - - let mut children = padded.children(); - let title_layout = children.next().unwrap(); - - let title_interaction = self.content.as_widget().mouse_interaction( - &tree.children[0], - title_layout, - cursor_position, - viewport, - renderer, - ); - - if let Some(controls) = &self.controls { - let controls_layout = children.next().unwrap(); - let controls_interaction = controls.as_widget().mouse_interaction( - &tree.children[1], - controls_layout, - cursor_position, - viewport, - renderer, - ); - - if title_layout.bounds().width + controls_layout.bounds().width - > padded.bounds().width - { - controls_interaction - } else { - controls_interaction.max(title_interaction) - } - } else { - title_interaction - } - } - - pub(crate) fn overlay<'b>( - &'b self, - tree: &'b mut Tree, - layout: Layout<'_>, - renderer: &Renderer, - ) -> Option<overlay::Element<'b, Message, Renderer>> { - let mut children = layout.children(); - let padded = children.next()?; - - let mut children = padded.children(); - let title_layout = children.next()?; - - let Self { - content, controls, .. - } = self; - - let mut states = tree.children.iter_mut(); - let title_state = states.next().unwrap(); - let controls_state = states.next().unwrap(); - - content - .as_widget() - .overlay(title_state, title_layout, renderer) - .or_else(move || { - controls.as_ref().and_then(|controls| { - let controls_layout = children.next()?; - - controls.as_widget().overlay( - controls_state, - controls_layout, - renderer, - ) - }) - }) - } -} |