ui: Use popover menus for tab bar in panes (#16497)

Closes #ISSUE

Release Notes:

- N/A
This commit is contained in:
Piotr Osiewicz 2024-08-22 18:05:23 +02:00 committed by GitHub
parent 72b5cda356
commit 182b7af299
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 326 additions and 358 deletions

View file

@ -8,13 +8,14 @@ use editor::actions::{
use editor::{Editor, EditorSettings};
use gpui::{
anchored, deferred, Action, AnchorCorner, ClickEvent, DismissEvent, ElementId, EventEmitter,
InteractiveElement, ParentElement, Render, Styled, Subscription, View, ViewContext, WeakView,
Action, AnchorCorner, ClickEvent, ElementId, EventEmitter, InteractiveElement, ParentElement,
Render, Styled, Subscription, View, ViewContext, WeakView,
};
use search::{buffer_search, BufferSearchBar};
use settings::{Settings, SettingsStore};
use ui::{
prelude::*, ButtonStyle, ContextMenu, IconButton, IconButtonShape, IconName, IconSize, Tooltip,
prelude::*, ButtonStyle, ContextMenu, IconButton, IconButtonShape, IconName, IconSize,
PopoverMenu, PopoverMenuHandle, Tooltip,
};
use workspace::{
item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
@ -27,10 +28,9 @@ pub struct QuickActionBar {
_inlay_hints_enabled_subscription: Option<Subscription>,
active_item: Option<Box<dyn ItemHandle>>,
buffer_search_bar: View<BufferSearchBar>,
repl_menu: Option<View<ContextMenu>>,
show: bool,
toggle_selections_menu: Option<View<ContextMenu>>,
toggle_settings_menu: Option<View<ContextMenu>>,
toggle_selections_handle: PopoverMenuHandle<ContextMenu>,
toggle_settings_handle: PopoverMenuHandle<ContextMenu>,
workspace: WeakView<Workspace>,
}
@ -44,10 +44,9 @@ impl QuickActionBar {
_inlay_hints_enabled_subscription: None,
active_item: None,
buffer_search_bar,
repl_menu: None,
show: true,
toggle_selections_menu: None,
toggle_settings_menu: None,
toggle_selections_handle: Default::default(),
toggle_settings_handle: Default::default(),
workspace: workspace.weak_handle(),
};
this.apply_settings(cx);
@ -79,17 +78,6 @@ impl QuickActionBar {
ToolbarItemLocation::Hidden
}
}
fn render_menu_overlay(menu: &View<ContextMenu>) -> Div {
div().absolute().bottom_0().right_0().size_0().child(
deferred(
anchored()
.anchor(AnchorCorner::TopRight)
.child(menu.clone()),
)
.with_priority(1),
)
}
}
impl Render for QuickActionBar {
@ -158,150 +146,155 @@ impl Render for QuickActionBar {
);
let editor_selections_dropdown = selection_menu_enabled.then(|| {
IconButton::new("toggle_editor_selections_icon", IconName::TextCursor)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
.style(ButtonStyle::Subtle)
.selected(self.toggle_selections_menu.is_some())
.on_click({
let focus = editor.focus_handle(cx);
cx.listener(move |quick_action_bar, _, cx| {
let focus = focus.clone();
let menu = ContextMenu::build(cx, move |menu, _| {
menu.context(focus.clone())
.action("Select All", Box::new(SelectAll))
.action(
"Select Next Occurrence",
Box::new(SelectNext {
replace_newest: false,
}),
)
.action("Expand Selection", Box::new(SelectLargerSyntaxNode))
.action("Shrink Selection", Box::new(SelectSmallerSyntaxNode))
.action("Add Cursor Above", Box::new(AddSelectionAbove))
.action("Add Cursor Below", Box::new(AddSelectionBelow))
.separator()
.action("Go to Symbol", Box::new(ToggleOutline))
.action("Go to Line/Column", Box::new(ToggleGoToLine))
.separator()
.action("Next Problem", Box::new(GoToDiagnostic))
.action("Previous Problem", Box::new(GoToPrevDiagnostic))
.separator()
.action("Next Hunk", Box::new(GoToHunk))
.action("Previous Hunk", Box::new(GoToPrevHunk))
.separator()
.action("Move Line Up", Box::new(MoveLineUp))
.action("Move Line Down", Box::new(MoveLineDown))
.action("Duplicate Selection", Box::new(DuplicateLineDown))
});
cx.subscribe(&menu, |quick_action_bar, _, _: &DismissEvent, _cx| {
quick_action_bar.toggle_selections_menu = None;
})
.detach();
quick_action_bar.toggle_selections_menu = Some(menu);
})
})
.when(self.toggle_selections_menu.is_none(), |this| {
this.tooltip(|cx| Tooltip::text("Selection Controls", cx))
let focus = editor.focus_handle(cx);
PopoverMenu::new("editor-selections-dropdown")
.trigger(
IconButton::new("toggle_editor_selections_icon", IconName::TextCursor)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
.style(ButtonStyle::Subtle)
.selected(self.toggle_selections_handle.is_deployed())
.when(!self.toggle_selections_handle.is_deployed(), |this| {
this.tooltip(|cx| Tooltip::text("Selection Controls", cx))
}),
)
.with_handle(self.toggle_selections_handle.clone())
.anchor(AnchorCorner::TopRight)
.menu(move |cx| {
let focus = focus.clone();
let menu = ContextMenu::build(cx, move |menu, _| {
menu.context(focus.clone())
.action("Select All", Box::new(SelectAll))
.action(
"Select Next Occurrence",
Box::new(SelectNext {
replace_newest: false,
}),
)
.action("Expand Selection", Box::new(SelectLargerSyntaxNode))
.action("Shrink Selection", Box::new(SelectSmallerSyntaxNode))
.action("Add Cursor Above", Box::new(AddSelectionAbove))
.action("Add Cursor Below", Box::new(AddSelectionBelow))
.separator()
.action("Go to Symbol", Box::new(ToggleOutline))
.action("Go to Line/Column", Box::new(ToggleGoToLine))
.separator()
.action("Next Problem", Box::new(GoToDiagnostic))
.action("Previous Problem", Box::new(GoToPrevDiagnostic))
.separator()
.action("Next Hunk", Box::new(GoToHunk))
.action("Previous Hunk", Box::new(GoToPrevHunk))
.separator()
.action("Move Line Up", Box::new(MoveLineUp))
.action("Move Line Down", Box::new(MoveLineDown))
.action("Duplicate Selection", Box::new(DuplicateLineDown))
});
Some(menu)
})
});
let editor_settings_dropdown =
IconButton::new("toggle_editor_settings_icon", IconName::Sliders)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
.style(ButtonStyle::Subtle)
.selected(self.toggle_settings_menu.is_some())
.on_click({
let editor = editor.clone();
cx.listener(move |quick_action_bar, _, cx| {
let menu = ContextMenu::build(cx, |mut menu, _| {
if supports_inlay_hints {
menu = menu.toggleable_entry(
"Inlay Hints",
inlay_hints_enabled,
IconPosition::Start,
Some(editor::actions::ToggleInlayHints.boxed_clone()),
{
let editor = editor.clone();
move |cx| {
editor.update(cx, |editor, cx| {
editor.toggle_inlay_hints(
&editor::actions::ToggleInlayHints,
cx,
);
});
}
},
);
}
menu = menu.toggleable_entry(
"Inline Git Blame",
git_blame_inline_enabled,
IconPosition::Start,
Some(editor::actions::ToggleGitBlameInline.boxed_clone()),
{
let editor = editor.clone();
move |cx| {
editor.update(cx, |editor, cx| {
editor.toggle_git_blame_inline(
&editor::actions::ToggleGitBlameInline,
cx,
)
});
}
},
);
menu = menu.toggleable_entry(
"Selection Menu",
selection_menu_enabled,
IconPosition::Start,
Some(editor::actions::ToggleSelectionMenu.boxed_clone()),
{
let editor = editor.clone();
move |cx| {
editor.update(cx, |editor, cx| {
editor.toggle_selection_menu(
&editor::actions::ToggleSelectionMenu,
cx,
)
});
}
},
);
menu = menu.toggleable_entry(
"Auto Signature Help",
auto_signature_help_enabled,
IconPosition::Start,
Some(editor::actions::ToggleAutoSignatureHelp.boxed_clone()),
{
let editor = editor.clone();
move |cx| {
editor.update(cx, |editor, cx| {
editor.toggle_auto_signature_help_menu(
&editor::actions::ToggleAutoSignatureHelp,
let editor = editor.downgrade();
let editor_settings_dropdown = PopoverMenu::new("editor-settings")
.trigger(
IconButton::new("toggle_editor_settings_icon", IconName::Sliders)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
.style(ButtonStyle::Subtle)
.selected(self.toggle_settings_handle.is_deployed())
.when(!self.toggle_settings_handle.is_deployed(), |this| {
this.tooltip(|cx| Tooltip::text("Editor Controls", cx))
}),
)
.anchor(AnchorCorner::TopRight)
.with_handle(self.toggle_settings_handle.clone())
.menu(move |cx| {
let menu = ContextMenu::build(cx, |mut menu, _| {
if supports_inlay_hints {
menu = menu.toggleable_entry(
"Inlay Hints",
inlay_hints_enabled,
IconPosition::Start,
Some(editor::actions::ToggleInlayHints.boxed_clone()),
{
let editor = editor.clone();
move |cx| {
editor
.update(cx, |editor, cx| {
editor.toggle_inlay_hints(
&editor::actions::ToggleInlayHints,
cx,
);
});
}
},
);
})
.ok();
}
},
);
}
menu
});
cx.subscribe(&menu, |quick_action_bar, _, _: &DismissEvent, _cx| {
quick_action_bar.toggle_settings_menu = None;
})
.detach();
quick_action_bar.toggle_settings_menu = Some(menu);
})
})
.when(self.toggle_settings_menu.is_none(), |this| {
this.tooltip(|cx| Tooltip::text("Editor Controls", cx))
menu = menu.toggleable_entry(
"Inline Git Blame",
git_blame_inline_enabled,
IconPosition::Start,
Some(editor::actions::ToggleGitBlameInline.boxed_clone()),
{
let editor = editor.clone();
move |cx| {
editor
.update(cx, |editor, cx| {
editor.toggle_git_blame_inline(
&editor::actions::ToggleGitBlameInline,
cx,
)
})
.ok();
}
},
);
menu = menu.toggleable_entry(
"Selection Menu",
selection_menu_enabled,
IconPosition::Start,
Some(editor::actions::ToggleSelectionMenu.boxed_clone()),
{
let editor = editor.clone();
move |cx| {
editor
.update(cx, |editor, cx| {
editor.toggle_selection_menu(
&editor::actions::ToggleSelectionMenu,
cx,
)
})
.ok();
}
},
);
menu = menu.toggleable_entry(
"Auto Signature Help",
auto_signature_help_enabled,
IconPosition::Start,
Some(editor::actions::ToggleAutoSignatureHelp.boxed_clone()),
{
let editor = editor.clone();
move |cx| {
editor
.update(cx, |editor, cx| {
editor.toggle_auto_signature_help_menu(
&editor::actions::ToggleAutoSignatureHelp,
cx,
);
})
.ok();
}
},
);
menu
});
Some(menu)
});
h_flex()
.id("quick action bar")
@ -316,21 +309,6 @@ impl Render for QuickActionBar {
)
.children(editor_selections_dropdown)
.child(editor_settings_dropdown)
.when_some(self.repl_menu.as_ref(), |el, repl_menu| {
el.child(Self::render_menu_overlay(repl_menu))
})
.when_some(
self.toggle_settings_menu.as_ref(),
|el, toggle_settings_menu| {
el.child(Self::render_menu_overlay(toggle_settings_menu))
},
)
.when_some(
self.toggle_selections_menu.as_ref(),
|el, toggle_selections_menu| {
el.child(Self::render_menu_overlay(toggle_selections_menu))
},
)
}
}