Menus · ContextMenu: styles size its host, so a list inside can fill it
This commit is contained in:
2 files changed
+45
-4
No files matched your search
+12
-4
@@ -2,8 +2,8 @@ use std::rc::Rc;
|
||||
|
||||
use gpui::{
|
||||
AnyElement, App, ClickEvent, Div, ElementId, Entity, InteractiveElement, IntoElement,
|
||||
MouseButton, ParentElement, Pixels, Point, RenderOnce, SharedString, Stateful, Styled, Window,
|
||||
div, prelude::*,
|
||||
MouseButton, ParentElement, Pixels, Point, RenderOnce, SharedString, Stateful, StyleRefinement,
|
||||
Styled, Window, div, prelude::*,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
@@ -221,13 +221,14 @@ impl RenderOnce for SplitButton {
|
||||
}
|
||||
}
|
||||
|
||||
/// Its children, and a menu that opens at the pointer on a right click.
|
||||
/// Its children, and a menu that opens at the pointer on a right click. Styles size the host, so a list inside can fill it.
|
||||
#[derive(IntoElement)]
|
||||
pub struct ContextMenu {
|
||||
id: ElementId,
|
||||
menu: Menu,
|
||||
request: Option<Option<(u64, Point<Pixels>)>>,
|
||||
children: SmallVec<[AnyElement; 2]>,
|
||||
base: Div,
|
||||
}
|
||||
|
||||
impl ContextMenu {
|
||||
@@ -237,6 +238,7 @@ impl ContextMenu {
|
||||
menu,
|
||||
request: None,
|
||||
children: SmallVec::new(),
|
||||
base: div(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,6 +255,12 @@ impl ParentElement for ContextMenu {
|
||||
}
|
||||
}
|
||||
|
||||
impl Styled for ContextMenu {
|
||||
fn style(&mut self) -> &mut StyleRefinement {
|
||||
self.base.style()
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for ContextMenu {
|
||||
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
let state = state(&self.id, window, cx);
|
||||
@@ -265,7 +273,7 @@ impl RenderOnce for ContextMenu {
|
||||
}
|
||||
}
|
||||
let (open, shut, menu) = (state.clone(), state.clone(), self.menu.clone());
|
||||
div()
|
||||
self.base
|
||||
.id(self.id.clone())
|
||||
.relative()
|
||||
.when(self.request.is_none(), |host| {
|
||||
|
||||
@@ -246,3 +246,36 @@ fn pie_confirm_keys_stay_inside_and_ignore_modifiers(cx: &mut TestAppContext) {
|
||||
assert_eq!(view.read_with(cx, |wheel, _| wheel.ran.clone()), ["copy"]);
|
||||
assert_eq!(view.read_with(cx, |wheel, _| wheel.enters_above), 0);
|
||||
}
|
||||
|
||||
/// A sized context menu over a child that fills it.
|
||||
struct Filled {
|
||||
seen: std::rc::Rc<std::cell::Cell<f32>>,
|
||||
}
|
||||
|
||||
impl Render for Filled {
|
||||
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
||||
let seen = self.seen.clone();
|
||||
let fill = gpui::canvas(
|
||||
move |bounds, _, _| seen.set(f32::from(bounds.size.height)),
|
||||
|_, _, _, _| {},
|
||||
)
|
||||
.size_full();
|
||||
div().h(px(200.)).w(px(100.)).child(
|
||||
crate::menus::ContextMenu::new("filled", crate::menus::Menu::new())
|
||||
.size_full()
|
||||
.child(fill),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_sized_context_menu_lets_its_child_fill_it(cx: &mut TestAppContext) {
|
||||
cx.update(Theme::init);
|
||||
let seen = std::rc::Rc::new(std::cell::Cell::new(0.0));
|
||||
let (_, cx) = cx.add_window_view({
|
||||
let seen = seen.clone();
|
||||
move |_, _| Filled { seen }
|
||||
});
|
||||
settle(cx);
|
||||
assert_eq!(seen.get(), 200.0);
|
||||
}
|
||||
Reference in new issue
Block a user