Add style
and padding
to Tooltip
This commit is contained in:
parent
9d4996cbab
commit
4e923290cc
@ -114,5 +114,25 @@ fn tooltip<'a>(
|
|||||||
position,
|
position,
|
||||||
)
|
)
|
||||||
.gap(10)
|
.gap(10)
|
||||||
|
.padding(20)
|
||||||
|
.style(style::Tooltip)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod style {
|
||||||
|
use iced::container;
|
||||||
|
use iced::Color;
|
||||||
|
|
||||||
|
pub struct Tooltip;
|
||||||
|
|
||||||
|
impl container::StyleSheet for Tooltip {
|
||||||
|
fn style(&self) -> container::Style {
|
||||||
|
container::Style {
|
||||||
|
text_color: Some(Color::from_rgb8(0xEE, 0xEE, 0xEE)),
|
||||||
|
background: Some(Color::from_rgb(0.11, 0.42, 0.87).into()),
|
||||||
|
border_radius: 12.0,
|
||||||
|
..container::Style::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
//! Decorate content and apply alignment.
|
//! Decorate content and apply alignment.
|
||||||
use crate::backend::{self, Backend};
|
use crate::backend::{self, Backend};
|
||||||
use crate::defaults::Defaults;
|
use crate::defaults::{self, Defaults};
|
||||||
use crate::{Primitive, Renderer, Vector};
|
use crate::{Primitive, Renderer, Vector};
|
||||||
|
|
||||||
|
use iced_native::container;
|
||||||
use iced_native::layout::{self, Layout};
|
use iced_native::layout::{self, Layout};
|
||||||
use iced_native::{Element, Point, Rectangle, Size, Text};
|
use iced_native::{Element, Point, Rectangle, Size, Text};
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ impl<B> iced_native::tooltip::Renderer for Renderer<B>
|
|||||||
where
|
where
|
||||||
B: Backend + backend::Text,
|
B: Backend + backend::Text,
|
||||||
{
|
{
|
||||||
type Style = ();
|
const DEFAULT_PADDING: u16 = 5;
|
||||||
|
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -30,10 +31,10 @@ where
|
|||||||
content: &Element<'_, Message, Self>,
|
content: &Element<'_, Message, Self>,
|
||||||
tooltip: &Text<Self>,
|
tooltip: &Text<Self>,
|
||||||
position: Position,
|
position: Position,
|
||||||
|
style_sheet: &<Self as container::Renderer>::Style,
|
||||||
gap: u16,
|
gap: u16,
|
||||||
|
padding: u16,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let bounds = content_layout.bounds();
|
|
||||||
|
|
||||||
let (content, mouse_interaction) = content.draw(
|
let (content, mouse_interaction) = content.draw(
|
||||||
self,
|
self,
|
||||||
&defaults,
|
&defaults,
|
||||||
@ -42,13 +43,26 @@ where
|
|||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let bounds = content_layout.bounds();
|
||||||
|
|
||||||
if bounds.contains(cursor_position) {
|
if bounds.contains(cursor_position) {
|
||||||
use iced_native::Widget;
|
use iced_native::Widget;
|
||||||
|
|
||||||
|
let gap = f32::from(gap);
|
||||||
|
let padding = f32::from(padding);
|
||||||
|
let style = style_sheet.style();
|
||||||
|
|
||||||
|
let defaults = Defaults {
|
||||||
|
text: defaults::Text {
|
||||||
|
color: style.text_color.unwrap_or(defaults.text.color),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let tooltip_layout = Widget::<(), Self>::layout(
|
let tooltip_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)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let tooltip_bounds = tooltip_layout.bounds();
|
let tooltip_bounds = tooltip_layout.bounds();
|
||||||
@ -59,22 +73,23 @@ where
|
|||||||
let y_center =
|
let y_center =
|
||||||
bounds.y + (bounds.height - tooltip_bounds.height) / 2.0;
|
bounds.y + (bounds.height - tooltip_bounds.height) / 2.0;
|
||||||
|
|
||||||
let gap = f32::from(gap);
|
|
||||||
|
|
||||||
let offset = match position {
|
let offset = match position {
|
||||||
Position::Top => Vector::new(
|
Position::Top => Vector::new(
|
||||||
x_center,
|
x_center,
|
||||||
bounds.y - tooltip_bounds.height - gap,
|
bounds.y - tooltip_bounds.height - gap - padding,
|
||||||
|
),
|
||||||
|
Position::Bottom => Vector::new(
|
||||||
|
x_center,
|
||||||
|
bounds.y + bounds.height + gap + padding,
|
||||||
|
),
|
||||||
|
Position::Left => Vector::new(
|
||||||
|
bounds.x - tooltip_bounds.width - gap - padding,
|
||||||
|
y_center,
|
||||||
|
),
|
||||||
|
Position::Right => Vector::new(
|
||||||
|
bounds.x + bounds.width + gap + padding,
|
||||||
|
y_center,
|
||||||
),
|
),
|
||||||
Position::Bottom => {
|
|
||||||
Vector::new(x_center, bounds.y + bounds.height + gap)
|
|
||||||
}
|
|
||||||
Position::Left => {
|
|
||||||
Vector::new(bounds.x - tooltip_bounds.width - gap, y_center)
|
|
||||||
}
|
|
||||||
Position::Right => {
|
|
||||||
Vector::new(bounds.x + bounds.width + gap, y_center)
|
|
||||||
}
|
|
||||||
Position::FollowCursor => Vector::new(
|
Position::FollowCursor => Vector::new(
|
||||||
cursor_position.x,
|
cursor_position.x,
|
||||||
cursor_position.y - tooltip_bounds.height,
|
cursor_position.y - tooltip_bounds.height,
|
||||||
@ -84,19 +99,42 @@ where
|
|||||||
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(offset, &tooltip_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::Clip {
|
Primitive::Group {
|
||||||
bounds: *viewport,
|
primitives: vec![
|
||||||
offset: Vector::new(0, 0),
|
content,
|
||||||
content: Box::new(Primitive::Group {
|
Primitive::Clip {
|
||||||
primitives: vec![content, tooltip],
|
bounds: *viewport,
|
||||||
}),
|
offset: Vector::new(0, 0),
|
||||||
|
content: Box::new(
|
||||||
|
if let Some(background) =
|
||||||
|
crate::container::background(
|
||||||
|
tooltip_bounds,
|
||||||
|
&style,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Primitive::Group {
|
||||||
|
primitives: vec![background, tooltip],
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tooltip
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
mouse_interaction,
|
mouse_interaction,
|
||||||
)
|
)
|
||||||
|
@ -3,6 +3,7 @@ use std::hash::Hash;
|
|||||||
|
|
||||||
use iced_core::Rectangle;
|
use iced_core::Rectangle;
|
||||||
|
|
||||||
|
use crate::widget::container;
|
||||||
use crate::widget::text::{self, Text};
|
use crate::widget::text::{self, Text};
|
||||||
use crate::{
|
use crate::{
|
||||||
event, layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
|
event, layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
|
||||||
@ -11,16 +12,18 @@ use crate::{
|
|||||||
|
|
||||||
/// An element to display a widget over another.
|
/// An element to display a widget over another.
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct Tooltip<'a, Message, Renderer: self::Renderer + text::Renderer> {
|
pub struct Tooltip<'a, Message, Renderer: self::Renderer> {
|
||||||
content: Element<'a, Message, Renderer>,
|
content: Element<'a, Message, Renderer>,
|
||||||
tooltip: Text<Renderer>,
|
tooltip: Text<Renderer>,
|
||||||
position: Position,
|
position: Position,
|
||||||
|
style: <Renderer as container::Renderer>::Style,
|
||||||
gap: u16,
|
gap: u16,
|
||||||
|
padding: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> Tooltip<'a, Message, Renderer>
|
impl<'a, Message, Renderer> Tooltip<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer + text::Renderer,
|
Renderer: self::Renderer,
|
||||||
{
|
{
|
||||||
/// Creates an empty [`Tooltip`].
|
/// Creates an empty [`Tooltip`].
|
||||||
///
|
///
|
||||||
@ -34,15 +37,32 @@ where
|
|||||||
content: content.into(),
|
content: content.into(),
|
||||||
tooltip,
|
tooltip,
|
||||||
position,
|
position,
|
||||||
|
style: Default::default(),
|
||||||
gap: 0,
|
gap: 0,
|
||||||
|
padding: Renderer::DEFAULT_PADDING,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the style of the [`Tooltip`].
|
||||||
|
pub fn style(
|
||||||
|
mut self,
|
||||||
|
style: impl Into<<Renderer as container::Renderer>::Style>,
|
||||||
|
) -> Self {
|
||||||
|
self.style = style.into();
|
||||||
|
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: u16) -> Self {
|
pub fn gap(mut self, gap: u16) -> Self {
|
||||||
self.gap = gap;
|
self.gap = gap;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the padding of the [`Tooltip`].
|
||||||
|
pub fn padding(mut self, padding: u16) -> Self {
|
||||||
|
self.padding = padding;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The position of the tooltip. Defaults to following the cursor.
|
/// The position of the tooltip. Defaults to following the cursor.
|
||||||
@ -63,7 +83,7 @@ pub enum Position {
|
|||||||
impl<'a, Message, Renderer> Widget<Message, Renderer>
|
impl<'a, Message, Renderer> Widget<Message, Renderer>
|
||||||
for Tooltip<'a, Message, Renderer>
|
for Tooltip<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer + text::Renderer,
|
Renderer: self::Renderer,
|
||||||
{
|
{
|
||||||
fn width(&self) -> Length {
|
fn width(&self) -> Length {
|
||||||
self.content.width()
|
self.content.width()
|
||||||
@ -117,7 +137,9 @@ where
|
|||||||
&self.content,
|
&self.content,
|
||||||
&self.tooltip,
|
&self.tooltip,
|
||||||
self.position,
|
self.position,
|
||||||
|
&self.style,
|
||||||
self.gap,
|
self.gap,
|
||||||
|
self.padding,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,9 +158,11 @@ where
|
|||||||
///
|
///
|
||||||
/// [`Tooltip`]: struct.Tooltip.html
|
/// [`Tooltip`]: struct.Tooltip.html
|
||||||
/// [renderer]: ../../renderer/index.html
|
/// [renderer]: ../../renderer/index.html
|
||||||
pub trait Renderer: crate::Renderer + text::Renderer {
|
pub trait Renderer:
|
||||||
/// The style supported by this renderer.
|
crate::Renderer + text::Renderer + container::Renderer
|
||||||
type Style: Default;
|
{
|
||||||
|
/// The default padding of a [`Tooltip`] drawn by this renderer.
|
||||||
|
const DEFAULT_PADDING: u16;
|
||||||
|
|
||||||
/// Draws a [`Tooltip`].
|
/// Draws a [`Tooltip`].
|
||||||
///
|
///
|
||||||
@ -152,14 +176,16 @@ pub trait Renderer: crate::Renderer + text::Renderer {
|
|||||||
content: &Element<'_, Message, Self>,
|
content: &Element<'_, Message, Self>,
|
||||||
tooltip: &Text<Self>,
|
tooltip: &Text<Self>,
|
||||||
position: Position,
|
position: Position,
|
||||||
|
style: &<Self as container::Renderer>::Style,
|
||||||
gap: u16,
|
gap: u16,
|
||||||
|
padding: u16,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> From<Tooltip<'a, Message, Renderer>>
|
impl<'a, Message, Renderer> From<Tooltip<'a, Message, Renderer>>
|
||||||
for Element<'a, Message, Renderer>
|
for Element<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: 'a + self::Renderer + text::Renderer,
|
Renderer: 'a + self::Renderer,
|
||||||
Message: 'a,
|
Message: 'a,
|
||||||
{
|
{
|
||||||
fn from(
|
fn from(
|
||||||
|
Loading…
Reference in New Issue
Block a user