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
8use crate::ToggleReplace;
9
10pub(super) fn render_action_button(
11 id_prefix: &'static str,
12 icon: ui::IconName,
13 active: bool,
14 tooltip: &'static str,
15 action: &'static dyn Action,
16 focus_handle: FocusHandle,
17) -> impl IntoElement {
18 IconButton::new(
19 SharedString::from(format!("{id_prefix}-{}", action.name())),
20 icon,
21 )
22 .shape(IconButtonShape::Square)
23 .on_click({
24 let focus_handle = focus_handle.clone();
25 move |_, window, cx| {
26 if !focus_handle.is_focused(&window) {
27 window.focus(&focus_handle);
28 }
29 window.dispatch_action(action.boxed_clone(), cx)
30 }
31 })
32 .tooltip(move |window, cx| Tooltip::for_action_in(tooltip, action, &focus_handle, window, cx))
33 .disabled(!active)
34}
35
36pub(crate) fn input_base_styles(border_color: Hsla, map: impl FnOnce(Div) -> Div) -> Div {
37 h_flex()
38 .min_w_32()
39 .map(map)
40 .h_8()
41 .pl_2()
42 .pr_1()
43 .py_1()
44 .border_1()
45 .border_color(border_color)
46 .rounded_lg()
47}
48
49pub(crate) fn toggle_replace_button(
50 id: &'static str,
51 focus_handle: FocusHandle,
52 replace_enabled: bool,
53 on_click: impl Fn(&gpui::ClickEvent, &mut Window, &mut App) + 'static,
54) -> IconButton {
55 IconButton::new(id, IconName::Replace)
56 .shape(IconButtonShape::Square)
57 .style(ButtonStyle::Subtle)
58 .when(replace_enabled, |button| button.style(ButtonStyle::Filled))
59 .on_click(on_click)
60 .toggle_state(replace_enabled)
61 .tooltip({
62 move |window, cx| {
63 Tooltip::for_action_in("Toggle Replace", &ToggleReplace, &focus_handle, window, cx)
64 }
65 })
66}
67
68pub(crate) fn render_text_input(
69 editor: &Entity<Editor>,
70 color_override: Option<Color>,
71 app: &App,
72) -> impl IntoElement {
73 let (color, use_syntax) = if editor.read(app).read_only(app) {
74 (app.theme().colors().text_disabled, false)
75 } else {
76 match color_override {
77 Some(color_override) => (color_override.color(app), false),
78 None => (app.theme().colors().text, true),
79 }
80 };
81
82 let settings = ThemeSettings::get_global(app);
83 let text_style = TextStyle {
84 color,
85 font_family: settings.buffer_font.family.clone(),
86 font_features: settings.buffer_font.features.clone(),
87 font_fallbacks: settings.buffer_font.fallbacks.clone(),
88 font_size: rems(0.875).into(),
89 font_weight: settings.buffer_font.weight,
90 line_height: relative(1.3),
91 ..TextStyle::default()
92 };
93
94 let mut editor_style = EditorStyle {
95 background: app.theme().colors().toolbar_background,
96 local_player: app.theme().players().local(),
97 text: text_style,
98 ..EditorStyle::default()
99 };
100 if use_syntax {
101 editor_style.syntax = app.theme().syntax().clone();
102 }
103
104 EditorElement::new(editor, editor_style)
105}