add theme for search mode option buttons, and adjust padding

KCaverly and Piotr created

Co-authored-by: Piotr <piotr@zed.dev>

Change summary

crates/search/src/project_search.rs | 74 +++++++++++-------------------
crates/theme/src/theme.rs           |  2 
styles/src/style_tree/search.ts     | 46 ++++++++++++++++++
3 files changed, 75 insertions(+), 47 deletions(-)

Detailed changes

crates/search/src/project_search.rs 🔗

@@ -12,7 +12,6 @@ use futures::StreamExt;
 use globset::{Glob, GlobMatcher};
 use gpui::color::Color;
 use gpui::geometry::rect::RectF;
-use gpui::geometry::vector::IntoVector2F;
 use gpui::json::{self, ToJson};
 use gpui::SceneBuilder;
 use gpui::{
@@ -965,46 +964,24 @@ impl Default for ProjectSearchBar {
     }
 }
 type CreatePath = fn(RectF, Color) -> Path;
-type AdjustBorder = fn(RectF, f32) -> RectF;
+
 pub struct ButtonSide {
     color: Color,
     factory: CreatePath,
-    border_adjustment: AdjustBorder,
-    border: Option<(f32, Color)>,
 }
 
 impl ButtonSide {
-    fn new(color: Color, factory: CreatePath, border_adjustment: AdjustBorder) -> Self {
-        Self {
-            color,
-            factory,
-            border_adjustment,
-            border: None,
-        }
-    }
-    pub fn with_border(mut self, width: f32, color: Color) -> Self {
-        self.border = Some((width, color));
-        self
+    fn new(color: Color, factory: CreatePath) -> Self {
+        Self { color, factory }
     }
     pub fn left(color: Color) -> Self {
-        Self::new(color, left_button_side, left_button_border_adjust)
+        Self::new(color, left_button_side)
     }
     pub fn right(color: Color) -> Self {
-        Self::new(color, right_button_side, right_button_border_adjust)
+        Self::new(color, right_button_side)
     }
 }
-fn left_button_border_adjust(bounds: RectF, width: f32) -> RectF {
-    let width = width.into_vector_2f();
-    let mut lower_right = bounds.clone().lower_right();
-    lower_right.set_x(lower_right.x() + width.x());
-    RectF::from_points(bounds.origin() + width, lower_right)
-}
-fn right_button_border_adjust(bounds: RectF, width: f32) -> RectF {
-    let width = width.into_vector_2f();
-    let mut origin = bounds.clone().origin();
-    origin.set_x(origin.x() - width.x());
-    RectF::from_points(origin, bounds.lower_right() - width)
-}
+
 fn left_button_side(bounds: RectF, color: Color) -> Path {
     use gpui::geometry::PathBuilder;
     let mut path = PathBuilder::new();
@@ -1017,6 +994,7 @@ fn left_button_side(bounds: RectF, color: Color) -> Path {
     let mut target = bounds.lower_left();
     target.set_y(target.y() + distance_to_line);
     path.line_to(target);
+    //path.curve_to(bounds.lower_right(), bounds.upper_right());
     path.curve_to(bounds.lower_right(), bounds.lower_left());
     path.build(color, None)
 }
@@ -1033,6 +1011,7 @@ fn right_button_side(bounds: RectF, color: Color) -> Path {
     let mut target = bounds.lower_right();
     target.set_y(target.y() + distance_to_line);
     path.line_to(target);
+    //path.curve_to(bounds.lower_right(), bounds.upper_right());
     path.curve_to(bounds.lower_left(), bounds.lower_right());
     path.build(color, None)
 }
@@ -1060,11 +1039,6 @@ impl Element<ProjectSearchBar> for ButtonSide {
         _: &mut ProjectSearchBar,
         _: &mut ViewContext<ProjectSearchBar>,
     ) -> Self::PaintState {
-        let mut bounds = bounds;
-        if let Some((border_width, border_color)) = self.border.as_ref() {
-            scene.push_path((self.factory)(bounds, border_color.clone()));
-            bounds = (self.border_adjustment)(bounds, *border_width);
-        };
         scene.push_path((self.factory)(bounds, self.color));
     }
 
@@ -1416,12 +1390,14 @@ impl ProjectSearchBar {
             let theme = theme::current(cx);
             let mut style = theme
                 .search
-                .option_button
+                .mode_button
                 .in_state(is_active)
                 .style_for(state)
                 .clone();
             style.container.border.right = false;
-
+            style.container.padding.right -= theme.search.mode_filling_width;
+            style.container.corner_radius = 0.;
+            debug_assert!(style.container.padding.right >= 0.);
             Flex::row()
                 .with_child(
                     Label::new(icon, style.text.clone())
@@ -1435,10 +1411,9 @@ impl ProjectSearchBar {
                             .background_color
                             .unwrap_or_else(gpui::color::Color::transparent_black),
                     )
-                    .with_border(style.container.border.width, style.container.border.color)
                     .contained()
                     .constrained()
-                    .with_max_width(theme.titlebar.avatar_ribbon.width / 2.)
+                    .with_max_width(theme.search.mode_filling_width)
                     .aligned()
                     .bottom(),
                 )
@@ -1470,11 +1445,15 @@ impl ProjectSearchBar {
 
         MouseEventHandler::<Self, _>::new(region_id, cx, |state, cx| {
             let theme = theme::current(cx);
-            let style = theme
+            let mut style = theme
                 .search
-                .option_button
+                .mode_button
                 .in_state(is_active)
-                .style_for(state);
+                .style_for(state)
+                .clone();
+
+            style.container.corner_radius = 0.;
+
             Label::new("Semantic", style.text.clone())
                 .contained()
                 .with_style(style.container)
@@ -1507,11 +1486,14 @@ impl ProjectSearchBar {
             let theme = theme::current(cx);
             let mut style = theme
                 .search
-                .option_button
+                .mode_button
                 .in_state(is_active)
                 .style_for(state)
                 .clone();
             style.container.border.left = false;
+            style.container.padding.left -= theme.search.mode_filling_width;
+            debug_assert!(style.container.padding.left >= 0.);
+            style.container.corner_radius = 0.;
             Flex::row()
                 .with_child(
                     ButtonSide::left(
@@ -1520,10 +1502,9 @@ impl ProjectSearchBar {
                             .background_color
                             .unwrap_or_else(gpui::color::Color::transparent_black),
                     )
-                    .with_border(style.container.border.width, style.container.border.color)
                     .contained()
                     .constrained()
-                    .with_max_width(theme.titlebar.avatar_ribbon.width / 2.)
+                    .with_max_width(theme.search.mode_filling_width)
                     .aligned()
                     .bottom(),
                 )
@@ -1768,15 +1749,16 @@ impl View for ProjectSearchBar {
                 .with_child(
                     Flex::column().with_child(
                         Flex::row()
+                            .align_children_center()
                             .with_child(normal_search)
                             .with_children(semantic_index)
                             .with_child(regex_button)
                             .constrained()
                             .with_height(theme.workspace.toolbar.height)
                             .contained()
+                            .with_style(theme.search.container)
                             .aligned()
-                            .right()
-                            .flex(1., true),
+                            .right(),
                     ),
                 )
                 .contained()

crates/theme/src/theme.rs 🔗

@@ -387,6 +387,8 @@ pub struct Search {
     pub minor_results_status: TextStyle,
     pub dismiss_button: Interactive<IconButton>,
     pub editor_icon: IconStyle,
+    pub mode_button: Toggleable<Interactive<ContainedText>>,
+    pub mode_filling_width: f32,
 }
 
 #[derive(Clone, Deserialize, Default, JsonSchema)]

styles/src/style_tree/search.ts 🔗

@@ -178,6 +178,50 @@ export default function search(): any {
                 margin: { right: 6 },
                 padding: { left: 4 }
             }
-        }
+        },
+        mode_button: toggleable({
+            base: interactive({
+                base: {
+                    ...text(theme.highest, "mono", "on"),
+                    background: background(theme.highest, "on"),
+
+                    border: border(theme.highest, "on"),
+
+                    padding: {
+                        bottom: 6,
+                        left: 10,
+                        right: 10,
+                        top: 6,
+                    },
+                    corner_radius: 2,
+                },
+                state: {
+                    hovered: {
+                        ...text(theme.highest, "mono", "on", "hovered"),
+                        background: background(theme.highest, "on", "hovered"),
+                        border: border(theme.highest, "on", "hovered"),
+                    },
+                    clicked: {
+                        ...text(theme.highest, "mono", "on", "pressed"),
+                        background: background(theme.highest, "on", "pressed"),
+                        border: border(theme.highest, "on", "pressed"),
+                    },
+                },
+            }),
+            state: {
+                active: {
+                    default: {
+                        ...text(theme.highest, "mono", "accent"),
+                    },
+                    hovered: {
+                        ...text(theme.highest, "mono", "accent", "hovered"),
+                    },
+                    clicked: {
+                        ...text(theme.highest, "mono", "accent", "pressed"),
+                    },
+                },
+            },
+        }),
+        mode_filling_width: 4.0,
     }
 }