Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic Element Content in Pane Grid TitleBar #657

Merged
merged 4 commits into from
Dec 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions examples/pane_grid/src/main.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -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)
Expand All @@ -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<Message> {
use keyboard::KeyCode;
use pane_grid::{Axis, Direction};
Expand Down
33 changes: 11 additions & 22 deletions graphics/src/widget/pane_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,11 @@
//! 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::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,
Expand All @@ -34,7 +29,7 @@ pub type PaneGrid<'a, Message, Backend> =

impl<B> pane_grid::Renderer for Renderer<B>
where
B: Backend + backend::Text,
B: Backend,
{
fn draw<Message>(
&mut self,
Expand Down Expand Up @@ -188,14 +183,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 {
Expand All @@ -205,16 +198,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 {
Expand All @@ -234,7 +223,7 @@ where
controls_primitive,
],
},
controls_interaction,
controls_interaction.max(title_interaction),
)
} else {
(
Expand All @@ -245,7 +234,7 @@ where
} else {
title_primitive
},
mouse::Interaction::default(),
title_interaction,
)
}
}
Expand Down
5 changes: 1 addition & 4 deletions native/src/renderer/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
) {
Expand Down
14 changes: 4 additions & 10 deletions native/src/widget/pane_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -586,18 +583,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<Message>(
&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;
Expand Down
109 changes: 37 additions & 72 deletions native/src/widget/pane_grid/title_bar.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
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<u16>,
content: Element<'a, Message, Renderer>,
controls: Option<Element<'a, Message, Renderer>>,
padding: u16,
always_show_controls: bool,
Expand All @@ -20,24 +19,20 @@ impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer>
where
Renderer: pane_grid::Renderer,
{
/// Creates a new [`TitleBar`] with the given title.
pub fn new(title: impl Into<String>) -> Self {
/// Creates a new [`TitleBar`] with the given content.
pub fn new<E>(content: E) -> Self
where
E: Into<Element<'a, Message, Renderer>>,
{
Self {
title: title.into(),
title_size: None,
content: content.into(),
controls: None,
padding: 0,
always_show_controls: false,
style: Renderer::Style::default(),
}
}

/// 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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

Expand All @@ -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
Expand All @@ -196,24 +166,19 @@ 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(
Size::new(max_size.width, height),
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));
Expand Down