Use a different fit mode for tooltips

This commit is contained in:
Antonio Scandurra 2022-06-15 16:44:08 +02:00
parent f2a48c6b02
commit 8a146e49ca
3 changed files with 39 additions and 19 deletions

View File

@ -94,7 +94,7 @@ impl View for ContextMenu {
Overlay::new(expanded_menu) Overlay::new(expanded_menu)
.hoverable(true) .hoverable(true)
.move_to_fit(true) .fit_mode(OverlayFitMode::SnapToWindow)
.with_abs_position(self.position) .with_abs_position(self.position)
.boxed() .boxed()
} }

View File

@ -1,25 +1,31 @@
use serde_json::json;
use crate::{ use crate::{
geometry::{rect::RectF, vector::Vector2F}, geometry::{rect::RectF, vector::Vector2F},
json::ToJson, json::ToJson,
DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, MouseRegion, DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, MouseRegion,
PaintContext, SizeConstraint, PaintContext, SizeConstraint,
}; };
use serde_json::json;
pub struct Overlay { pub struct Overlay {
child: ElementBox, child: ElementBox,
abs_position: Option<Vector2F>, abs_position: Option<Vector2F>,
move_to_fit: bool, fit_mode: OverlayFitMode,
hoverable: bool, hoverable: bool,
} }
#[derive(Copy, Clone)]
pub enum OverlayFitMode {
SnapToWindow,
FlipAlignment,
None,
}
impl Overlay { impl Overlay {
pub fn new(child: ElementBox) -> Self { pub fn new(child: ElementBox) -> Self {
Self { Self {
child, child,
abs_position: None, abs_position: None,
move_to_fit: false, fit_mode: OverlayFitMode::None,
hoverable: false, hoverable: false,
} }
} }
@ -29,8 +35,8 @@ impl Overlay {
self self
} }
pub fn move_to_fit(mut self, align_to_fit: bool) -> Self { pub fn fit_mode(mut self, fit_mode: OverlayFitMode) -> Self {
self.move_to_fit = align_to_fit; self.fit_mode = fit_mode;
self self
} }
@ -76,18 +82,32 @@ impl Element for Overlay {
}); });
} }
if self.move_to_fit { match self.fit_mode {
// Snap the right edge of the overlay to the right edge of the window if OverlayFitMode::SnapToWindow => {
// its horizontal bounds overflow. // Snap the right edge of the overlay to the right edge of the window if
if bounds.lower_right().x() > cx.window_size.x() { // its horizontal bounds overflow.
bounds.set_origin_x((cx.window_size.x() - bounds.width()).max(0.)); if bounds.lower_right().x() > cx.window_size.x() {
} bounds.set_origin_x((cx.window_size.x() - bounds.width()).max(0.));
}
// Snap the bottom edge of the overlay to the bottom edge of the window if // Snap the bottom edge of the overlay to the bottom edge of the window if
// its vertical bounds overflow. // its vertical bounds overflow.
if bounds.lower_right().y() > cx.window_size.y() { if bounds.lower_right().y() > cx.window_size.y() {
bounds.set_origin_y((cx.window_size.y() - bounds.height()).max(0.)); bounds.set_origin_y((cx.window_size.y() - bounds.height()).max(0.));
}
} }
OverlayFitMode::FlipAlignment => {
// Right-align overlay if its horizontal bounds overflow.
if bounds.lower_right().x() > cx.window_size.x() {
bounds.set_origin_x(bounds.origin_x() - bounds.width());
}
// Bottom-align overlay if its vertical bounds overflow.
if bounds.lower_right().y() > cx.window_size.y() {
bounds.set_origin_y(bounds.origin_y() - bounds.height());
}
}
OverlayFitMode::None => {}
} }
self.child.paint(bounds.origin(), bounds, cx); self.child.paint(bounds.origin(), bounds, cx);

View File

@ -1,6 +1,6 @@
use super::{ use super::{
ContainerStyle, Element, ElementBox, Flex, KeystrokeLabel, MouseEventHandler, Overlay, ContainerStyle, Element, ElementBox, Flex, KeystrokeLabel, MouseEventHandler, Overlay,
ParentElement, Text, OverlayFitMode, ParentElement, Text,
}; };
use crate::{ use crate::{
fonts::TextStyle, fonts::TextStyle,
@ -79,7 +79,7 @@ impl Tooltip {
}) })
.boxed(), .boxed(),
) )
.move_to_fit(true) .fit_mode(OverlayFitMode::FlipAlignment)
.with_abs_position(state.position.get()) .with_abs_position(state.position.get())
.boxed(), .boxed(),
) )