diff --git a/crates/activity_indicator/src/activity_indicator.rs b/crates/activity_indicator/src/activity_indicator.rs index 21f7bff6d3976..973f845c17766 100644 --- a/crates/activity_indicator/src/activity_indicator.rs +++ b/crates/activity_indicator/src/activity_indicator.rs @@ -493,7 +493,7 @@ impl Render for ActivityIndicator { }), ), ) - .anchor(gpui::AnchorCorner::BottomLeft) + .anchor(gpui::Corner::BottomLeft) .menu(move |cx| { let strong_this = this.upgrade()?; let mut has_work = false; diff --git a/crates/assistant/src/inline_assistant.rs b/crates/assistant/src/inline_assistant.rs index 9886ee4b8d0df..640fea59872ad 100644 --- a/crates/assistant/src/inline_assistant.rs +++ b/crates/assistant/src/inline_assistant.rs @@ -1556,7 +1556,7 @@ impl Render for PromptEditor { anchored() .position_mode(gpui::AnchoredPositionMode::Local) .position(point(px(0.), px(24.))) - .anchor(gpui::AnchorCorner::TopLeft) + .anchor(gpui::Corner::TopLeft) .child(self.render_rate_limit_notice(cx)), ) })), diff --git a/crates/assistant/src/slash_command_picker.rs b/crates/assistant/src/slash_command_picker.rs index 310e11322ebdb..bad56a45a5cbe 100644 --- a/crates/assistant/src/slash_command_picker.rs +++ b/crates/assistant/src/slash_command_picker.rs @@ -316,8 +316,8 @@ impl RenderOnce for SlashCommandSelector { PopoverMenu::new("model-switcher") .menu(move |_cx| Some(picker_view.clone())) .trigger(self.trigger) - .attach(gpui::AnchorCorner::TopLeft) - .anchor(gpui::AnchorCorner::BottomLeft) + .attach(gpui::Corner::TopLeft) + .anchor(gpui::Corner::BottomLeft) .offset(gpui::Point { x: px(0.0), y: px(-16.0), diff --git a/crates/assistant2/src/context_strip.rs b/crates/assistant2/src/context_strip.rs index fa0f7cab8a187..9392a034517ff 100644 --- a/crates/assistant2/src/context_strip.rs +++ b/crates/assistant2/src/context_strip.rs @@ -53,8 +53,8 @@ impl Render for ContextStrip { .icon_size(IconSize::Small) .style(ui::ButtonStyle::Filled), ) - .attach(gpui::AnchorCorner::TopLeft) - .anchor(gpui::AnchorCorner::BottomLeft) + .attach(gpui::Corner::TopLeft) + .anchor(gpui::Corner::BottomLeft) .offset(gpui::Point { x: px(0.0), y: px(-16.0), diff --git a/crates/assistant2/src/inline_assistant.rs b/crates/assistant2/src/inline_assistant.rs index 4f260518ae44e..a10480c33731f 100644 --- a/crates/assistant2/src/inline_assistant.rs +++ b/crates/assistant2/src/inline_assistant.rs @@ -1670,7 +1670,7 @@ impl Render for PromptEditor { gpui::AnchoredPositionMode::Local, ) .position(point(px(0.), px(24.))) - .anchor(gpui::AnchorCorner::TopLeft) + .anchor(gpui::Corner::TopLeft) .child(self.render_rate_limit_notice(cx)), ) })), diff --git a/crates/collab_ui/src/collab_panel.rs b/crates/collab_ui/src/collab_panel.rs index 2572fa48b741d..f5e345043dacb 100644 --- a/crates/collab_ui/src/collab_panel.rs +++ b/crates/collab_ui/src/collab_panel.rs @@ -2708,7 +2708,7 @@ impl Render for CollabPanel { deferred( anchored() .position(*position) - .anchor(gpui::AnchorCorner::TopLeft) + .anchor(gpui::Corner::TopLeft) .child(menu.clone()), ) .with_priority(1) diff --git a/crates/collab_ui/src/collab_panel/channel_modal.rs b/crates/collab_ui/src/collab_panel/channel_modal.rs index 3c61c479452c3..a4a7acd1e5e9e 100644 --- a/crates/collab_ui/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui/src/collab_panel/channel_modal.rs @@ -409,7 +409,7 @@ impl PickerDelegate for ChannelModalDelegate { Some( deferred( anchored() - .anchor(gpui::AnchorCorner::TopRight) + .anchor(gpui::Corner::TopRight) .child(menu.clone()), ) .with_priority(1), diff --git a/crates/collab_ui/src/collab_ui.rs b/crates/collab_ui/src/collab_ui.rs index 67c4ad6dad847..82d10a957e6c0 100644 --- a/crates/collab_ui/src/collab_ui.rs +++ b/crates/collab_ui/src/collab_ui.rs @@ -44,7 +44,7 @@ fn notification_window_options( let notification_margin_height = px(-48.); let bounds = gpui::Bounds:: { - origin: screen.bounds().upper_right() + origin: screen.bounds().top_right() - point( size.width + notification_margin_width, notification_margin_height, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 59c990b69da6f..be04c692e14e7 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -31,13 +31,13 @@ use file_icons::FileIcons; use git::{blame::BlameEntry, diff::DiffHunkStatus, Oid}; use gpui::{ anchored, deferred, div, fill, outline, point, px, quad, relative, size, svg, - transparent_black, Action, AnchorCorner, AnyElement, AvailableSpace, Bounds, ClickEvent, - ClipboardItem, ContentMask, Corners, CursorStyle, DispatchPhase, Edges, Element, - ElementInputHandler, Entity, FontId, GlobalElementId, HighlightStyle, Hitbox, Hsla, - InteractiveElement, IntoElement, Length, ModifiersChangedEvent, MouseButton, MouseDownEvent, - MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, - ShapedLine, SharedString, Size, StatefulInteractiveElement, Style, Styled, Subscription, - TextRun, TextStyleRefinement, View, ViewContext, WeakView, WindowContext, + transparent_black, Action, AnyElement, AvailableSpace, Bounds, ClickEvent, ClipboardItem, + ContentMask, Corner, Corners, CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, + Entity, FontId, GlobalElementId, HighlightStyle, Hitbox, Hsla, InteractiveElement, IntoElement, + Length, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, + PaintQuad, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, + Size, StatefulInteractiveElement, Style, Styled, Subscription, TextRun, TextStyleRefinement, + View, ViewContext, WeakView, WindowContext, }; use itertools::Itertools; use language::{ @@ -706,7 +706,7 @@ impl EditorElement { let mut scroll_delta = gpui::Point::::default(); let vertical_margin = position_map.line_height.min(text_bounds.size.height / 3.0); let top = text_bounds.origin.y + vertical_margin; - let bottom = text_bounds.lower_left().y - vertical_margin; + let bottom = text_bounds.bottom_left().y - vertical_margin; if event.position.y < top { scroll_delta.y = -scale_vertical_mouse_autoscroll_delta(top - event.position.y); } @@ -716,7 +716,7 @@ impl EditorElement { let horizontal_margin = position_map.line_height.min(text_bounds.size.width / 3.0); let left = text_bounds.origin.x + horizontal_margin; - let right = text_bounds.upper_right().x - horizontal_margin; + let right = text_bounds.top_right().x - horizontal_margin; if event.position.x < left { scroll_delta.x = -scale_horizontal_mouse_autoscroll_delta(left - event.position.x); } @@ -1213,7 +1213,7 @@ impl EditorElement { let track_bounds = Bounds::from_corners( point(self.scrollbar_left(&bounds), bounds.origin.y), - point(bounds.lower_right().x, bounds.lower_left().y), + point(bounds.bottom_right().x, bounds.bottom_left().y), ); let settings = EditorSettings::get_global(cx); @@ -2824,7 +2824,7 @@ impl EditorElement { list_origin.x = (cx.viewport_size().width - list_width).max(Pixels::ZERO); } - if list_origin.y + list_height > text_hitbox.lower_right().y { + if list_origin.y + list_height > text_hitbox.bottom_right().y { list_origin.y -= line_height + list_height; } @@ -3067,7 +3067,7 @@ impl EditorElement { anchored() .position(position) .child(context_menu) - .anchor(AnchorCorner::TopLeft) + .anchor(Corner::TopLeft) .snap_to_window_with_margin(px(8.)), ) .with_priority(1) @@ -3132,7 +3132,7 @@ impl EditorElement { for mut hover_popover in hover_popovers { let size = hover_popover.layout_as_root(AvailableSpace::min_size(), cx); let horizontal_offset = - (text_hitbox.upper_right().x - (hovered_point.x + size.width)).min(Pixels::ZERO); + (text_hitbox.top_right().x - (hovered_point.x + size.width)).min(Pixels::ZERO); overall_height += HOVER_POPOVER_GAP + size.height; @@ -4407,7 +4407,7 @@ impl EditorElement { } fn scrollbar_left(&self, bounds: &Bounds) -> Pixels { - bounds.upper_right().x - self.style.scrollbar_width + bounds.top_right().x - self.style.scrollbar_width } fn column_pixels(&self, column: usize, cx: &WindowContext) -> Pixels { @@ -5488,7 +5488,7 @@ impl Element for EditorElement { cx.insert_hitbox(gutter_bounds(bounds, gutter_dimensions), false); let text_hitbox = cx.insert_hitbox( Bounds { - origin: gutter_hitbox.upper_right(), + origin: gutter_hitbox.top_right(), size: size(text_width, bounds.size.height), }, false, diff --git a/crates/editor/src/hunk_diff.rs b/crates/editor/src/hunk_diff.rs index b52086f71d968..76e7a92036517 100644 --- a/crates/editor/src/hunk_diff.rs +++ b/crates/editor/src/hunk_diff.rs @@ -1,8 +1,7 @@ use collections::{HashMap, HashSet}; use git::diff::DiffHunkStatus; use gpui::{ - Action, AnchorCorner, AppContext, CursorStyle, Hsla, Model, MouseButton, Subscription, Task, - View, + Action, AppContext, Corner, CursorStyle, Hsla, Model, MouseButton, Subscription, Task, View, }; use language::{Buffer, BufferId, Point}; use multi_buffer::{ @@ -743,7 +742,7 @@ impl Editor { }, ), ) - .anchor(AnchorCorner::TopRight) + .anchor(Corner::TopRight) .with_handle(hunk_controls_menu_handle) .menu(move |cx| { let focus = focus.clone(); diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index b88be232913f0..55c02c87af97b 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -1261,8 +1261,8 @@ impl PickerDelegate for FileFinderDelegate { .child( PopoverMenu::new("menu-popover") .with_handle(self.popover_menu_handle.clone()) - .attach(gpui::AnchorCorner::TopRight) - .anchor(gpui::AnchorCorner::BottomRight) + .attach(gpui::Corner::TopRight) + .anchor(gpui::Corner::BottomRight) .trigger( Button::new("actions-trigger", "Split Options") .selected_label_color(Color::Accent) diff --git a/crates/gpui/examples/gradient.rs b/crates/gpui/examples/gradient.rs index b0e1af5acb1c7..dcdfaa52573c2 100644 --- a/crates/gpui/examples/gradient.rs +++ b/crates/gpui/examples/gradient.rs @@ -218,13 +218,13 @@ impl Render for GradientViewer { let height = square_bounds.size.height; let horizontal_offset = height; let vertical_offset = px(30.); - let mut path = gpui::Path::new(square_bounds.lower_left()); + let mut path = gpui::Path::new(square_bounds.bottom_left()); path.line_to(square_bounds.origin + point(horizontal_offset, vertical_offset)); path.line_to( - square_bounds.upper_right() + point(-horizontal_offset, vertical_offset), + square_bounds.top_right() + point(-horizontal_offset, vertical_offset), ); - path.line_to(square_bounds.lower_right()); - path.line_to(square_bounds.lower_left()); + path.line_to(square_bounds.bottom_right()); + path.line_to(square_bounds.bottom_left()); cx.paint_path( path, linear_gradient( diff --git a/crates/gpui/examples/painting.rs b/crates/gpui/examples/painting.rs index 6e5fe25dfd2b4..6b9f4952c6a2a 100644 --- a/crates/gpui/examples/painting.rs +++ b/crates/gpui/examples/painting.rs @@ -49,17 +49,17 @@ impl PaintingViewer { let height = square_bounds.size.height; let horizontal_offset = height; let vertical_offset = px(30.); - let mut path = Path::new(square_bounds.lower_left()); + let mut path = Path::new(square_bounds.bottom_left()); path.curve_to( square_bounds.origin + point(horizontal_offset, vertical_offset), square_bounds.origin + point(px(0.0), vertical_offset), ); - path.line_to(square_bounds.upper_right() + point(-horizontal_offset, vertical_offset)); + path.line_to(square_bounds.top_right() + point(-horizontal_offset, vertical_offset)); path.curve_to( - square_bounds.lower_right(), - square_bounds.upper_right() + point(px(0.0), vertical_offset), + square_bounds.bottom_right(), + square_bounds.top_right() + point(px(0.0), vertical_offset), ); - path.line_to(square_bounds.lower_left()); + path.line_to(square_bounds.bottom_left()); lines.push(path); Self { diff --git a/crates/gpui/examples/window_positioning.rs b/crates/gpui/examples/window_positioning.rs index 5505478140933..10651c9640ba1 100644 --- a/crates/gpui/examples/window_positioning.rs +++ b/crates/gpui/examples/window_positioning.rs @@ -86,7 +86,7 @@ fn main() { .unwrap(); let bounds = Bounds { - origin: screen.bounds().upper_right() + origin: screen.bounds().top_right() - point(size.width + margin_offset, -margin_offset), size, }; @@ -101,7 +101,7 @@ fn main() { .unwrap(); let bounds = Bounds { - origin: screen.bounds().lower_left() + origin: screen.bounds().bottom_left() - point(-margin_offset, size.height + margin_offset), size, }; @@ -116,7 +116,7 @@ fn main() { .unwrap(); let bounds = Bounds { - origin: screen.bounds().lower_right() + origin: screen.bounds().bottom_right() - point(size.width + margin_offset, size.height + margin_offset), size, }; diff --git a/crates/gpui/src/elements/anchored.rs b/crates/gpui/src/elements/anchored.rs index 7872ba6349bf1..2991353f7cc24 100644 --- a/crates/gpui/src/elements/anchored.rs +++ b/crates/gpui/src/elements/anchored.rs @@ -2,8 +2,8 @@ use smallvec::SmallVec; use taffy::style::{Display, Position}; use crate::{ - point, AnyElement, Bounds, Edges, Element, GlobalElementId, IntoElement, LayoutId, - ParentElement, Pixels, Point, Size, Style, WindowContext, + point, AnyElement, Axis, Bounds, Corner, Edges, Element, GlobalElementId, IntoElement, + LayoutId, ParentElement, Pixels, Point, Size, Style, WindowContext, }; /// The state that the anchored element element uses to track its children. @@ -15,7 +15,7 @@ pub struct AnchoredState { /// will avoid overflowing the window bounds. pub struct Anchored { children: SmallVec<[AnyElement; 2]>, - anchor_corner: AnchorCorner, + anchor_corner: Corner, fit_mode: AnchoredFitMode, anchor_position: Option>, position_mode: AnchoredPositionMode, @@ -26,7 +26,7 @@ pub struct Anchored { pub fn anchored() -> Anchored { Anchored { children: SmallVec::new(), - anchor_corner: AnchorCorner::TopLeft, + anchor_corner: Corner::TopLeft, fit_mode: AnchoredFitMode::SwitchAnchor, anchor_position: None, position_mode: AnchoredPositionMode::Window, @@ -35,7 +35,7 @@ pub fn anchored() -> Anchored { impl Anchored { /// Sets which corner of the anchored element should be anchored to the current position. - pub fn anchor(mut self, anchor: AnchorCorner) -> Self { + pub fn anchor(mut self, anchor: Corner) -> Self { self.anchor_corner = anchor; self } @@ -120,7 +120,7 @@ impl Element for Anchored { for child_layout_id in &request_layout.child_layout_ids { let child_bounds = cx.layout_bounds(*child_layout_id); child_min = child_min.min(&child_bounds.origin); - child_max = child_max.max(&child_bounds.lower_right()); + child_max = child_max.max(&child_bounds.bottom_right()); } let size: Size = (child_max - child_min).into(); @@ -140,19 +140,23 @@ impl Element for Anchored { let mut anchor_corner = self.anchor_corner; if desired.left() < limits.left() || desired.right() > limits.right() { - let switched = anchor_corner - .switch_axis(Axis::Horizontal) - .get_bounds(origin, size); + let switched = Bounds::from_corner_and_size( + anchor_corner.other_side_corner_along(Axis::Horizontal), + origin, + size, + ); if !(switched.left() < limits.left() || switched.right() > limits.right()) { - anchor_corner = anchor_corner.switch_axis(Axis::Horizontal); + anchor_corner = anchor_corner.other_side_corner_along(Axis::Horizontal); desired = switched } } if desired.top() < limits.top() || desired.bottom() > limits.bottom() { - let switched = anchor_corner - .switch_axis(Axis::Vertical) - .get_bounds(origin, size); + let switched = Bounds::from_corner_and_size( + anchor_corner.other_side_corner_along(Axis::Vertical), + origin, + size, + ); if !(switched.top() < limits.top() || switched.bottom() > limits.bottom()) { desired = switched; } @@ -214,11 +218,6 @@ impl IntoElement for Anchored { } } -enum Axis { - Horizontal, - Vertical, -} - /// Which algorithm to use when fitting the anchored element to be inside the window. #[derive(Copy, Clone, PartialEq)] pub enum AnchoredFitMode { @@ -243,83 +242,25 @@ impl AnchoredPositionMode { fn get_position_and_bounds( &self, anchor_position: Option>, - anchor_corner: AnchorCorner, + anchor_corner: Corner, size: Size, bounds: Bounds, ) -> (Point, Bounds) { match self { AnchoredPositionMode::Window => { let anchor_position = anchor_position.unwrap_or(bounds.origin); - let bounds = anchor_corner.get_bounds(anchor_position, size); + let bounds = Bounds::from_corner_and_size(anchor_corner, anchor_position, size); (anchor_position, bounds) } AnchoredPositionMode::Local => { let anchor_position = anchor_position.unwrap_or_default(); - let bounds = anchor_corner.get_bounds(bounds.origin + anchor_position, size); + let bounds = Bounds::from_corner_and_size( + anchor_corner, + bounds.origin + anchor_position, + size, + ); (anchor_position, bounds) } } } } - -/// Which corner of the anchored element should be considered the anchor. -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum AnchorCorner { - /// The top left corner - TopLeft, - /// The top right corner - TopRight, - /// The bottom left corner - BottomLeft, - /// The bottom right corner - BottomRight, -} - -impl AnchorCorner { - fn get_bounds(&self, origin: Point, size: Size) -> Bounds { - let origin = match self { - Self::TopLeft => origin, - Self::TopRight => Point { - x: origin.x - size.width, - y: origin.y, - }, - Self::BottomLeft => Point { - x: origin.x, - y: origin.y - size.height, - }, - Self::BottomRight => Point { - x: origin.x - size.width, - y: origin.y - size.height, - }, - }; - - Bounds { origin, size } - } - - /// Get the point corresponding to this anchor corner in `bounds`. - pub fn corner(&self, bounds: Bounds) -> Point { - match self { - Self::TopLeft => bounds.origin, - Self::TopRight => bounds.upper_right(), - Self::BottomLeft => bounds.lower_left(), - Self::BottomRight => bounds.lower_right(), - } - } - - fn switch_axis(self, axis: Axis) -> Self { - match axis { - Axis::Vertical => match self { - AnchorCorner::TopLeft => AnchorCorner::BottomLeft, - AnchorCorner::TopRight => AnchorCorner::BottomRight, - AnchorCorner::BottomLeft => AnchorCorner::TopLeft, - AnchorCorner::BottomRight => AnchorCorner::TopRight, - }, - Axis::Horizontal => match self { - AnchorCorner::TopLeft => AnchorCorner::TopRight, - AnchorCorner::TopRight => AnchorCorner::TopLeft, - AnchorCorner::BottomLeft => AnchorCorner::BottomRight, - AnchorCorner::BottomRight => AnchorCorner::BottomLeft, - }, - } - } -} diff --git a/crates/gpui/src/elements/div.rs b/crates/gpui/src/elements/div.rs index 909af004a5d2f..3f826ca00790b 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -1193,7 +1193,7 @@ impl Element for Div { for (ix, child_layout_id) in request_layout.child_layout_ids.iter().enumerate() { let child_bounds = cx.layout_bounds(*child_layout_id); child_min = child_min.min(&child_bounds.origin); - child_max = child_max.max(&child_bounds.lower_right()); + child_max = child_max.max(&child_bounds.bottom_right()); state.child_bounds.push(child_bounds); if let Some(requested) = requested.as_ref() { @@ -1208,7 +1208,7 @@ impl Element for Div { for child_layout_id in &request_layout.child_layout_ids { let child_bounds = cx.layout_bounds(*child_layout_id); child_min = child_min.min(&child_bounds.origin); - child_max = child_max.max(&child_bounds.lower_right()); + child_max = child_max.max(&child_bounds.bottom_right()); } (child_max - child_min).into() }; diff --git a/crates/gpui/src/elements/uniform_list.rs b/crates/gpui/src/elements/uniform_list.rs index 703d9bebe64e5..4c2b449b41090 100644 --- a/crates/gpui/src/elements/uniform_list.rs +++ b/crates/gpui/src/elements/uniform_list.rs @@ -219,7 +219,7 @@ impl Element for UniformList { let padded_bounds = Bounds::from_corners( bounds.origin + point(border.left + padding.left, border.top + padding.top), - bounds.lower_right() + bounds.bottom_right() - point(border.right + padding.right, border.bottom + padding.bottom), ); @@ -261,7 +261,7 @@ impl Element for UniformList { let padded_bounds = Bounds::from_corners( bounds.origin + point(border.left + padding.left, border.top), - bounds.lower_right() - point(border.right + padding.right, border.bottom), + bounds.bottom_right() - point(border.right + padding.right, border.bottom), ); if let Some(handle) = self.scroll_handle.as_mut() { diff --git a/crates/gpui/src/geometry.rs b/crates/gpui/src/geometry.rs index 5a5c77c619cc8..7fc5681657a62 100644 --- a/crates/gpui/src/geometry.rs +++ b/crates/gpui/src/geometry.rs @@ -694,7 +694,7 @@ impl Size { /// Represents a rectangular area in a 2D space with an origin point and a size. /// /// The `Bounds` struct is generic over a type `T` which represents the type of the coordinate system. -/// The origin is represented as a `Point` which defines the upper-left corner of the rectangle, +/// The origin is represented as a `Point` which defines the top left corner of the rectangle, /// and the size is represented as a `Size` which defines the width and height of the rectangle. /// /// # Examples @@ -757,16 +757,16 @@ impl Bounds where T: Clone + Debug + Sub + Default, { - /// Constructs a `Bounds` from two corner points: the upper-left and lower-right corners. + /// Constructs a `Bounds` from two corner points: the top left and bottom right corners. /// /// This function calculates the origin and size of the `Bounds` based on the provided corner points. - /// The origin is set to the upper-left corner, and the size is determined by the difference between - /// the x and y coordinates of the lower-right and upper-left points. + /// The origin is set to the top left corner, and the size is determined by the difference between + /// the x and y coordinates of the bottom right and top left points. /// /// # Arguments /// - /// * `upper_left` - A `Point` representing the upper-left corner of the rectangle. - /// * `lower_right` - A `Point` representing the lower-right corner of the rectangle. + /// * `upper_left` - A `Point` representing the top left corner of the rectangle. + /// * `bottom_right` - A `Point` representing the bottom right corner of the rectangle. /// /// # Returns /// @@ -777,25 +777,53 @@ where /// ``` /// # use gpui::{Bounds, Point}; /// let upper_left = Point { x: 0, y: 0 }; - /// let lower_right = Point { x: 10, y: 10 }; - /// let bounds = Bounds::from_corners(upper_left, lower_right); + /// let bottom_right = Point { x: 10, y: 10 }; + /// let bounds = Bounds::from_corners(upper_left, bottom_right); /// /// assert_eq!(bounds.origin, upper_left); /// assert_eq!(bounds.size.width, 10); /// assert_eq!(bounds.size.height, 10); /// ``` - pub fn from_corners(upper_left: Point, lower_right: Point) -> Self { + pub fn from_corners(upper_left: Point, bottom_right: Point) -> Self { let origin = Point { x: upper_left.x.clone(), y: upper_left.y.clone(), }; let size = Size { - width: lower_right.x - upper_left.x, - height: lower_right.y - upper_left.y, + width: bottom_right.x - upper_left.x, + height: bottom_right.y - upper_left.y, }; Bounds { origin, size } } + /// Constructs a `Bounds` from a corner point and size. + /// + /// # Examples + /// + /// ``` + /// # use zed::{Bounds, Corner, Point}; + /// todo! + /// ``` + pub fn from_corner_and_size(corner: Corner, origin: Point, size: Size) -> Bounds { + let origin = match corner { + Corner::TopLeft => origin, + Corner::TopRight => Point { + x: origin.x - size.width.clone(), + y: origin.y, + }, + Corner::BottomLeft => Point { + x: origin.x, + y: origin.y - size.height.clone(), + }, + Corner::BottomRight => Point { + x: origin.x - size.width.clone(), + y: origin.y - size.height.clone(), + }, + }; + + Bounds { origin, size } + } + /// Creates a new `Bounds` with the specified origin and size. /// /// # Arguments @@ -849,8 +877,8 @@ where /// assert_eq!(bounds1.intersects(&bounds3), false); // Non-overlapping bounds /// ``` pub fn intersects(&self, other: &Bounds) -> bool { - let my_lower_right = self.lower_right(); - let their_lower_right = other.lower_right(); + let my_lower_right = self.bottom_right(); + let their_lower_right = other.bottom_right(); self.origin.x < their_lower_right.x && my_lower_right.x > other.origin.x @@ -996,8 +1024,8 @@ impl + Sub Self { let upper_left = self.origin.max(&other.origin); - let lower_right = self.lower_right().min(&other.lower_right()); - Self::from_corners(upper_left, lower_right) + let bottom_right = self.bottom_right().min(&other.bottom_right()); + Self::from_corners(upper_left, bottom_right) } /// Computes the union of two `Bounds`. @@ -1035,7 +1063,7 @@ impl + Sub Self { let top_left = self.origin.min(&other.origin); - let bottom_right = self.lower_right().max(&other.lower_right()); + let bottom_right = self.bottom_right().max(&other.bottom_right()); Bounds::from_corners(top_left, bottom_right) } } @@ -1123,11 +1151,11 @@ where self.origin.x.clone() + self.size.width.clone() } - /// Returns the upper-right corner point of the bounds. + /// Returns the top right corner point of the bounds. /// /// # Returns /// - /// A `Point` representing the upper-right corner of the bounds. + /// A `Point` representing the top right corner of the bounds. /// /// # Examples /// @@ -1137,21 +1165,21 @@ where /// origin: Point { x: 0, y: 0 }, /// size: Size { width: 10, height: 20 }, /// }; - /// let upper_right = bounds.upper_right(); - /// assert_eq!(upper_right, Point { x: 10, y: 0 }); + /// let top_right = bounds.top_right(); + /// assert_eq!(top_right, Point { x: 10, y: 0 }); /// ``` - pub fn upper_right(&self) -> Point { + pub fn top_right(&self) -> Point { Point { x: self.origin.x.clone() + self.size.width.clone(), y: self.origin.y.clone(), } } - /// Returns the lower-right corner point of the bounds. + /// Returns the bottom right corner point of the bounds. /// /// # Returns /// - /// A `Point` representing the lower-right corner of the bounds. + /// A `Point` representing the bottom right corner of the bounds. /// /// # Examples /// @@ -1161,21 +1189,21 @@ where /// origin: Point { x: 0, y: 0 }, /// size: Size { width: 10, height: 20 }, /// }; - /// let lower_right = bounds.lower_right(); - /// assert_eq!(lower_right, Point { x: 10, y: 20 }); + /// let bottom_right = bounds.bottom_right(); + /// assert_eq!(bottom_right, Point { x: 10, y: 20 }); /// ``` - pub fn lower_right(&self) -> Point { + pub fn bottom_right(&self) -> Point { Point { x: self.origin.x.clone() + self.size.width.clone(), y: self.origin.y.clone() + self.size.height.clone(), } } - /// Returns the lower-left corner point of the bounds. + /// Returns the bottom left corner point of the bounds. /// /// # Returns /// - /// A `Point` representing the lower-left corner of the bounds. + /// A `Point` representing the bottom left corner of the bounds. /// /// # Examples /// @@ -1185,15 +1213,41 @@ where /// origin: Point { x: 0, y: 0 }, /// size: Size { width: 10, height: 20 }, /// }; - /// let lower_left = bounds.lower_left(); - /// assert_eq!(lower_left, Point { x: 0, y: 20 }); + /// let bottom_left = bounds.bottom_left(); + /// assert_eq!(bottom_left, Point { x: 0, y: 20 }); /// ``` - pub fn lower_left(&self) -> Point { + pub fn bottom_left(&self) -> Point { Point { x: self.origin.x.clone(), y: self.origin.y.clone() + self.size.height.clone(), } } + + /// Returns the requested corner point of the bounds. + /// + /// # Returns + /// + /// A `Point` representing the corner of the bounds requested by the parameter. + /// + /// # Examples + /// + /// ``` + /// # use zed::{Bounds, Corner, Point, Size}; + /// let bounds = Bounds { + /// origin: Point { x: 0, y: 0 }, + /// size: Size { width: 10, height: 20 }, + /// }; + /// let bottom_left = bounds.corner(Corner::BottomLeft); + /// assert_eq!(bottom_left, Point { x: 0, y: 20 }); + /// ``` + pub fn corner(&self, corner: Corner) -> Point { + match corner { + Corner::TopLeft => self.origin.clone(), + Corner::TopRight => self.top_right(), + Corner::BottomLeft => self.bottom_left(), + Corner::BottomRight => self.bottom_right(), + } + } } impl Bounds @@ -1861,6 +1915,64 @@ impl From for Edges { } } +/// Identifies a corner of a 2d box. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum Corner { + /// The top left corner + TopLeft, + /// The top right corner + TopRight, + /// The bottom left corner + BottomLeft, + /// The bottom right corner + BottomRight, +} + +impl Corner { + /// Returns the directly opposite corner. + /// + /// # Examples + /// + /// ``` + /// # use zed::Corner; + /// assert_eq!(Corner::TopLeft.opposite_corner(), Corner::BottomRight); + /// ``` + pub fn opposite_corner(self) -> Self { + match self { + Corner::TopLeft => Corner::BottomRight, + Corner::TopRight => Corner::BottomLeft, + Corner::BottomLeft => Corner::TopRight, + Corner::BottomRight => Corner::TopLeft, + } + } + + /// Returns the corner across from this corner, moving along the specified axis. + /// + /// # Examples + /// + /// ``` + /// # use zed::Corner; + /// let result = Corner::TopLeft.other_side_corner_along(Axis::Horizontal); + /// assert_eq!(result, Corner::TopRight); + /// ``` + pub fn other_side_corner_along(self, axis: Axis) -> Self { + match axis { + Axis::Vertical => match self { + Corner::TopLeft => Corner::BottomLeft, + Corner::TopRight => Corner::BottomRight, + Corner::BottomLeft => Corner::TopLeft, + Corner::BottomRight => Corner::TopRight, + }, + Axis::Horizontal => match self { + Corner::TopLeft => Corner::TopRight, + Corner::TopRight => Corner::TopLeft, + Corner::BottomLeft => Corner::BottomRight, + Corner::BottomRight => Corner::BottomLeft, + }, + } + } +} + /// Represents the corners of a box in a 2D space, such as border radius. /// /// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`. @@ -1914,6 +2026,33 @@ where bottom_left: value, } } + + /// Returns the requested corner. + /// + /// # Returns + /// + /// A `Point` representing the corner requested by the parameter. + /// + /// # Examples + /// + /// ``` + /// # use zed::{Corner, Corners}; + /// let corners = Corners { + /// top_left: 1, + /// top_right: 2, + /// bottom_left: 3, + /// bottom_right: 4 + /// }; + /// assert_eq!(corners.corner(Corner::BottomLeft), 3); + /// ``` + pub fn corner(&self, corner: Corner) -> T { + match corner { + Corner::TopLeft => self.top_left.clone(), + Corner::TopRight => self.top_right.clone(), + Corner::BottomLeft => self.bottom_left.clone(), + Corner::BottomRight => self.bottom_right.clone(), + } + } } impl Corners { diff --git a/crates/gpui/src/style.rs b/crates/gpui/src/style.rs index c35f4926e0856..87c3de5ca2ae3 100644 --- a/crates/gpui/src/style.rs +++ b/crates/gpui/src/style.rs @@ -509,7 +509,7 @@ impl Style { } => None, _ => { let mut min = bounds.origin; - let mut max = bounds.lower_right(); + let mut max = bounds.bottom_right(); if self .border_color @@ -530,12 +530,12 @@ impl Style { // x visible, y hidden (true, false) => Bounds::from_corners( point(min.x, bounds.origin.y), - point(max.x, bounds.lower_right().y), + point(max.x, bounds.bottom_right().y), ), // x hidden, y visible (false, true) => Bounds::from_corners( point(bounds.origin.x, min.y), - point(bounds.lower_right().x, max.y), + point(bounds.bottom_right().x, max.y), ), // both hidden (false, false) => Bounds::from_corners(min, max), @@ -604,19 +604,19 @@ impl Style { let top_bounds = Bounds::from_corners( bounds.origin, - bounds.upper_right() + point(Pixels::ZERO, max_border_width.max(max_corner_radius)), + bounds.top_right() + point(Pixels::ZERO, max_border_width.max(max_corner_radius)), ); let bottom_bounds = Bounds::from_corners( - bounds.lower_left() - point(Pixels::ZERO, max_border_width.max(max_corner_radius)), - bounds.lower_right(), + bounds.bottom_left() - point(Pixels::ZERO, max_border_width.max(max_corner_radius)), + bounds.bottom_right(), ); let left_bounds = Bounds::from_corners( - top_bounds.lower_left(), + top_bounds.bottom_left(), bottom_bounds.origin + point(max_border_width, Pixels::ZERO), ); let right_bounds = Bounds::from_corners( - top_bounds.lower_right() - point(max_border_width, Pixels::ZERO), - bottom_bounds.upper_right(), + top_bounds.bottom_right() - point(max_border_width, Pixels::ZERO), + bottom_bounds.top_right(), ); let mut background = self.border_color.unwrap_or_default(); diff --git a/crates/inline_completion_button/src/inline_completion_button.rs b/crates/inline_completion_button/src/inline_completion_button.rs index ab32d127f0a27..1f52cca3be38b 100644 --- a/crates/inline_completion_button/src/inline_completion_button.rs +++ b/crates/inline_completion_button/src/inline_completion_button.rs @@ -4,7 +4,7 @@ use editor::{scroll::Autoscroll, Editor}; use feature_flags::{FeatureFlagAppExt, ZetaFeatureFlag}; use fs::Fs; use gpui::{ - actions, div, Action, AnchorCorner, AppContext, AsyncWindowContext, Entity, IntoElement, + actions, div, Action, AppContext, AsyncWindowContext, Corner, Entity, IntoElement, ParentElement, Render, Subscription, View, ViewContext, WeakView, WindowContext, }; use language::{ @@ -123,7 +123,7 @@ impl Render for InlineCompletionButton { _ => this.update(cx, |this, cx| this.build_copilot_start_menu(cx)), }) }) - .anchor(AnchorCorner::BottomRight) + .anchor(Corner::BottomRight) .trigger( IconButton::new("copilot-icon", icon) .tooltip(|cx| Tooltip::text("GitHub Copilot", cx)), @@ -191,7 +191,7 @@ impl Render for InlineCompletionButton { ), _ => None, }) - .anchor(AnchorCorner::BottomRight) + .anchor(Corner::BottomRight) .trigger( IconButton::new("supermaven-icon", icon) .tooltip(move |cx| Tooltip::text(tooltip_text.clone(), cx)), diff --git a/crates/language_model_selector/src/language_model_selector.rs b/crates/language_model_selector/src/language_model_selector.rs index fb41eb6a127a0..7d77bfd6ea2f9 100644 --- a/crates/language_model_selector/src/language_model_selector.rs +++ b/crates/language_model_selector/src/language_model_selector.rs @@ -107,7 +107,7 @@ impl RenderOnce for LanguageModelSelectorPopoverMenu { PopoverMenu::new("model-switcher") .menu(move |_cx| Some(language_model_selector.clone())) .trigger(self.trigger) - .attach(gpui::AnchorCorner::BottomLeft) + .attach(gpui::Corner::BottomLeft) .when_some(self.handle.clone(), |menu, handle| menu.with_handle(handle)) } } diff --git a/crates/language_tools/src/lsp_log.rs b/crates/language_tools/src/lsp_log.rs index bd8df70e13876..83e85db8888b1 100644 --- a/crates/language_tools/src/lsp_log.rs +++ b/crates/language_tools/src/lsp_log.rs @@ -3,7 +3,7 @@ use copilot::Copilot; use editor::{actions::MoveToEnd, Editor, EditorEvent}; use futures::{channel::mpsc, StreamExt}; use gpui::{ - actions, div, AnchorCorner, AppContext, Context, EventEmitter, FocusHandle, FocusableView, + actions, div, AppContext, Context, Corner, EventEmitter, FocusHandle, FocusableView, IntoElement, Model, ModelContext, ParentElement, Render, Styled, Subscription, View, ViewContext, VisualContext, WeakModel, WindowContext, }; @@ -1158,7 +1158,7 @@ impl Render for LspLogToolbarItemView { .collect(); let log_toolbar_view = cx.view().clone(); let lsp_menu = PopoverMenu::new("LspLogView") - .anchor(AnchorCorner::TopLeft) + .anchor(Corner::TopLeft) .trigger(Button::new( "language_server_menu_header", current_server @@ -1214,7 +1214,7 @@ impl Render for LspLogToolbarItemView { let rpc_trace_enabled = server.rpc_trace_enabled; let log_view = log_view.clone(); PopoverMenu::new("LspViewSelector") - .anchor(AnchorCorner::TopLeft) + .anchor(Corner::TopLeft) .trigger(Button::new( "language_server_menu_header", server.selected_entry.label(), @@ -1301,7 +1301,7 @@ impl Render for LspLogToolbarItemView { let log_view = log_view.clone(); div().child( PopoverMenu::new("lsp-trace-level-menu") - .anchor(AnchorCorner::TopLeft) + .anchor(Corner::TopLeft) .trigger(Button::new( "language_server_trace_level_selector", "Trace level", @@ -1359,7 +1359,7 @@ impl Render for LspLogToolbarItemView { let log_view = log_view.clone(); div().child( PopoverMenu::new("lsp-log-level-menu") - .anchor(AnchorCorner::TopLeft) + .anchor(Corner::TopLeft) .trigger(Button::new( "language_server_log_level_selector", "Log level", diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index 24ae0ba4a2f06..586ae89a5bb05 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -4257,7 +4257,7 @@ impl OutlinePanel { deferred( anchored() .position(*position) - .anchor(gpui::AnchorCorner::TopLeft) + .anchor(gpui::Corner::TopLeft) .child(menu.clone()), ) .with_priority(1) diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 1f4fd50f41051..34f7cc84f67ef 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -4102,7 +4102,7 @@ impl Render for ProjectPanel { deferred( anchored() .position(*position) - .anchor(gpui::AnchorCorner::TopLeft) + .anchor(gpui::Corner::TopLeft) .child(menu.clone()), ) .with_priority(1) diff --git a/crates/repl/src/components/kernel_options.rs b/crates/repl/src/components/kernel_options.rs index c83e6fbc9c2fc..77fdffd1e5e07 100644 --- a/crates/repl/src/components/kernel_options.rs +++ b/crates/repl/src/components/kernel_options.rs @@ -253,7 +253,7 @@ impl RenderOnce for KernelSelector { PopoverMenu::new("kernel-switcher") .menu(move |_cx| Some(picker_view.clone())) .trigger(self.trigger) - .attach(gpui::AnchorCorner::BottomLeft) + .attach(gpui::Corner::BottomLeft) .when_some(self.handle, |menu, handle| menu.with_handle(handle)) } } diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 51a95bc3ee2ee..8f1afad3d5509 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -1461,7 +1461,7 @@ impl Terminal { fn drag_line_delta(&self, e: &MouseMoveEvent, region: Bounds) -> Option { //TODO: Why do these need to be doubled? Probably the same problem that the IME has let top = region.origin.y + (self.last_content.size.line_height * 2.); - let bottom = region.lower_left().y - (self.last_content.size.line_height * 2.); + let bottom = region.bottom_left().y - (self.last_content.size.line_height * 2.); let scroll_delta = if e.position.y < top { (top - e.position.y).pow(1.1) } else if e.position.y > bottom { diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index da1bb7c4068fd..04e2c8fdd49aa 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -12,7 +12,7 @@ use collections::HashMap; use db::kvp::KEY_VALUE_STORE; use futures::future::join_all; use gpui::{ - actions, Action, AnchorCorner, AnyView, AppContext, AsyncWindowContext, Entity, EventEmitter, + actions, Action, AnyView, AppContext, AsyncWindowContext, Corner, Entity, EventEmitter, ExternalPaths, FocusHandle, FocusableView, IntoElement, Model, ParentElement, Pixels, Render, Styled, Task, View, ViewContext, VisualContext, WeakView, WindowContext, }; @@ -141,7 +141,7 @@ impl TerminalPanel { .icon_size(IconSize::Small) .tooltip(|cx| Tooltip::text("New…", cx)), ) - .anchor(AnchorCorner::TopRight) + .anchor(Corner::TopRight) .with_handle(pane.new_item_context_menu_handle.clone()) .menu(move |cx| { let focus_handle = focus_handle.clone(); @@ -171,7 +171,7 @@ impl TerminalPanel { .icon_size(IconSize::Small) .tooltip(|cx| Tooltip::text("Split Pane", cx)), ) - .anchor(AnchorCorner::TopRight) + .anchor(Corner::TopRight) .with_handle(pane.split_item_context_menu_handle.clone()) .menu({ let split_context = split_context.clone(); diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 9f101fe0575b0..0211661b5b886 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -987,7 +987,7 @@ impl Render for TerminalView { deferred( anchored() .position(*position) - .anchor(gpui::AnchorCorner::TopLeft) + .anchor(gpui::Corner::TopLeft) .child(menu.clone()), ) .with_priority(1) diff --git a/crates/title_bar/src/collab.rs b/crates/title_bar/src/collab.rs index d1eafe8da752d..671fa1870aba2 100644 --- a/crates/title_bar/src/collab.rs +++ b/crates/title_bar/src/collab.rs @@ -73,17 +73,17 @@ fn render_color_ribbon(color: Hsla) -> impl Element { let height = bounds.size.height; let horizontal_offset = height; let vertical_offset = px(height.0 / 2.0); - let mut path = Path::new(bounds.lower_left()); + let mut path = Path::new(bounds.bottom_left()); path.curve_to( bounds.origin + point(horizontal_offset, vertical_offset), bounds.origin + point(px(0.0), vertical_offset), ); - path.line_to(bounds.upper_right() + point(-horizontal_offset, vertical_offset)); + path.line_to(bounds.top_right() + point(-horizontal_offset, vertical_offset)); path.curve_to( - bounds.lower_right(), - bounds.upper_right() + point(px(0.0), vertical_offset), + bounds.bottom_right(), + bounds.top_right() + point(px(0.0), vertical_offset), ); - path.line_to(bounds.lower_left()); + path.line_to(bounds.bottom_left()); cx.paint_path(path, color); }, ) diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index b6e08e21262ef..a9b650c57e040 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -615,7 +615,7 @@ impl TitleBar { .style(ButtonStyle::Subtle) .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)), ) - .anchor(gpui::AnchorCorner::TopRight) + .anchor(gpui::Corner::TopRight) } else { PopoverMenu::new("user-menu") .menu(|cx| { diff --git a/crates/ui/src/components/dropdown_menu.rs b/crates/ui/src/components/dropdown_menu.rs index 2fa32894b4078..5d537954722c5 100644 --- a/crates/ui/src/components/dropdown_menu.rs +++ b/crates/ui/src/components/dropdown_menu.rs @@ -1,5 +1,5 @@ #![allow(missing_docs)] -use gpui::{AnchorCorner, ClickEvent, CursorStyle, MouseButton, View}; +use gpui::{ClickEvent, Corner, CursorStyle, MouseButton, View}; use crate::{prelude::*, ContextMenu, PopoverMenu}; @@ -46,7 +46,7 @@ impl RenderOnce for DropdownMenu { .full_width(self.full_width) .menu(move |_cx| Some(self.menu.clone())) .trigger(DropdownMenuTrigger::new(self.label).full_width(self.full_width)) - .attach(AnchorCorner::BottomLeft) + .attach(Corner::BottomLeft) } } diff --git a/crates/ui/src/components/popover_menu.rs b/crates/ui/src/components/popover_menu.rs index d9d502efeaab0..100d5f6332e99 100644 --- a/crates/ui/src/components/popover_menu.rs +++ b/crates/ui/src/components/popover_menu.rs @@ -3,10 +3,10 @@ use std::{cell::RefCell, rc::Rc}; use gpui::{ - anchored, deferred, div, point, prelude::FluentBuilder, px, size, AnchorCorner, AnyElement, - Bounds, DismissEvent, DispatchPhase, Element, ElementId, GlobalElementId, HitboxId, - InteractiveElement, IntoElement, LayoutId, Length, ManagedView, MouseDownEvent, ParentElement, - Pixels, Point, Style, View, VisualContext, WindowContext, + anchored, deferred, div, point, prelude::FluentBuilder, px, size, AnyElement, Bounds, Corner, + DismissEvent, DispatchPhase, Element, ElementId, GlobalElementId, HitboxId, InteractiveElement, + IntoElement, LayoutId, Length, ManagedView, MouseDownEvent, ParentElement, Pixels, Point, + Style, View, VisualContext, WindowContext, }; use crate::prelude::*; @@ -89,8 +89,8 @@ pub struct PopoverMenu { >, >, menu_builder: Option Option> + 'static>>, - anchor: AnchorCorner, - attach: Option, + anchor: Corner, + attach: Option, offset: Option>, trigger_handle: Option>, full_width: bool, @@ -103,7 +103,7 @@ impl PopoverMenu { id: id.into(), child_builder: None, menu_builder: None, - anchor: AnchorCorner::TopLeft, + anchor: Corner::TopLeft, attach: None, offset: None, trigger_handle: None, @@ -140,13 +140,13 @@ impl PopoverMenu { /// anchor defines which corner of the menu to anchor to the attachment point /// (by default the cursor position, but see attach) - pub fn anchor(mut self, anchor: AnchorCorner) -> Self { + pub fn anchor(mut self, anchor: Corner) -> Self { self.anchor = anchor; self } /// attach defines which corner of the handle to attach the menu's anchor to - pub fn attach(mut self, attach: AnchorCorner) -> Self { + pub fn attach(mut self, attach: Corner) -> Self { self.attach = Some(attach); self } @@ -157,12 +157,12 @@ impl PopoverMenu { self } - fn resolved_attach(&self) -> AnchorCorner { + fn resolved_attach(&self) -> Corner { self.attach.unwrap_or(match self.anchor { - AnchorCorner::TopLeft => AnchorCorner::BottomLeft, - AnchorCorner::TopRight => AnchorCorner::BottomRight, - AnchorCorner::BottomLeft => AnchorCorner::TopLeft, - AnchorCorner::BottomRight => AnchorCorner::TopRight, + Corner::TopLeft => Corner::BottomLeft, + Corner::TopRight => Corner::BottomRight, + Corner::BottomLeft => Corner::TopLeft, + Corner::BottomRight => Corner::TopRight, }) } @@ -171,8 +171,8 @@ impl PopoverMenu { // Default offset = 4px padding + 1px border let offset = rems_from_px(5.) * cx.rem_size(); match self.anchor { - AnchorCorner::TopRight | AnchorCorner::BottomRight => point(offset, px(0.)), - AnchorCorner::TopLeft | AnchorCorner::BottomLeft => point(-offset, px(0.)), + Corner::TopRight | Corner::BottomRight => point(offset, px(0.)), + Corner::TopLeft | Corner::BottomLeft => point(-offset, px(0.)), } }) } @@ -259,7 +259,7 @@ impl Element for PopoverMenu { .anchor(self.anchor); if let Some(child_bounds) = element_state.child_bounds { anchored = anchored.position( - self.resolved_attach().corner(child_bounds) + self.resolved_offset(cx), + child_bounds.corner(self.resolved_attach()) + self.resolved_offset(cx), ); } let mut element = deferred(anchored.child(div().occlude().child(menu.clone()))) diff --git a/crates/ui/src/components/right_click_menu.rs b/crates/ui/src/components/right_click_menu.rs index f68b85016c4d1..03e168cbca134 100644 --- a/crates/ui/src/components/right_click_menu.rs +++ b/crates/ui/src/components/right_click_menu.rs @@ -3,18 +3,17 @@ use std::{cell::RefCell, rc::Rc}; use gpui::{ - anchored, deferred, div, px, AnchorCorner, AnyElement, Bounds, DismissEvent, DispatchPhase, - Element, ElementId, GlobalElementId, Hitbox, InteractiveElement, IntoElement, LayoutId, - ManagedView, MouseButton, MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext, - WindowContext, + anchored, deferred, div, px, AnyElement, Bounds, Corner, DismissEvent, DispatchPhase, Element, + ElementId, GlobalElementId, Hitbox, InteractiveElement, IntoElement, LayoutId, ManagedView, + MouseButton, MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext, WindowContext, }; pub struct RightClickMenu { id: ElementId, child_builder: Option AnyElement + 'static>>, menu_builder: Option View + 'static>>, - anchor: Option, - attach: Option, + anchor: Option, + attach: Option, } impl RightClickMenu { @@ -30,13 +29,13 @@ impl RightClickMenu { /// anchor defines which corner of the menu to anchor to the attachment point /// (by default the cursor position, but see attach) - pub fn anchor(mut self, anchor: AnchorCorner) -> Self { + pub fn anchor(mut self, anchor: Corner) -> Self { self.anchor = Some(anchor); self } /// attach defines which corner of the handle to attach the menu's anchor to - pub fn attach(mut self, attach: AnchorCorner) -> Self { + pub fn attach(mut self, attach: Corner) -> Self { self.attach = Some(attach); self } @@ -238,7 +237,7 @@ impl Element for RightClickMenu { *menu.borrow_mut() = Some(new_menu); *position.borrow_mut() = if let Some(child_bounds) = child_bounds { if let Some(attach) = attach { - attach.corner(child_bounds) + child_bounds.corner(attach) } else { cx.mouse_position() } diff --git a/crates/ui/src/components/scrollbar.rs b/crates/ui/src/components/scrollbar.rs index 7dbda4b3fbccf..dea8b3a396544 100644 --- a/crates/ui/src/components/scrollbar.rs +++ b/crates/ui/src/components/scrollbar.rs @@ -236,12 +236,12 @@ impl Element for Scrollbar { let padded_bounds = if is_vertical { Bounds::from_corners( bounds.origin + point(Pixels::ZERO, extra_padding), - bounds.lower_right() - point(Pixels::ZERO, extra_padding * 3), + bounds.bottom_right() - point(Pixels::ZERO, extra_padding * 3), ) } else { Bounds::from_corners( bounds.origin + point(extra_padding, Pixels::ZERO), - bounds.lower_right() - point(extra_padding * 3, Pixels::ZERO), + bounds.bottom_right() - point(extra_padding * 3, Pixels::ZERO), ) }; diff --git a/crates/ui/src/components/stories/context_menu.rs b/crates/ui/src/components/stories/context_menu.rs index e7218a686726a..5b4f88457b961 100644 --- a/crates/ui/src/components/stories/context_menu.rs +++ b/crates/ui/src/components/stories/context_menu.rs @@ -1,4 +1,4 @@ -use gpui::{actions, AnchorCorner, Render, View}; +use gpui::{actions, Corner, Render, View}; use story::Story; use crate::prelude::*; @@ -47,8 +47,8 @@ impl Render for ContextMenuStory { .child( right_click_menu("test1") .trigger(Label::new("BOTTOM LEFT")) - .anchor(AnchorCorner::BottomLeft) - .attach(AnchorCorner::TopLeft) + .anchor(Corner::BottomLeft) + .attach(Corner::TopLeft) .menu(move |cx| build_menu(cx, "bottom left")), ), ) @@ -60,14 +60,14 @@ impl Render for ContextMenuStory { .child( right_click_menu("test3") .trigger(Label::new("TOP RIGHT")) - .anchor(AnchorCorner::TopRight) + .anchor(Corner::TopRight) .menu(move |cx| build_menu(cx, "top right")), ) .child( right_click_menu("test4") .trigger(Label::new("BOTTOM RIGHT")) - .anchor(AnchorCorner::BottomRight) - .attach(AnchorCorner::TopRight) + .anchor(Corner::BottomRight) + .attach(Corner::TopRight) .menu(move |cx| build_menu(cx, "bottom right")), ), ) diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 73fbbda3897f8..fa69c9aa6127e 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -3,10 +3,10 @@ use crate::{status_bar::StatusItemView, Workspace}; use crate::{DraggedDock, Event, Pane}; use client::proto; use gpui::{ - deferred, div, px, Action, AnchorCorner, AnyView, AppContext, Axis, Entity, EntityId, - EventEmitter, FocusHandle, FocusableView, IntoElement, KeyContext, MouseButton, MouseDownEvent, - MouseUpEvent, ParentElement, Render, SharedString, StyleRefinement, Styled, Subscription, View, - ViewContext, VisualContext, WeakView, WindowContext, + deferred, div, px, Action, AnyView, AppContext, Axis, Corner, Entity, EntityId, EventEmitter, + FocusHandle, FocusableView, IntoElement, KeyContext, MouseButton, MouseDownEvent, MouseUpEvent, + ParentElement, Render, SharedString, StyleRefinement, Styled, Subscription, View, ViewContext, + VisualContext, WeakView, WindowContext, }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -719,10 +719,8 @@ impl Render for PanelButtons { let dock_position = dock.position; let (menu_anchor, menu_attach) = match dock.position { - DockPosition::Left => (AnchorCorner::BottomLeft, AnchorCorner::TopLeft), - DockPosition::Bottom | DockPosition::Right => { - (AnchorCorner::BottomRight, AnchorCorner::TopRight) - } + DockPosition::Left => (Corner::BottomLeft, Corner::TopLeft), + DockPosition::Bottom | DockPosition::Right => (Corner::BottomRight, Corner::TopRight), }; let buttons = dock diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 4ca7f3cc1c062..fd14755d3852f 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -14,8 +14,8 @@ use anyhow::Result; use collections::{BTreeSet, HashMap, HashSet, VecDeque}; use futures::{stream::FuturesUnordered, StreamExt}; use gpui::{ - actions, anchored, deferred, impl_actions, prelude::*, Action, AnchorCorner, AnyElement, - AppContext, AsyncWindowContext, ClickEvent, ClipboardItem, Div, DragMoveEvent, EntityId, + actions, anchored, deferred, impl_actions, prelude::*, Action, AnyElement, AppContext, + AsyncWindowContext, ClickEvent, ClipboardItem, Corner, Div, DragMoveEvent, EntityId, EventEmitter, ExternalPaths, FocusHandle, FocusOutEvent, FocusableView, KeyContext, Model, MouseButton, MouseDownEvent, NavigationDirection, Pixels, Point, PromptLevel, Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakFocusHandle, WeakView, @@ -432,7 +432,7 @@ impl Pane { .icon_size(IconSize::Small) .tooltip(|cx| Tooltip::text("New...", cx)), ) - .anchor(AnchorCorner::TopRight) + .anchor(Corner::TopRight) .with_handle(pane.new_item_context_menu_handle.clone()) .menu(move |cx| { Some(ContextMenu::build(cx, |menu, _| { @@ -465,7 +465,7 @@ impl Pane { .icon_size(IconSize::Small) .tooltip(|cx| Tooltip::text("Split Pane", cx)), ) - .anchor(AnchorCorner::TopRight) + .anchor(Corner::TopRight) .with_handle(pane.split_item_context_menu_handle.clone()) .menu(move |cx| { ContextMenu::build(cx, |menu, _| { @@ -2506,12 +2506,7 @@ impl Pane { pub fn render_menu_overlay(menu: &View) -> Div { div().absolute().bottom_0().right_0().size_0().child( - deferred( - anchored() - .anchor(AnchorCorner::TopRight) - .child(menu.clone()), - ) - .with_priority(1), + deferred(anchored().anchor(Corner::TopRight).child(menu.clone())).with_priority(1), ) } diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 4461e58925862..722c48f0585ae 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -758,9 +758,9 @@ impl SplitDirection { pub fn edge(&self, rect: Bounds) -> Pixels { match self { Self::Up => rect.origin.y, - Self::Down => rect.lower_left().y, - Self::Left => rect.lower_left().x, - Self::Right => rect.lower_right().x, + Self::Down => rect.bottom_left().y, + Self::Left => rect.bottom_left().x, + Self::Right => rect.bottom_right().x, } } @@ -771,7 +771,7 @@ impl SplitDirection { size: size(bounds.size.width, length), }, Self::Down => Bounds { - origin: point(bounds.lower_left().x, bounds.lower_left().y - length), + origin: point(bounds.bottom_left().x, bounds.bottom_left().y - length), size: size(bounds.size.width, length), }, Self::Left => Bounds { @@ -779,7 +779,7 @@ impl SplitDirection { size: size(length, bounds.size.height), }, Self::Right => Bounds { - origin: point(bounds.lower_right().x - length, bounds.lower_left().y), + origin: point(bounds.bottom_right().x - length, bounds.bottom_left().y), size: size(length, bounds.size.height), }, } diff --git a/crates/zed/src/zed/quick_action_bar.rs b/crates/zed/src/zed/quick_action_bar.rs index 5f11cfa44aa79..95d5d59943a0f 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -10,7 +10,7 @@ use editor::actions::{ }; use editor::{Editor, EditorSettings}; use gpui::{ - Action, AnchorCorner, ClickEvent, ElementId, EventEmitter, FocusHandle, FocusableView, + Action, ClickEvent, Corner, ElementId, EventEmitter, FocusHandle, FocusableView, InteractiveElement, ParentElement, Render, Styled, Subscription, View, ViewContext, WeakView, }; use search::{buffer_search, BufferSearchBar}; @@ -168,7 +168,7 @@ impl Render for QuickActionBar { }), ) .with_handle(self.toggle_selections_handle.clone()) - .anchor(AnchorCorner::TopRight) + .anchor(Corner::TopRight) .menu(move |cx| { let focus = focus.clone(); let menu = ContextMenu::build(cx, move |menu, _| { @@ -217,7 +217,7 @@ impl Render for QuickActionBar { this.tooltip(|cx| Tooltip::text("Editor Controls", cx)) }), ) - .anchor(AnchorCorner::TopRight) + .anchor(Corner::TopRight) .with_handle(self.toggle_settings_handle.clone()) .menu(move |cx| { let menu = ContextMenu::build(cx, |mut menu, _| {