mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
ui: Improve submenu rendering when there's not enough space (#54773)
This PR makes the submenu render on the left of the trigger if there's not enough space (200px of available width) on the right. This improves the rendering overall, I believe, as it's better than the submenu rendering _on top_ of the parent menu. Release Notes: - N/A
This commit is contained in:
parent
442790c9bb
commit
77805330c0
1 changed files with 37 additions and 10 deletions
|
|
@ -26,6 +26,7 @@ struct OpenSubmenu {
|
|||
entity: Entity<ContextMenu>,
|
||||
trigger_bounds: Option<Bounds<Pixels>>,
|
||||
offset: Option<Pixels>,
|
||||
flip_left: bool,
|
||||
_dismiss_subscription: Subscription,
|
||||
}
|
||||
|
||||
|
|
@ -1301,6 +1302,11 @@ impl ContextMenu {
|
|||
let (submenu, dismiss_subscription) =
|
||||
Self::create_submenu(builder, cx.entity(), window, cx);
|
||||
|
||||
let flip_left = self
|
||||
.main_menu_observed_bounds
|
||||
.get()
|
||||
.is_some_and(|bounds| bounds.right() + px(200.0) > window.viewport_size().width);
|
||||
|
||||
// If we're switching from one submenu item to another, throw away any previously-captured
|
||||
// offset so we don't reuse a stale position.
|
||||
self.main_menu_observed_bounds.set(None);
|
||||
|
|
@ -1322,6 +1328,7 @@ impl ContextMenu {
|
|||
entity: submenu,
|
||||
trigger_bounds,
|
||||
offset: None,
|
||||
flip_left,
|
||||
_dismiss_subscription: dismiss_subscription,
|
||||
});
|
||||
|
||||
|
|
@ -1665,6 +1672,7 @@ impl ContextMenu {
|
|||
ix: usize,
|
||||
submenu: Entity<ContextMenu>,
|
||||
offset: Pixels,
|
||||
flip_left: bool,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let bounds_cell = self.main_menu_observed_bounds.clone();
|
||||
|
|
@ -1684,9 +1692,9 @@ impl ContextMenu {
|
|||
div()
|
||||
.id(("submenu-container", ix))
|
||||
.absolute()
|
||||
.left_full()
|
||||
.ml_neg_0p5()
|
||||
.top(offset)
|
||||
.when(flip_left, |this| this.right_full().mr_neg_0p5())
|
||||
.when(!flip_left, |this| this.left_full().ml_neg_0p5())
|
||||
.on_hover(cx.listener(|this, hovered, _, _| {
|
||||
if *hovered {
|
||||
this.hover_target = HoverTarget::Submenu;
|
||||
|
|
@ -1694,7 +1702,11 @@ impl ContextMenu {
|
|||
}))
|
||||
.child(
|
||||
anchored()
|
||||
.anchor(Anchor::TopLeft)
|
||||
.anchor(if flip_left {
|
||||
Anchor::TopRight
|
||||
} else {
|
||||
Anchor::TopLeft
|
||||
})
|
||||
.snap_to_window_with_margin(px(8.0))
|
||||
.child(
|
||||
div()
|
||||
|
|
@ -2093,7 +2105,12 @@ impl Render for ContextMenu {
|
|||
}
|
||||
|
||||
focus_submenu = Some(open_submenu.entity.read(cx).focus_handle.clone());
|
||||
Some((open_submenu.item_index, open_submenu.entity.clone(), offset))
|
||||
Some((
|
||||
open_submenu.item_index,
|
||||
open_submenu.entity.clone(),
|
||||
offset,
|
||||
open_submenu.flip_left,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -2262,9 +2279,14 @@ impl Render for ContextMenu {
|
|||
.child(render_aside(aside, cx))
|
||||
}))
|
||||
})
|
||||
.when_some(submenu_container, |this, (ix, submenu, offset)| {
|
||||
this.child(self.render_submenu_container(ix, submenu, offset, cx))
|
||||
})
|
||||
.when_some(
|
||||
submenu_container,
|
||||
|this, (ix, submenu, offset, flip_left)| {
|
||||
this.child(
|
||||
self.render_submenu_container(ix, submenu, offset, flip_left, cx),
|
||||
)
|
||||
},
|
||||
)
|
||||
} else {
|
||||
v_flex()
|
||||
.w_full()
|
||||
|
|
@ -2273,9 +2295,14 @@ impl Render for ContextMenu {
|
|||
.justify_end()
|
||||
.children(aside.map(|(_, aside)| render_aside(aside, cx)))
|
||||
.child(render_menu(cx, window))
|
||||
.when_some(submenu_container, |this, (ix, submenu, offset)| {
|
||||
this.child(self.render_submenu_container(ix, submenu, offset, cx))
|
||||
})
|
||||
.when_some(
|
||||
submenu_container,
|
||||
|this, (ix, submenu, offset, flip_left)| {
|
||||
this.child(
|
||||
self.render_submenu_container(ix, submenu, offset, flip_left, cx),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue