
This PR fixes the inconsistent sizing between the buffer search and the project search when both elements have both a primary and secondary item shown in the toolbar. Release Notes: - Fixed some inconsistent sizing in the buffer search and project search when both have two rows of tools in the toolbar.
190 lines
6.5 KiB
Rust
190 lines
6.5 KiB
Rust
use assistant::{AssistantPanel, InlineAssist};
|
|
use editor::Editor;
|
|
|
|
use gpui::{
|
|
Action, ClickEvent, ElementId, EventEmitter, InteractiveElement, ParentElement, Render, Styled,
|
|
Subscription, View, ViewContext, WeakView,
|
|
};
|
|
use search::{buffer_search, BufferSearchBar};
|
|
use ui::{prelude::*, ButtonSize, ButtonStyle, Icon, IconButton, IconSize, Tooltip};
|
|
use workspace::{
|
|
item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
|
|
};
|
|
|
|
pub struct QuickActionBar {
|
|
buffer_search_bar: View<BufferSearchBar>,
|
|
active_item: Option<Box<dyn ItemHandle>>,
|
|
_inlay_hints_enabled_subscription: Option<Subscription>,
|
|
workspace: WeakView<Workspace>,
|
|
}
|
|
|
|
impl QuickActionBar {
|
|
pub fn new(buffer_search_bar: View<BufferSearchBar>, workspace: &Workspace) -> Self {
|
|
Self {
|
|
buffer_search_bar,
|
|
active_item: None,
|
|
_inlay_hints_enabled_subscription: None,
|
|
workspace: workspace.weak_handle(),
|
|
}
|
|
}
|
|
|
|
fn active_editor(&self) -> Option<View<Editor>> {
|
|
self.active_item
|
|
.as_ref()
|
|
.and_then(|item| item.downcast::<Editor>())
|
|
}
|
|
}
|
|
|
|
impl Render for QuickActionBar {
|
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
|
let Some(editor) = self.active_editor() else {
|
|
return div().id("empty quick action bar");
|
|
};
|
|
|
|
let inlay_hints_button = Some(QuickActionBarButton::new(
|
|
"toggle inlay hints",
|
|
Icon::InlayHint,
|
|
editor.read(cx).inlay_hints_enabled(),
|
|
Box::new(editor::ToggleInlayHints),
|
|
"Toggle Inlay Hints",
|
|
{
|
|
let editor = editor.clone();
|
|
move |_, cx| {
|
|
editor.update(cx, |editor, cx| {
|
|
editor.toggle_inlay_hints(&editor::ToggleInlayHints, cx);
|
|
});
|
|
}
|
|
},
|
|
))
|
|
.filter(|_| editor.read(cx).supports_inlay_hints(cx));
|
|
|
|
let search_button = Some(QuickActionBarButton::new(
|
|
"toggle buffer search",
|
|
Icon::MagnifyingGlass,
|
|
!self.buffer_search_bar.read(cx).is_dismissed(),
|
|
Box::new(buffer_search::Deploy { focus: false }),
|
|
"Buffer Search",
|
|
{
|
|
let buffer_search_bar = self.buffer_search_bar.clone();
|
|
move |_, cx| {
|
|
buffer_search_bar.update(cx, |search_bar, cx| {
|
|
search_bar.toggle(&buffer_search::Deploy { focus: true }, cx)
|
|
});
|
|
}
|
|
},
|
|
))
|
|
.filter(|_| editor.is_singleton(cx));
|
|
|
|
let assistant_button = QuickActionBarButton::new(
|
|
"toggle inline assistant",
|
|
Icon::MagicWand,
|
|
false,
|
|
Box::new(InlineAssist),
|
|
"Inline Assist",
|
|
{
|
|
let workspace = self.workspace.clone();
|
|
move |_, cx| {
|
|
if let Some(workspace) = workspace.upgrade() {
|
|
workspace.update(cx, |workspace, cx| {
|
|
AssistantPanel::inline_assist(workspace, &InlineAssist, cx);
|
|
});
|
|
}
|
|
}
|
|
},
|
|
);
|
|
|
|
h_stack()
|
|
.id("quick action bar")
|
|
.gap_2()
|
|
.children(inlay_hints_button)
|
|
.children(search_button)
|
|
.child(assistant_button)
|
|
}
|
|
}
|
|
|
|
impl EventEmitter<ToolbarItemEvent> for QuickActionBar {}
|
|
|
|
#[derive(IntoElement)]
|
|
struct QuickActionBarButton {
|
|
id: ElementId,
|
|
icon: Icon,
|
|
toggled: bool,
|
|
action: Box<dyn Action>,
|
|
tooltip: SharedString,
|
|
on_click: Box<dyn Fn(&ClickEvent, &mut WindowContext)>,
|
|
}
|
|
|
|
impl QuickActionBarButton {
|
|
fn new(
|
|
id: impl Into<ElementId>,
|
|
icon: Icon,
|
|
toggled: bool,
|
|
action: Box<dyn Action>,
|
|
tooltip: impl Into<SharedString>,
|
|
on_click: impl Fn(&ClickEvent, &mut WindowContext) + 'static,
|
|
) -> Self {
|
|
Self {
|
|
id: id.into(),
|
|
icon,
|
|
toggled,
|
|
action,
|
|
tooltip: tooltip.into(),
|
|
on_click: Box::new(on_click),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl RenderOnce for QuickActionBarButton {
|
|
fn render(self, _: &mut WindowContext) -> impl IntoElement {
|
|
let tooltip = self.tooltip.clone();
|
|
let action = self.action.boxed_clone();
|
|
|
|
IconButton::new(self.id.clone(), self.icon)
|
|
.size(ButtonSize::Compact)
|
|
.icon_size(IconSize::Small)
|
|
.style(ButtonStyle::Subtle)
|
|
.selected(self.toggled)
|
|
.tooltip(move |cx| Tooltip::for_action(tooltip.clone(), &*action, cx))
|
|
.on_click(move |event, cx| (self.on_click)(event, cx))
|
|
}
|
|
}
|
|
|
|
impl ToolbarItemView for QuickActionBar {
|
|
fn set_active_pane_item(
|
|
&mut self,
|
|
active_pane_item: Option<&dyn ItemHandle>,
|
|
cx: &mut ViewContext<Self>,
|
|
) -> ToolbarItemLocation {
|
|
match active_pane_item {
|
|
Some(active_item) => {
|
|
self.active_item = Some(active_item.boxed_clone());
|
|
self._inlay_hints_enabled_subscription.take();
|
|
|
|
if let Some(editor) = active_item.downcast::<Editor>() {
|
|
let mut inlay_hints_enabled = editor.read(cx).inlay_hints_enabled();
|
|
let mut supports_inlay_hints = editor.read(cx).supports_inlay_hints(cx);
|
|
self._inlay_hints_enabled_subscription =
|
|
Some(cx.observe(&editor, move |_, editor, cx| {
|
|
let editor = editor.read(cx);
|
|
let new_inlay_hints_enabled = editor.inlay_hints_enabled();
|
|
let new_supports_inlay_hints = editor.supports_inlay_hints(cx);
|
|
let should_notify = inlay_hints_enabled != new_inlay_hints_enabled
|
|
|| supports_inlay_hints != new_supports_inlay_hints;
|
|
inlay_hints_enabled = new_inlay_hints_enabled;
|
|
supports_inlay_hints = new_supports_inlay_hints;
|
|
if should_notify {
|
|
cx.notify()
|
|
}
|
|
}));
|
|
ToolbarItemLocation::PrimaryRight
|
|
} else {
|
|
ToolbarItemLocation::Hidden
|
|
}
|
|
}
|
|
None => {
|
|
self.active_item = None;
|
|
ToolbarItemLocation::Hidden
|
|
}
|
|
}
|
|
}
|
|
}
|