From 8a146e49ca11991bc8de05a882a5a30d5a4b1466 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Jun 2022 16:44:08 +0200 Subject: [PATCH] Use a different fit mode for tooltips --- crates/context_menu/src/context_menu.rs | 2 +- crates/gpui/src/elements/overlay.rs | 50 +++++++++++++++++-------- crates/gpui/src/elements/tooltip.rs | 4 +- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index 6915bd775335b4fd933e5bf61be9a10c6d1e6e4f..2123aadf4c34e97a8f0348ead2e8f140c4ec7dc0 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -94,7 +94,7 @@ impl View for ContextMenu { Overlay::new(expanded_menu) .hoverable(true) - .move_to_fit(true) + .fit_mode(OverlayFitMode::SnapToWindow) .with_abs_position(self.position) .boxed() } diff --git a/crates/gpui/src/elements/overlay.rs b/crates/gpui/src/elements/overlay.rs index 1843b65c10a10dcf7818c113e3ac2bc2f6aeebdf..4ed0ca7d228db1524d5519336e7da579e8100d25 100644 --- a/crates/gpui/src/elements/overlay.rs +++ b/crates/gpui/src/elements/overlay.rs @@ -1,25 +1,31 @@ -use serde_json::json; - use crate::{ geometry::{rect::RectF, vector::Vector2F}, json::ToJson, DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, MouseRegion, PaintContext, SizeConstraint, }; +use serde_json::json; pub struct Overlay { child: ElementBox, abs_position: Option, - move_to_fit: bool, + fit_mode: OverlayFitMode, hoverable: bool, } +#[derive(Copy, Clone)] +pub enum OverlayFitMode { + SnapToWindow, + FlipAlignment, + None, +} + impl Overlay { pub fn new(child: ElementBox) -> Self { Self { child, abs_position: None, - move_to_fit: false, + fit_mode: OverlayFitMode::None, hoverable: false, } } @@ -29,8 +35,8 @@ impl Overlay { self } - pub fn move_to_fit(mut self, align_to_fit: bool) -> Self { - self.move_to_fit = align_to_fit; + pub fn fit_mode(mut self, fit_mode: OverlayFitMode) -> Self { + self.fit_mode = fit_mode; self } @@ -76,18 +82,32 @@ impl Element for Overlay { }); } - if self.move_to_fit { - // Snap the right edge of the overlay to the right edge of the window if - // its horizontal bounds overflow. - if bounds.lower_right().x() > cx.window_size.x() { - bounds.set_origin_x((cx.window_size.x() - bounds.width()).max(0.)); + match self.fit_mode { + OverlayFitMode::SnapToWindow => { + // Snap the right edge of the overlay to the right edge of the window if + // its horizontal bounds overflow. + 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 + // its vertical bounds overflow. + if bounds.lower_right().y() > cx.window_size.y() { + 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()); + } - // Snap the bottom edge of the overlay to the bottom edge of the window if - // its vertical bounds overflow. - if bounds.lower_right().y() > cx.window_size.y() { - bounds.set_origin_y((cx.window_size.y() - bounds.height()).max(0.)); + // 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); diff --git a/crates/gpui/src/elements/tooltip.rs b/crates/gpui/src/elements/tooltip.rs index 252d81e46d4f653f3a25780c104cb79cfe074cc9..a7800a28f62335caaa826fc91d7d9d24407b7bcf 100644 --- a/crates/gpui/src/elements/tooltip.rs +++ b/crates/gpui/src/elements/tooltip.rs @@ -1,6 +1,6 @@ use super::{ ContainerStyle, Element, ElementBox, Flex, KeystrokeLabel, MouseEventHandler, Overlay, - ParentElement, Text, + OverlayFitMode, ParentElement, Text, }; use crate::{ fonts::TextStyle, @@ -79,7 +79,7 @@ impl Tooltip { }) .boxed(), ) - .move_to_fit(true) + .fit_mode(OverlayFitMode::FlipAlignment) .with_abs_position(state.position.get()) .boxed(), )