assistant2: Fix inline context picker and handle dismiss (#23081)
The new `ContextMenu`-based `ContextPicker` requires initialization when opened, but we were only doing this for the `ContextStrip` picker, not the inline one. Additionally, because we have a wrapper element around ContextMenu, we need to propagate the `DismissEvent` so that it properly closes when Escape is pressed. Release Notes: - N/A
This commit is contained in:
parent
7c2c409f6d
commit
4054d4a5b7
8 changed files with 42 additions and 17 deletions
|
@ -65,14 +65,15 @@ impl ContextPicker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_mode(&mut self, cx: &mut ViewContext<Self>) {
|
pub fn init(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
self.mode = ContextPickerMode::Default(self.build(cx));
|
self.mode = ContextPickerMode::Default(self.build_menu(cx));
|
||||||
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(&mut self, cx: &mut ViewContext<Self>) -> View<ContextMenu> {
|
fn build_menu(&mut self, cx: &mut ViewContext<Self>) -> View<ContextMenu> {
|
||||||
let context_picker = cx.view().clone();
|
let context_picker = cx.view().clone();
|
||||||
|
|
||||||
ContextMenu::build(cx, move |menu, cx| {
|
let menu = ContextMenu::build(cx, move |menu, cx| {
|
||||||
let kind_entry = |kind: &'static ContextKind| {
|
let kind_entry = |kind: &'static ContextKind| {
|
||||||
let context_picker = context_picker.clone();
|
let context_picker = context_picker.clone();
|
||||||
|
|
||||||
|
@ -90,11 +91,24 @@ impl ContextPicker {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(ix, entry)| self.recent_menu_item(context_picker.clone(), ix, entry));
|
.map(|(ix, entry)| self.recent_menu_item(context_picker.clone(), ix, entry));
|
||||||
|
|
||||||
menu.when(has_recent, |menu| menu.label("Recent"))
|
let menu = menu
|
||||||
|
.when(has_recent, |menu| menu.label("Recent"))
|
||||||
.extend(recent_entries)
|
.extend(recent_entries)
|
||||||
.when(has_recent, |menu| menu.separator())
|
.when(has_recent, |menu| menu.separator())
|
||||||
.extend(ContextKind::all().into_iter().map(kind_entry))
|
.extend(ContextKind::all().into_iter().map(kind_entry));
|
||||||
|
|
||||||
|
match self.confirm_behavior {
|
||||||
|
ConfirmBehavior::KeepOpen => menu.keep_open_on_confirm(),
|
||||||
|
ConfirmBehavior::Close => menu,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.subscribe(&menu, move |_, _, _: &DismissEvent, cx| {
|
||||||
|
cx.emit(DismissEvent);
|
||||||
})
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
menu
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_kind(&mut self, kind: ContextKind, cx: &mut ViewContext<Self>) {
|
fn select_kind(&mut self, kind: ContextKind, cx: &mut ViewContext<Self>) {
|
||||||
|
|
|
@ -221,8 +221,7 @@ impl PickerDelegate for DirectoryContextPickerDelegate {
|
||||||
|
|
||||||
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
||||||
self.context_picker
|
self.context_picker
|
||||||
.update(cx, |this, cx| {
|
.update(cx, |_, cx| {
|
||||||
this.reset_mode(cx);
|
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
|
@ -222,8 +222,7 @@ impl PickerDelegate for FetchContextPickerDelegate {
|
||||||
|
|
||||||
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
||||||
self.context_picker
|
self.context_picker
|
||||||
.update(cx, |this, cx| {
|
.update(cx, |_, cx| {
|
||||||
this.reset_mode(cx);
|
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
|
@ -239,8 +239,7 @@ impl PickerDelegate for FileContextPickerDelegate {
|
||||||
|
|
||||||
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
||||||
self.context_picker
|
self.context_picker
|
||||||
.update(cx, |this, cx| {
|
.update(cx, |_, cx| {
|
||||||
this.reset_mode(cx);
|
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
|
@ -176,8 +176,7 @@ impl PickerDelegate for ThreadContextPickerDelegate {
|
||||||
|
|
||||||
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
||||||
self.context_picker
|
self.context_picker
|
||||||
.update(cx, |this, cx| {
|
.update(cx, |_, cx| {
|
||||||
this.reset_mode(cx);
|
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
|
@ -168,7 +168,7 @@ impl Render for ContextStrip {
|
||||||
PopoverMenu::new("context-picker")
|
PopoverMenu::new("context-picker")
|
||||||
.menu(move |cx| {
|
.menu(move |cx| {
|
||||||
context_picker.update(cx, |this, cx| {
|
context_picker.update(cx, |this, cx| {
|
||||||
this.reset_mode(cx);
|
this.init(cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(context_picker.clone())
|
Some(context_picker.clone())
|
||||||
|
|
|
@ -281,7 +281,13 @@ impl Render for MessageEditor {
|
||||||
})
|
})
|
||||||
.child(
|
.child(
|
||||||
PopoverMenu::new("inline-context-picker")
|
PopoverMenu::new("inline-context-picker")
|
||||||
.menu(move |_cx| Some(inline_context_picker.clone()))
|
.menu(move |cx| {
|
||||||
|
inline_context_picker.update(cx, |this, cx| {
|
||||||
|
this.init(cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
Some(inline_context_picker.clone())
|
||||||
|
})
|
||||||
.attach(gpui::Corner::TopLeft)
|
.attach(gpui::Corner::TopLeft)
|
||||||
.anchor(gpui::Corner::BottomLeft)
|
.anchor(gpui::Corner::BottomLeft)
|
||||||
.offset(gpui::Point {
|
.offset(gpui::Point {
|
||||||
|
|
|
@ -112,6 +112,7 @@ pub struct ContextMenu {
|
||||||
delayed: bool,
|
delayed: bool,
|
||||||
clicked: bool,
|
clicked: bool,
|
||||||
_on_blur_subscription: Subscription,
|
_on_blur_subscription: Subscription,
|
||||||
|
keep_open_on_confirm: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FocusableView for ContextMenu {
|
impl FocusableView for ContextMenu {
|
||||||
|
@ -144,6 +145,7 @@ impl ContextMenu {
|
||||||
delayed: false,
|
delayed: false,
|
||||||
clicked: false,
|
clicked: false,
|
||||||
_on_blur_subscription,
|
_on_blur_subscription,
|
||||||
|
keep_open_on_confirm: true,
|
||||||
},
|
},
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
|
@ -304,6 +306,11 @@ impl ContextMenu {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn keep_open_on_confirm(mut self) -> Self {
|
||||||
|
self.keep_open_on_confirm = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) {
|
pub fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) {
|
||||||
let context = self.action_context.as_ref();
|
let context = self.action_context.as_ref();
|
||||||
if let Some(
|
if let Some(
|
||||||
|
@ -318,7 +325,9 @@ impl ContextMenu {
|
||||||
(handler)(context, cx)
|
(handler)(context, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.emit(DismissEvent);
|
if !self.keep_open_on_confirm {
|
||||||
|
cx.emit(DismissEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
|
pub fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue