Merge branch 'master' into dev/system-information
This commit is contained in:
commit
27fdc70756
90 changed files with 1363 additions and 334 deletions
|
|
@ -11,6 +11,8 @@ use std::fmt;
|
|||
/// [`Command`]: crate::Command
|
||||
pub enum Action<T> {
|
||||
/// Run a [`Future`] to completion.
|
||||
///
|
||||
/// [`Future`]: iced_futures::BoxFuture
|
||||
Future(iced_futures::BoxFuture<T>),
|
||||
|
||||
/// Run a clipboard action.
|
||||
|
|
@ -25,6 +27,8 @@ pub enum Action<T> {
|
|||
|
||||
impl<T> Action<T> {
|
||||
/// Applies a transformation to the result of a [`Command`].
|
||||
///
|
||||
/// [`Command`]: crate::Command
|
||||
pub fn map<A>(
|
||||
self,
|
||||
f: impl Fn(T) -> A + 'static + MaybeSend + Sync,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::hash::{Hash, Hasher as _};
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// An [`Image`] handle.
|
||||
/// A handle of some image data.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Handle {
|
||||
id: u64,
|
||||
|
|
@ -79,7 +79,7 @@ impl Hash for Handle {
|
|||
}
|
||||
}
|
||||
|
||||
/// The data of an [`Image`].
|
||||
/// The data of a raster image.
|
||||
#[derive(Clone, Hash)]
|
||||
pub enum Data {
|
||||
/// File data
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
//! - Build a new renderer, see the [renderer] module.
|
||||
//! - Build a custom widget, start at the [`Widget`] trait.
|
||||
//!
|
||||
//! [`iced_core`]: https://github.com/iced-rs/iced/tree/master/core
|
||||
//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/master/winit
|
||||
//! [`iced_core`]: https://github.com/iced-rs/iced/tree/0.4/core
|
||||
//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/0.4/winit
|
||||
//! [`druid`]: https://github.com/xi-editor/druid
|
||||
//! [`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle
|
||||
//! [renderer]: crate::renderer
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ where
|
|||
event::Status::Ignored
|
||||
}
|
||||
|
||||
/// Returns the current [`mouse::Interaction`] of the [`Widget`].
|
||||
/// Returns the current [`mouse::Interaction`] of the [`Overlay`].
|
||||
///
|
||||
/// By default, it returns [`mouse::Interaction::Idle`].
|
||||
fn mouse_interaction(
|
||||
|
|
|
|||
|
|
@ -1,24 +1,4 @@
|
|||
//! Write your own renderer.
|
||||
//!
|
||||
//! You will need to implement the `Renderer` trait first. It simply contains
|
||||
//! an `Output` associated type.
|
||||
//!
|
||||
//! There is no common trait to draw all the widgets. Instead, every [`Widget`]
|
||||
//! constrains its generic `Renderer` type as necessary.
|
||||
//!
|
||||
//! This approach is flexible and composable. For instance, the
|
||||
//! [`Text`] widget only needs a [`text::Renderer`] while a [`Checkbox`] widget
|
||||
//! needs both a [`text::Renderer`] and a [`checkbox::Renderer`], reusing logic.
|
||||
//!
|
||||
//! In the end, a __renderer__ satisfying all the constraints is
|
||||
//! needed to build a [`UserInterface`].
|
||||
//!
|
||||
//! [`Widget`]: crate::Widget
|
||||
//! [`UserInterface`]: crate::UserInterface
|
||||
//! [`Text`]: crate::widget::Text
|
||||
//! [`text::Renderer`]: crate::widget::text::Renderer
|
||||
//! [`Checkbox`]: crate::widget::Checkbox
|
||||
//! [`checkbox::Renderer`]: crate::widget::checkbox::Renderer
|
||||
#[cfg(debug_assertions)]
|
||||
mod null;
|
||||
#[cfg(debug_assertions)]
|
||||
|
|
@ -27,8 +7,7 @@ pub use null::Null;
|
|||
use crate::layout;
|
||||
use crate::{Background, Color, Element, Rectangle, Vector};
|
||||
|
||||
/// A component that can take the state of a user interface and produce an
|
||||
/// output for its users.
|
||||
/// A component that can be used by widgets to draw themselves on a screen.
|
||||
pub trait Renderer: Sized {
|
||||
/// Lays out the elements of a user interface.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::hash::{Hash, Hasher as _};
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// An [`Svg`] handle.
|
||||
/// A handle of Svg data.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Handle {
|
||||
id: u64,
|
||||
|
|
@ -55,7 +55,7 @@ impl Hash for Handle {
|
|||
}
|
||||
}
|
||||
|
||||
/// The data of an [`Svg`].
|
||||
/// The data of a vectorial image.
|
||||
#[derive(Clone, Hash)]
|
||||
pub enum Data {
|
||||
/// File data
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ pub enum Hit {
|
|||
}
|
||||
|
||||
impl Hit {
|
||||
/// Computes the cursor position corresponding to this [`HitTestResult`] .
|
||||
/// Computes the cursor position of the [`Hit`] .
|
||||
pub fn cursor(self) -> usize {
|
||||
match self {
|
||||
Self::CharOffset(i) => i,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
|
|||
/// The [`integration` example] uses a [`UserInterface`] to integrate Iced in
|
||||
/// an existing graphical application.
|
||||
///
|
||||
/// [`integration` example]: https://github.com/iced-rs/iced/tree/0.3/examples/integration
|
||||
/// [`integration` example]: https://github.com/iced-rs/iced/tree/0.4/examples/integration
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct UserInterface<'a, Message, Renderer> {
|
||||
root: Element<'a, Message, Renderer>,
|
||||
|
|
@ -264,11 +264,10 @@ where
|
|||
|
||||
/// Draws the [`UserInterface`] with the provided [`Renderer`].
|
||||
///
|
||||
/// It returns the some [`Renderer::Output`]. You should update the icon of
|
||||
/// the mouse cursor accordingly in your system.
|
||||
/// It returns the current [`mouse::Interaction`]. You should update the
|
||||
/// icon of the mouse cursor accordingly in your system.
|
||||
///
|
||||
/// [`Renderer`]: crate::Renderer
|
||||
/// [`Renderer::Output`]: crate::Renderer::Output
|
||||
///
|
||||
/// # Example
|
||||
/// We can finally draw our [counter](index.html#usage) by
|
||||
|
|
|
|||
|
|
@ -93,12 +93,12 @@ use crate::{Clipboard, Layout, Length, Point, Rectangle, Shell};
|
|||
/// - [`geometry`], a custom widget showcasing how to draw geometry with the
|
||||
/// `Mesh2D` primitive in [`iced_wgpu`].
|
||||
///
|
||||
/// [examples]: https://github.com/iced-rs/iced/tree/0.3/examples
|
||||
/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.3/examples/bezier_tool
|
||||
/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.3/examples/custom_widget
|
||||
/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.3/examples/geometry
|
||||
/// [examples]: https://github.com/iced-rs/iced/tree/0.4/examples
|
||||
/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.4/examples/bezier_tool
|
||||
/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.4/examples/custom_widget
|
||||
/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.4/examples/geometry
|
||||
/// [`lyon`]: https://github.com/nical/lyon
|
||||
/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.3/wgpu
|
||||
/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.4/wgpu
|
||||
pub trait Widget<Message, Renderer>
|
||||
where
|
||||
Renderer: crate::Renderer,
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ impl<'a, Message, Renderer: text::Renderer> Checkbox<'a, Message, Renderer> {
|
|||
|
||||
/// Sets the [`Font`] of the text of the [`Checkbox`].
|
||||
///
|
||||
/// [`Font`]: crate::widget::text::Renderer::Font
|
||||
/// [`Font`]: crate::text::Renderer::Font
|
||||
pub fn font(mut self, font: Renderer::Font) -> Self {
|
||||
self.font = font;
|
||||
self
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
|
|||
|
||||
/// Sets the vertical spacing _between_ elements.
|
||||
///
|
||||
/// Custom margins per element do not exist in Iced. You should use this
|
||||
/// Custom margins per element do not exist in iced. You should use this
|
||||
/// method instead! While less flexible, it helps you keep spacing between
|
||||
/// elements consistent.
|
||||
pub fn spacing(mut self, units: u16) -> Self {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
|
||||
//! drag and drop, and hotkey support.
|
||||
//!
|
||||
//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.3/examples/pane_grid
|
||||
//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.4/examples/pane_grid
|
||||
mod axis;
|
||||
mod configuration;
|
||||
mod content;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::widget::pane_grid::Axis;
|
|||
|
||||
/// The arrangement of a [`PaneGrid`].
|
||||
///
|
||||
/// [`PaneGrid`]: crate::pane_grid::PaneGrid
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Configuration<T> {
|
||||
/// A split of the available space.
|
||||
|
|
@ -21,6 +21,6 @@ pub enum Configuration<T> {
|
|||
},
|
||||
/// A [`Pane`].
|
||||
///
|
||||
/// [`Pane`]: crate::pane_grid::Pane
|
||||
/// [`Pane`]: crate::widget::pane_grid::Pane
|
||||
Pane(T),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ where
|
|||
{
|
||||
/// Draws the [`Content`] with the provided [`Renderer`] and [`Layout`].
|
||||
///
|
||||
/// [`Renderer`]: crate::widget::pane_grid::Renderer
|
||||
/// [`Renderer`]: crate::Renderer
|
||||
pub fn draw(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! The state of a [`PaneGrid`].
|
||||
//!
|
||||
//! [`PaneGrid`]: crate::widget::PaneGrid
|
||||
use crate::widget::pane_grid::{
|
||||
Axis, Configuration, Direction, Node, Pane, Split,
|
||||
};
|
||||
|
|
@ -21,9 +23,13 @@ use std::collections::{BTreeMap, HashMap};
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct State<T> {
|
||||
/// The panes of the [`PaneGrid`].
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
pub panes: HashMap<Pane, T>,
|
||||
|
||||
/// The internal state of the [`PaneGrid`].
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
pub internal: Internal,
|
||||
|
||||
pub(super) action: Action,
|
||||
|
|
@ -198,6 +204,8 @@ impl<T> State<T> {
|
|||
}
|
||||
|
||||
/// The internal state of a [`PaneGrid`].
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Internal {
|
||||
layout: Node,
|
||||
|
|
@ -207,6 +215,8 @@ pub struct Internal {
|
|||
impl Internal {
|
||||
/// Initializes the [`Internal`] state of a [`PaneGrid`] from a
|
||||
/// [`Configuration`].
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
pub fn from_configuration<T>(
|
||||
panes: &mut HashMap<Pane, T>,
|
||||
content: Configuration<T>,
|
||||
|
|
@ -248,11 +258,17 @@ impl Internal {
|
|||
}
|
||||
|
||||
/// The current action of a [`PaneGrid`].
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Action {
|
||||
/// The [`PaneGrid`] is idle.
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
Idle,
|
||||
/// A [`Pane`] in the [`PaneGrid`] is being dragged.
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
Dragging {
|
||||
/// The [`Pane`] being dragged.
|
||||
pane: Pane,
|
||||
|
|
@ -260,6 +276,8 @@ pub enum Action {
|
|||
origin: Point,
|
||||
},
|
||||
/// A [`Split`] in the [`PaneGrid`] is being dragged.
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
Resizing {
|
||||
/// The [`Split`] being dragged.
|
||||
split: Split,
|
||||
|
|
@ -288,6 +306,8 @@ impl Action {
|
|||
|
||||
impl Internal {
|
||||
/// Calculates the current [`Pane`] regions from the [`PaneGrid`] layout.
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
pub fn pane_regions(
|
||||
&self,
|
||||
spacing: f32,
|
||||
|
|
@ -297,6 +317,8 @@ impl Internal {
|
|||
}
|
||||
|
||||
/// Calculates the current [`Split`] regions from the [`PaneGrid`] layout.
|
||||
///
|
||||
/// [`PaneGrid`]: crate::widget::PaneGrid
|
||||
pub fn split_regions(
|
||||
&self,
|
||||
spacing: f32,
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ where
|
|||
{
|
||||
/// Draws the [`TitleBar`] with the provided [`Renderer`] and [`Layout`].
|
||||
///
|
||||
/// [`Renderer`]: crate::widget::pane_grid::Renderer
|
||||
/// [`Renderer`]: crate::Renderer
|
||||
pub fn draw(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
|
|
|
|||
|
|
@ -402,21 +402,24 @@ pub fn draw<T, Renderer>(
|
|||
if let Some(label) =
|
||||
label.as_ref().map(String::as_str).or_else(|| placeholder)
|
||||
{
|
||||
let text_size = f32::from(text_size.unwrap_or(renderer.default_size()));
|
||||
|
||||
renderer.fill_text(Text {
|
||||
content: label,
|
||||
size: f32::from(text_size.unwrap_or(renderer.default_size())),
|
||||
size: text_size,
|
||||
font: font.clone(),
|
||||
color: is_selected
|
||||
.then(|| style.text_color)
|
||||
.unwrap_or(style.placeholder_color),
|
||||
bounds: Rectangle {
|
||||
x: bounds.x + f32::from(padding.left),
|
||||
y: bounds.center_y(),
|
||||
..bounds
|
||||
y: bounds.center_y() - text_size / 2.0,
|
||||
width: bounds.width - f32::from(padding.horizontal()),
|
||||
height: text_size,
|
||||
},
|
||||
horizontal_alignment: alignment::Horizontal::Left,
|
||||
vertical_alignment: alignment::Vertical::Center,
|
||||
})
|
||||
vertical_alignment: alignment::Vertical::Top,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> {
|
|||
|
||||
/// Sets the horizontal spacing _between_ elements.
|
||||
///
|
||||
/// Custom margins per element do not exist in Iced. You should use this
|
||||
/// Custom margins per element do not exist in iced. You should use this
|
||||
/// method instead! While less flexible, it helps you keep spacing between
|
||||
/// elements consistent.
|
||||
pub fn spacing(mut self, units: u16) -> Self {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ impl<Renderer: text::Renderer> Text<Renderer> {
|
|||
|
||||
/// Sets the [`Font`] of the [`Text`].
|
||||
///
|
||||
/// [`Font`]: Renderer::Font
|
||||
/// [`Font`]: crate::text::Renderer::Font
|
||||
pub fn font(mut self, font: impl Into<Renderer::Font>) -> Self {
|
||||
self.font = font.into();
|
||||
self
|
||||
|
|
@ -77,7 +77,7 @@ impl<Renderer: text::Renderer> Text<Renderer> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the [`HorizontalAlignment`] of the [`Text`].
|
||||
/// Sets the [`alignment::Horizontal`] of the [`Text`].
|
||||
pub fn horizontal_alignment(
|
||||
mut self,
|
||||
alignment: alignment::Horizontal,
|
||||
|
|
@ -86,7 +86,7 @@ impl<Renderer: text::Renderer> Text<Renderer> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the [`VerticalAlignment`] of the [`Text`].
|
||||
/// Sets the [`alignment::Vertical`] of the [`Text`].
|
||||
pub fn vertical_alignment(
|
||||
mut self,
|
||||
alignment: alignment::Vertical,
|
||||
|
|
|
|||
|
|
@ -108,10 +108,9 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the [`Font`] of the [`Text`].
|
||||
/// Sets the [`Font`] of the [`TextInput`].
|
||||
///
|
||||
/// [`Font`]: crate::widget::text::Renderer::Font
|
||||
/// [`Text`]: crate::widget::Text
|
||||
/// [`Font`]: crate::text::Renderer::Font
|
||||
pub fn font(mut self, font: Renderer::Font) -> Self {
|
||||
self.font = font;
|
||||
self
|
||||
|
|
@ -157,6 +156,8 @@ where
|
|||
|
||||
/// Draws the [`TextInput`] with the given [`Renderer`], overriding its
|
||||
/// [`Value`] if provided.
|
||||
///
|
||||
/// [`Renderer`]: text::Renderer
|
||||
pub fn draw(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
|
|
@ -570,6 +571,8 @@ where
|
|||
|
||||
/// Draws the [`TextInput`] with the given [`Renderer`], overriding its
|
||||
/// [`Value`] if provided.
|
||||
///
|
||||
/// [`Renderer`]: text::Renderer
|
||||
pub fn draw<Renderer>(
|
||||
renderer: &mut Renderer,
|
||||
layout: Layout<'_>,
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ impl<'a, Message, Renderer: text::Renderer> Toggler<'a, Message, Renderer> {
|
|||
}
|
||||
|
||||
/// Sets the [`Font`] of the text of the [`Toggler`]
|
||||
///
|
||||
/// [`Font`]: crate::text::Renderer::Font
|
||||
pub fn font(mut self, font: Renderer::Font) -> Self {
|
||||
self.font = font;
|
||||
self
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ where
|
|||
/// The default padding of a [`Tooltip`] drawn by this renderer.
|
||||
const DEFAULT_PADDING: u16 = 5;
|
||||
|
||||
/// Creates an empty [`Tooltip`].
|
||||
/// Creates a new [`Tooltip`].
|
||||
///
|
||||
/// [`Tooltip`]: struct.Tooltip.html
|
||||
pub fn new(
|
||||
|
|
@ -98,6 +98,117 @@ pub enum Position {
|
|||
Right,
|
||||
}
|
||||
|
||||
/// Draws a [`Tooltip`].
|
||||
pub fn draw<Renderer: crate::Renderer>(
|
||||
renderer: &mut Renderer,
|
||||
inherited_style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
viewport: &Rectangle,
|
||||
position: Position,
|
||||
gap: u16,
|
||||
padding: u16,
|
||||
style_sheet: &dyn container::StyleSheet,
|
||||
layout_text: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node,
|
||||
draw_text: impl FnOnce(
|
||||
&mut Renderer,
|
||||
&renderer::Style,
|
||||
Layout<'_>,
|
||||
Point,
|
||||
&Rectangle,
|
||||
),
|
||||
) {
|
||||
let bounds = layout.bounds();
|
||||
|
||||
if bounds.contains(cursor_position) {
|
||||
let gap = f32::from(gap);
|
||||
let style = style_sheet.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, viewport.size())
|
||||
.pad(Padding::new(padding)),
|
||||
);
|
||||
|
||||
let padding = f32::from(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 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(*viewport, |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,
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> Widget<Message, Renderer>
|
||||
for Tooltip<'a, Message, Renderer>
|
||||
where
|
||||
|
|
@ -169,100 +280,32 @@ where
|
|||
viewport,
|
||||
);
|
||||
|
||||
let bounds = layout.bounds();
|
||||
|
||||
if bounds.contains(cursor_position) {
|
||||
let gap = f32::from(self.gap);
|
||||
let style = self.style_sheet.style();
|
||||
|
||||
let defaults = renderer::Style {
|
||||
text_color: style
|
||||
.text_color
|
||||
.unwrap_or(inherited_style.text_color),
|
||||
};
|
||||
|
||||
let text_layout = Widget::<(), Renderer>::layout(
|
||||
&self.tooltip,
|
||||
renderer,
|
||||
&layout::Limits::new(Size::ZERO, viewport.size())
|
||||
.pad(Padding::new(self.padding)),
|
||||
);
|
||||
|
||||
let padding = f32::from(self.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 self.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 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(*viewport, |renderer| {
|
||||
container::draw_background(renderer, &style, tooltip_bounds);
|
||||
let tooltip = &self.tooltip;
|
||||
|
||||
draw(
|
||||
renderer,
|
||||
inherited_style,
|
||||
layout,
|
||||
cursor_position,
|
||||
viewport,
|
||||
self.position,
|
||||
self.gap,
|
||||
self.padding,
|
||||
self.style_sheet.as_ref(),
|
||||
|renderer, limits| {
|
||||
Widget::<(), Renderer>::layout(tooltip, renderer, limits)
|
||||
},
|
||||
|renderer, defaults, layout, cursor_position, viewport| {
|
||||
Widget::<(), Renderer>::draw(
|
||||
&self.tooltip,
|
||||
tooltip,
|
||||
renderer,
|
||||
&defaults,
|
||||
Layout::with_offset(
|
||||
Vector::new(
|
||||
tooltip_bounds.x + padding,
|
||||
tooltip_bounds.y + padding,
|
||||
),
|
||||
&text_layout,
|
||||
),
|
||||
defaults,
|
||||
layout,
|
||||
cursor_position,
|
||||
viewport,
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -273,8 +316,8 @@ where
|
|||
Message: 'a,
|
||||
{
|
||||
fn from(
|
||||
column: Tooltip<'a, Message, Renderer>,
|
||||
tooltip: Tooltip<'a, Message, Renderer>,
|
||||
) -> Element<'a, Message, Renderer> {
|
||||
Element::new(column)
|
||||
Element::new(tooltip)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue