Detailed changes
@@ -16,9 +16,11 @@ mod palette;
mod panel;
mod player;
mod player_stack;
+mod slot;
mod stack;
mod tab;
mod toast;
+mod toggle;
mod tool_divider;
pub use avatar::*;
@@ -39,7 +41,9 @@ pub use palette::*;
pub use panel::*;
pub use player::*;
pub use player_stack::*;
+pub use slot::*;
pub use stack::*;
pub use tab::*;
pub use toast::*;
+pub use toggle::*;
pub use tool_divider::*;
@@ -2,8 +2,27 @@ use std::sync::Arc;
use gpui2::{div, rems, DefiniteLength, Hsla, MouseButton, WindowContext};
-use crate::prelude::*;
use crate::{h_stack, Icon, IconColor, IconElement, Label, LabelColor, LineHeightStyle};
+use crate::{prelude::*, IconButton};
+
+/// Provides the flexibility to use either a standard
+/// button or an icon button in a given context.
+pub enum ButtonOrIconButton<V: 'static> {
+ Button(Button<V>),
+ IconButton(IconButton<V>),
+}
+
+impl<V: 'static> From<Button<V>> for ButtonOrIconButton<V> {
+ fn from(value: Button<V>) -> Self {
+ Self::Button(value)
+ }
+}
+
+impl<V: 'static> From<IconButton<V>> for ButtonOrIconButton<V> {
+ fn from(value: IconButton<V>) -> Self {
+ Self::IconButton(value)
+ }
+}
#[derive(Default, PartialEq, Clone, Copy)]
pub enum IconPosition {
@@ -8,7 +8,7 @@ pub enum ContextMenuItem {
}
impl ContextMenuItem {
- fn to_list_item<V: 'static>(self) -> ListItem<V> {
+ fn to_list_item<V: 'static>(self) -> ListItem {
match self {
ContextMenuItem::Header(label) => ListSubHeader::new(label).into(),
ContextMenuItem::Entry(label) => {
@@ -49,15 +49,12 @@ impl ContextMenu {
.bg(cx.theme().colors().elevated_surface)
.border()
.border_color(cx.theme().colors().border)
- .child(
- List::new(
- self.items
- .into_iter()
- .map(ContextMenuItem::to_list_item)
- .collect(),
- )
- .toggle(ToggleState::Toggled),
- )
+ .child(List::new(
+ self.items
+ .into_iter()
+ .map(ContextMenuItem::to_list_item::<V>)
+ .collect(),
+ ))
}
}
@@ -1,11 +1,11 @@
-use gpui2::{div, px, relative, Div};
+use gpui2::div;
use crate::settings::user_settings;
use crate::{
- h_stack, v_stack, Avatar, ClickHandler, Icon, IconColor, IconElement, IconSize, Label,
- LabelColor,
+ disclosure_control, h_stack, v_stack, Avatar, Icon, IconColor, IconElement, IconSize, Label,
+ LabelColor, Toggle,
};
-use crate::{prelude::*, Button};
+use crate::{prelude::*, GraphicSlot};
#[derive(Clone, Copy, Default, Debug, PartialEq)]
pub enum ListItemVariant {
@@ -29,7 +29,7 @@ pub struct ListHeader {
left_icon: Option<Icon>,
meta: Option<ListHeaderMeta>,
variant: ListItemVariant,
- toggleable: Toggleable,
+ toggle: Toggle,
}
impl ListHeader {
@@ -39,17 +39,12 @@ impl ListHeader {
left_icon: None,
meta: None,
variant: ListItemVariant::default(),
- toggleable: Toggleable::NotToggleable,
+ toggle: Toggle::NotToggleable,
}
}
- pub fn toggle(mut self, toggle: ToggleState) -> Self {
- self.toggleable = toggle.into();
- self
- }
-
- pub fn toggleable(mut self, toggleable: Toggleable) -> Self {
- self.toggleable = toggleable;
+ pub fn toggle(mut self, toggle: Toggle) -> Self {
+ self.toggle = toggle;
self
}
@@ -63,30 +58,8 @@ impl ListHeader {
self
}
- fn disclosure_control<V: 'static>(&self) -> Div<V> {
- let is_toggleable = self.toggleable != Toggleable::NotToggleable;
- let is_toggled = Toggleable::is_toggled(&self.toggleable);
-
- match (is_toggleable, is_toggled) {
- (false, _) => div(),
- (_, true) => div().child(
- IconElement::new(Icon::ChevronDown)
- .color(IconColor::Muted)
- .size(IconSize::Small),
- ),
- (_, false) => div().child(
- IconElement::new(Icon::ChevronRight)
- .color(IconColor::Muted)
- .size(IconSize::Small),
- ),
- }
- }
-
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
- let is_toggleable = self.toggleable != Toggleable::NotToggleable;
- let is_toggled = self.toggleable.is_toggled();
-
- let disclosure_control = self.disclosure_control();
+ let disclosure_control = disclosure_control(self.toggle);
let meta = match self.meta {
Some(ListHeaderMeta::Tools(icons)) => div().child(
@@ -193,12 +166,6 @@ impl ListSubHeader {
}
}
-#[derive(Clone)]
-pub enum LeftContent {
- Icon(Icon),
- Avatar(SharedString),
-}
-
#[derive(Default, PartialEq, Copy, Clone)]
pub enum ListEntrySize {
#[default]
@@ -207,44 +174,36 @@ pub enum ListEntrySize {
}
#[derive(Component)]
-pub enum ListItem<V: 'static> {
+pub enum ListItem {
Entry(ListEntry),
- Details(ListDetailsEntry<V>),
Separator(ListSeparator),
Header(ListSubHeader),
}
-impl<V: 'static> From<ListEntry> for ListItem<V> {
+impl From<ListEntry> for ListItem {
fn from(entry: ListEntry) -> Self {
Self::Entry(entry)
}
}
-impl<V: 'static> From<ListDetailsEntry<V>> for ListItem<V> {
- fn from(entry: ListDetailsEntry<V>) -> Self {
- Self::Details(entry)
- }
-}
-
-impl<V: 'static> From<ListSeparator> for ListItem<V> {
+impl From<ListSeparator> for ListItem {
fn from(entry: ListSeparator) -> Self {
Self::Separator(entry)
}
}
-impl<V: 'static> From<ListSubHeader> for ListItem<V> {
+impl From<ListSubHeader> for ListItem {
fn from(entry: ListSubHeader) -> Self {
Self::Header(entry)
}
}
-impl<V: 'static> ListItem<V> {
- fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+impl ListItem {
+ fn render<V: 'static>(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
match self {
ListItem::Entry(entry) => div().child(entry.render(view, cx)),
ListItem::Separator(separator) => div().child(separator.render(view, cx)),
ListItem::Header(header) => div().child(header.render(view, cx)),
- ListItem::Details(details) => div().child(details.render(view, cx)),
}
}
@@ -263,31 +222,29 @@ impl<V: 'static> ListItem<V> {
#[derive(Component)]
pub struct ListEntry {
- disclosure_control_style: DisclosureControlVisibility,
+ disabled: bool,
+ // TODO: Reintroduce this
+ // disclosure_control_style: DisclosureControlVisibility,
indent_level: u32,
label: Label,
- left_content: Option<LeftContent>,
- variant: ListItemVariant,
- size: ListEntrySize,
- state: InteractionState,
- toggle: Option<ToggleState>,
+ left_slot: Option<GraphicSlot>,
overflow: OverflowStyle,
+ size: ListEntrySize,
+ toggle: Toggle,
+ variant: ListItemVariant,
}
impl ListEntry {
pub fn new(label: Label) -> Self {
Self {
- disclosure_control_style: DisclosureControlVisibility::default(),
+ disabled: false,
indent_level: 0,
label,
- variant: ListItemVariant::default(),
- left_content: None,
- size: ListEntrySize::default(),
- state: InteractionState::default(),
- // TODO: Should use Toggleable::NotToggleable
- // or remove Toggleable::NotToggleable from the system
- toggle: None,
+ left_slot: None,
overflow: OverflowStyle::Hidden,
+ size: ListEntrySize::default(),
+ toggle: Toggle::NotToggleable,
+ variant: ListItemVariant::default(),
}
}
@@ -301,28 +258,23 @@ impl ListEntry {
self
}
- pub fn toggle(mut self, toggle: ToggleState) -> Self {
- self.toggle = Some(toggle);
+ pub fn toggle(mut self, toggle: Toggle) -> Self {
+ self.toggle = toggle;
self
}
- pub fn left_content(mut self, left_content: LeftContent) -> Self {
- self.left_content = Some(left_content);
+ pub fn left_content(mut self, left_content: GraphicSlot) -> Self {
+ self.left_slot = Some(left_content);
self
}
pub fn left_icon(mut self, left_icon: Icon) -> Self {
- self.left_content = Some(LeftContent::Icon(left_icon));
+ self.left_slot = Some(GraphicSlot::Icon(left_icon));
self
}
pub fn left_avatar(mut self, left_avatar: impl Into<SharedString>) -> Self {
- self.left_content = Some(LeftContent::Avatar(left_avatar.into()));
- self
- }
-
- pub fn state(mut self, state: InteractionState) -> Self {
- self.state = state;
+ self.left_slot = Some(GraphicSlot::Avatar(left_avatar.into()));
self
}
@@ -331,63 +283,19 @@ impl ListEntry {
self
}
- pub fn disclosure_control_style(
- mut self,
- disclosure_control_style: DisclosureControlVisibility,
- ) -> Self {
- self.disclosure_control_style = disclosure_control_style;
- self
- }
-
- fn label_color(&self) -> LabelColor {
- match self.state {
- InteractionState::Disabled => LabelColor::Disabled,
- _ => Default::default(),
- }
- }
-
- fn icon_color(&self) -> IconColor {
- match self.state {
- InteractionState::Disabled => IconColor::Disabled,
- _ => Default::default(),
- }
- }
-
- fn disclosure_control<V: 'static>(
- &mut self,
- cx: &mut ViewContext<V>,
- ) -> Option<impl Component<V>> {
- let disclosure_control_icon = if let Some(ToggleState::Toggled) = self.toggle {
- IconElement::new(Icon::ChevronDown)
- } else {
- IconElement::new(Icon::ChevronRight)
- }
- .color(IconColor::Muted)
- .size(IconSize::Small);
-
- match (self.toggle, self.disclosure_control_style) {
- (Some(_), DisclosureControlVisibility::OnHover) => {
- Some(div().absolute().neg_left_5().child(disclosure_control_icon))
- }
- (Some(_), DisclosureControlVisibility::Always) => {
- Some(div().child(disclosure_control_icon))
- }
- (None, _) => None,
- }
- }
-
- fn render<V: 'static>(mut self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
let settings = user_settings(cx);
- let left_content = match self.left_content.clone() {
- Some(LeftContent::Icon(i)) => Some(
+ let left_content = match self.left_slot.clone() {
+ Some(GraphicSlot::Icon(i)) => Some(
h_stack().child(
IconElement::new(i)
.size(IconSize::Small)
.color(IconColor::Muted),
),
),
- Some(LeftContent::Avatar(src)) => Some(h_stack().child(Avatar::new(src))),
+ Some(GraphicSlot::Avatar(src)) => Some(h_stack().child(Avatar::new(src))),
+ Some(GraphicSlot::PublicActor(src)) => Some(h_stack().child(Avatar::new(src))),
None => None,
};
@@ -400,10 +308,7 @@ impl ListEntry {
.relative()
.group("")
.bg(cx.theme().colors().surface)
- .when(self.state == InteractionState::Focused, |this| {
- this.border()
- .border_color(cx.theme().colors().border_focused)
- })
+ // TODO: Add focus state
.child(
sized_item
.when(self.variant == ListItemVariant::Inset, |this| this.px_2())
@@ -425,131 +330,13 @@ impl ListEntry {
.gap_1()
.items_center()
.relative()
- .children(self.disclosure_control(cx))
+ .child(disclosure_control(self.toggle))
.children(left_content)
.child(self.label),
)
}
}
-struct ListDetailsEntryHandlers<V: 'static> {
- click: Option<ClickHandler<V>>,
-}
-
-impl<V: 'static> Default for ListDetailsEntryHandlers<V> {
- fn default() -> Self {
- Self { click: None }
- }
-}
-
-#[derive(Component)]
-pub struct ListDetailsEntry<V: 'static> {
- label: SharedString,
- meta: Option<SharedString>,
- left_content: Option<LeftContent>,
- handlers: ListDetailsEntryHandlers<V>,
- actions: Option<Vec<Button<V>>>,
- // TODO: make this more generic instead of
- // specifically for notifications
- seen: bool,
-}
-
-impl<V: 'static> ListDetailsEntry<V> {
- pub fn new(label: impl Into<SharedString>) -> Self {
- Self {
- label: label.into(),
- meta: None,
- left_content: None,
- handlers: ListDetailsEntryHandlers::default(),
- actions: None,
- seen: false,
- }
- }
-
- pub fn meta(mut self, meta: impl Into<SharedString>) -> Self {
- self.meta = Some(meta.into());
- self
- }
-
- pub fn seen(mut self, seen: bool) -> Self {
- self.seen = seen;
- self
- }
-
- pub fn on_click(mut self, handler: ClickHandler<V>) -> Self {
- self.handlers.click = Some(handler);
- self
- }
-
- pub fn actions(mut self, actions: Vec<Button<V>>) -> Self {
- self.actions = Some(actions);
- self
- }
-
- fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
- let settings = user_settings(cx);
-
- let (item_bg, item_bg_hover, item_bg_active) = (
- cx.theme().colors().ghost_element,
- cx.theme().colors().ghost_element_hover,
- cx.theme().colors().ghost_element_active,
- );
-
- let label_color = match self.seen {
- true => LabelColor::Muted,
- false => LabelColor::Default,
- };
-
- div()
- .relative()
- .group("")
- .bg(item_bg)
- .px_2()
- .py_1p5()
- .w_full()
- .z_index(1)
- .when(!self.seen, |this| {
- this.child(
- div()
- .absolute()
- .left(px(3.0))
- .top_3()
- .rounded_full()
- .border_2()
- .border_color(cx.theme().colors().surface)
- .w(px(9.0))
- .h(px(9.0))
- .z_index(2)
- .bg(cx.theme().status().info),
- )
- })
- .child(
- v_stack()
- .w_full()
- .line_height(relative(1.2))
- .gap_1()
- .child(
- div()
- .w_5()
- .h_5()
- .rounded_full()
- .bg(cx.theme().colors().icon_accent),
- )
- .child(Label::new(self.label.clone()).color(label_color))
- .children(
- self.meta
- .map(|meta| Label::new(meta).color(LabelColor::Muted)),
- )
- .child(
- h_stack()
- .gap_1()
- .justify_end()
- .children(self.actions.unwrap_or_default()),
- ),
- )
- }
-}
-
#[derive(Clone, Component)]
pub struct ListSeparator;
@@ -564,20 +351,22 @@ impl ListSeparator {
}
#[derive(Component)]
-pub struct List<V: 'static> {
- items: Vec<ListItem<V>>,
+pub struct List {
+ items: Vec<ListItem>,
+ /// Message to display when the list is empty
+ /// Defaults to "No items"
empty_message: SharedString,
header: Option<ListHeader>,
- toggleable: Toggleable,
+ toggle: Toggle,
}
-impl<V: 'static> List<V> {
- pub fn new(items: Vec<ListItem<V>>) -> Self {
+impl List {
+ pub fn new(items: Vec<ListItem>) -> Self {
Self {
items,
empty_message: "No items".into(),
header: None,
- toggleable: Toggleable::default(),
+ toggle: Toggle::NotToggleable,
}
}
@@ -591,19 +380,16 @@ impl<V: 'static> List<V> {
self
}
- pub fn toggle(mut self, toggle: ToggleState) -> Self {
- self.toggleable = toggle.into();
+ pub fn toggle(mut self, toggle: Toggle) -> Self {
+ self.toggle = toggle;
self
}
- fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
- let is_toggleable = self.toggleable != Toggleable::NotToggleable;
- let is_toggled = Toggleable::is_toggled(&self.toggleable);
-
- let list_content = match (self.items.is_empty(), is_toggled) {
+ fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ let list_content = match (self.items.is_empty(), self.toggle) {
(false, _) => div().children(self.items),
- (true, false) => div(),
- (true, true) => {
+ (true, Toggle::Toggled(false)) => div(),
+ (true, _) => {
div().child(Label::new(self.empty_message.clone()).color(LabelColor::Muted))
}
};
@@ -611,7 +397,7 @@ impl<V: 'static> List<V> {
v_stack()
.w_full()
.py_1()
- .children(self.header.map(|header| header.toggleable(self.toggleable)))
+ .children(self.header.map(|header| header))
.child(list_content)
}
}
@@ -2,6 +2,24 @@ use gpui2::{Hsla, ViewContext};
use crate::prelude::*;
+/// Represents a person with a Zed account's public profile.
+/// All data in this struct should be considered public.
+pub struct PublicPlayer {
+ pub username: SharedString,
+ pub avatar: SharedString,
+ pub is_contact: bool,
+}
+
+impl PublicPlayer {
+ pub fn new(username: impl Into<SharedString>, avatar: impl Into<SharedString>) -> Self {
+ Self {
+ username: username.into(),
+ avatar: avatar.into(),
+ is_contact: false,
+ }
+ }
+}
+
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
pub enum PlayerStatus {
#[default]
@@ -0,0 +1,14 @@
+use gpui2::SharedString;
+
+use crate::Icon;
+
+#[derive(Debug, Clone)]
+/// A slot utility that provides a way to to pass either
+/// an icon or an image to a component.
+///
+/// Can be filled with a []
+pub enum GraphicSlot {
+ Icon(Icon),
+ Avatar(SharedString),
+ PublicActor(SharedString),
+}
@@ -0,0 +1,61 @@
+use gpui2::{div, Component, ParentElement};
+
+use crate::{Icon, IconColor, IconElement, IconSize};
+
+/// Whether the entry is toggleable, and if so, whether it is currently toggled.
+///
+/// To make an element toggleable, simply add a `Toggle::Toggled(_)` and handle it's cases.
+///
+/// You can check if an element is toggleable with `.is_toggleable()`
+///
+/// Possible values:
+/// - `Toggle::NotToggleable` - The entry is not toggleable
+/// - `Toggle::Toggled(true)` - The entry is toggleable and toggled
+/// - `Toggle::Toggled(false)` - The entry is toggleable and not toggled
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum Toggle {
+ NotToggleable,
+ Toggled(bool),
+}
+
+impl Toggle {
+ /// Returns true if the entry is toggled (or is not toggleable.)
+ ///
+ /// As element that isn't toggleable is always "expanded" or "enabled"
+ /// returning true in that case makes sense.
+ pub fn is_toggled(&self) -> bool {
+ match self {
+ Self::Toggled(false) => false,
+ _ => true,
+ }
+ }
+
+ pub fn is_toggleable(&self) -> bool {
+ match self {
+ Self::Toggled(_) => true,
+ _ => false,
+ }
+ }
+}
+
+impl From<bool> for Toggle {
+ fn from(toggled: bool) -> Self {
+ Toggle::Toggled(toggled)
+ }
+}
+
+pub fn disclosure_control<V: 'static>(toggle: Toggle) -> impl Component<V> {
+ match (toggle.is_toggleable(), toggle.is_toggled()) {
+ (false, _) => div(),
+ (_, true) => div().child(
+ IconElement::new(Icon::ChevronDown)
+ .color(IconColor::Muted)
+ .size(IconSize::Small),
+ ),
+ (_, false) => div().child(
+ IconElement::new(Icon::ChevronRight)
+ .color(IconColor::Muted)
+ .size(IconSize::Small),
+ ),
+ }
+}
@@ -10,24 +10,6 @@ pub use theme2::ActiveTheme;
use gpui2::Hsla;
use strum::EnumIter;
-/// Represents a person with a Zed account's public profile.
-/// All data in this struct should be considered public.
-pub struct PublicActor {
- pub username: SharedString,
- pub avatar: SharedString,
- pub is_contact: bool,
-}
-
-impl PublicActor {
- pub fn new(username: impl Into<SharedString>, avatar: impl Into<SharedString>) -> Self {
- Self {
- username: username.into(),
- avatar: avatar.into(),
- is_contact: false,
- }
- }
-}
-
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
pub enum FileSystemStatus {
#[default]
@@ -179,61 +161,3 @@ pub enum SelectedState {
PartiallySelected,
Selected,
}
-
-#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
-pub enum Toggleable {
- Toggleable(ToggleState),
- #[default]
- NotToggleable,
-}
-
-impl Toggleable {
- pub fn is_toggled(&self) -> bool {
- match self {
- Self::Toggleable(ToggleState::Toggled) => true,
- _ => false,
- }
- }
-}
-
-impl From<ToggleState> for Toggleable {
- fn from(state: ToggleState) -> Self {
- Self::Toggleable(state)
- }
-}
-
-#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
-pub enum ToggleState {
- /// The "on" state of a toggleable element.
- ///
- /// Example:
- /// - A collasable list that is currently expanded
- /// - A toggle button that is currently on.
- Toggled,
- /// The "off" state of a toggleable element.
- ///
- /// Example:
- /// - A collasable list that is currently collapsed
- /// - A toggle button that is currently off.
- #[default]
- NotToggled,
-}
-
-impl From<Toggleable> for ToggleState {
- fn from(toggleable: Toggleable) -> Self {
- match toggleable {
- Toggleable::Toggleable(state) => state,
- Toggleable::NotToggleable => ToggleState::NotToggled,
- }
- }
-}
-
-impl From<bool> for ToggleState {
- fn from(toggled: bool) -> Self {
- if toggled {
- ToggleState::Toggled
- } else {
- ToggleState::NotToggled
- }
- }
-}
@@ -7,13 +7,13 @@ use gpui2::{AppContext, ViewContext};
use rand::Rng;
use theme2::ActiveTheme;
+use crate::HighlightedText;
use crate::{
Buffer, BufferRow, BufferRows, Button, EditorPane, FileSystemStatus, GitStatus,
- HighlightedLine, Icon, Keybinding, Label, LabelColor, ListEntry, ListEntrySize, ListSubHeader,
- Livestream, MicStatus, ModifierKeys, Notification, PaletteItem, Player, PlayerCallStatus,
- PlayerWithCallStatus, PublicActor, ScreenShareStatus, Symbol, Tab, ToggleState, VideoStatus,
+ HighlightedLine, Icon, Keybinding, Label, LabelColor, ListEntry, ListEntrySize, Livestream,
+ MicStatus, ModifierKeys, Notification, PaletteItem, Player, PlayerCallStatus,
+ PlayerWithCallStatus, PublicPlayer, ScreenShareStatus, Symbol, Tab, Toggle, VideoStatus,
};
-use crate::{HighlightedText, ListDetailsEntry};
use crate::{ListItem, NotificationAction};
pub fn static_tabs_example() -> Vec<Tab> {
@@ -345,7 +345,7 @@ pub fn static_new_notification_items_2<V: 'static>() -> Vec<Notification<V>> {
DateTime::parse_from_rfc3339("2023-11-02T12:09:07Z")
.unwrap()
.naive_local(),
- PublicActor::new("as-cii", "http://github.com/as-cii.png?s=50"),
+ PublicPlayer::new("as-cii", "http://github.com/as-cii.png?s=50"),
[
NotificationAction::new(
Button::new("Decline"),
@@ -374,7 +374,7 @@ pub fn static_new_notification_items_2<V: 'static>() -> Vec<Notification<V>> {
DateTime::parse_from_rfc3339("2023-11-01T12:09:07Z")
.unwrap()
.naive_local(),
- PublicActor::new("as-cii", "http://github.com/as-cii.png?s=50"),
+ PublicPlayer::new("as-cii", "http://github.com/as-cii.png?s=50"),
[
NotificationAction::new(
Button::new("Decline"),
@@ -403,7 +403,7 @@ pub fn static_new_notification_items_2<V: 'static>() -> Vec<Notification<V>> {
DateTime::parse_from_rfc3339("2022-10-25T12:09:07Z")
.unwrap()
.naive_local(),
- PublicActor::new("as-cii", "http://github.com/as-cii.png?s=50"),
+ PublicPlayer::new("as-cii", "http://github.com/as-cii.png?s=50"),
[
NotificationAction::new(
Button::new("Decline"),
@@ -432,7 +432,7 @@ pub fn static_new_notification_items_2<V: 'static>() -> Vec<Notification<V>> {
DateTime::parse_from_rfc3339("2021-10-12T12:09:07Z")
.unwrap()
.naive_local(),
- PublicActor::new("as-cii", "http://github.com/as-cii.png?s=50"),
+ PublicPlayer::new("as-cii", "http://github.com/as-cii.png?s=50"),
[
NotificationAction::new(
Button::new("Decline"),
@@ -461,7 +461,7 @@ pub fn static_new_notification_items_2<V: 'static>() -> Vec<Notification<V>> {
DateTime::parse_from_rfc3339("1969-07-20T00:00:00Z")
.unwrap()
.naive_local(),
- PublicActor::new("as-cii", "http://github.com/as-cii.png?s=50"),
+ PublicPlayer::new("as-cii", "http://github.com/as-cii.png?s=50"),
[
NotificationAction::new(
Button::new("Decline"),
@@ -478,89 +478,12 @@ pub fn static_new_notification_items_2<V: 'static>() -> Vec<Notification<V>> {
]
}
-pub fn static_new_notification_items<V: 'static>() -> Vec<ListItem<V>> {
- vec![
- ListItem::Header(ListSubHeader::new("New")),
- ListItem::Details(
- ListDetailsEntry::new("maxdeviant invited you to join a stream in #design.")
- .meta("4 people in stream."),
- ),
- ListItem::Details(ListDetailsEntry::new(
- "nathansobo accepted your contact request.",
- )),
- ListItem::Header(ListSubHeader::new("Earlier")),
- ListItem::Details(
- ListDetailsEntry::new("mikaylamaki added you as a contact.").actions(vec![
- Button::new("Decline"),
- Button::new("Accept").variant(crate::ButtonVariant::Filled),
- ]),
- ),
- ListItem::Details(
- ListDetailsEntry::new("maxdeviant invited you to a stream in #design.")
- .seen(true)
- .meta("This stream has ended."),
- ),
- ListItem::Details(ListDetailsEntry::new(
- "as-cii accepted your contact request.",
- )),
- ListItem::Details(
- ListDetailsEntry::new("You were added as an admin on the #gpui2 channel.").seen(true),
- ),
- ListItem::Details(ListDetailsEntry::new(
- "osiewicz accepted your contact request.",
- )),
- ListItem::Details(ListDetailsEntry::new(
- "ConradIrwin accepted your contact request.",
- )),
- ListItem::Details(
- ListDetailsEntry::new("nathansobo invited you to a stream in #gpui2.")
- .seen(true)
- .meta("This stream has ended."),
- ),
- ListItem::Details(ListDetailsEntry::new(
- "nathansobo accepted your contact request.",
- )),
- ListItem::Header(ListSubHeader::new("Earlier")),
- ListItem::Details(
- ListDetailsEntry::new("mikaylamaki added you as a contact.").actions(vec![
- Button::new("Decline"),
- Button::new("Accept").variant(crate::ButtonVariant::Filled),
- ]),
- ),
- ListItem::Details(
- ListDetailsEntry::new("maxdeviant invited you to a stream in #design.")
- .seen(true)
- .meta("This stream has ended."),
- ),
- ListItem::Details(ListDetailsEntry::new(
- "as-cii accepted your contact request.",
- )),
- ListItem::Details(
- ListDetailsEntry::new("You were added as an admin on the #gpui2 channel.").seen(true),
- ),
- ListItem::Details(ListDetailsEntry::new(
- "osiewicz accepted your contact request.",
- )),
- ListItem::Details(ListDetailsEntry::new(
- "ConradIrwin accepted your contact request.",
- )),
- ListItem::Details(
- ListDetailsEntry::new("nathansobo invited you to a stream in #gpui2.")
- .seen(true)
- .meta("This stream has ended."),
- ),
- ]
- .into_iter()
- .map(From::from)
- .collect()
-}
-
-pub fn static_project_panel_project_items<V: 'static>() -> Vec<ListItem<V>> {
+pub fn static_project_panel_project_items() -> Vec<ListItem> {
vec![
ListEntry::new(Label::new("zed"))
.left_icon(Icon::FolderOpen.into())
.indent_level(0)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new(".cargo"))
.left_icon(Icon::Folder.into())
.indent_level(1),
@@ -579,14 +502,14 @@ pub fn static_project_panel_project_items<V: 'static>() -> Vec<ListItem<V>> {
ListEntry::new(Label::new("assets"))
.left_icon(Icon::Folder.into())
.indent_level(1)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("cargo-target").color(LabelColor::Hidden))
.left_icon(Icon::Folder.into())
.indent_level(1),
ListEntry::new(Label::new("crates"))
.left_icon(Icon::FolderOpen.into())
.indent_level(1)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("activity_indicator"))
.left_icon(Icon::Folder.into())
.indent_level(2),
@@ -608,38 +531,38 @@ pub fn static_project_panel_project_items<V: 'static>() -> Vec<ListItem<V>> {
ListEntry::new(Label::new("sqlez").color(LabelColor::Modified))
.left_icon(Icon::Folder.into())
.indent_level(2)
- .toggle(ToggleState::NotToggled),
+ .toggle(Toggle::Toggled(false)),
ListEntry::new(Label::new("gpui2"))
.left_icon(Icon::FolderOpen.into())
.indent_level(2)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("src"))
.left_icon(Icon::FolderOpen.into())
.indent_level(3)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("derive_element.rs"))
.left_icon(Icon::FileRust.into())
.indent_level(4),
ListEntry::new(Label::new("storybook").color(LabelColor::Modified))
.left_icon(Icon::FolderOpen.into())
.indent_level(1)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("docs").color(LabelColor::Default))
.left_icon(Icon::Folder.into())
.indent_level(2)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("src").color(LabelColor::Modified))
.left_icon(Icon::FolderOpen.into())
.indent_level(3)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("ui").color(LabelColor::Modified))
.left_icon(Icon::FolderOpen.into())
.indent_level(4)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("component").color(LabelColor::Created))
.left_icon(Icon::FolderOpen.into())
.indent_level(5)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("facepile.rs").color(LabelColor::Default))
.left_icon(Icon::FileRust.into())
.indent_level(6),
@@ -682,7 +605,7 @@ pub fn static_project_panel_project_items<V: 'static>() -> Vec<ListItem<V>> {
.collect()
}
-pub fn static_project_panel_single_items<V: 'static>() -> Vec<ListItem<V>> {
+pub fn static_project_panel_single_items() -> Vec<ListItem> {
vec![
ListEntry::new(Label::new("todo.md"))
.left_icon(Icon::FileDoc.into())
@@ -699,7 +622,7 @@ pub fn static_project_panel_single_items<V: 'static>() -> Vec<ListItem<V>> {
.collect()
}
-pub fn static_collab_panel_current_call<V: 'static>() -> Vec<ListItem<V>> {
+pub fn static_collab_panel_current_call() -> Vec<ListItem> {
vec![
ListEntry::new(Label::new("as-cii")).left_avatar("http://github.com/as-cii.png?s=50"),
ListEntry::new(Label::new("nathansobo"))
@@ -712,7 +635,7 @@ pub fn static_collab_panel_current_call<V: 'static>() -> Vec<ListItem<V>> {
.collect()
}
-pub fn static_collab_panel_channels<V: 'static>() -> Vec<ListItem<V>> {
+pub fn static_collab_panel_channels() -> Vec<ListItem> {
vec![
ListEntry::new(Label::new("zed"))
.left_icon(Icon::Hash.into())
@@ -1,7 +1,6 @@
-use crate::prelude::*;
+use crate::{prelude::*, Toggle};
use crate::{
- static_collab_panel_channels, static_collab_panel_current_call, v_stack, Icon, List,
- ListHeader, ToggleState,
+ static_collab_panel_channels, static_collab_panel_current_call, v_stack, Icon, List, ListHeader,
};
#[derive(Component)]
@@ -34,17 +33,17 @@ impl CollabPanel {
.header(
ListHeader::new("CRDB")
.left_icon(Icon::Hash.into())
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
),
)
.child(
v_stack().id("channels").py_1().child(
List::new(static_collab_panel_channels())
- .header(ListHeader::new("CHANNELS").toggle(ToggleState::Toggled))
+ .header(ListHeader::new("CHANNELS").toggle(Toggle::Toggled(true)))
.empty_message("No channels yet. Add a channel to get started.")
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
),
)
.child(
@@ -52,9 +51,9 @@ impl CollabPanel {
List::new(static_collab_panel_current_call())
.header(
ListHeader::new("CONTACTS – ONLINE")
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
)
- .toggle(ToggleState::Toggled),
+ .toggle(Toggle::Toggled(true)),
),
)
.child(
@@ -62,9 +61,9 @@ impl CollabPanel {
List::new(static_collab_panel_current_call())
.header(
ListHeader::new("CONTACTS – OFFLINE")
- .toggle(ToggleState::NotToggled),
+ .toggle(Toggle::Toggled(false)),
)
- .toggle(ToggleState::NotToggled),
+ .toggle(Toggle::Toggled(false)),
),
),
)
@@ -1,8 +1,8 @@
use crate::utils::naive_format_distance_from_now;
use crate::{
- h_stack, prelude::*, static_new_notification_items_2, v_stack, Avatar, Button, Icon,
- IconButton, IconElement, Label, LabelColor, LineHeightStyle, ListHeaderMeta, ListSeparator,
- UnreadIndicator,
+ h_stack, prelude::*, static_new_notification_items_2, v_stack, Avatar, ButtonOrIconButton,
+ Icon, IconElement, Label, LabelColor, LineHeightStyle, ListHeaderMeta, ListSeparator,
+ PublicPlayer, UnreadIndicator,
};
use crate::{ClickHandler, ListHeader};
@@ -57,23 +57,6 @@ impl NotificationsPanel {
}
}
-pub enum ButtonOrIconButton<V: 'static> {
- Button(Button<V>),
- IconButton(IconButton<V>),
-}
-
-impl<V: 'static> From<Button<V>> for ButtonOrIconButton<V> {
- fn from(value: Button<V>) -> Self {
- Self::Button(value)
- }
-}
-
-impl<V: 'static> From<IconButton<V>> for ButtonOrIconButton<V> {
- fn from(value: IconButton<V>) -> Self {
- Self::IconButton(value)
- }
-}
-
pub struct NotificationAction<V: 'static> {
button: ButtonOrIconButton<V>,
tooltip: SharedString,
@@ -102,7 +85,7 @@ impl<V: 'static> NotificationAction<V> {
}
pub enum ActorOrIcon {
- Actor(PublicActor),
+ Actor(PublicPlayer),
Icon(Icon),
}
@@ -171,7 +154,7 @@ impl<V> Notification<V> {
id: impl Into<ElementId>,
message: impl Into<SharedString>,
date_received: NaiveDateTime,
- actor: PublicActor,
+ actor: PublicPlayer,
click_action: ClickHandler<V>,
) -> Self {
Self::new(
@@ -210,7 +193,7 @@ impl<V> Notification<V> {
id: impl Into<ElementId>,
message: impl Into<SharedString>,
date_received: NaiveDateTime,
- actor: PublicActor,
+ actor: PublicPlayer,
actions: [NotificationAction<V>; 2],
) -> Self {
Self::new(
@@ -18,8 +18,7 @@ impl ProjectPanel {
.id(self.id.clone())
.flex()
.flex_col()
- .w_full()
- .h_full()
+ .size_full()
.bg(cx.theme().colors().surface)
.child(
div()
@@ -30,15 +29,13 @@ impl ProjectPanel {
.overflow_y_scroll()
.child(
List::new(static_project_panel_single_items())
- .header(ListHeader::new("FILES").toggle(ToggleState::Toggled))
- .empty_message("No files in directory")
- .toggle(ToggleState::Toggled),
+ .header(ListHeader::new("FILES"))
+ .empty_message("No files in directory"),
)
.child(
List::new(static_project_panel_project_items())
- .header(ListHeader::new("PROJECT").toggle(ToggleState::Toggled))
- .empty_message("No folders in directory")
- .toggle(ToggleState::Toggled),
+ .header(ListHeader::new("PROJECT"))
+ .empty_message("No folders in directory"),
),
)
.child(