diff options
author | 2023-03-04 05:37:11 +0100 | |
---|---|---|
committer | 2023-03-04 05:37:11 +0100 | |
commit | 3a0d34c0240f4421737a6a08761f99d6f8140d02 (patch) | |
tree | c9a4a6b8e9c1db1b8fcd05bc98e3f131d5ef4bd5 /native/src/widget/tooltip.rs | |
parent | c54409d1711e1f615c7ea4b02c082954e340632a (diff) | |
download | iced-3a0d34c0240f4421737a6a08761f99d6f8140d02.tar.gz iced-3a0d34c0240f4421737a6a08761f99d6f8140d02.tar.bz2 iced-3a0d34c0240f4421737a6a08761f99d6f8140d02.zip |
Create `iced_widget` subcrate and re-organize the whole codebase
Diffstat (limited to 'native/src/widget/tooltip.rs')
-rw-r--r-- | native/src/widget/tooltip.rs | 387 |
1 files changed, 0 insertions, 387 deletions
diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs deleted file mode 100644 index 2a24c055..00000000 --- a/native/src/widget/tooltip.rs +++ /dev/null @@ -1,387 +0,0 @@ -//! Display a widget over another. -use crate::event; -use crate::layout; -use crate::mouse; -use crate::renderer; -use crate::text; -use crate::widget; -use crate::widget::container; -use crate::widget::overlay; -use crate::widget::{Text, Tree}; -use crate::{ - Clipboard, Element, Event, Layout, Length, Padding, Pixels, Point, - Rectangle, Shell, Size, Vector, Widget, -}; - -use std::borrow::Cow; - -/// An element to display a widget over another. -#[allow(missing_debug_implementations)] -pub struct Tooltip<'a, Message, Renderer: text::Renderer> -where - Renderer: text::Renderer, - Renderer::Theme: container::StyleSheet + widget::text::StyleSheet, -{ - content: Element<'a, Message, Renderer>, - tooltip: Text<'a, Renderer>, - position: Position, - gap: f32, - padding: f32, - snap_within_viewport: bool, - style: <Renderer::Theme as container::StyleSheet>::Style, -} - -impl<'a, Message, Renderer> Tooltip<'a, Message, Renderer> -where - Renderer: text::Renderer, - Renderer::Theme: container::StyleSheet + widget::text::StyleSheet, -{ - /// The default padding of a [`Tooltip`] drawn by this renderer. - const DEFAULT_PADDING: f32 = 5.0; - - /// Creates a new [`Tooltip`]. - /// - /// [`Tooltip`]: struct.Tooltip.html - pub fn new( - content: impl Into<Element<'a, Message, Renderer>>, - tooltip: impl Into<Cow<'a, str>>, - position: Position, - ) -> Self { - Tooltip { - content: content.into(), - tooltip: Text::new(tooltip), - position, - gap: 0.0, - padding: Self::DEFAULT_PADDING, - snap_within_viewport: true, - style: Default::default(), - } - } - - /// 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 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: impl Into<Pixels>) -> Self { - self.gap = gap.into().0; - self - } - - /// Sets the padding of the [`Tooltip`]. - pub fn padding(mut self, padding: impl Into<Pixels>) -> Self { - self.padding = padding.into().0; - self - } - - /// Sets whether the [`Tooltip`] is snapped within the viewport. - pub fn snap_within_viewport(mut self, snap: bool) -> Self { - self.snap_within_viewport = snap; - self - } - - /// Sets the style of the [`Tooltip`]. - pub fn style( - mut self, - style: impl Into<<Renderer::Theme as container::StyleSheet>::Style>, - ) -> Self { - self.style = style.into(); - self - } -} - -impl<'a, Message, Renderer> Widget<Message, Renderer> - for Tooltip<'a, Message, Renderer> -where - Renderer: text::Renderer, - Renderer::Theme: container::StyleSheet + widget::text::StyleSheet, -{ - fn children(&self) -> Vec<Tree> { - vec![Tree::new(&self.content)] - } - - fn diff(&self, tree: &mut Tree) { - tree.diff_children(std::slice::from_ref(&self.content)) - } - - fn width(&self) -> Length { - self.content.as_widget().width() - } - - fn height(&self) -> Length { - self.content.as_widget().height() - } - - fn layout( - &self, - renderer: &Renderer, - limits: &layout::Limits, - ) -> layout::Node { - self.content.as_widget().layout(renderer, limits) - } - - fn on_event( - &mut self, - tree: &mut Tree, - event: Event, - layout: Layout<'_>, - cursor_position: Point, - renderer: &Renderer, - clipboard: &mut dyn Clipboard, - shell: &mut Shell<'_, Message>, - ) -> event::Status { - self.content.as_widget_mut().on_event( - &mut tree.children[0], - event, - layout, - cursor_position, - renderer, - clipboard, - shell, - ) - } - - fn mouse_interaction( - &self, - tree: &Tree, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - renderer: &Renderer, - ) -> mouse::Interaction { - self.content.as_widget().mouse_interaction( - &tree.children[0], - layout, - cursor_position, - viewport, - renderer, - ) - } - - fn draw( - &self, - tree: &Tree, - renderer: &mut Renderer, - theme: &Renderer::Theme, - inherited_style: &renderer::Style, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) { - self.content.as_widget().draw( - &tree.children[0], - renderer, - theme, - inherited_style, - layout, - cursor_position, - viewport, - ); - - let tooltip = &self.tooltip; - - draw( - renderer, - theme, - inherited_style, - layout, - cursor_position, - viewport, - self.position, - self.gap, - self.padding, - self.snap_within_viewport, - &self.style, - |renderer, limits| { - Widget::<(), Renderer>::layout(tooltip, renderer, limits) - }, - |renderer, defaults, layout, cursor_position, viewport| { - Widget::<(), Renderer>::draw( - tooltip, - &Tree::empty(), - renderer, - theme, - defaults, - layout, - cursor_position, - viewport, - ); - }, - ); - } - - fn overlay<'b>( - &'b mut self, - tree: &'b mut Tree, - layout: Layout<'_>, - renderer: &Renderer, - ) -> Option<overlay::Element<'b, Message, Renderer>> { - self.content.as_widget_mut().overlay( - &mut tree.children[0], - layout, - renderer, - ) - } -} - -impl<'a, Message, Renderer> From<Tooltip<'a, Message, Renderer>> - for Element<'a, Message, Renderer> -where - Message: 'a, - Renderer: 'a + text::Renderer, - Renderer::Theme: container::StyleSheet + widget::text::StyleSheet, -{ - fn from( - tooltip: Tooltip<'a, Message, Renderer>, - ) -> Element<'a, Message, Renderer> { - Element::new(tooltip) - } -} - -/// 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, -} - -/// Draws a [`Tooltip`]. -pub fn draw<Renderer>( - renderer: &mut Renderer, - theme: &Renderer::Theme, - inherited_style: &renderer::Style, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - position: Position, - gap: f32, - padding: f32, - snap_within_viewport: bool, - style: &<Renderer::Theme as container::StyleSheet>::Style, - layout_text: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node, - draw_text: impl FnOnce( - &mut Renderer, - &renderer::Style, - Layout<'_>, - Point, - &Rectangle, - ), -) where - Renderer: crate::Renderer, - Renderer::Theme: container::StyleSheet, -{ - use container::StyleSheet; - - let bounds = layout.bounds(); - - if bounds.contains(cursor_position) { - let style = theme.appearance(style); - - let defaults = renderer::Style { - text_color: style.text_color.unwrap_or(inherited_style.text_color), - }; - - let text_layout = layout_text( - renderer, - &layout::Limits::new( - Size::ZERO, - snap_within_viewport - .then(|| viewport.size()) - .unwrap_or(Size::INFINITY), - ) - .pad(Padding::new(padding)), - ); - - let text_bounds = text_layout.bounds(); - let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0; - let y_center = bounds.y + (bounds.height - text_bounds.height) / 2.0; - - let mut tooltip_bounds = { - let offset = match position { - Position::Top => Vector::new( - x_center, - bounds.y - text_bounds.height - gap - padding, - ), - Position::Bottom => Vector::new( - x_center, - bounds.y + bounds.height + gap + padding, - ), - Position::Left => Vector::new( - bounds.x - text_bounds.width - gap - padding, - y_center, - ), - Position::Right => Vector::new( - bounds.x + bounds.width + gap + padding, - y_center, - ), - Position::FollowCursor => Vector::new( - 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 snap_within_viewport { - 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; - } - } - - renderer.with_layer(Rectangle::with_size(Size::INFINITY), |renderer| { - container::draw_background(renderer, &style, tooltip_bounds); - - draw_text( - renderer, - &defaults, - Layout::with_offset( - Vector::new( - tooltip_bounds.x + padding, - tooltip_bounds.y + padding, - ), - &text_layout, - ), - cursor_position, - viewport, - ) - }); - } -} |