diff options
| author | 2021-02-24 01:42:08 +0100 | |
|---|---|---|
| committer | 2021-02-24 01:42:08 +0100 | |
| commit | a5fddf9ee648927b294ef34e8819855d5e117b26 (patch) | |
| tree | 96f5454cdb07249beefdb0b804de3b10f5ff6cb6 /native | |
| parent | 6759a5c56fc53286d77698ac9a86812b6d7b03ff (diff) | |
| parent | 2736e4ca35f17a92768f0be682acf6da3b574cb6 (diff) | |
| download | iced-a5fddf9ee648927b294ef34e8819855d5e117b26.tar.gz iced-a5fddf9ee648927b294ef34e8819855d5e117b26.tar.bz2 iced-a5fddf9ee648927b294ef34e8819855d5e117b26.zip | |
Merge pull request #465 from yusdacra/tooltip-widget
Tooltip widget
Diffstat (limited to '')
| -rw-r--r-- | native/src/layout.rs | 7 | ||||
| -rw-r--r-- | native/src/widget.rs | 3 | ||||
| -rw-r--r-- | native/src/widget/tooltip.rs | 210 | 
3 files changed, 218 insertions, 2 deletions
| diff --git a/native/src/layout.rs b/native/src/layout.rs index 6d144902..b4b4a021 100644 --- a/native/src/layout.rs +++ b/native/src/layout.rs @@ -19,11 +19,14 @@ pub struct Layout<'a> {  }  impl<'a> Layout<'a> { -    pub(crate) fn new(node: &'a Node) -> Self { +    /// Creates a new [`Layout`] for the given [`Node`] at the origin. +    pub fn new(node: &'a Node) -> Self {          Self::with_offset(Vector::new(0.0, 0.0), node)      } -    pub(crate) fn with_offset(offset: Vector, node: &'a Node) -> Self { +    /// Creates a new [`Layout`] for the given [`Node`] with the provided offset +    /// from the origin. +    pub fn with_offset(offset: Vector, node: &'a Node) -> Self {          let bounds = node.bounds();          Self { diff --git a/native/src/widget.rs b/native/src/widget.rs index 3677713a..d5c353df 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -36,6 +36,7 @@ pub mod space;  pub mod svg;  pub mod text;  pub mod text_input; +pub mod tooltip;  #[doc(no_inline)]  pub use button::Button; @@ -71,6 +72,8 @@ pub use svg::Svg;  pub use text::Text;  #[doc(no_inline)]  pub use text_input::TextInput; +#[doc(no_inline)] +pub use tooltip::Tooltip;  use crate::event::{self, Event};  use crate::layout; diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs new file mode 100644 index 00000000..ab07868c --- /dev/null +++ b/native/src/widget/tooltip.rs @@ -0,0 +1,210 @@ +//! Display a widget over another. +use std::hash::Hash; + +use iced_core::Rectangle; + +use crate::widget::container; +use crate::widget::text::{self, Text}; +use crate::{ +    event, layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, +    Widget, +}; + +/// An element to display a widget over another. +#[allow(missing_debug_implementations)] +pub struct Tooltip<'a, Message, Renderer: self::Renderer> { +    content: Element<'a, Message, Renderer>, +    tooltip: Text<Renderer>, +    position: Position, +    style: <Renderer as container::Renderer>::Style, +    gap: u16, +    padding: u16, +} + +impl<'a, Message, Renderer> Tooltip<'a, Message, Renderer> +where +    Renderer: self::Renderer, +{ +    /// Creates an empty [`Tooltip`]. +    /// +    /// [`Tooltip`]: struct.Tooltip.html +    pub fn new( +        content: impl Into<Element<'a, Message, Renderer>>, +        tooltip: impl ToString, +        position: Position, +    ) -> Self { +        Tooltip { +            content: content.into(), +            tooltip: Text::new(tooltip.to_string()), +            position, +            style: Default::default(), +            gap: 0, +            padding: Renderer::DEFAULT_PADDING, +        } +    } + +    /// Sets the size of the text of the [`Tooltip`]. +    pub fn size(mut self, size: u16) -> Self { +        self.tooltip = self.tooltip.size(size); +        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`]. +    pub fn gap(mut self, gap: u16) -> Self { +        self.gap = gap; +        self +    } + +    /// Sets the padding of the [`Tooltip`]. +    pub fn padding(mut self, padding: u16) -> Self { +        self.padding = padding; +        self +    } + +    /// 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 +    } +} + +/// The position of the tooltip. Defaults to following the cursor. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Position { +    /// The tooltip will follow the cursor. +    FollowCursor, +    /// The tooltip will appear on the top of the widget. +    Top, +    /// The tooltip will appear on the bottom of the widget. +    Bottom, +    /// The tooltip will appear on the left of the widget. +    Left, +    /// The tooltip will appear on the right of the widget. +    Right, +} + +impl<'a, Message, Renderer> Widget<Message, Renderer> +    for Tooltip<'a, Message, Renderer> +where +    Renderer: self::Renderer, +{ +    fn width(&self) -> Length { +        self.content.width() +    } + +    fn height(&self) -> Length { +        self.content.height() +    } + +    fn layout( +        &self, +        renderer: &Renderer, +        limits: &layout::Limits, +    ) -> layout::Node { +        self.content.layout(renderer, limits) +    } + +    fn on_event( +        &mut self, +        event: Event, +        layout: Layout<'_>, +        cursor_position: Point, +        messages: &mut Vec<Message>, +        renderer: &Renderer, +        clipboard: Option<&dyn Clipboard>, +    ) -> event::Status { +        self.content.widget.on_event( +            event, +            layout, +            cursor_position, +            messages, +            renderer, +            clipboard, +        ) +    } + +    fn draw( +        &self, +        renderer: &mut Renderer, +        defaults: &Renderer::Defaults, +        layout: Layout<'_>, +        cursor_position: Point, +        viewport: &Rectangle, +    ) -> Renderer::Output { +        self::Renderer::draw( +            renderer, +            defaults, +            cursor_position, +            layout, +            viewport, +            &self.content, +            &self.tooltip, +            self.position, +            &self.style, +            self.gap, +            self.padding, +        ) +    } + +    fn hash_layout(&self, state: &mut Hasher) { +        struct Marker; +        std::any::TypeId::of::<Marker>().hash(state); + +        self.content.hash_layout(state); +    } +} + +/// The renderer of a [`Tooltip`]. +/// +/// Your [renderer] will need to implement this trait before being +/// able to use a [`Tooltip`] in your user interface. +/// +/// [`Tooltip`]: struct.Tooltip.html +/// [renderer]: ../../renderer/index.html +pub trait Renderer: +    crate::Renderer + text::Renderer + container::Renderer +{ +    /// The default padding of a [`Tooltip`] drawn by this renderer. +    const DEFAULT_PADDING: u16; + +    /// Draws a [`Tooltip`]. +    /// +    /// [`Tooltip`]: struct.Tooltip.html +    fn draw<Message>( +        &mut self, +        defaults: &Self::Defaults, +        cursor_position: Point, +        content_layout: Layout<'_>, +        viewport: &Rectangle, +        content: &Element<'_, Message, Self>, +        tooltip: &Text<Self>, +        position: Position, +        style: &<Self as container::Renderer>::Style, +        gap: u16, +        padding: u16, +    ) -> Self::Output; +} + +impl<'a, Message, Renderer> From<Tooltip<'a, Message, Renderer>> +    for Element<'a, Message, Renderer> +where +    Renderer: 'a + self::Renderer, +    Message: 'a, +{ +    fn from( +        column: Tooltip<'a, Message, Renderer>, +    ) -> Element<'a, Message, Renderer> { +        Element::new(column) +    } +} | 
