diff options
author | 2020-06-10 16:27:28 +0200 | |
---|---|---|
committer | 2020-06-10 16:27:28 +0200 | |
commit | 3cfe6e428be22fdbf715f1f28caec0c802fd069e (patch) | |
tree | 372809f6d7a150ed94c484aeca1cb92f076492af /native | |
parent | ac7816e8caa1f4fea02fc740c6c84f4439206795 (diff) | |
download | iced-3cfe6e428be22fdbf715f1f28caec0c802fd069e.tar.gz iced-3cfe6e428be22fdbf715f1f28caec0c802fd069e.tar.bz2 iced-3cfe6e428be22fdbf715f1f28caec0c802fd069e.zip |
Lay out title text dynamically in `TitleBar`
Diffstat (limited to 'native')
-rw-r--r-- | native/src/renderer/null.rs | 48 | ||||
-rw-r--r-- | native/src/widget/pane_grid.rs | 17 | ||||
-rw-r--r-- | native/src/widget/pane_grid/content.rs | 6 | ||||
-rw-r--r-- | native/src/widget/pane_grid/title_bar.rs | 90 |
4 files changed, 121 insertions, 40 deletions
diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index 29df3e14..d6a8e18f 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -1,7 +1,8 @@ use crate::{ - button, checkbox, column, container, progress_bar, radio, row, scrollable, - slider, text, text_input, Color, Element, Font, HorizontalAlignment, - Layout, Point, Rectangle, Renderer, Size, VerticalAlignment, + button, checkbox, column, container, pane_grid, progress_bar, radio, row, + scrollable, slider, text, text_input, Color, Element, Font, + HorizontalAlignment, Layout, Point, Rectangle, Renderer, Size, + VerticalAlignment, }; /// A renderer that does nothing. @@ -241,3 +242,44 @@ impl container::Renderer for Null { ) { } } + +impl pane_grid::Renderer for Null { + fn draw<Message>( + &mut self, + _defaults: &Self::Defaults, + _content: &[(pane_grid::Pane, pane_grid::Content<'_, Message, Self>)], + _dragging: Option<(pane_grid::Pane, Point)>, + _resizing: Option<pane_grid::Axis>, + _layout: Layout<'_>, + _cursor_position: Point, + ) { + } + + fn draw_pane<Message>( + &mut self, + _defaults: &Self::Defaults, + _bounds: Rectangle, + _style: &Self::Style, + _title_bar: Option<( + &pane_grid::TitleBar<'_, Message, Self>, + Layout<'_>, + )>, + _body: (&Element<'_, Message, Self>, Layout<'_>), + _cursor_position: Point, + ) { + } + + fn draw_title_bar<Message>( + &mut self, + _defaults: &Self::Defaults, + _bounds: Rectangle, + _style: &Self::Style, + _title: &str, + _title_size: u16, + _title_font: Self::Font, + _title_bounds: Rectangle, + _controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, + _cursor_position: Point, + ) { + } +} diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index 8fb6c20c..a3282ed7 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -29,8 +29,8 @@ pub use state::{Focus, State}; pub use title_bar::TitleBar; use crate::{ - container, keyboard, layout, mouse, row, Clipboard, Element, Event, Hasher, - Layout, Length, Point, Rectangle, Size, Widget, + container, keyboard, layout, mouse, row, text, Clipboard, Element, Event, + Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; /// A collection of panes distributed using either vertical or horizontal splits @@ -86,7 +86,7 @@ use crate::{ /// [`PaneGrid`]: struct.PaneGrid.html /// [`State`]: struct.State.html #[allow(missing_debug_implementations)] -pub struct PaneGrid<'a, Message, Renderer: container::Renderer> { +pub struct PaneGrid<'a, Message, Renderer: self::Renderer> { state: &'a mut state::Internal, pressed_modifiers: &'a mut keyboard::ModifiersState, elements: Vec<(Pane, Content<'a, Message, Renderer>)>, @@ -101,7 +101,7 @@ pub struct PaneGrid<'a, Message, Renderer: container::Renderer> { impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> where - Renderer: container::Renderer, + Renderer: self::Renderer, { /// Creates a [`PaneGrid`] with the given [`State`] and view function. /// @@ -646,7 +646,9 @@ where /// /// [`PaneGrid`]: struct.PaneGrid.html /// [renderer]: ../../renderer/index.html -pub trait Renderer: crate::Renderer + container::Renderer + Sized { +pub trait Renderer: + crate::Renderer + container::Renderer + text::Renderer + Sized +{ /// Draws a [`PaneGrid`]. /// /// It receives: @@ -694,7 +696,10 @@ pub trait Renderer: crate::Renderer + container::Renderer + Sized { defaults: &Self::Defaults, bounds: Rectangle, style: &Self::Style, - title: (&Element<'_, Message, Self>, Layout<'_>), + title: &str, + title_size: u16, + title_font: Self::Font, + title_bounds: Rectangle, controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, cursor_position: Point, ) -> Self::Output; 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<TitleBar<'a, Message, Renderer>>, 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<Element<'a, Message, Renderer>>) -> 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, diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index dc96dcbf..bdf87c17 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -1,10 +1,10 @@ -use crate::container; use crate::layout; use crate::pane_grid; -use crate::{Clipboard, Element, Event, Layout, Point, Size}; +use crate::{Clipboard, Element, Event, Layout, Point, Rectangle, Size}; -pub struct TitleBar<'a, Message, Renderer: container::Renderer> { - title: Element<'a, Message, Renderer>, +pub struct TitleBar<'a, Message, Renderer: pane_grid::Renderer> { + title: String, + title_size: Option<u16>, controls: Option<Element<'a, Message, Renderer>>, padding: u16, style: Renderer::Style, @@ -12,17 +12,29 @@ pub struct TitleBar<'a, Message, Renderer: container::Renderer> { impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer> where - Renderer: container::Renderer, + Renderer: pane_grid::Renderer, { - pub fn new(title: impl Into<Element<'a, Message, Renderer>>) -> Self { + pub fn new(title: impl Into<String>) -> Self { Self { title: title.into(), + title_size: None, controls: None, padding: 0, style: Renderer::Style::default(), } } + /// Sets the size of the title of the [`TitleBar`]. + /// + /// [`TitleBar`]: struct.Text.html + pub fn title_size(mut self, size: u16) -> Self { + self.title_size = Some(size); + self + } + + /// Sets the controls of the [`TitleBar`]. + /// + /// [`TitleBar`]: struct.TitleBar.html pub fn controls( mut self, controls: impl Into<Element<'a, Message, Renderer>>, @@ -68,24 +80,38 @@ where let title_layout = children.next().unwrap(); let controls_layout = children.next().unwrap(); + let (title_bounds, controls) = if show_controls { + (title_layout.bounds(), Some((controls, controls_layout))) + } else { + ( + Rectangle { + width: padded.bounds().width, + ..title_layout.bounds() + }, + None, + ) + }; + renderer.draw_title_bar( defaults, layout.bounds(), &self.style, - (&self.title, title_layout), - if show_controls { - Some((controls, controls_layout)) - } else { - None - }, + &self.title, + self.title_size.unwrap_or(Renderer::DEFAULT_SIZE), + Renderer::Font::default(), + title_bounds, + controls, cursor_position, ) } else { - renderer.draw_title_bar( + renderer.draw_title_bar::<()>( defaults, layout.bounds(), &self.style, - (&self.title, padded), + &self.title, + self.title_size.unwrap_or(Renderer::DEFAULT_SIZE), + Renderer::Font::default(), + padded.bounds(), None, cursor_position, ) @@ -122,39 +148,47 @@ where ) -> layout::Node { let padding = f32::from(self.padding); let limits = limits.pad(padding); + let max_size = limits.max(); - let node = if let Some(controls) = &self.controls { - let max_size = limits.max(); + let title_size = self.title_size.unwrap_or(Renderer::DEFAULT_SIZE); + let title_font = Renderer::Font::default(); + let (title_width, title_height) = renderer.measure( + &self.title, + title_size, + title_font, + Size::new(f32::INFINITY, max_size.height), + ); + + let mut node = if let Some(controls) = &self.controls { let mut controls_layout = controls .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 mut title_layout = self.title.layout( - renderer, - &layout::Limits::new( - Size::ZERO, - Size::new(space_before_controls, max_size.height), - ), - ); - - title_layout.move_to(Point::new(padding, padding)); - controls_layout - .move_to(Point::new(space_before_controls + padding, padding)); + let mut title_layout = layout::Node::new(Size::new( + title_width.min(space_before_controls), + title_height, + )); let title_size = title_layout.size(); let height = title_size.height.max(controls_size.height); + title_layout + .move_to(Point::new(0.0, (height - title_size.height) / 2.0)); + 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 { - self.title.layout(renderer, &limits) + layout::Node::new(Size::new(title_width, title_height)) }; + node.move_to(Point::new(padding, padding)); + layout::Node::with_children(node.size().pad(padding), vec![node]) } |