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::{
|
use gpui::{
|
||||||
AnyElement, App, ClickEvent, Div, ElementId, Entity, InteractiveElement, IntoElement,
|
AnyElement, App, ClickEvent, Div, ElementId, Entity, InteractiveElement, IntoElement,
|
||||||
MouseButton, ParentElement, Pixels, Point, RenderOnce, SharedString, Stateful, Styled, Window,
|
MouseButton, ParentElement, Pixels, Point, RenderOnce, SharedString, Stateful, StyleRefinement,
|
||||||
div, prelude::*,
|
Styled, Window, div, prelude::*,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
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)]
|
#[derive(IntoElement)]
|
||||||
pub struct ContextMenu {
|
pub struct ContextMenu {
|
||||||
id: ElementId,
|
id: ElementId,
|
||||||
menu: Menu,
|
menu: Menu,
|
||||||
request: Option<Option<(u64, Point<Pixels>)>>,
|
request: Option<Option<(u64, Point<Pixels>)>>,
|
||||||
children: SmallVec<[AnyElement; 2]>,
|
children: SmallVec<[AnyElement; 2]>,
|
||||||
|
base: Div,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextMenu {
|
impl ContextMenu {
|
||||||
@@ -237,6 +238,7 @@ impl ContextMenu {
|
|||||||
menu,
|
menu,
|
||||||
request: None,
|
request: None,
|
||||||
children: SmallVec::new(),
|
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 {
|
impl RenderOnce for ContextMenu {
|
||||||
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
let state = state(&self.id, window, cx);
|
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());
|
let (open, shut, menu) = (state.clone(), state.clone(), self.menu.clone());
|
||||||
div()
|
self.base
|
||||||
.id(self.id.clone())
|
.id(self.id.clone())
|
||||||
.relative()
|
.relative()
|
||||||
.when(self.request.is_none(), |host| {
|
.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.ran.clone()), ["copy"]);
|
||||||
assert_eq!(view.read_with(cx, |wheel, _| wheel.enters_above), 0);
|
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