Merge pull request #2228 from jhannyj/better-tooltips

Refactor tooltip function to accept a generic element as a tooltip
This commit is contained in:
Héctor Ramón 2024-02-09 02:24:53 +01:00 committed by GitHub
commit 7a20c8640f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 21 additions and 40 deletions

View file

@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Dracula, Nord, Solarized, and Gruvbox variants for `Theme`. [#2170](https://github.com/iced-rs/iced/pull/2170) - Dracula, Nord, Solarized, and Gruvbox variants for `Theme`. [#2170](https://github.com/iced-rs/iced/pull/2170)
- `From<T> where T: Into<PathBuf>` for `svg::Handle`. [#2235](https://github.com/iced-rs/iced/pull/2235) - `From<T> where T: Into<PathBuf>` for `svg::Handle`. [#2235](https://github.com/iced-rs/iced/pull/2235)
- `on_open` and `on_close` handlers for `PickList`. [#2174](https://github.com/iced-rs/iced/pull/2174) - `on_open` and `on_close` handlers for `PickList`. [#2174](https://github.com/iced-rs/iced/pull/2174)
- Support for generic `Element` in `Tooltip`. [#2228](https://github.com/iced-rs/iced/pull/2228)
### Changed ### Changed
- Enable WebGPU backend in `wgpu` by default instead of WebGL. [#2068](https://github.com/iced-rs/iced/pull/2068) - Enable WebGPU backend in `wgpu` by default instead of WebGL. [#2068](https://github.com/iced-rs/iced/pull/2068)

View file

@ -123,20 +123,21 @@ where
Button::new(content) Button::new(content)
} }
/// Creates a new [`Tooltip`] with the provided content, tooltip text, and [`tooltip::Position`]. /// Creates a new [`Tooltip`] for the provided content with the given
/// [`Element`] and [`tooltip::Position`].
/// ///
/// [`Tooltip`]: crate::Tooltip /// [`Tooltip`]: crate::Tooltip
/// [`tooltip::Position`]: crate::tooltip::Position /// [`tooltip::Position`]: crate::tooltip::Position
pub fn tooltip<'a, Message, Theme, Renderer>( pub fn tooltip<'a, Message, Theme, Renderer>(
content: impl Into<Element<'a, Message, Theme, Renderer>>, content: impl Into<Element<'a, Message, Theme, Renderer>>,
tooltip: impl ToString, tooltip: impl Into<Element<'a, Message, Theme, Renderer>>,
position: tooltip::Position, position: tooltip::Position,
) -> crate::Tooltip<'a, Message, Theme, Renderer> ) -> crate::Tooltip<'a, Message, Theme, Renderer>
where where
Theme: container::StyleSheet + text::StyleSheet, Theme: container::StyleSheet + text::StyleSheet,
Renderer: core::text::Renderer, Renderer: core::text::Renderer,
{ {
Tooltip::new(content, tooltip.to_string(), position) Tooltip::new(content, tooltip, position)
} }
/// Creates a new [`Text`] widget with the provided content. /// Creates a new [`Text`] widget with the provided content.

View file

@ -11,9 +11,6 @@ use crate::core::{
Clipboard, Element, Length, Padding, Pixels, Point, Rectangle, Shell, Size, Clipboard, Element, Length, Padding, Pixels, Point, Rectangle, Shell, Size,
Vector, Vector,
}; };
use crate::Text;
use std::borrow::Cow;
/// An element to display a widget over another. /// An element to display a widget over another.
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
@ -27,7 +24,7 @@ pub struct Tooltip<
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
content: Element<'a, Message, Theme, Renderer>, content: Element<'a, Message, Theme, Renderer>,
tooltip: Text<'a, Theme, Renderer>, tooltip: Element<'a, Message, Theme, Renderer>,
position: Position, position: Position,
gap: f32, gap: f32,
padding: f32, padding: f32,
@ -48,12 +45,12 @@ where
/// [`Tooltip`]: struct.Tooltip.html /// [`Tooltip`]: struct.Tooltip.html
pub fn new( pub fn new(
content: impl Into<Element<'a, Message, Theme, Renderer>>, content: impl Into<Element<'a, Message, Theme, Renderer>>,
tooltip: impl Into<Cow<'a, str>>, tooltip: impl Into<Element<'a, Message, Theme, Renderer>>,
position: Position, position: Position,
) -> Self { ) -> Self {
Tooltip { Tooltip {
content: content.into(), content: content.into(),
tooltip: Text::new(tooltip), tooltip: tooltip.into(),
position, position,
gap: 0.0, gap: 0.0,
padding: Self::DEFAULT_PADDING, padding: Self::DEFAULT_PADDING,
@ -62,26 +59,6 @@ where
} }
} }
/// Sets the size of the text of the [`Tooltip`].
pub fn size(mut self, size: impl Into<Pixels>) -> Self {
self.tooltip = self.tooltip.size(size);
self
}
/// Sets the [`text::Shaping`] strategy of the [`Tooltip`].
pub fn text_shaping(mut self, shaping: text::Shaping) -> Self {
self.tooltip = self.tooltip.shaping(shaping);
self
}
/// Sets the font of the [`Tooltip`].
///
/// [`Font`]: Renderer::Font
pub fn font(mut self, font: impl Into<Renderer::Font>) -> Self {
self.tooltip = self.tooltip.font(font);
self
}
/// Sets the gap between the content and its [`Tooltip`]. /// Sets the gap between the content and its [`Tooltip`].
pub fn gap(mut self, gap: impl Into<Pixels>) -> Self { pub fn gap(mut self, gap: impl Into<Pixels>) -> Self {
self.gap = gap.into().0; self.gap = gap.into().0;
@ -119,12 +96,15 @@ where
fn children(&self) -> Vec<widget::Tree> { fn children(&self) -> Vec<widget::Tree> {
vec![ vec![
widget::Tree::new(&self.content), widget::Tree::new(&self.content),
widget::Tree::new(&self.tooltip as &dyn Widget<Message, _, _>), widget::Tree::new(&self.tooltip),
] ]
} }
fn diff(&self, tree: &mut widget::Tree) { fn diff(&self, tree: &mut widget::Tree) {
tree.diff_children(&[self.content.as_widget(), &self.tooltip]); tree.diff_children(&[
self.content.as_widget(),
self.tooltip.as_widget(),
]);
} }
fn state(&self) -> widget::tree::State { fn state(&self) -> widget::tree::State {
@ -312,13 +292,13 @@ enum State {
}, },
} }
struct Overlay<'a, 'b, Theme, Renderer> struct Overlay<'a, 'b, Message, Theme, Renderer>
where where
Theme: container::StyleSheet + widget::text::StyleSheet, Theme: container::StyleSheet + widget::text::StyleSheet,
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
position: Point, position: Point,
tooltip: &'b Text<'a, Theme, Renderer>, tooltip: &'b Element<'a, Message, Theme, Renderer>,
state: &'b mut widget::Tree, state: &'b mut widget::Tree,
cursor_position: Point, cursor_position: Point,
content_bounds: Rectangle, content_bounds: Rectangle,
@ -331,7 +311,7 @@ where
impl<'a, 'b, Message, Theme, Renderer> impl<'a, 'b, Message, Theme, Renderer>
overlay::Overlay<Message, Theme, Renderer> overlay::Overlay<Message, Theme, Renderer>
for Overlay<'a, 'b, Theme, Renderer> for Overlay<'a, 'b, Message, Theme, Renderer>
where where
Theme: container::StyleSheet + widget::text::StyleSheet, Theme: container::StyleSheet + widget::text::StyleSheet,
Renderer: text::Renderer, Renderer: text::Renderer,
@ -339,8 +319,7 @@ where
fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node { fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
let viewport = Rectangle::with_size(bounds); let viewport = Rectangle::with_size(bounds);
let text_layout = Widget::<(), Theme, Renderer>::layout( let tooltip_layout = self.tooltip.as_widget().layout(
self.tooltip,
self.state, self.state,
renderer, renderer,
&layout::Limits::new( &layout::Limits::new(
@ -352,7 +331,7 @@ where
.shrink(Padding::new(self.padding)), .shrink(Padding::new(self.padding)),
); );
let text_bounds = text_layout.bounds(); let text_bounds = tooltip_layout.bounds();
let x_center = self.position.x let x_center = self.position.x
+ (self.content_bounds.width - text_bounds.width) / 2.0; + (self.content_bounds.width - text_bounds.width) / 2.0;
let y_center = self.position.y let y_center = self.position.y
@ -429,7 +408,8 @@ where
layout::Node::with_children( layout::Node::with_children(
tooltip_bounds.size(), tooltip_bounds.size(),
vec![text_layout.translate(Vector::new(self.padding, self.padding))], vec![tooltip_layout
.translate(Vector::new(self.padding, self.padding))],
) )
.translate(Vector::new(tooltip_bounds.x, tooltip_bounds.y)) .translate(Vector::new(tooltip_bounds.x, tooltip_bounds.y))
} }
@ -450,8 +430,7 @@ where
text_color: style.text_color.unwrap_or(inherited_style.text_color), text_color: style.text_color.unwrap_or(inherited_style.text_color),
}; };
Widget::<(), Theme, Renderer>::draw( self.tooltip.as_widget().draw(
self.tooltip,
self.state, self.state,
renderer, renderer,
theme, theme,