Let toolbar items specify `flex` when they have a primary location

Antonio Scandurra created

Change summary

crates/breadcrumbs/src/breadcrumbs.rs |  2 
crates/search/src/project_search.rs   |  4 +
crates/workspace/src/toolbar.rs       | 68 ++++++++++++++++------------
3 files changed, 42 insertions(+), 32 deletions(-)

Detailed changes

crates/breadcrumbs/src/breadcrumbs.rs 🔗

@@ -117,7 +117,7 @@ impl ToolbarItemView for Breadcrumbs {
                         ToolbarItemLocation::Hidden
                     }
                 } else {
-                    ToolbarItemLocation::PrimaryLeft
+                    ToolbarItemLocation::PrimaryLeft { flex: None }
                 }
             } else {
                 ToolbarItemLocation::Hidden

crates/search/src/project_search.rs 🔗

@@ -769,7 +769,9 @@ impl ToolbarItemView for ProjectSearchBar {
         if let Some(search) = active_pane_item.and_then(|i| i.downcast::<ProjectSearchView>()) {
             self.subscription = Some(cx.observe(&search, |_, _, cx| cx.notify()));
             self.active_project_search = Some(search);
-            ToolbarItemLocation::PrimaryLeft
+            ToolbarItemLocation::PrimaryLeft {
+                flex: Some((1., false)),
+            }
         } else {
             ToolbarItemLocation::Hidden
         }

crates/workspace/src/toolbar.rs 🔗

@@ -31,11 +31,11 @@ trait ToolbarItemViewHandle {
     ) -> ToolbarItemLocation;
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum ToolbarItemLocation {
     Hidden,
-    PrimaryLeft,
-    PrimaryRight,
+    PrimaryLeft { flex: Option<(f32, bool)> },
+    PrimaryRight { flex: Option<(f32, bool)> },
     Secondary,
 }
 
@@ -61,44 +61,52 @@ impl View for Toolbar {
         let mut secondary_item = None;
 
         for (item, position) in &self.items {
-            match position {
+            match *position {
                 ToolbarItemLocation::Hidden => {}
-                ToolbarItemLocation::PrimaryLeft => primary_left_items.push(item),
-                ToolbarItemLocation::PrimaryRight => primary_right_items.push(item),
-                ToolbarItemLocation::Secondary => secondary_item = Some(item),
+                ToolbarItemLocation::PrimaryLeft { flex } => {
+                    let left_item = ChildView::new(item.as_ref())
+                        .aligned()
+                        .contained()
+                        .with_margin_right(theme.item_spacing);
+                    if let Some((flex, expanded)) = flex {
+                        primary_left_items.push(left_item.flex(flex, expanded).boxed());
+                    } else {
+                        primary_left_items.push(left_item.boxed());
+                    }
+                }
+                ToolbarItemLocation::PrimaryRight { flex } => {
+                    let right_item = ChildView::new(item.as_ref())
+                        .aligned()
+                        .contained()
+                        .with_margin_left(theme.item_spacing)
+                        .flex_float();
+                    if let Some((flex, expanded)) = flex {
+                        primary_right_items.push(right_item.flex(flex, expanded).boxed());
+                    } else {
+                        primary_right_items.push(right_item.boxed());
+                    }
+                }
+                ToolbarItemLocation::Secondary => {
+                    secondary_item = Some(
+                        ChildView::new(item.as_ref())
+                            .constrained()
+                            .with_height(theme.height)
+                            .boxed(),
+                    );
+                }
             }
         }
 
         Flex::column()
             .with_child(
                 Flex::row()
-                    .with_children(primary_left_items.iter().map(|i| {
-                        ChildView::new(i.as_ref())
-                            .aligned()
-                            .contained()
-                            .with_margin_right(theme.item_spacing)
-                            .flex(1., false)
-                            .boxed()
-                    }))
-                    .with_children(primary_right_items.iter().map(|i| {
-                        ChildView::new(i.as_ref())
-                            .aligned()
-                            .contained()
-                            .with_margin_left(theme.item_spacing)
-                            .flex_float()
-                            .flex(1., false)
-                            .boxed()
-                    }))
+                    .with_children(primary_left_items)
+                    .with_children(primary_right_items)
                     .constrained()
                     .with_height(theme.height)
                     .boxed(),
             )
-            .with_children(secondary_item.map(|item| {
-                ChildView::new(item.as_ref())
-                    .constrained()
-                    .with_height(theme.height)
-                    .boxed()
-            }))
+            .with_children(secondary_item)
             .contained()
             .with_style(theme.container)
             .boxed()