Add facepile, indicator, follow_group

This commit is contained in:
Nate Butler 2023-09-15 22:10:51 -04:00
parent 9f2a9d43b1
commit db1dacde5d
9 changed files with 142 additions and 19 deletions

View file

@ -5,7 +5,7 @@ pub enum ButtonVariant {
Filled,
}
#[derive(Default, PartialEq)]
#[derive(Default, PartialEq, Clone, Copy)]
pub enum Shape {
#[default]
Circle,

View file

@ -2,20 +2,17 @@ mod component;
mod element;
mod module;
pub use component::tab::tab;
pub use component::tab::Tab;
pub use component::facepile::*;
pub use component::follow_group::*;
pub use component::tab::*;
pub use module::chat_panel::chat_panel;
pub use module::status_bar::status_bar;
pub use module::status_bar::StatusBar;
pub use module::tab_bar::tab_bar;
pub use module::title_bar::title_bar;
pub use module::chat_panel::*;
pub use module::status_bar::*;
pub use module::tab_bar::*;
pub use module::title_bar::*;
pub use element::avatar::avatar;
pub use element::avatar::Avatar;
pub use element::icon_button::icon_button;
pub use element::icon_button::IconButton;
pub use element::text_button::text_button;
pub use element::text_button::TextButton;
pub use element::tool_divider::tool_divider;
pub use element::tool_divider::ToolDivider;
pub use element::avatar::*;
pub use element::icon_button::*;
pub use element::indicator::*;
pub use element::text_button::*;
pub use element::tool_divider::*;

View file

@ -1 +1,3 @@
pub(crate) mod facepile;
pub(crate) mod follow_group;
pub(crate) mod tab;

View file

@ -0,0 +1,31 @@
use crate::theme::theme;
use crate::ui::Avatar;
use gpui2::style::StyleHelpers;
use gpui2::{elements::div, IntoElement};
use gpui2::{Element, ParentElement, ViewContext};
#[derive(Element)]
pub struct Facepile {
players: Vec<Avatar>,
}
pub fn facepile(players: Vec<Avatar>) -> Facepile {
Facepile { players }
}
impl Facepile {
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let theme = theme(cx);
let player_list = self
.players
.iter()
.map(|player| div().right_1().child(player.clone()));
div()
.relative()
.p_1()
.flex()
.items_center()
.children(player_list)
}
}

View file

@ -0,0 +1,52 @@
use crate::theme::theme;
use crate::ui::{facepile, indicator, Avatar};
use gpui2::style::StyleHelpers;
use gpui2::{elements::div, IntoElement};
use gpui2::{Element, ParentElement, ViewContext};
#[derive(Element)]
pub struct FollowGroup {
player: usize,
players: Vec<Avatar>,
}
pub fn follow_group(players: Vec<Avatar>) -> FollowGroup {
FollowGroup { player: 0, players }
}
impl FollowGroup {
pub fn player(mut self, player: usize) -> Self {
self.player = player;
self
}
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let theme = theme(cx);
let player_bg = theme.players[self.player].selection;
div()
.h_full()
.flex()
.flex_col()
.gap_px()
.justify_center()
.child(
div()
.flex()
.justify_center()
.w_full()
.child(indicator().player(self.player)),
)
.child(
div()
.flex()
.items_center()
.justify_center()
.h_6()
.px_1()
.rounded_lg()
.fill(player_bg)
.child(facepile(self.players.clone())),
)
}
}

View file

@ -1,4 +1,5 @@
pub(crate) mod avatar;
pub(crate) mod icon_button;
pub(crate) mod indicator;
pub(crate) mod text_button;
pub(crate) mod tool_divider;

View file

@ -7,7 +7,7 @@ use gpui2::{Element, ViewContext};
pub type UnknownString = ArcCow<'static, str>;
#[derive(Element)]
#[derive(Element, Clone)]
pub struct Avatar {
src: ArcCow<'static, str>,
shape: Shape,

View file

@ -0,0 +1,32 @@
use crate::theme::theme;
use gpui2::style::StyleHelpers;
use gpui2::{elements::div, IntoElement};
use gpui2::{Element, ViewContext};
#[derive(Element)]
pub struct Indicator {
player: usize,
}
pub fn indicator() -> Indicator {
Indicator { player: 0 }
}
impl Indicator {
pub fn player(mut self, player: usize) -> Self {
self.player = player;
self
}
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let theme = theme(cx);
let player_color = theme.players[self.player].cursor;
div()
.w_4()
.h_1()
.rounded_bl_sm()
.rounded_br_sm()
.fill(player_color)
}
}

View file

@ -2,7 +2,7 @@ use std::marker::PhantomData;
use crate::prelude::Shape;
use crate::theme::theme;
use crate::ui::{avatar, icon_button, text_button, tool_divider};
use crate::ui::{avatar, follow_group, icon_button, text_button, tool_divider};
use gpui2::style::StyleHelpers;
use gpui2::{elements::div, IntoElement};
use gpui2::{Element, ParentElement, ViewContext};
@ -21,6 +21,10 @@ pub fn title_bar<V: 'static>() -> TitleBar<V> {
impl<V: 'static> TitleBar<V> {
fn render(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let theme = theme(cx);
let player_list = vec![
avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
];
div()
.flex()
@ -70,9 +74,13 @@ impl<V: 'static> TitleBar<V> {
.flex()
.items_center()
.gap_1()
.child(text_button("maxbrunsfeld"))
.child(text_button("zed"))
.child(text_button("nate/gpui2-ui-components")),
),
)
.child(follow_group(player_list.clone()).player(0))
.child(follow_group(player_list.clone()).player(1))
.child(follow_group(player_list.clone()).player(2)),
)
.child(
div()