diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 99e5fbbcb1e805fa40d6c70c96161c1a53ca00a8..e3559038ae0a5c87a4352713e71da4f229242b17 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -451,11 +451,12 @@ impl ProjectSearchView { .detach(); let included_files_editor = cx.add_view(|cx| { - let editor = Editor::single_line( - Some(Arc::new(|theme| theme.search.editor.input.clone())), + Editor::single_line( + Some(Arc::new(|theme| { + theme.search.include_exclude_editor.input.clone() + })), cx, - ); - editor + ) }); // Subcribe to include_files_editor in order to reraise editor events for workspace item activation purposes cx.subscribe(&included_files_editor, |_, _, event, cx| { @@ -464,11 +465,12 @@ impl ProjectSearchView { .detach(); let excluded_files_editor = cx.add_view(|cx| { - let editor = Editor::single_line( - Some(Arc::new(|theme| theme.search.editor.input.clone())), + Editor::single_line( + Some(Arc::new(|theme| { + theme.search.include_exclude_editor.input.clone() + })), cx, - ); - editor + ) }); // Subcribe to excluded_files_editor in order to reraise editor events for workspace item activation purposes cx.subscribe(&excluded_files_editor, |_, _, event, cx| { @@ -935,101 +937,119 @@ impl View for ProjectSearchBar { let included_files_view = ChildView::new(&search.included_files_editor, cx) .aligned() .left() - .flex(0.5, true); + .flex(1.0, true); let excluded_files_view = ChildView::new(&search.excluded_files_editor, cx) .aligned() .right() - .flex(0.5, true); + .flex(1.0, true); + + let row_spacing = theme.workspace.toolbar.container.padding.bottom; - Flex::row() + Flex::column() .with_child( Flex::row() .with_child( - ChildView::new(&search.query_editor, cx) + Flex::row() + .with_child( + ChildView::new(&search.query_editor, cx) + .aligned() + .left() + .flex(1., true), + ) + .with_children(search.active_match_index.map(|match_ix| { + Label::new( + format!( + "{}/{}", + match_ix + 1, + search.model.read(cx).match_ranges.len() + ), + theme.search.match_index.text.clone(), + ) + .contained() + .with_style(theme.search.match_index.container) + .aligned() + })) + .contained() + .with_style(editor_container) .aligned() - .left() - .flex(1., true), + .constrained() + .with_min_width(theme.search.editor.min_width) + .with_max_width(theme.search.editor.max_width) + .flex(1., false), + ) + .with_child( + Flex::row() + .with_child(self.render_nav_button("<", Direction::Prev, cx)) + .with_child(self.render_nav_button(">", Direction::Next, cx)) + .aligned(), ) - .with_children(search.active_match_index.map(|match_ix| { - Label::new( - format!( - "{}/{}", - match_ix + 1, - search.model.read(cx).match_ranges.len() - ), - theme.search.match_index.text.clone(), - ) - .contained() - .with_style(theme.search.match_index.container) - .aligned() - })) - .contained() - .with_style(editor_container) - .aligned() - .constrained() - .with_min_width(theme.search.editor.min_width) - .with_max_width(theme.search.editor.max_width) - .flex(1., false), - ) - .with_child( - Flex::row() - .with_child(self.render_nav_button("<", Direction::Prev, cx)) - .with_child(self.render_nav_button(">", Direction::Next, cx)) - .aligned(), - ) - .with_child( - Flex::row() - .with_child(self.render_option_button( - "Case", - SearchOption::CaseSensitive, - cx, - )) - .with_child(self.render_option_button("Word", SearchOption::WholeWord, cx)) - .with_child(self.render_option_button("Regex", SearchOption::Regex, cx)) - .contained() - .with_style(theme.search.option_button_group) - .aligned(), - ) - // TODO kb better layout - .with_child( - Flex::row() .with_child( - Label::new( - "Include:", - theme.search.include_exclude_inputs.text.clone(), - ) - .contained() - .with_style(theme.search.include_exclude_inputs.container) - .aligned(), + Flex::row() + .with_child(self.render_option_button( + "Case", + SearchOption::CaseSensitive, + cx, + )) + .with_child(self.render_option_button( + "Word", + SearchOption::WholeWord, + cx, + )) + .with_child(self.render_option_button( + "Regex", + SearchOption::Regex, + cx, + )) + .contained() + .with_style(theme.search.option_button_group) + .aligned(), ) - .with_child(included_files_view) .contained() - .with_style(theme.search.editor.input.container) - .aligned() - .constrained() - .with_min_width(theme.search.editor.min_width) - .with_max_width(theme.search.editor.max_width) - .flex(1., false), + .with_margin_bottom(row_spacing), ) .with_child( Flex::row() + // TODO kb better layout .with_child( - Label::new( - "Exclude:", - theme.search.include_exclude_inputs.text.clone(), - ) - .contained() - .with_style(theme.search.include_exclude_inputs.container) - .aligned(), + Flex::row() + .with_child( + Label::new( + "Include:", + theme.search.include_exclude_inputs.text.clone(), + ) + .contained() + .with_style(theme.search.include_exclude_inputs.container) + .aligned(), + ) + .with_child(included_files_view) + .contained() + .with_style(theme.search.include_exclude_editor.input.container) + .aligned() + .constrained() + .with_min_width(theme.search.include_exclude_editor.min_width) + .with_max_width(theme.search.include_exclude_editor.max_width) + .flex(1., false), ) - .with_child(excluded_files_view) - .contained() - .with_style(theme.search.editor.input.container) - .aligned() - .constrained() - .with_min_width(theme.search.editor.min_width) - .with_max_width(theme.search.editor.max_width) - .flex(1., false), + .with_child( + Flex::row() + .with_child( + Label::new( + "Exclude:", + theme.search.include_exclude_inputs.text.clone(), + ) + .contained() + .with_style(theme.search.include_exclude_inputs.container) + .aligned(), + ) + .with_child(excluded_files_view) + .contained() + .with_style(theme.search.include_exclude_editor.input.container) + .aligned() + .constrained() + .with_min_width(theme.search.include_exclude_editor.min_width) + .with_max_width(theme.search.include_exclude_editor.max_width) + .flex(1., false), + ), ) .contained() .with_style(theme.search.container) @@ -1061,6 +1081,10 @@ impl ToolbarItemView for ProjectSearchBar { ToolbarItemLocation::Hidden } } + + fn row_count(&self) -> usize { + 2 + } } #[cfg(test)] diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index e8c56ac71aaf1ca1290062df16b8fecd08dbc544..2e1a94595790004a458a2624998fca55e3d05655 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -319,6 +319,7 @@ pub struct Search { pub editor: FindEditor, pub invalid_editor: ContainerStyle, pub option_button_group: ContainerStyle, + pub include_exclude_editor: FindEditor, pub include_exclude_inputs: ContainedText, pub option_button: Interactive, pub match_background: Color, diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs index eac9963d38ddcedbaea32c9722b8df2667d2299e..c40c88e3a1f4334d606eb8d66f0211e17dab682c 100644 --- a/crates/workspace/src/toolbar.rs +++ b/crates/workspace/src/toolbar.rs @@ -22,6 +22,10 @@ pub trait ToolbarItemView: View { } fn pane_focus_update(&mut self, _pane_focused: bool, _cx: &mut ViewContext) {} + + fn row_count(&self) -> usize { + 1 + } } trait ToolbarItemViewHandle { @@ -33,6 +37,7 @@ trait ToolbarItemViewHandle { cx: &mut WindowContext, ) -> ToolbarItemLocation; fn pane_focus_update(&mut self, pane_focused: bool, cx: &mut WindowContext); + fn row_count(&self, cx: &WindowContext) -> usize; } #[derive(Copy, Clone, Debug, PartialEq)] @@ -66,12 +71,14 @@ impl View for Toolbar { let mut primary_right_items = Vec::new(); let mut secondary_item = None; let spacing = theme.item_spacing; + let mut primary_items_row_count = 1; for (item, position) in &self.items { match *position { ToolbarItemLocation::Hidden => {} ToolbarItemLocation::PrimaryLeft { flex } => { + primary_items_row_count = primary_items_row_count.max(item.row_count(cx)); let left_item = ChildView::new(item.as_any(), cx) .aligned() .contained() @@ -84,6 +91,7 @@ impl View for Toolbar { } ToolbarItemLocation::PrimaryRight { flex } => { + primary_items_row_count = primary_items_row_count.max(item.row_count(cx)); let right_item = ChildView::new(item.as_any(), cx) .aligned() .contained() @@ -100,7 +108,7 @@ impl View for Toolbar { secondary_item = Some( ChildView::new(item.as_any(), cx) .constrained() - .with_height(theme.height) + .with_height(theme.height * item.row_count(cx) as f32) .into_any(), ); } @@ -117,7 +125,7 @@ impl View for Toolbar { } let container_style = theme.container; - let height = theme.height; + let height = theme.height * primary_items_row_count as f32; let button_style = theme.nav_button; let tooltip_style = cx.global::().theme.tooltip.clone(); @@ -338,6 +346,10 @@ impl ToolbarItemViewHandle for ViewHandle { cx.notify(); }); } + + fn row_count(&self, cx: &WindowContext) -> usize { + self.read(cx).row_count() + } } impl From<&dyn ToolbarItemViewHandle> for AnyViewHandle { diff --git a/styles/src/styleTree/search.ts b/styles/src/styleTree/search.ts index 22c136368f525b6c5ad7c3f5f3af0bd5e1ef45c9..71f1fc3fa965665fc9243f09fe73e42b85b0d1eb 100644 --- a/styles/src/styleTree/search.ts +++ b/styles/src/styleTree/search.ts @@ -64,9 +64,16 @@ export default function search(colorScheme: ColorScheme) { ...editor, border: border(layer, "negative"), }, + includeExcludeEditor: { + ...editor, + minWidth: 100, + maxWidth: 250, + }, matchIndex: { ...text(layer, "mono", "variant"), - padding: 6, + padding: { + left: 6, + }, }, optionButtonGroup: { padding: { @@ -76,7 +83,9 @@ export default function search(colorScheme: ColorScheme) { }, includeExcludeInputs: { ...text(layer, "mono", "variant"), - padding: 6, + padding: { + right: 6, + }, }, resultsStatus: { ...text(layer, "mono", "on"),