Add Flex `with_reversed_paint_order` & initially move face piles to left

Julia and Petros Amoiridis created

Co-Authored-By: Petros Amoiridis <petros@zed.dev>

Change summary

crates/collab_ui/src/collab_titlebar_item.rs | 11 ++++++-----
crates/gpui/src/elements/flex.rs             | 21 ++++++++++++++++++++-
2 files changed, 26 insertions(+), 6 deletions(-)

Detailed changes

crates/collab_ui/src/collab_titlebar_item.rs 🔗

@@ -87,6 +87,9 @@ impl View for CollabTitlebarItem {
             left_container.add_child(self.render_toggle_collaborator_list_button(&theme, cx));
         }
 
+        left_container.add_children(self.render_current_user(&workspace, &theme, cx));
+        left_container.add_children(self.render_collaborators(&workspace, &theme, cx));
+
         let mut right_container = Flex::row();
 
         right_container.add_children(self.render_toggle_screen_sharing_button(&theme, cx));
@@ -100,8 +103,6 @@ impl View for CollabTitlebarItem {
                 right_container.add_child(self.render_toggle_contacts_button(&theme, cx));
             }
         }
-        right_container.add_children(self.render_collaborators(&workspace, &theme, cx));
-        right_container.add_children(self.render_current_user(&workspace, &theme, cx));
         right_container.add_children(self.render_connection_status(&workspace, cx));
 
         Stack::new()
@@ -506,7 +507,7 @@ impl CollabTitlebarItem {
                         .get(&participant.peer_id)
                         .map(|collaborator| collaborator.replica_id);
                     let user = participant.user.clone();
-                    Some(self.render_avatar(
+                    Some(self.render_face_pile(
                         &user,
                         replica_id,
                         Some((
@@ -535,7 +536,7 @@ impl CollabTitlebarItem {
         let replica_id = workspace.read(cx).project().read(cx).replica_id();
         let status = *workspace.read(cx).client().status().borrow();
         if let Some(user) = user {
-            Some(self.render_avatar(&user, Some(replica_id), None, workspace, theme, cx))
+            Some(self.render_face_pile(&user, Some(replica_id), None, workspace, theme, cx))
         } else if matches!(status, client::Status::UpgradeRequired) {
             None
         } else {
@@ -559,7 +560,7 @@ impl CollabTitlebarItem {
         }
     }
 
-    fn render_avatar(
+    fn render_face_pile(
         &self,
         user: &User,
         replica_id: Option<ReplicaId>,

crates/gpui/src/elements/flex.rs 🔗

@@ -20,6 +20,7 @@ struct ScrollState {
 
 pub struct Flex {
     axis: Axis,
+    paint_reversed: bool,
     children: Vec<ElementBox>,
     scroll_state: Option<(ElementStateHandle<Rc<ScrollState>>, usize)>,
 }
@@ -28,6 +29,7 @@ impl Flex {
     pub fn new(axis: Axis) -> Self {
         Self {
             axis,
+            paint_reversed: false,
             children: Default::default(),
             scroll_state: None,
         }
@@ -41,6 +43,11 @@ impl Flex {
         Self::new(Axis::Vertical)
     }
 
+    pub fn with_reversed_paint_order(mut self) -> Self {
+        self.paint_reversed = true;
+        self
+    }
+
     pub fn scrollable<Tag, V>(
         mut self,
         element_id: usize,
@@ -296,7 +303,7 @@ impl Element for Flex {
             }
         }
 
-        for child in &mut self.children {
+        let mut child_action = |child: &mut ElementBox| {
             if remaining_space > 0. {
                 if let Some(metadata) = child.metadata::<FlexParentData>() {
                     if metadata.float {
@@ -308,11 +315,23 @@ impl Element for Flex {
                     }
                 }
             }
+
             child.paint(child_origin, visible_bounds, cx);
+
             match self.axis {
                 Axis::Horizontal => child_origin += vec2f(child.size().x(), 0.0),
                 Axis::Vertical => child_origin += vec2f(0.0, child.size().y()),
             }
+        };
+
+        if self.paint_reversed {
+            for child in self.children.iter_mut().rev() {
+                child_action(child);
+            }
+        } else {
+            for child in &mut self.children {
+                child_action(child);
+            }
         }
 
         if overflowing {