From bf4211b03a1357590f98b96f3cc2c859ebc0b194 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:56:51 +0100 Subject: [PATCH] Use facepile for avatars --- crates/collab_ui2/src/collab_titlebar_item.rs | 23 ++-- crates/collab_ui2/src/face_pile.rs | 107 +++++++----------- crates/workspace2/src/workspace2.rs | 2 - 3 files changed, 54 insertions(+), 78 deletions(-) diff --git a/crates/collab_ui2/src/collab_titlebar_item.rs b/crates/collab_ui2/src/collab_titlebar_item.rs index 67b7d8d1a2..0ba5c3e707 100644 --- a/crates/collab_ui2/src/collab_titlebar_item.rs +++ b/crates/collab_ui2/src/collab_titlebar_item.rs @@ -31,9 +31,9 @@ use std::sync::Arc; use call::ActiveCall; use client::{Client, UserStore}; use gpui::{ - div, px, rems, AppContext, Div, InteractiveElement, IntoElement, Model, MouseButton, - ParentElement, Render, Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, - VisualContext, WeakView, WindowBounds, + div, px, rems, AppContext, Div, Element, InteractiveElement, IntoElement, Model, MouseButton, + ParentElement, Render, RenderOnce, Stateful, StatefulInteractiveElement, Styled, Subscription, + ViewContext, VisualContext, WeakView, WindowBounds, }; use project::Project; use theme::ActiveTheme; @@ -41,6 +41,8 @@ use ui::{h_stack, Avatar, Button, ButtonVariant, Color, IconButton, KeyBinding, use util::ResultExt; use workspace::Workspace; +use crate::face_pile::FacePile; + // const MAX_PROJECT_NAME_LENGTH: usize = 40; // const MAX_BRANCH_NAME_LENGTH: usize = 40; @@ -178,16 +180,21 @@ impl Render for CollabTitlebarItem { .when_some( users.zip(current_user.clone()), |this, (remote_participants, current_user)| { - this.children( + let mut pile = FacePile::default(); + pile.extend( current_user .avatar .clone() - .map(|avatar| div().child(Avatar::data(avatar.clone()))) + .map(|avatar| { + div().child(Avatar::data(avatar.clone())).into_any_element() + }) .into_iter() .chain(remote_participants.into_iter().flat_map(|(user, peer_id)| { user.avatar.as_ref().map(|avatar| { div() - .child(Avatar::data(avatar.clone()).into_element()) + .child( + Avatar::data(avatar.clone()).into_element().into_any(), + ) .on_mouse_down(MouseButton::Left, { let workspace = workspace.clone(); move |_, cx| { @@ -198,9 +205,11 @@ impl Render for CollabTitlebarItem { .log_err(); } }) + .into_any_element() }) })), - ) + ); + this.child(pile.render(cx)) }, ) .child(div().flex_1()) diff --git a/crates/collab_ui2/src/face_pile.rs b/crates/collab_ui2/src/face_pile.rs index 077b813fbd..953470b854 100644 --- a/crates/collab_ui2/src/face_pile.rs +++ b/crates/collab_ui2/src/face_pile.rs @@ -1,54 +1,50 @@ -// use std::ops::Range; +use gpui::{ + div, AnyElement, Div, IntoElement as _, ParentElement as _, Render, RenderOnce, Styled, + ViewContext, WindowContext, +}; +use ui::Avatar; -// use gpui::{ -// geometry::{ -// rect::RectF, -// vector::{vec2f, Vector2F}, -// }, -// json::ToJson, -// serde_json::{self, json}, -// AnyElement, Axis, Element, View, ViewContext, -// }; +#[derive(Default)] +pub(crate) struct FacePile { + faces: Vec, +} -// pub(crate) struct FacePile { -// overlap: f32, -// faces: Vec>, -// } +impl RenderOnce for FacePile { + type Rendered = Div; -// impl FacePile { -// pub fn new(overlap: f32) -> Self { -// Self { -// overlap, -// faces: Vec::new(), -// } -// } -// } + fn render(self, _: &mut WindowContext) -> Self::Rendered { + let player_count = self.faces.len(); + let player_list = self.faces.into_iter().enumerate().map(|(ix, player)| { + let isnt_last = ix < player_count - 1; -// impl Element for FacePile { -// type LayoutState = (); -// type PaintState = (); + div().when(isnt_last, |div| div.neg_mr_2()).child(player) + }); + div().p_1().flex().items_center().children(player_list) + } +} +// impl Element for FacePile { +// type State = (); // fn layout( // &mut self, -// constraint: gpui::SizeConstraint, -// view: &mut V, -// cx: &mut ViewContext, -// ) -> (Vector2F, Self::LayoutState) { -// debug_assert!(constraint.max_along(Axis::Horizontal) == f32::INFINITY); - +// state: Option, +// cx: &mut WindowContext, +// ) -> (LayoutId, Self::State) { // let mut width = 0.; // let mut max_height = 0.; +// let mut faces = Vec::with_capacity(self.faces.len()); // for face in &mut self.faces { -// let layout = face.layout(constraint, view, cx); +// let layout = face.layout(cx); // width += layout.x(); // max_height = f32::max(max_height, layout.y()); +// faces.push(layout); // } // width -= self.overlap * self.faces.len().saturating_sub(1) as f32; - -// ( -// Vector2F::new(width, max_height.clamp(1., constraint.max.y())), -// (), -// ) +// (cx.request_layout(&Style::default(), faces), ()) +// // ( +// // Vector2F::new(width, max_height.clamp(1., constraint.max.y())), +// // (), +// // )) // } // fn paint( @@ -77,37 +73,10 @@ // () // } - -// fn rect_for_text_range( -// &self, -// _: Range, -// _: RectF, -// _: RectF, -// _: &Self::LayoutState, -// _: &Self::PaintState, -// _: &V, -// _: &ViewContext, -// ) -> Option { -// None -// } - -// fn debug( -// &self, -// bounds: RectF, -// _: &Self::LayoutState, -// _: &Self::PaintState, -// _: &V, -// _: &ViewContext, -// ) -> serde_json::Value { -// json!({ -// "type": "FacePile", -// "bounds": bounds.to_json() -// }) -// } // } -// impl Extend> for FacePile { -// fn extend>>(&mut self, children: T) { -// self.faces.extend(children); -// } -// } +impl Extend for FacePile { + fn extend>(&mut self, children: T) { + self.faces.extend(children); + } +} diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index fd52276ef4..73bfc63332 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -2003,8 +2003,6 @@ impl Workspace { self.active_pane.update(cx, |pane, cx| { pane.add_item(shared_screen, false, true, None, cx) }); - } else { - dbg!("WTF"); } }