From f54590d7adac611db84b88cbcbf4f56c7542039c Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Tue, 8 Dec 2020 18:47:01 -0600 Subject: [PATCH 1/4] Replace TitleBar string title with generic Content --- graphics/src/widget/pane_grid.rs | 28 ++---- native/src/renderer/null.rs | 5 +- native/src/widget/pane_grid.rs | 9 +- native/src/widget/pane_grid/title_bar.rs | 111 ++++++++--------------- 4 files changed, 51 insertions(+), 102 deletions(-) diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs index f09984fc76..b438023235 100644 --- a/graphics/src/widget/pane_grid.rs +++ b/graphics/src/widget/pane_grid.rs @@ -12,11 +12,7 @@ use crate::defaults; use crate::{Primitive, Renderer}; use iced_native::mouse; use iced_native::pane_grid; -use iced_native::text; -use iced_native::{ - Element, HorizontalAlignment, Layout, Point, Rectangle, Vector, - VerticalAlignment, -}; +use iced_native::{Element, Layout, Point, Rectangle, Vector}; pub use iced_native::pane_grid::{ Axis, Configuration, Content, Direction, DragEvent, Pane, ResizeEvent, @@ -188,14 +184,12 @@ where defaults: &Self::Defaults, bounds: Rectangle, style_sheet: &Self::Style, - title: &str, - title_size: u16, - title_font: Self::Font, - title_bounds: Rectangle, + content: (&Element<'_, Message, Self>, Layout<'_>), controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, cursor_position: Point, ) -> Self::Output { let style = style_sheet.style(); + let (title_content, title_layout) = content; let defaults = Self::Defaults { text: defaults::Text { @@ -205,16 +199,12 @@ where let background = crate::widget::container::background(bounds, &style); - let (title_primitive, _) = text::Renderer::draw( + let (title_primitive, title_interaction) = title_content.draw( self, &defaults, - title_bounds, - title, - title_size, - title_font, - None, - HorizontalAlignment::Left, - VerticalAlignment::Top, + title_layout, + cursor_position, + &bounds, ); if let Some((controls, controls_layout)) = controls { @@ -234,7 +224,7 @@ where controls_primitive, ], }, - controls_interaction, + controls_interaction.max(title_interaction), ) } else { ( @@ -245,7 +235,7 @@ where } else { title_primitive }, - mouse::Interaction::default(), + title_interaction, ) } } diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index 91ee9a2873..bea8041c09 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -276,10 +276,7 @@ impl pane_grid::Renderer for Null { _defaults: &Self::Defaults, _bounds: Rectangle, _style: &Self::Style, - _title: &str, - _title_size: u16, - _title_font: Self::Font, - _title_bounds: Rectangle, + _content: (&Element<'_, Message, Self>, Layout<'_>), _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 ff19cbc27e..85ef021f3c 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -586,18 +586,15 @@ pub trait Renderer: /// It receives: /// - the bounds, style of the [`TitleBar`] /// - the style of the [`TitleBar`] - /// - the title of the [`TitleBar`] with its size, font, and bounds - /// - the controls of the [`TitleBar`] with their [`Layout`+, if any + /// - the content of the [`TitleBar`] with its layout + /// - the controls of the [`TitleBar`] with their [`Layout`], if any /// - the cursor position fn draw_title_bar( &mut self, defaults: &Self::Defaults, bounds: Rectangle, style: &Self::Style, - title: &str, - title_size: u16, - title_font: Self::Font, - title_bounds: Rectangle, + content: (&Element<'_, Message, Self>, Layout<'_>), controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, cursor_position: Point, ) -> Self::Output; diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index 475cb9aec7..a73acff720 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -1,30 +1,31 @@ use crate::event::{self, Event}; use crate::layout; use crate::pane_grid; -use crate::{Clipboard, Element, Hasher, Layout, Point, Rectangle, Size}; +use crate::{Clipboard, Element, Hasher, Layout, Point, Size}; /// The title bar of a [`Pane`]. /// /// [`Pane`]: crate::widget::pane_grid::Pane #[allow(missing_debug_implementations)] pub struct TitleBar<'a, Message, Renderer: pane_grid::Renderer> { - title: String, - title_size: Option, + content: Element<'a, Message, Renderer>, controls: Option>, padding: u16, always_show_controls: bool, style: Renderer::Style, } -impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer> +impl<'a, Message, Renderer: 'a> TitleBar<'a, Message, Renderer> where Renderer: pane_grid::Renderer, { - /// Creates a new [`TitleBar`] with the given title. - pub fn new(title: impl Into) -> Self { + /// Creates a new [`TitleBar`] with the given content. + pub fn new(content: E) -> Self + where + E: Into>, + { Self { - title: title.into(), - title_size: None, + content: content.into(), controls: None, padding: 0, always_show_controls: false, @@ -32,12 +33,6 @@ where } } - /// Sets the size of the title of the [`TitleBar`]. - pub fn title_size(mut self, size: u16) -> Self { - self.title_size = Some(size); - self - } - /// Sets the controls of the [`TitleBar`]. pub fn controls( mut self, @@ -91,48 +86,29 @@ where let mut children = layout.children(); let padded = children.next().unwrap(); - if let Some(controls) = &self.controls { - let mut children = padded.children(); - let title_layout = children.next().unwrap(); + let mut children = padded.children(); + let title_layout = children.next().unwrap(); + + let controls = if let Some(controls) = &self.controls { let controls_layout = children.next().unwrap(); - let (title_bounds, controls) = - if show_controls || self.always_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, - self.title_size.unwrap_or(renderer.default_size()), - Renderer::Font::default(), - title_bounds, - controls, - cursor_position, - ) + if show_controls || self.always_show_controls { + Some((controls, controls_layout)) + } else { + None + } } else { - renderer.draw_title_bar::<()>( - defaults, - layout.bounds(), - &self.style, - &self.title, - self.title_size.unwrap_or(renderer.default_size()), - Renderer::Font::default(), - padded.bounds(), - None, - cursor_position, - ) - } + None + }; + + renderer.draw_title_bar( + defaults, + layout.bounds(), + &self.style, + (&self.content, title_layout), + controls, + cursor_position, + ) } /// Returns whether the mouse cursor is over the pick area of the @@ -165,8 +141,7 @@ where pub(crate) fn hash_layout(&self, hasher: &mut Hasher) { use std::hash::Hash; - self.title.hash(hasher); - self.title_size.hash(hasher); + self.content.hash_layout(hasher); self.padding.hash(hasher); } @@ -179,15 +154,10 @@ where let limits = limits.pad(padding); 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 title_layout = self + .content + .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 @@ -196,16 +166,8 @@ where let controls_size = controls_layout.size(); let space_before_controls = max_size.width - controls_size.width; - 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( @@ -213,7 +175,10 @@ where vec![title_layout, controls_layout], ) } else { - layout::Node::new(Size::new(max_size.width, title_height)) + layout::Node::with_children( + Size::new(max_size.width, title_size.height), + vec![title_layout], + ) }; node.move_to(Point::new(padding, padding)); From fb478a4014021d200a76c93d7f93f57371a843d8 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Tue, 8 Dec 2020 18:47:47 -0600 Subject: [PATCH 2/4] Update PaneGrid example with more complex TitleBar --- examples/pane_grid/src/main.rs | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index 3c3256cfb4..c44d24fde3 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -1,7 +1,7 @@ use iced::{ button, executor, keyboard, pane_grid, scrollable, Align, Application, - Button, Column, Command, Container, Element, HorizontalAlignment, Length, - PaneGrid, Scrollable, Settings, Subscription, Text, + Button, Color, Column, Command, Container, Element, HorizontalAlignment, + Length, PaneGrid, Row, Scrollable, Settings, Subscription, Text, }; use iced_native::{event, subscription, Event}; @@ -141,10 +141,21 @@ impl Application for Example { let pane_grid = PaneGrid::new(&mut self.panes, |pane, content| { let is_focused = focus == Some(pane); - let title_bar = - pane_grid::TitleBar::new(format!("Pane {}", content.id)) - .padding(10) - .style(style::TitleBar { is_focused }); + let title = Row::with_children(vec![ + Text::new("Pane").into(), + Text::new(content.id.to_string()) + .color(if is_focused { + PANE_ID_COLOR_FOCUSED + } else { + PANE_ID_COLOR_UNFOCUSED + }) + .into(), + ]) + .spacing(5); + + let title_bar = pane_grid::TitleBar::new(title) + .padding(10) + .style(style::TitleBar { is_focused }); pane_grid::Content::new(content.view(pane, total_panes)) .title_bar(title_bar) @@ -165,6 +176,17 @@ impl Application for Example { } } +const PANE_ID_COLOR_UNFOCUSED: Color = Color::from_rgb( + 0xFF as f32 / 255.0, + 0xC7 as f32 / 255.0, + 0xC7 as f32 / 255.0, +); +const PANE_ID_COLOR_FOCUSED: Color = Color::from_rgb( + 0xFF as f32 / 255.0, + 0x47 as f32 / 255.0, + 0x47 as f32 / 255.0, +); + fn handle_hotkey(key_code: keyboard::KeyCode) -> Option { use keyboard::KeyCode; use pane_grid::{Axis, Direction}; From f2c2f3fc7588054417a0c44d3890defa976c5f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 22 Dec 2020 14:44:44 +0100 Subject: [PATCH 3/4] Remove unnecessary `text::Renderer` bound for `PaneGrid` This is no longer necessary, as we do not render text directly anymore. --- graphics/src/widget/pane_grid.rs | 5 ++--- native/src/widget/pane_grid.rs | 5 +---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs index b438023235..294784472d 100644 --- a/graphics/src/widget/pane_grid.rs +++ b/graphics/src/widget/pane_grid.rs @@ -7,9 +7,8 @@ //! drag and drop, and hotkey support. //! //! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.2/examples/pane_grid -use crate::backend::{self, Backend}; use crate::defaults; -use crate::{Primitive, Renderer}; +use crate::{Backend, Primitive, Renderer}; use iced_native::mouse; use iced_native::pane_grid; use iced_native::{Element, Layout, Point, Rectangle, Vector}; @@ -30,7 +29,7 @@ pub type PaneGrid<'a, Message, Backend> = impl pane_grid::Renderer for Renderer where - B: Backend + backend::Text, + B: Backend, { fn draw( &mut self, diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index 85ef021f3c..9cf8bc341d 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -33,7 +33,6 @@ use crate::layout; use crate::mouse; use crate::overlay; use crate::row; -use crate::text; use crate::{ Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget, @@ -543,9 +542,7 @@ where /// able to use a [`PaneGrid`] in your user interface. /// /// [renderer]: crate::renderer -pub trait Renderer: - crate::Renderer + container::Renderer + text::Renderer + Sized -{ +pub trait Renderer: crate::Renderer + container::Renderer + Sized { /// Draws a [`PaneGrid`]. /// /// It receives: From e815c5bbd72f618ad890e1d3c5a67c811cd07108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 22 Dec 2020 14:47:18 +0100 Subject: [PATCH 4/4] Remove unnecessary lifetime bound in `TitleBar` --- native/src/widget/pane_grid/title_bar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index a73acff720..30e88e6f5c 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -15,7 +15,7 @@ pub struct TitleBar<'a, Message, Renderer: pane_grid::Renderer> { style: Renderer::Style, } -impl<'a, Message, Renderer: 'a> TitleBar<'a, Message, Renderer> +impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer> where Renderer: pane_grid::Renderer, {