Merge pull request #771 from hecrj/fix/tooltip-layering

Reposition `Tooltip` inside `viewport` bounds
This commit is contained in:
Héctor Ramón 2021-03-10 03:28:04 +01:00 committed by GitHub
commit 939fcfe9db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 44 deletions

View file

@ -45,6 +45,7 @@ where
layout: Layout<'_>, layout: Layout<'_>,
style_sheet: &<Self as pane_grid::Renderer>::Style, style_sheet: &<Self as pane_grid::Renderer>::Style,
cursor_position: Point, cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output { ) -> Self::Output {
let pane_cursor_position = if dragging.is_some() { let pane_cursor_position = if dragging.is_some() {
// TODO: Remove once cursor availability is encoded in the type // TODO: Remove once cursor availability is encoded in the type
@ -62,8 +63,13 @@ where
.zip(layout.children()) .zip(layout.children())
.enumerate() .enumerate()
.map(|(i, ((id, pane), layout))| { .map(|(i, ((id, pane), layout))| {
let (primitive, new_mouse_interaction) = let (primitive, new_mouse_interaction) = pane.draw(
pane.draw(self, defaults, layout, pane_cursor_position); self,
defaults,
layout,
pane_cursor_position,
viewport,
);
if new_mouse_interaction > mouse_interaction { if new_mouse_interaction > mouse_interaction {
mouse_interaction = new_mouse_interaction; mouse_interaction = new_mouse_interaction;
@ -180,12 +186,13 @@ where
title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>, title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>,
body: (&Element<'_, Message, Self>, Layout<'_>), body: (&Element<'_, Message, Self>, Layout<'_>),
cursor_position: Point, cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output { ) -> Self::Output {
let style = style_sheet.style(); let style = style_sheet.style();
let (body, body_layout) = body; let (body, body_layout) = body;
let (body_primitive, body_interaction) = let (body_primitive, body_interaction) =
body.draw(self, defaults, body_layout, cursor_position, &bounds); body.draw(self, defaults, body_layout, cursor_position, viewport);
let background = crate::widget::container::background(bounds, &style); let background = crate::widget::container::background(bounds, &style);
@ -199,6 +206,7 @@ where
defaults, defaults,
title_bar_layout, title_bar_layout,
cursor_position, cursor_position,
viewport,
show_controls, show_controls,
); );
@ -240,6 +248,7 @@ where
content: (&Element<'_, Message, Self>, Layout<'_>), content: (&Element<'_, Message, Self>, Layout<'_>),
controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>,
cursor_position: Point, cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output { ) -> Self::Output {
let style = style_sheet.style(); let style = style_sheet.style();
let (title_content, title_layout) = content; let (title_content, title_layout) = content;
@ -257,7 +266,7 @@ where
&defaults, &defaults,
title_layout, title_layout,
cursor_position, cursor_position,
&bounds, viewport,
); );
if let Some((controls, controls_layout)) = controls { if let Some((controls, controls_layout)) = controls {
@ -266,7 +275,7 @@ where
&defaults, &defaults,
controls_layout, controls_layout,
cursor_position, cursor_position,
&bounds, viewport,
); );
( (

View file

@ -58,60 +58,83 @@ where
}, },
}; };
let tooltip_layout = Widget::<(), Self>::layout( let text_layout = Widget::<(), Self>::layout(
tooltip, tooltip,
self, self,
&layout::Limits::new(Size::ZERO, viewport.size()) &layout::Limits::new(Size::ZERO, viewport.size())
.pad(f32::from(padding)), .pad(f32::from(padding)),
); );
let tooltip_bounds = tooltip_layout.bounds(); let text_bounds = text_layout.bounds();
let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0;
let x_center =
bounds.x + (bounds.width - tooltip_bounds.width) / 2.0;
let y_center = let y_center =
bounds.y + (bounds.height - tooltip_bounds.height) / 2.0; bounds.y + (bounds.height - text_bounds.height) / 2.0;
let offset = match position { let mut tooltip_bounds = {
Position::Top => Vector::new( let offset = match position {
x_center, Position::Top => Vector::new(
bounds.y - tooltip_bounds.height - gap - padding, x_center,
), bounds.y - text_bounds.height - gap - padding,
Position::Bottom => Vector::new( ),
x_center, Position::Bottom => Vector::new(
bounds.y + bounds.height + gap + padding, x_center,
), bounds.y + bounds.height + gap + padding,
Position::Left => Vector::new( ),
bounds.x - tooltip_bounds.width - gap - padding, Position::Left => Vector::new(
y_center, bounds.x - text_bounds.width - gap - padding,
), y_center,
Position::Right => Vector::new( ),
bounds.x + bounds.width + gap + padding, Position::Right => Vector::new(
y_center, bounds.x + bounds.width + gap + padding,
), y_center,
Position::FollowCursor => Vector::new( ),
cursor_position.x, Position::FollowCursor => Vector::new(
cursor_position.y - tooltip_bounds.height, cursor_position.x,
), cursor_position.y - text_bounds.height,
),
};
Rectangle {
x: offset.x - padding,
y: offset.y - padding,
width: text_bounds.width + padding * 2.0,
height: text_bounds.height + padding * 2.0,
}
}; };
if tooltip_bounds.x < viewport.x {
tooltip_bounds.x = viewport.x;
} else if viewport.x + viewport.width
< tooltip_bounds.x + tooltip_bounds.width
{
tooltip_bounds.x =
viewport.x + viewport.width - tooltip_bounds.width;
}
if tooltip_bounds.y < viewport.y {
tooltip_bounds.y = viewport.y;
} else if viewport.y + viewport.height
< tooltip_bounds.y + tooltip_bounds.height
{
tooltip_bounds.y =
viewport.y + viewport.height - tooltip_bounds.height;
}
let (tooltip, _) = Widget::<(), Self>::draw( let (tooltip, _) = Widget::<(), Self>::draw(
tooltip, tooltip,
self, self,
&defaults, &defaults,
Layout::with_offset(offset, &tooltip_layout), Layout::with_offset(
Vector::new(
tooltip_bounds.x + padding,
tooltip_bounds.y + padding,
),
&text_layout,
),
cursor_position, cursor_position,
viewport, viewport,
); );
let tooltip_bounds = Rectangle {
x: offset.x - padding,
y: offset.y - padding,
width: tooltip_bounds.width + padding * 2.0,
height: tooltip_bounds.height + padding * 2.0,
};
( (
Primitive::Group { Primitive::Group {
primitives: vec![ primitives: vec![

View file

@ -257,6 +257,7 @@ impl pane_grid::Renderer for Null {
_layout: Layout<'_>, _layout: Layout<'_>,
_style: &<Self as pane_grid::Renderer>::Style, _style: &<Self as pane_grid::Renderer>::Style,
_cursor_position: Point, _cursor_position: Point,
_viewport: &Rectangle,
) { ) {
} }
@ -271,6 +272,7 @@ impl pane_grid::Renderer for Null {
)>, )>,
_body: (&Element<'_, Message, Self>, Layout<'_>), _body: (&Element<'_, Message, Self>, Layout<'_>),
_cursor_position: Point, _cursor_position: Point,
_viewport: &Rectangle,
) { ) {
} }
@ -282,6 +284,7 @@ impl pane_grid::Renderer for Null {
_content: (&Element<'_, Message, Self>, Layout<'_>), _content: (&Element<'_, Message, Self>, Layout<'_>),
_controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, _controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>,
_cursor_position: Point, _cursor_position: Point,
_viewport: &Rectangle,
) { ) {
} }
} }

View file

@ -478,7 +478,7 @@ where
defaults: &Renderer::Defaults, defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
_viewport: &Rectangle, viewport: &Rectangle,
) -> Renderer::Output { ) -> Renderer::Output {
let picked_split = self let picked_split = self
.state .state
@ -537,6 +537,7 @@ where
layout, layout,
&self.style, &self.style,
cursor_position, cursor_position,
viewport,
) )
} }
@ -594,6 +595,7 @@ pub trait Renderer: crate::Renderer + container::Renderer + Sized {
layout: Layout<'_>, layout: Layout<'_>,
style: &<Self as self::Renderer>::Style, style: &<Self as self::Renderer>::Style,
cursor_position: Point, cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output; ) -> Self::Output;
/// Draws a [`Pane`]. /// Draws a [`Pane`].
@ -611,6 +613,7 @@ pub trait Renderer: crate::Renderer + container::Renderer + Sized {
title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>, title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>,
body: (&Element<'_, Message, Self>, Layout<'_>), body: (&Element<'_, Message, Self>, Layout<'_>),
cursor_position: Point, cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output; ) -> Self::Output;
/// Draws a [`TitleBar`]. /// Draws a [`TitleBar`].
@ -629,6 +632,7 @@ pub trait Renderer: crate::Renderer + container::Renderer + Sized {
content: (&Element<'_, Message, Self>, Layout<'_>), content: (&Element<'_, Message, Self>, Layout<'_>),
controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>, controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>,
cursor_position: Point, cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output; ) -> Self::Output;
} }

View file

@ -3,7 +3,7 @@ use crate::event::{self, Event};
use crate::layout; use crate::layout;
use crate::overlay; use crate::overlay;
use crate::pane_grid::{self, TitleBar}; use crate::pane_grid::{self, TitleBar};
use crate::{Clipboard, Element, Hasher, Layout, Point, Size}; use crate::{Clipboard, Element, Hasher, Layout, Point, Rectangle, Size};
/// The content of a [`Pane`]. /// The content of a [`Pane`].
/// ///
@ -60,6 +60,7 @@ where
defaults: &Renderer::Defaults, defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
viewport: &Rectangle,
) -> Renderer::Output { ) -> Renderer::Output {
if let Some(title_bar) = &self.title_bar { if let Some(title_bar) = &self.title_bar {
let mut children = layout.children(); let mut children = layout.children();
@ -73,6 +74,7 @@ where
Some((title_bar, title_bar_layout)), Some((title_bar, title_bar_layout)),
(&self.body, body_layout), (&self.body, body_layout),
cursor_position, cursor_position,
viewport,
) )
} else { } else {
renderer.draw_pane( renderer.draw_pane(
@ -82,6 +84,7 @@ where
None, None,
(&self.body, layout), (&self.body, layout),
cursor_position, cursor_position,
viewport,
) )
} }
} }

View file

@ -2,7 +2,7 @@ use crate::container;
use crate::event::{self, Event}; use crate::event::{self, Event};
use crate::layout; use crate::layout;
use crate::pane_grid; use crate::pane_grid;
use crate::{Clipboard, Element, Hasher, Layout, Point, Size}; use crate::{Clipboard, Element, Hasher, Layout, Point, Rectangle, Size};
/// The title bar of a [`Pane`]. /// The title bar of a [`Pane`].
/// ///
@ -85,6 +85,7 @@ where
defaults: &Renderer::Defaults, defaults: &Renderer::Defaults,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
viewport: &Rectangle,
show_controls: bool, show_controls: bool,
) -> Renderer::Output { ) -> Renderer::Output {
let mut children = layout.children(); let mut children = layout.children();
@ -112,6 +113,7 @@ where
(&self.content, title_layout), (&self.content, title_layout),
controls, controls,
cursor_position, cursor_position,
viewport,
) )
} }