diff --git a/crates/assistant2/src/message_editor.rs b/crates/assistant2/src/message_editor.rs index 54a818c7db..c11f4056cc 100644 --- a/crates/assistant2/src/message_editor.rs +++ b/crates/assistant2/src/message_editor.rs @@ -10,7 +10,7 @@ use language_model::{LanguageModelRegistry, LanguageModelRequestTool}; use language_model_selector::LanguageModelSelector; use rope::Point; use settings::Settings; -use theme::ThemeSettings; +use theme::{get_ui_font_size, ThemeSettings}; use ui::{ prelude::*, ButtonLike, ElevationIndex, KeyBinding, PopoverMenu, PopoverMenuHandle, SwitchWithLabel, @@ -276,7 +276,7 @@ impl Render for MessageEditor { .anchor(gpui::Corner::BottomLeft) .offset(gpui::Point { x: px(0.0), - y: px(-16.0), + y: (-get_ui_font_size(cx) * 2) - px(4.0), }) .with_handle(self.inline_context_picker_menu_handle.clone()), ) diff --git a/crates/gpui/src/elements/anchored.rs b/crates/gpui/src/elements/anchored.rs index 2991353f7c..4dba2b580a 100644 --- a/crates/gpui/src/elements/anchored.rs +++ b/crates/gpui/src/elements/anchored.rs @@ -19,6 +19,7 @@ pub struct Anchored { fit_mode: AnchoredFitMode, anchor_position: Option>, position_mode: AnchoredPositionMode, + offset: Option>, } /// anchored gives you an element that will avoid overflowing the window bounds. @@ -30,6 +31,7 @@ pub fn anchored() -> Anchored { fit_mode: AnchoredFitMode::SwitchAnchor, anchor_position: None, position_mode: AnchoredPositionMode::Window, + offset: None, } } @@ -47,6 +49,13 @@ impl Anchored { self } + /// Offset the final position by this amount. + /// Useful when you want to anchor to an element but offset from it, such as in PopoverMenu. + pub fn offset(mut self, offset: Point) -> Self { + self.offset = Some(offset); + self + } + /// Sets the position mode for this anchored element. Local will have this /// interpret its [`Anchored::position`] as relative to the parent element. /// While Window will have it interpret the position as relative to the window. @@ -129,6 +138,7 @@ impl Element for Anchored { self.anchor_corner, size, bounds, + self.offset, ); let limits = Bounds { @@ -245,18 +255,22 @@ impl AnchoredPositionMode { anchor_corner: Corner, size: Size, bounds: Bounds, + offset: Option>, ) -> (Point, Bounds) { + let offset = offset.unwrap_or_default(); + match self { AnchoredPositionMode::Window => { let anchor_position = anchor_position.unwrap_or(bounds.origin); - let bounds = Bounds::from_corner_and_size(anchor_corner, anchor_position, size); + let bounds = + Bounds::from_corner_and_size(anchor_corner, anchor_position + offset, size); (anchor_position, bounds) } AnchoredPositionMode::Local => { let anchor_position = anchor_position.unwrap_or_default(); let bounds = Bounds::from_corner_and_size( anchor_corner, - bounds.origin + anchor_position, + bounds.origin + anchor_position + offset, size, ); (anchor_position, bounds) diff --git a/crates/ui/src/components/popover_menu.rs b/crates/ui/src/components/popover_menu.rs index 100d5f6332..28fc881baf 100644 --- a/crates/ui/src/components/popover_menu.rs +++ b/crates/ui/src/components/popover_menu.rs @@ -254,13 +254,14 @@ impl Element for PopoverMenu { let mut menu_layout_id = None; let menu_element = element_state.menu.borrow_mut().as_mut().map(|menu| { + let offset = self.resolved_offset(cx); let mut anchored = anchored() .snap_to_window_with_margin(px(8.)) - .anchor(self.anchor); + .anchor(self.anchor) + .offset(offset); if let Some(child_bounds) = element_state.child_bounds { - anchored = anchored.position( - child_bounds.corner(self.resolved_attach()) + self.resolved_offset(cx), - ); + anchored = + anchored.position(child_bounds.corner(self.resolved_attach()) + offset); } let mut element = deferred(anchored.child(div().occlude().child(menu.clone()))) .with_priority(1)