This commit is contained in:
Piotr Osiewicz 2023-11-14 16:56:31 +01:00
parent dfd68d4cb8
commit 6c69e40e5c
5 changed files with 158 additions and 94 deletions

View file

@ -910,7 +910,6 @@ impl SearchableItem for Editor {
}
fn update_matches(&mut self, matches: Vec<Range<Anchor>>, cx: &mut ViewContext<Self>) {
dbg!(&matches);
self.highlight_background::<BufferSearchHighlights>(
matches,
|theme| theme.title_bar_background, // todo: update theme

View file

@ -10,16 +10,16 @@ use collections::HashMap;
use editor::Editor;
use futures::channel::oneshot;
use gpui::{
action, actions, div, Action, AnyElement, AnyView, AppContext, Component, Div, Entity,
EventEmitter, ParentElement as _, Render, Subscription, Svg, Task, View, ViewContext,
VisualContext as _, WindowContext,
action, actions, blue, div, red, white, Action, AnyElement, AnyView, AppContext, Component,
Div, Entity, EventEmitter, Hsla, ParentElement as _, Render, Styled, Subscription, Svg, Task,
View, ViewContext, VisualContext as _, WindowContext,
};
use project::search::SearchQuery;
use serde::Deserialize;
use std::{any::Any, sync::Arc};
use theme::ActiveTheme;
use ui::{IconButton, Label};
use ui::{h_stack, Icon, IconButton, IconElement, Label, StyledExt};
use util::ResultExt;
use workspace::{
item::ItemHandle,
@ -66,31 +66,8 @@ pub struct BufferSearchBar {
impl EventEmitter<Event> for BufferSearchBar {}
impl EventEmitter<workspace::ToolbarItemEvent> for BufferSearchBar {}
impl Render for BufferSearchBar {
// fn ui_name() -> &'static str {
// "BufferSearchBar"
// }
// fn update_keymap_context(
// &self,
// keymap: &mut gpui::keymap_matcher::KeymapContext,
// cx: &AppContext,
// ) {
// Self::reset_to_default_keymap_context(keymap);
// let in_replace = self
// .replacement_editor
// .read_with(cx, |_, cx| cx.is_self_focused())
// .unwrap_or(false);
// if in_replace {
// keymap.add_identifier("in_replace");
// }
// }
// fn focus_in(&mut self, _: View, cx: &mut ViewContext<Self>) {
// cx.focus(&self.query_editor);
// }
type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let theme = cx.theme().clone();
// let query_container_style = if self.query_contains_error {
// theme.search.invalid_editor
// } else {
@ -147,61 +124,104 @@ impl Render for BufferSearchBar {
self.replacement_editor.update(cx, |editor, cx| {
editor.set_placeholder_text("Replace with...", cx);
});
let search_button_for_mode = |mode, side, cx: &mut ViewContext<BufferSearchBar>| {
let is_active = self.current_mode == mode;
render_search_mode_button(
mode,
side,
is_active,
move |this, cx| {
this.activate_search_mode(mode, cx);
},
cx,
)
};
let search_option_button = |option| {
let is_active = self.search_options.contains(option);
option.as_button(is_active)
};
let match_count = self
.active_searchable_item
.as_ref()
.and_then(|searchable_item| {
if self.query(cx).is_empty() {
return None;
}
let matches = self
.searchable_items_with_matches
.get(&searchable_item.downgrade())?;
let message = if let Some(match_ix) = self.active_match_index {
format!("{}/{}", match_ix + 1, matches.len())
} else {
"No matches".to_string()
};
Some(ui::Label::new(message))
});
let nav_button_for_direction = |label, direction, cx: &mut ViewContext<Self>| {
render_nav_button(
label,
direction,
self.active_match_index.is_some(),
move |this, cx| match direction {
Direction::Prev => this.select_prev_match(&Default::default(), cx),
Direction::Next => this.select_next_match(&Default::default(), cx),
},
cx,
)
};
div()
.w_full()
.border()
.border_color(blue())
.flex() // Make this div a flex container
.justify_between()
.child(
div()
.flex()
.border_1()
.border_color(red())
.rounded_md()
.w_96()
.items_center()
.child(IconElement::new(Icon::MagnifyingGlass))
.child(self.query_editor.clone())
.child(self.replacement_editor.clone())
// let search_button_for_mode = |mode, side, cx: &mut ViewContext<BufferSearchBar>| {
// let is_active = self.current_mode == mode;
.children(
supported_options
.case
.then(|| search_option_button(SearchOptions::CASE_SENSITIVE)),
)
.children(
supported_options
.word
.then(|| search_option_button(SearchOptions::WHOLE_WORD)),
),
)
.child(div().w_auto().flex_row())
.child(search_button_for_mode(
SearchMode::Text,
Some(Side::Left),
cx,
))
.child(search_button_for_mode(
SearchMode::Regex,
Some(Side::Right),
cx,
))
.when(supported_options.replacement, |this| {
this.child(super::toggle_replace_button(self.replace_enabled))
})
.when(self.replace_enabled, |this| {
this.child(div().w_80().child(self.replacement_editor.clone()))
})
.children(match_count)
.child(nav_button_for_direction("<", Direction::Prev, cx))
.child(nav_button_for_direction(">", Direction::Next, cx))
.flex()
.justify_between()
// render_search_mode_button(
// mode,
// side,
// is_active,
// move |_, this, cx| {
// this.activate_search_mode(mode, cx);
// },
// cx,
// )
// };
// let search_option_button = |option| {
// let is_active = self.search_options.contains(option);
// option.as_button(is_active)
// };
// let match_count = self
// .active_searchable_item
// .as_ref()
// .and_then(|searchable_item| {
// if self.query(cx).is_empty() {
// return None;
// }
// let matches = self
// .searchable_items_with_matches
// .get(&searchable_item.downgrade())?;
// let message = if let Some(match_ix) = self.active_match_index {
// format!("{}/{}", match_ix + 1, matches.len())
// } else {
// "No matches".to_string()
// };
// Some(
// Label::new(message)
// .contained()
// .with_style(theme.search.match_index.container)
// .aligned(),
// )
// });
// let nav_button_for_direction = |label, direction, cx: &mut ViewContext<Self>| {
// render_nav_button(
// label,
// direction,
// self.active_match_index.is_some(),
// move |_, this, cx| match direction {
// Direction::Prev => this.select_prev_match(&Default::default(), cx),
// Direction::Next => this.select_next_match(&Default::default(), cx),
// },
// cx,
// )
// };
// let query_column = Flex::row()
// .with_child(
// Svg::for_style(theme.search.editor_icon.clone().icon)
@ -351,7 +371,6 @@ impl ToolbarItemView for BufferSearchBar {
impl BufferSearchBar {
pub fn register(workspace: &mut Workspace) {
workspace.register_action(|workspace, a: &Deploy, cx| {
dbg!("Setting");
workspace.active_pane().update(cx, |this, cx| {
this.toolbar().update(cx, |this, cx| {
let view = cx.build_view(|cx| BufferSearchBar::new(cx));
@ -361,6 +380,43 @@ impl BufferSearchBar {
})
});
});
fn register_action<A: Action>(
workspace: &mut Workspace,
update: fn(&mut BufferSearchBar, &mut ViewContext<'_, BufferSearchBar>),
) {
workspace.register_action(move |workspace, _: &A, cx| {
workspace.active_pane().update(cx, move |this, cx| {
this.toolbar().update(cx, move |toolbar, cx| {
let Some(search_bar) = toolbar.item_of_type::<BufferSearchBar>() else {
return;
};
search_bar.update(cx, |this, cx| update(this, cx))
})
});
});
}
register_action::<ToggleCaseSensitive>(workspace, |this, cx| {
this.toggle_search_option(SearchOptions::CASE_SENSITIVE, cx)
});
register_action::<ToggleWholeWord>(workspace, |this: &mut BufferSearchBar, cx| {
this.toggle_search_option(SearchOptions::WHOLE_WORD, cx)
});
register_action::<ToggleReplace>(workspace, |this: &mut BufferSearchBar, cx| {
dbg!("Toggling");
this.toggle_replace(&ToggleReplace, cx)
});
// workspace.register_action(|workspace, _: &ToggleCaseSensitive, cx| {
// workspace.active_pane().update(cx, |this, cx| {
// this.toolbar().update(cx, |toolbar, cx| {
// let Some(search_bar) = toolbar.item_of_type::<BufferSearchBar>() else {
// return;
// };
// search_bar.update(cx, |this, cx| {
// this.toggle_search_option(SearchOptions::CASE_SENSITIVE, cx);
// })
// })
// });
// });
}
pub fn new(cx: &mut ViewContext<Self>) -> Self {
dbg!("New");

View file

@ -100,6 +100,7 @@ fn toggle_replace_button<V: 'static>(active: bool) -> impl Component<V> {
ui::IconButton::new(0, ui::Icon::Replace)
.on_click(|_: &mut V, cx| {
cx.dispatch_action(Box::new(ToggleReplace));
cx.notify();
})
.variant(ui::ButtonVariant::Ghost)
.when(active, |button| button.variant(ButtonVariant::Filled))

View file

@ -1,11 +1,11 @@
use std::borrow::Cow;
use std::{borrow::Cow, sync::Arc};
use gpui::{
div, Action, AnyElement, Component, CursorStyle, Element, MouseButton, MouseDownEvent, Svg,
View, ViewContext,
div, Action, AnyElement, Component, CursorStyle, Element, MouseButton, MouseDownEvent,
ParentElement as _, StatelessInteractive, Styled, Svg, View, ViewContext,
};
use theme::ActiveTheme;
use ui::Label;
use ui::{Button, Label};
use workspace::searchable::Direction;
use crate::{
@ -17,19 +17,16 @@ pub(super) fn render_nav_button<V: 'static>(
icon: &'static str,
direction: Direction,
active: bool,
on_click: impl Fn(MouseDownEvent, &mut V, &mut ViewContext<V>) + 'static,
on_click: impl Fn(&mut V, &mut ViewContext<V>) + 'static + Send + Sync,
cx: &mut ViewContext<V>,
) -> impl Component<V> {
let action: Box<dyn Action>;
let tooltip;
match direction {
Direction::Prev => {
action = Box::new(SelectPrevMatch);
tooltip = "Select Previous Match";
}
Direction::Next => {
action = Box::new(SelectNextMatch);
tooltip = "Select Next Match";
}
};
@ -40,7 +37,7 @@ pub(super) fn render_nav_button<V: 'static>(
// CursorStyle::default()
// };
// enum NavButton {}
div()
Button::new(icon).on_click(Arc::new(on_click))
// MouseEventHandler::new::<NavButton, _>(direction as usize, cx, |state, cx| {
// let theme = cx.theme();
// let style = theme
@ -86,12 +83,23 @@ pub(crate) fn render_search_mode_button<V: 'static>(
mode: SearchMode,
side: Option<Side>,
is_active: bool,
//on_click: impl Fn(MouseClick, &mut V, &mut ViewContext<V>) + 'static,
on_click: impl Fn(&mut V, &mut ViewContext<V>) + 'static,
cx: &mut ViewContext<V>,
) -> impl Component<V> {
//let tooltip_style = cx.theme().tooltip.clone();
enum SearchModeButton {}
div()
.border_2()
.rounded_md()
.when(side == Some(Side::Left), |this| {
this.border_r_0().rounded_tr_none().rounded_br_none()
})
.when(side == Some(Side::Right), |this| {
this.border_l_0().rounded_bl_none().rounded_tl_none()
})
.on_key_down(move |v, _, _, cx| on_click(v, cx))
.child(Label::new(mode.label()))
// MouseEventHandler::new::<SearchModeButton, _>(mode.region_id(), cx, |state, cx| {
// let theme = cx.theme();
// let style = theme

View file

@ -1,7 +1,7 @@
use crate::ItemHandle;
use gpui::{
div, AnyView, Div, Entity, EntityId, EventEmitter, ParentElement, Render, View, ViewContext,
WindowContext,
div, AnyView, Div, Entity, EntityId, EventEmitter, ParentElement, Render, Styled, View,
ViewContext, WindowContext,
};
pub enum ToolbarItemEvent {