search_bar.rs

  1use editor::{Editor, EditorElement, EditorStyle};
  2use gpui::{Action, Entity, FocusHandle, Hsla, IntoElement, TextStyle};
  3use settings::Settings;
  4use theme::ThemeSettings;
  5use ui::{IconButton, IconButtonShape};
  6use ui::{Tooltip, prelude::*};
  7
  8pub(super) enum ActionButtonState {
  9    Disabled,
 10    Toggled,
 11}
 12
 13pub(super) fn render_action_button(
 14    id_prefix: &'static str,
 15    icon: ui::IconName,
 16    button_state: Option<ActionButtonState>,
 17    tooltip: &'static str,
 18    action: &'static dyn Action,
 19    focus_handle: FocusHandle,
 20) -> impl IntoElement {
 21    IconButton::new(
 22        SharedString::from(format!("{id_prefix}-{}", action.name())),
 23        icon,
 24    )
 25    .shape(IconButtonShape::Square)
 26    .on_click({
 27        let focus_handle = focus_handle.clone();
 28        move |_, window, cx| {
 29            if !focus_handle.is_focused(window) {
 30                window.focus(&focus_handle, cx);
 31            }
 32            window.dispatch_action(action.boxed_clone(), cx);
 33        }
 34    })
 35    .tooltip(move |_window, cx| Tooltip::for_action_in(tooltip, action, &focus_handle, cx))
 36    .when_some(button_state, |this, state| match state {
 37        ActionButtonState::Toggled => this.toggle_state(true),
 38        ActionButtonState::Disabled => this.disabled(true),
 39    })
 40}
 41
 42pub(crate) fn input_base_styles(border_color: Hsla, map: impl FnOnce(Div) -> Div) -> Div {
 43    h_flex()
 44        .map(map)
 45        .min_w_32()
 46        .h_8()
 47        .pl_2()
 48        .pr_1()
 49        .border_1()
 50        .border_color(border_color)
 51        .rounded_md()
 52}
 53pub(crate) fn filter_search_results_input(
 54    border_color: Hsla,
 55    map: impl FnOnce(Div) -> Div,
 56    cx: &App,
 57) -> Div {
 58    input_base_styles(border_color, map).pl_0().child(
 59        h_flex()
 60            .mr_2()
 61            .px_2()
 62            .h_full()
 63            .border_r_1()
 64            .border_color(cx.theme().colors().border)
 65            .bg(cx.theme().colors().text_accent.opacity(0.05))
 66            .child(Label::new("Find in Results").color(Color::Muted)),
 67    )
 68}
 69
 70pub(crate) fn render_text_input(
 71    editor: &Entity<Editor>,
 72    color_override: Option<Color>,
 73    app: &App,
 74) -> impl IntoElement {
 75    let (color, use_syntax) = if editor.read(app).read_only(app) {
 76        (app.theme().colors().text_disabled, false)
 77    } else {
 78        match color_override {
 79            Some(color_override) => (color_override.color(app), false),
 80            None => (app.theme().colors().text, true),
 81        }
 82    };
 83
 84    let settings = ThemeSettings::get_global(app);
 85    let text_style = TextStyle {
 86        color,
 87        font_family: settings.buffer_font.family.clone(),
 88        font_features: settings.buffer_font.features.clone(),
 89        font_fallbacks: settings.buffer_font.fallbacks.clone(),
 90        font_size: rems(0.875).into(),
 91        font_weight: settings.buffer_font.weight,
 92        line_height: relative(1.3),
 93        ..TextStyle::default()
 94    };
 95
 96    let mut editor_style = EditorStyle {
 97        background: app.theme().colors().toolbar_background,
 98        local_player: app.theme().players().local(),
 99        text: text_style,
100        ..EditorStyle::default()
101    };
102    if use_syntax {
103        editor_style.syntax = app.theme().syntax().clone();
104    }
105
106    EditorElement::new(editor, editor_style)
107}
108
109/// This element makes all search inputs align as if they were in the same column
110pub(crate) fn alignment_element() -> Div {
111    div().size_5().flex_none().ml_0p5()
112}