Element refinement passing on ui2

This commit is contained in:
Nathan Sobo 2023-11-18 20:05:47 -07:00
parent be33f000e2
commit adc355a1e6
87 changed files with 2066 additions and 1372 deletions

View file

@ -1,4 +1,4 @@
use gpui::{div, Action};
use gpui::{div, Action, Div, RenderOnce};
use crate::settings::user_settings;
use crate::{
@ -22,7 +22,7 @@ pub enum ListHeaderMeta {
Text(Label),
}
#[derive(Component)]
#[derive(RenderOnce)]
pub struct ListHeader {
label: SharedString,
left_icon: Option<Icon>,
@ -31,33 +31,10 @@ pub struct ListHeader {
toggle: Toggle,
}
impl ListHeader {
pub fn new(label: impl Into<SharedString>) -> Self {
Self {
label: label.into(),
left_icon: None,
meta: None,
variant: ListItemVariant::default(),
toggle: Toggle::NotToggleable,
}
}
impl<V: 'static> Component<V> for ListHeader {
type Rendered = Div<V>;
pub fn toggle(mut self, toggle: Toggle) -> Self {
self.toggle = toggle;
self
}
pub fn left_icon(mut self, left_icon: Option<Icon>) -> Self {
self.left_icon = left_icon;
self
}
pub fn meta(mut self, meta: Option<ListHeaderMeta>) -> Self {
self.meta = meta;
self
}
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
let disclosure_control = disclosure_control(self.toggle);
let meta = match self.meta {
@ -79,11 +56,6 @@ impl ListHeader {
h_stack()
.w_full()
.bg(cx.theme().colors().surface_background)
// TODO: Add focus state
// .when(self.state == InteractionState::Focused, |this| {
// this.border()
// .border_color(cx.theme().colors().border_focused)
// })
.relative()
.child(
div()
@ -117,7 +89,94 @@ impl ListHeader {
}
}
#[derive(Component, Clone)]
impl ListHeader {
pub fn new(label: impl Into<SharedString>) -> Self {
Self {
label: label.into(),
left_icon: None,
meta: None,
variant: ListItemVariant::default(),
toggle: Toggle::NotToggleable,
}
}
pub fn toggle(mut self, toggle: Toggle) -> Self {
self.toggle = toggle;
self
}
pub fn left_icon(mut self, left_icon: Option<Icon>) -> Self {
self.left_icon = left_icon;
self
}
pub fn meta(mut self, meta: Option<ListHeaderMeta>) -> Self {
self.meta = meta;
self
}
// before_ship!("delete")
// fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
// let disclosure_control = disclosure_control(self.toggle);
// let meta = match self.meta {
// Some(ListHeaderMeta::Tools(icons)) => div().child(
// h_stack()
// .gap_2()
// .items_center()
// .children(icons.into_iter().map(|i| {
// IconElement::new(i)
// .color(TextColor::Muted)
// .size(IconSize::Small)
// })),
// ),
// Some(ListHeaderMeta::Button(label)) => div().child(label),
// Some(ListHeaderMeta::Text(label)) => div().child(label),
// None => div(),
// };
// h_stack()
// .w_full()
// .bg(cx.theme().colors().surface_background)
// // TODO: Add focus state
// // .when(self.state == InteractionState::Focused, |this| {
// // this.border()
// // .border_color(cx.theme().colors().border_focused)
// // })
// .relative()
// .child(
// div()
// .h_5()
// .when(self.variant == ListItemVariant::Inset, |this| this.px_2())
// .flex()
// .flex_1()
// .items_center()
// .justify_between()
// .w_full()
// .gap_1()
// .child(
// h_stack()
// .gap_1()
// .child(
// div()
// .flex()
// .gap_1()
// .items_center()
// .children(self.left_icon.map(|i| {
// IconElement::new(i)
// .color(TextColor::Muted)
// .size(IconSize::Small)
// }))
// .child(Label::new(self.label.clone()).color(TextColor::Muted)),
// )
// .child(disclosure_control),
// )
// .child(meta),
// )
// }
}
#[derive(Clone)]
pub struct ListSubHeader {
label: SharedString,
left_icon: Option<Icon>,
@ -172,7 +231,7 @@ pub enum ListEntrySize {
Medium,
}
#[derive(Component, Clone)]
#[derive(RenderOnce, Clone)]
pub enum ListItem {
Entry(ListEntry),
Separator(ListSeparator),
@ -197,15 +256,19 @@ impl From<ListSubHeader> for ListItem {
}
}
impl ListItem {
fn render<V: 'static>(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
impl<V: 'static> Component<V> for ListItem {
type Rendered = Div<V>;
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
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)),
}
}
}
impl ListItem {
pub fn new(label: Label) -> Self {
Self::Entry(ListEntry::new(label))
}
@ -219,7 +282,7 @@ impl ListItem {
}
}
#[derive(Component)]
// #[derive(RenderOnce)]
pub struct ListEntry {
disabled: bool,
// TODO: Reintroduce this
@ -377,20 +440,24 @@ impl ListEntry {
}
}
#[derive(Clone, Component)]
#[derive(RenderOnce, Clone)]
pub struct ListSeparator;
impl ListSeparator {
pub fn new() -> Self {
Self
}
}
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
impl<V: 'static> Component<V> for ListSeparator {
type Rendered = Div<V>;
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
div().h_px().w_full().bg(cx.theme().colors().border_variant)
}
}
#[derive(Component)]
#[derive(RenderOnce)]
pub struct List {
items: Vec<ListItem>,
/// Message to display when the list is empty
@ -400,6 +467,26 @@ pub struct List {
toggle: Toggle,
}
impl<V: 'static> Component<V> for List {
type Rendered = Div<V>;
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
let list_content = match (self.items.is_empty(), self.toggle) {
(false, _) => div().children(self.items),
(true, Toggle::Toggled(false)) => div(),
(true, _) => {
div().child(Label::new(self.empty_message.clone()).color(TextColor::Muted))
}
};
v_stack()
.w_full()
.py_1()
.children(self.header.map(|header| header))
.child(list_content)
}
}
impl List {
pub fn new(items: Vec<ListItem>) -> Self {
Self {