Dismiss context menu when (right-)mousing down outside of it

This commit is contained in:
Antonio Scandurra 2022-05-28 08:51:46 +02:00
parent fb26f8195b
commit e7ab61d125
2 changed files with 62 additions and 40 deletions

View file

@ -237,49 +237,55 @@ impl ContextMenu {
} }
fn render_menu(&self, cx: &mut RenderContext<Self>) -> impl Element { fn render_menu(&self, cx: &mut RenderContext<Self>) -> impl Element {
enum Tag {} enum Menu {}
enum MenuItem {}
let style = cx.global::<Settings>().theme.context_menu.clone(); let style = cx.global::<Settings>().theme.context_menu.clone();
Flex::column() MouseEventHandler::new::<Menu, _, _>(0, cx, |_, cx| {
.with_children(self.items.iter().enumerate().map(|(ix, item)| { Flex::column()
match item { .with_children(self.items.iter().enumerate().map(|(ix, item)| {
ContextMenuItem::Item { label, action } => { match item {
let action = action.boxed_clone(); ContextMenuItem::Item { label, action } => {
MouseEventHandler::new::<Tag, _, _>(ix, cx, |state, _| { let action = action.boxed_clone();
let style = MouseEventHandler::new::<MenuItem, _, _>(ix, cx, |state, _| {
style.item.style_for(state, Some(ix) == self.selected_index); let style =
Flex::row() style.item.style_for(state, Some(ix) == self.selected_index);
.with_child( Flex::row()
Label::new(label.to_string(), style.label.clone()).boxed(), .with_child(
) Label::new(label.to_string(), style.label.clone()).boxed(),
.with_child({
KeystrokeLabel::new(
action.boxed_clone(),
style.keystroke.container,
style.keystroke.text.clone(),
) )
.flex_float() .with_child({
KeystrokeLabel::new(
action.boxed_clone(),
style.keystroke.container,
style.keystroke.text.clone(),
)
.flex_float()
.boxed()
})
.contained()
.with_style(style.container)
.boxed() .boxed()
}) })
.contained() .with_cursor_style(CursorStyle::PointingHand)
.with_style(style.container) .on_click(move |_, _, cx| {
.boxed() cx.dispatch_any_action(action.boxed_clone());
}) cx.dispatch_action(Cancel);
.with_cursor_style(CursorStyle::PointingHand) })
.on_click(move |_, _, cx| { .boxed()
cx.dispatch_any_action(action.boxed_clone()); }
cx.dispatch_action(Cancel); ContextMenuItem::Separator => Empty::new()
}) .constrained()
.boxed() .with_height(1.)
.contained()
.with_style(style.separator)
.boxed(),
} }
ContextMenuItem::Separator => Empty::new() }))
.constrained() .contained()
.with_height(1.) .with_style(style.container)
.contained() .boxed()
.with_style(style.separator) })
.boxed(), .on_mouse_down_out(|_, cx| cx.dispatch_action(Cancel))
} .on_right_mouse_down_out(|_, cx| cx.dispatch_action(Cancel))
}))
.contained()
.with_style(style.container)
} }
} }

View file

@ -88,6 +88,22 @@ impl MouseEventHandler {
self self
} }
pub fn on_mouse_down_out(
mut self,
handler: impl Fn(Vector2F, &mut EventContext) + 'static,
) -> Self {
self.mouse_down_out = Some(Rc::new(handler));
self
}
pub fn on_right_mouse_down_out(
mut self,
handler: impl Fn(Vector2F, &mut EventContext) + 'static,
) -> Self {
self.right_mouse_down_out = Some(Rc::new(handler));
self
}
pub fn on_drag(mut self, handler: impl Fn(Vector2F, &mut EventContext) + 'static) -> Self { pub fn on_drag(mut self, handler: impl Fn(Vector2F, &mut EventContext) + 'static) -> Self {
self.drag = Some(Rc::new(handler)); self.drag = Some(Rc::new(handler));
self self