From a11bcf5af0be26671ba90097c64021014ab2092d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 4 Jun 2020 07:13:38 +0200 Subject: Draft first-class `TitleBar` in `pane_grid` --- native/src/widget/pane_grid/content.rs | 112 +++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 27 deletions(-) (limited to 'native/src/widget/pane_grid/content.rs') diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index 8822083e..e1374c82 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -1,30 +1,88 @@ -use crate::pane_grid::Axis; +use crate::layout; +use crate::pane_grid::{self, TitleBar}; +use crate::{Clipboard, Element, Event, Hasher, Layout, Point}; -/// The content of a [`PaneGrid`]. +/// The content of a [`Pane`]. /// -/// [`PaneGrid`]: struct.PaneGrid.html -#[derive(Debug, Clone)] -pub enum Content { - /// A split of the available space. - Split { - /// The direction of the split. - axis: Axis, - - /// The ratio of the split in [0.0, 1.0]. - ratio: f32, - - /// The left/top [`Content`] of the split. - /// - /// [`Content`]: enum.Node.html - a: Box>, - - /// The right/bottom [`Content`] of the split. - /// - /// [`Content`]: enum.Node.html - b: Box>, - }, - /// A [`Pane`]. - /// - /// [`Pane`]: struct.Pane.html - Pane(T), +/// [`Pane`]: struct.Pane.html +pub struct Content<'a, Message, Renderer> { + title_bar: Option>, + body: Element<'a, Message, Renderer>, +} + +impl<'a, Message, Renderer> Content<'a, Message, Renderer> { + pub fn new(body: impl Into>) -> Self { + Self { + title_bar: None, + body: body.into(), + } + } + + pub fn title_bar( + mut self, + title_bar: TitleBar<'a, Message, Renderer>, + ) -> Self { + self.title_bar = Some(title_bar); + self + } +} + +impl<'a, Message, Renderer> Content<'a, Message, Renderer> +where + Renderer: pane_grid::Renderer, +{ + pub fn draw( + &self, + renderer: &mut Renderer, + defaults: &Renderer::Defaults, + layout: Layout<'_>, + cursor_position: Point, + ) -> Renderer::Output { + renderer.draw_pane( + defaults, + self.title_bar.as_ref(), + &self.body, + layout, + cursor_position, + ) + } + + pub(crate) fn is_over_drag_target( + &self, + _layout: Layout<'_>, + _cursor_position: Point, + ) -> bool { + false + } + + pub(crate) fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + self.body.layout(renderer, limits) + } + + pub(crate) fn on_event( + &mut self, + event: Event, + layout: Layout<'_>, + cursor_position: Point, + messages: &mut Vec, + renderer: &Renderer, + clipboard: Option<&dyn Clipboard>, + ) { + self.body.on_event( + event, + layout, + cursor_position, + messages, + renderer, + clipboard, + ) + } + + pub(crate) fn hash_layout(&self, state: &mut Hasher) { + self.body.hash_layout(state); + } } -- cgit From 4e1e0e0890b83fb1c4c4406791e3aa63bba58a93 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 5 Jun 2020 06:52:07 +0200 Subject: Draft drawing logic for `Content` and `TitleBar` --- native/src/widget/pane_grid/content.rs | 77 ++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 12 deletions(-) (limited to 'native/src/widget/pane_grid/content.rs') diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index e1374c82..a30b0e7d 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -1,16 +1,20 @@ +use crate::container; use crate::layout; use crate::pane_grid::{self, TitleBar}; -use crate::{Clipboard, Element, Event, Hasher, Layout, Point}; +use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size}; /// The content of a [`Pane`]. /// /// [`Pane`]: struct.Pane.html -pub struct Content<'a, Message, Renderer> { +pub struct Content<'a, Message, Renderer: container::Renderer> { title_bar: Option>, body: Element<'a, Message, Renderer>, } -impl<'a, Message, Renderer> Content<'a, Message, Renderer> { +impl<'a, Message, Renderer> Content<'a, Message, Renderer> +where + Renderer: container::Renderer, +{ pub fn new(body: impl Into>) -> Self { Self { title_bar: None, @@ -29,7 +33,7 @@ impl<'a, Message, Renderer> Content<'a, Message, Renderer> { impl<'a, Message, Renderer> Content<'a, Message, Renderer> where - Renderer: pane_grid::Renderer, + Renderer: pane_grid::Renderer + container::Renderer, { pub fn draw( &self, @@ -38,13 +42,25 @@ where layout: Layout<'_>, cursor_position: Point, ) -> Renderer::Output { - renderer.draw_pane( - defaults, - self.title_bar.as_ref(), - &self.body, - layout, - cursor_position, - ) + if let Some(title_bar) = &self.title_bar { + let mut children = layout.children(); + let title_bar_layout = children.next().unwrap(); + let body_layout = children.next().unwrap(); + + renderer.draw_pane( + defaults, + Some((title_bar, title_bar_layout)), + (&self.body, body_layout), + cursor_position, + ) + } else { + renderer.draw_pane( + defaults, + None, + (&self.body, layout), + cursor_position, + ) + } } pub(crate) fn is_over_drag_target( @@ -60,7 +76,34 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.body.layout(renderer, limits) + 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.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.layout(renderer, limits) + } } pub(crate) fn on_event( @@ -86,3 +129,13 @@ where self.body.hash_layout(state); } } + +impl<'a, T, Message, Renderer> From for Content<'a, Message, Renderer> +where + T: Into>, + Renderer: pane_grid::Renderer + container::Renderer, +{ + fn from(element: T) -> Self { + Self::new(element) + } +} -- cgit From 4dc5bffdfbfb09a017f35c12b484301fcf044876 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 5 Jun 2020 14:02:29 +0200 Subject: Draft draggable and graphics logic for `TitleBar` --- native/src/widget/pane_grid/content.rs | 60 +++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'native/src/widget/pane_grid/content.rs') diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index a30b0e7d..843dcec4 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -1,7 +1,7 @@ use crate::container; use crate::layout; use crate::pane_grid::{self, TitleBar}; -use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size}; +use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size, Vector}; /// The content of a [`Pane`]. /// @@ -9,6 +9,7 @@ use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size}; pub struct Content<'a, Message, Renderer: container::Renderer> { title_bar: Option>, body: Element<'a, Message, Renderer>, + style: Renderer::Style, } impl<'a, Message, Renderer> Content<'a, Message, Renderer> @@ -19,6 +20,7 @@ where Self { title_bar: None, body: body.into(), + style: Renderer::Style::default(), } } @@ -29,6 +31,14 @@ where self.title_bar = Some(title_bar); self } + + /// Sets the style of the [`TitleBar`]. + /// + /// [`TitleBar`]: struct.TitleBar.html + pub fn style(mut self, style: impl Into) -> Self { + self.style = style.into(); + self + } } impl<'a, Message, Renderer> Content<'a, Message, Renderer> @@ -49,6 +59,8 @@ where renderer.draw_pane( defaults, + layout.bounds(), + &self.style, Some((title_bar, title_bar_layout)), (&self.body, body_layout), cursor_position, @@ -56,6 +68,8 @@ where } else { renderer.draw_pane( defaults, + layout.bounds(), + &self.style, None, (&self.body, layout), cursor_position, @@ -63,12 +77,25 @@ where } } - pub(crate) fn is_over_drag_target( + pub fn drag_origin( &self, - _layout: Layout<'_>, - _cursor_position: Point, - ) -> bool { - false + layout: Layout<'_>, + cursor_position: Point, + ) -> Option { + if let Some(title_bar) = &self.title_bar { + let mut children = layout.children(); + let title_bar_layout = children.next().unwrap(); + + if title_bar.is_over_draggable(title_bar_layout, cursor_position) { + let position = layout.position(); + + Some(cursor_position - Vector::new(position.x, position.y)) + } else { + None + } + } else { + None + } } pub(crate) fn layout( @@ -115,14 +142,31 @@ where renderer: &Renderer, clipboard: Option<&dyn Clipboard>, ) { + let body_layout = if let Some(title_bar) = &mut self.title_bar { + let mut children = layout.children(); + + title_bar.on_event( + event.clone(), + children.next().unwrap(), + cursor_position, + messages, + renderer, + clipboard, + ); + + children.next().unwrap() + } else { + layout + }; + self.body.on_event( event, - layout, + body_layout, cursor_position, messages, renderer, clipboard, - ) + ); } pub(crate) fn hash_layout(&self, state: &mut Hasher) { -- cgit From 3cfe6e428be22fdbf715f1f28caec0c802fd069e Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 10 Jun 2020 16:27:28 +0200 Subject: Lay out title text dynamically in `TitleBar` --- native/src/widget/pane_grid/content.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'native/src/widget/pane_grid/content.rs') diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index 843dcec4..55fa4c60 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -6,7 +6,7 @@ use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size, Vector}; /// The content of a [`Pane`]. /// /// [`Pane`]: struct.Pane.html -pub struct Content<'a, Message, Renderer: container::Renderer> { +pub struct Content<'a, Message, Renderer: pane_grid::Renderer> { title_bar: Option>, body: Element<'a, Message, Renderer>, style: Renderer::Style, @@ -14,7 +14,7 @@ pub struct Content<'a, Message, Renderer: container::Renderer> { impl<'a, Message, Renderer> Content<'a, Message, Renderer> where - Renderer: container::Renderer, + Renderer: pane_grid::Renderer, { pub fn new(body: impl Into>) -> Self { Self { @@ -43,7 +43,7 @@ where impl<'a, Message, Renderer> Content<'a, Message, Renderer> where - Renderer: pane_grid::Renderer + container::Renderer, + Renderer: pane_grid::Renderer, { pub fn draw( &self, -- cgit From e3cd947437cad1a53715b77b63e6c7a348de97c5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 9 Jul 2020 05:26:11 +0200 Subject: Write documentation for new `PaneGrid` API --- native/src/widget/pane_grid/content.rs | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'native/src/widget/pane_grid/content.rs') diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index 55fa4c60..1f5ce640 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -1,11 +1,12 @@ use crate::container; use crate::layout; use crate::pane_grid::{self, TitleBar}; -use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size, Vector}; +use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size}; /// The content of a [`Pane`]. /// /// [`Pane`]: struct.Pane.html +#[allow(missing_debug_implementations)] pub struct Content<'a, Message, Renderer: pane_grid::Renderer> { title_bar: Option>, body: Element<'a, Message, Renderer>, @@ -16,6 +17,9 @@ impl<'a, Message, Renderer> Content<'a, Message, Renderer> where Renderer: pane_grid::Renderer, { + /// Creates a new [`Content`] with the provided body. + /// + /// [`Content`]: struct.Content.html pub fn new(body: impl Into>) -> Self { Self { title_bar: None, @@ -24,6 +28,10 @@ where } } + /// Sets the [`TitleBar`] of this [`Content`]. + /// + /// [`TitleBar`]: struct.TitleBar.html + /// [`Content`]: struct.Content.html pub fn title_bar( mut self, title_bar: TitleBar<'a, Message, Renderer>, @@ -45,6 +53,11 @@ impl<'a, Message, Renderer> Content<'a, Message, Renderer> where Renderer: pane_grid::Renderer, { + /// Draws the [`Content`] with the provided [`Renderer`] and [`Layout`]. + /// + /// [`Content`]: struct.Content.html + /// [`Renderer`]: trait.Renderer.html + /// [`Layout`]: ../layout/struct.Layout.html pub fn draw( &self, renderer: &mut Renderer, @@ -77,24 +90,23 @@ where } } - pub fn drag_origin( + /// Returns whether the [`Content`] with the given [`Layout`] can be picked + /// at the provided cursor position. + /// + /// [`Content`]: struct.Content.html + /// [`Layout`]: ../layout/struct.Layout.html + pub fn can_be_picked_at( &self, layout: Layout<'_>, cursor_position: Point, - ) -> Option { + ) -> bool { if let Some(title_bar) = &self.title_bar { let mut children = layout.children(); let title_bar_layout = children.next().unwrap(); - if title_bar.is_over_draggable(title_bar_layout, cursor_position) { - let position = layout.position(); - - Some(cursor_position - Vector::new(position.x, position.y)) - } else { - None - } + title_bar.is_over_pick_area(title_bar_layout, cursor_position) } else { - None + false } } -- cgit