From bb6d8d8f60eef9aa03cccd9b217eb7bcf9ed9b04 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 11 Aug 2024 14:46:55 +0800 Subject: [PATCH] Cleanup first version impls (#132) --- crates/app/src/story_workspace.rs | 2 +- crates/story/src/button_story.rs | 2 +- crates/story/src/dropdown_story.rs | 7 +- crates/story/src/input_story.rs | 4 +- crates/story/src/picker_story.rs | 8 +- crates/story/src/popup_story.rs | 2 +- crates/story/src/progress_story.rs | 2 +- crates/story/src/scrollable_story.rs | 2 +- crates/story/src/table_story.rs | 27 ++++--- crates/story/src/text_story.rs | 54 ++++++-------- crates/story/src/tooltip_story.rs | 8 +- crates/story/src/webview_story.rs | 2 +- crates/ui/src/button.rs | 15 ++-- crates/ui/src/checkbox.rs | 34 ++++----- crates/ui/src/clickable.rs | 5 -- crates/ui/src/clipboard.rs | 2 +- crates/ui/src/context_menu.rs | 5 +- crates/ui/src/disableable.rs | 3 - crates/ui/src/divider.rs | 2 +- crates/ui/src/dropdown.rs | 3 +- crates/ui/src/icon.rs | 2 +- crates/ui/src/input/input.rs | 4 +- crates/ui/src/label.rs | 13 +--- crates/ui/src/lib.rs | 13 +--- crates/ui/src/list/list_item.rs | 4 +- crates/ui/src/popover.rs | 10 ++- crates/ui/src/popup_menu.rs | 4 +- crates/ui/src/radio.rs | 16 ++-- crates/ui/src/resizable/panel.rs | 2 +- crates/ui/src/selectable.rs | 57 --------------- crates/ui/src/stack.rs | 19 ----- crates/ui/src/{styled_ext.rs => styled.rs} | 85 ++++++---------------- crates/ui/src/switch.rs | 2 +- crates/ui/src/tab/tab.rs | 2 +- crates/ui/src/tab/tab_bar.rs | 2 +- crates/ui/src/table.rs | 2 +- crates/ui/src/time/calendar.rs | 2 +- crates/ui/src/time/date_picker.rs | 9 ++- crates/ui/src/tooltip.rs | 7 +- crates/workspace/src/notification.rs | 8 +- 40 files changed, 152 insertions(+), 300 deletions(-) delete mode 100644 crates/ui/src/clickable.rs delete mode 100644 crates/ui/src/disableable.rs delete mode 100644 crates/ui/src/selectable.rs delete mode 100644 crates/ui/src/stack.rs rename crates/ui/src/{styled_ext.rs => styled.rs} (78%) diff --git a/crates/app/src/story_workspace.rs b/crates/app/src/story_workspace.rs index 87fb1610..334f1214 100644 --- a/crates/app/src/story_workspace.rs +++ b/crates/app/src/story_workspace.rs @@ -14,7 +14,7 @@ use ui::{ popover::Popover, popup_menu::PopupMenu, theme::{ActiveTheme, Theme}, - Clickable as _, IconName, Sizable, + IconName, Sizable, }; use crate::app_state::AppState; diff --git a/crates/story/src/button_story.rs b/crates/story/src/button_story.rs index 3b4f678a..06d4c0a8 100644 --- a/crates/story/src/button_story.rs +++ b/crates/story/src/button_story.rs @@ -9,7 +9,7 @@ use ui::{ h_flex, prelude::FluentBuilder, theme::ActiveTheme, - v_flex, Clickable, Disableable as _, Icon, IconName, Selectable as _, Sizable as _, + v_flex, Disableable as _, Icon, IconName, Selectable as _, Sizable as _, }; use crate::section; diff --git a/crates/story/src/dropdown_story.rs b/crates/story/src/dropdown_story.rs index df0fecab..e6074dab 100644 --- a/crates/story/src/dropdown_story.rs +++ b/crates/story/src/dropdown_story.rs @@ -7,7 +7,7 @@ use ui::{ dropdown::{Dropdown, DropdownEvent, DropdownItem, SearchableVec}, h_flex, theme::ActiveTheme, - v_flex, IconName, Selection, Sizable, + v_flex, IconName, Sizable, }; struct Country { @@ -129,11 +129,6 @@ impl DropdownStory { }) } - #[allow(unused)] - fn on_click(sel: &Selection, cx: &mut WindowContext) { - println!("Check value changed: {}", sel); - } - fn on_dropdown_event( &mut self, _: View>>, diff --git a/crates/story/src/input_story.rs b/crates/story/src/input_story.rs index c9418e1b..66ff8a96 100644 --- a/crates/story/src/input_story.rs +++ b/crates/story/src/input_story.rs @@ -10,7 +10,7 @@ use ui::{ h_flex, input::{InputEvent, OtpInput, TextInput}, prelude::FluentBuilder as _, - v_flex, Clickable, FocusableCycle, IconName, Selection, Sizable, + v_flex, FocusableCycle, IconName, Sizable, }; use crate::section; @@ -170,7 +170,7 @@ impl InputStory { }; } - fn toggle_opt_masked(&mut self, _: &Selection, cx: &mut ViewContext) { + fn toggle_opt_masked(&mut self, _: &bool, cx: &mut ViewContext) { self.otp_masked = !self.otp_masked; self.otp_input .update(cx, |input, cx| input.set_masked(self.otp_masked, cx)); diff --git a/crates/story/src/picker_story.rs b/crates/story/src/picker_story.rs index 9ce60bb5..24e98a4c 100644 --- a/crates/story/src/picker_story.rs +++ b/crates/story/src/picker_story.rs @@ -12,7 +12,7 @@ use ui::{ h_flex, list::{List, ListDelegate, ListItem}, theme::ActiveTheme as _, - v_flex, Clickable as _, Icon, IconName, StyledExt, + v_flex, Icon, IconName, StyledExt, }; pub struct ListItemDeletegate { @@ -272,7 +272,11 @@ impl Render for PickerStory { .occlude() .w(px(450.)) .h(px(350.)) - .elevation_3(cx) + .bg(cx.theme().popover) + .border_1() + .border_color(cx.theme().border) + .shadow_lg() + .rounded_lg() .child(self.list.clone()) .on_mouse_down_out(cx.listener(|this, _, cx| { this.open = false; diff --git a/crates/story/src/popup_story.rs b/crates/story/src/popup_story.rs index 7fc348e6..776378df 100644 --- a/crates/story/src/popup_story.rs +++ b/crates/story/src/popup_story.rs @@ -13,7 +13,7 @@ use ui::{ popup_menu::PopupMenuExt, prelude::FluentBuilder, switch::Switch, - v_flex, Clickable as _, IconName, Sizable, + v_flex, IconName, Sizable, }; actions!( diff --git a/crates/story/src/progress_story.rs b/crates/story/src/progress_story.rs index d9661ab0..44ab451d 100644 --- a/crates/story/src/progress_story.rs +++ b/crates/story/src/progress_story.rs @@ -10,7 +10,7 @@ use ui::{ progress::Progress, skeleton::Skeleton, slider::{Slider, SliderEvent}, - v_flex, Clickable, IconName, Sizable, + v_flex, IconName, Sizable, }; pub struct ProgressStory { diff --git a/crates/story/src/scrollable_story.rs b/crates/story/src/scrollable_story.rs index baf26946..08bf5a0f 100644 --- a/crates/story/src/scrollable_story.rs +++ b/crates/story/src/scrollable_story.rs @@ -9,7 +9,7 @@ use ui::button::Button; use ui::divider::Divider; use ui::scroll::{Scrollbar, ScrollbarAxis, ScrollbarState}; use ui::theme::ActiveTheme; -use ui::{h_flex, v_flex, Clickable, StyledExt as _}; +use ui::{h_flex, v_flex, StyledExt as _}; pub struct ScrollableStory { scroll_handle: ScrollHandle, diff --git a/crates/story/src/table_story.rs b/crates/story/src/table_story.rs index b3c82311..78d8d611 100644 --- a/crates/story/src/table_story.rs +++ b/crates/story/src/table_story.rs @@ -9,7 +9,7 @@ use ui::{ label::Label, table::{ColSort, Table, TableDelegate, TableEvent}, theme::ActiveTheme as _, - v_flex, Icon, IconName, Selectable, Selection, + v_flex, Icon, IconName, Selectable, }; struct Customer { @@ -226,10 +226,18 @@ impl TableDelegate for CustomerTableDelegate { } fn col_sort(&self, col_ix: usize) -> Option { + if !self.col_sort { + return None; + } + self.columns.get(col_ix).and_then(|c| c.sort) } fn perform_sort(&mut self, col_ix: usize, sort: ColSort, _: &mut ViewContext>) { + if !self.col_sort { + return; + } + if let Some(col) = self.columns.get_mut(col_ix) { col.sort = Some(sort); let asc = matches!(sort, ColSort::Ascending); @@ -328,34 +336,35 @@ impl TableStory { Self { table } } - fn toggle_loop_selection(&mut self, s: &Selection, cx: &mut ViewContext) { + fn toggle_loop_selection(&mut self, checked: &bool, cx: &mut ViewContext) { let table = self.table.clone(); table.update(cx, |table, cx| { - table.delegate_mut().loop_selection = s.is_selected(); + table.delegate_mut().loop_selection = *checked; cx.notify(); }); } - fn toggle_col_resize(&mut self, s: &Selection, cx: &mut ViewContext) { + fn toggle_col_resize(&mut self, checked: &bool, cx: &mut ViewContext) { let table = self.table.clone(); table.update(cx, |table, cx| { - table.delegate_mut().col_resize = s.is_selected(); + table.delegate_mut().col_resize = *checked; cx.notify(); }); } - fn toggle_col_order(&mut self, s: &Selection, cx: &mut ViewContext) { + fn toggle_col_order(&mut self, checked: &bool, cx: &mut ViewContext) { let table = self.table.clone(); table.update(cx, |table, cx| { - table.delegate_mut().col_order = s.is_selected(); + table.delegate_mut().col_order = *checked; cx.notify(); }); } - fn toggle_col_sort(&mut self, s: &Selection, cx: &mut ViewContext) { + fn toggle_col_sort(&mut self, checked: &bool, cx: &mut ViewContext) { let table = self.table.clone(); table.update(cx, |table, cx| { - table.delegate_mut().col_sort = s.is_selected(); + println!("- toggle_col_sort: {}", checked); + table.delegate_mut().col_sort = *checked; cx.notify(); }); } diff --git a/crates/story/src/text_story.rs b/crates/story/src/text_story.rs index 233c609d..ff52b953 100644 --- a/crates/story/src/text_story.rs +++ b/crates/story/src/text_story.rs @@ -11,28 +11,28 @@ use ui::{ label::Label, link::Link, radio::Radio, - v_flex, Clickable, Disableable as _, IconName, Selection, StyledExt, + v_flex, Disableable as _, IconName, StyledExt, }; use crate::section; pub struct TextStory { - check1: Selection, - check2: Selection, - check3: Selection, - select1: bool, - select2: bool, + check1: bool, + check2: bool, + check3: bool, + radio_check1: bool, + radio_check2: bool, masked: bool, } impl TextStory { pub(crate) fn new(_cx: &mut WindowContext) -> Self { Self { - check1: Selection::Unselected, - check2: Selection::Indeterminate, - check3: Selection::Selected, - select1: false, - select2: true, + check1: false, + check2: false, + check3: true, + radio_check1: false, + radio_check2: true, masked: false, } } @@ -42,8 +42,8 @@ impl TextStory { } #[allow(unused)] - fn on_click(sel: &Selection, cx: &mut WindowContext) { - println!("Check value changed: {}", sel); + fn on_click(checked: &bool, cx: &mut WindowContext) { + println!("Check value changed: {}", checked); } } @@ -122,7 +122,7 @@ impl Render for TextStory { Checkbox::new("check1") .checked(self.check1) .on_click(cx.listener(|v, _, _| { - v.check1 = v.check1.inverse(); + v.check1 = !v.check1; })), ) .child( @@ -130,7 +130,7 @@ impl Render for TextStory { .checked(self.check2) .label("Subscribe to newsletter") .on_click(cx.listener(|v, _, _| { - v.check2 = v.check2.inverse(); + v.check2 = !v.check2; })), ) .child( @@ -138,7 +138,7 @@ impl Render for TextStory { .checked(self.check3) .label("Remember me") .on_click(cx.listener(|v, _, _| { - v.check3 = v.check3.inverse(); + v.check3 = !v.check3; })), ) .child( @@ -158,21 +158,15 @@ impl Render for TextStory { .child( Checkbox::new("check3") .label("Disabled Checked") - .checked(Selection::Selected) + .checked(true) .disabled(true), ) .child( Checkbox::new("check3_1") .label("Disabled Unchecked") - .checked(Selection::Unselected) + .checked(false) .disabled(true), ) - .child( - Checkbox::new("check3_2") - .label("Disabled Indeterminate") - .checked(Selection::Indeterminate) - .disabled(true), - ), ), ) .child( @@ -183,30 +177,30 @@ impl Render for TextStory { .items_start() .child( Radio::new("radio1") - .selected(self.select1) + .checked(self.radio_check1) .on_click(cx.listener(|this, v, _cx| { - this.select1 = *v; + this.radio_check1 = *v; })), ) .child( Radio::new("radio2") .label("Radio") - .selected(self.select2) + .checked(self.radio_check2) .on_click(cx.listener(|this, v, _cx| { - this.select2 = *v; + this.radio_check2 = *v; })), ) .child( Radio::new("radio3") .label("Disabled Radio") - .selected(true) + .checked(true) .disabled(true), ) .child( div().w(px(200.)).child( Radio::new("radio3") .label("Warp: A long long long text radio label") - .selected(true) + .checked(true) .disabled(true), ), ) diff --git a/crates/story/src/tooltip_story.rs b/crates/story/src/tooltip_story.rs index c1dc6216..2ed30de6 100644 --- a/crates/story/src/tooltip_story.rs +++ b/crates/story/src/tooltip_story.rs @@ -9,7 +9,7 @@ use ui::{ h_flex, label::Label, tooltip::Tooltip, - v_flex, Selection, + v_flex, }; pub struct TooltipStory; @@ -51,11 +51,7 @@ impl Render for TooltipStory { .child( div() .cursor(CursorStyle::PointingHand) - .child( - Checkbox::new("check") - .label("Remember me") - .checked(Selection::Selected), - ) + .child(Checkbox::new("check").label("Remember me").checked(true)) .id("tooltip-4") .tooltip(|cx| Tooltip::new("Checked!", cx)), ) diff --git a/crates/story/src/webview_story.rs b/crates/story/src/webview_story.rs index 897a0d7e..4b5bdc24 100644 --- a/crates/story/src/webview_story.rs +++ b/crates/story/src/webview_story.rs @@ -9,7 +9,7 @@ use ui::{ theme::ActiveTheme, v_flex, webview::WebView, - Clickable, IconName, + IconName, }; pub struct WebViewStory { diff --git a/crates/ui/src/button.rs b/crates/ui/src/button.rs index 9e1233ff..8ad6aa2e 100644 --- a/crates/ui/src/button.rs +++ b/crates/ui/src/button.rs @@ -1,9 +1,8 @@ use crate::{ h_flex, indicator::Indicator, - styled_ext::Sizable, theme::{ActiveTheme, Colorize as _}, - Clickable, Disableable, Icon, Selectable, Size, + Disableable, Icon, Selectable, Sizable, Size, }; use gpui::{ div, prelude::FluentBuilder as _, px, AnyElement, ClickEvent, Div, ElementId, FocusHandle, @@ -226,6 +225,11 @@ impl Button { self.compact = true; self } + + pub fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self { + self.on_click = Some(Box::new(handler)); + self + } } impl Disableable for Button { @@ -242,13 +246,6 @@ impl Selectable for Button { } } -impl Clickable for Button { - fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self { - self.on_click = Some(Box::new(handler)); - self - } -} - impl Sizable for Button { fn with_size(mut self, size: impl Into) -> Self { self.size = size.into(); diff --git a/crates/ui/src/checkbox.rs b/crates/ui/src/checkbox.rs index 58be8d68..b4953931 100644 --- a/crates/ui/src/checkbox.rs +++ b/crates/ui/src/checkbox.rs @@ -5,29 +5,25 @@ use gpui::{ }; use crate::{ - disableable::Disableable, - selectable::{Selectable, Selection}, - stack::{h_flex, v_flex}, + h_flex, theme::{ActiveTheme, Colorize as _}, - IconName, + v_flex, Disableable, IconName, Selectable, }; -type OnClick = Box; - #[derive(IntoElement)] pub struct Checkbox { id: ElementId, - checked: Selection, + checked: bool, disabled: bool, label: Option, - on_click: Option, + on_click: Option>, } impl Checkbox { pub fn new(id: impl Into) -> Self { Self { id: id.into(), - checked: Selection::Unselected, + checked: false, disabled: false, label: None, on_click: None, @@ -39,12 +35,12 @@ impl Checkbox { self } - pub fn checked(mut self, checked: impl Into) -> Self { - self.checked = checked.into(); + pub fn checked(mut self, checked: bool) -> Self { + self.checked = checked; self } - pub fn on_click(mut self, handler: impl Fn(&Selection, &mut WindowContext) + 'static) -> Self { + pub fn on_click(mut self, handler: impl Fn(&bool, &mut WindowContext) + 'static) -> Self { self.on_click = Some(Box::new(handler)); self } @@ -59,11 +55,7 @@ impl Disableable for Checkbox { impl Selectable for Checkbox { fn selected(self, selected: bool) -> Self { - self.checked(if selected { - Selection::Selected - } else { - Selection::Unselected - }) + self.checked(selected) } } @@ -96,7 +88,7 @@ impl RenderOnce for Checkbox { .size_4() .flex_shrink_0() .map(|this| match self.checked { - Selection::Unselected => this.bg(theme.transparent), + false => this.bg(theme.transparent), _ => this.bg(color), }) .group_hover(group_id, |this| { @@ -114,8 +106,7 @@ impl RenderOnce for Checkbox { .size_3() .text_color(icon_color) .map(|this| match self.checked { - Selection::Selected => this.path(IconName::Check.path()), - Selection::Indeterminate => this.path(IconName::Minus.path()), + true => this.path(IconName::Check.path()), _ => this, }), ), @@ -138,7 +129,8 @@ impl RenderOnce for Checkbox { self.on_click.filter(|_| !self.disabled), |this, on_click| { this.on_click(move |_, cx| { - on_click(&self.checked.inverse(), cx); + let checked = !self.checked; + on_click(&checked, cx); cx.refresh() }) }, diff --git a/crates/ui/src/clickable.rs b/crates/ui/src/clickable.rs deleted file mode 100644 index b25f6b0e..00000000 --- a/crates/ui/src/clickable.rs +++ /dev/null @@ -1,5 +0,0 @@ -use gpui::{ClickEvent, WindowContext}; - -pub trait Clickable { - fn on_click(self, handler: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self; -} diff --git a/crates/ui/src/clipboard.rs b/crates/ui/src/clipboard.rs index 902613ef..306fff45 100644 --- a/crates/ui/src/clipboard.rs +++ b/crates/ui/src/clipboard.rs @@ -3,7 +3,7 @@ use gpui::{ RenderOnce, SharedString, Styled, WindowContext, }; -use crate::{button::Button, h_flex, Clickable, IconName, Sizable}; +use crate::{button::Button, h_flex, IconName, Sizable}; #[derive(IntoElement)] pub struct Clipboard { diff --git a/crates/ui/src/context_menu.rs b/crates/ui/src/context_menu.rs index 44d4dcac..ff168685 100644 --- a/crates/ui/src/context_menu.rs +++ b/crates/ui/src/context_menu.rs @@ -7,7 +7,7 @@ use gpui::{ Position, Stateful, Style, Styled as _, View, WindowContext, }; -use crate::{popup_menu::PopupMenu, theme::ActiveTheme as _, StyledExt as _}; +use crate::{popup_menu::PopupMenu, theme::ActiveTheme}; pub fn init(_cx: &mut AppContext) {} @@ -128,10 +128,11 @@ impl Element for ContextMenu { this.child( div() - .elevation_2(cx) .bg(cx.theme().popover) .border_1() .border_color(cx.theme().border) + .shadow_lg() + .rounded_lg() .child(menu) .on_mouse_down_out(move |_, cx| { *open.borrow_mut() = false; diff --git a/crates/ui/src/disableable.rs b/crates/ui/src/disableable.rs deleted file mode 100644 index 7f107fd5..00000000 --- a/crates/ui/src/disableable.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait Disableable { - fn disabled(self, disabled: bool) -> Self; -} diff --git a/crates/ui/src/divider.rs b/crates/ui/src/divider.rs index ec90ad38..abd1dc7f 100644 --- a/crates/ui/src/divider.rs +++ b/crates/ui/src/divider.rs @@ -46,7 +46,7 @@ impl RenderOnce for Divider { self.base .map(|this| match self.axis { - Axis::Vertical => this.v_flex().h_full(), + Axis::Vertical => this.flex().flex_row().items_center().h_full(), Axis::Horizontal => this.h_flex().w_full(), }) .child( diff --git a/crates/ui/src/dropdown.rs b/crates/ui/src/dropdown.rs index 4bf4adc0..596e5046 100644 --- a/crates/ui/src/dropdown.rs +++ b/crates/ui/src/dropdown.rs @@ -10,9 +10,8 @@ use crate::{ h_flex, input::ClearButton, list::{self, List, ListDelegate, ListItem}, - styled_ext::StyleSized, theme::ActiveTheme, - Clickable, Icon, IconName, Sizable, Size, StyledExt, + Icon, IconName, Sizable, Size, StyleSized, StyledExt, }; actions!(dropdown, [Up, Down, Enter, Escape]); diff --git a/crates/ui/src/icon.rs b/crates/ui/src/icon.rs index 12be983c..0888aae1 100644 --- a/crates/ui/src/icon.rs +++ b/crates/ui/src/icon.rs @@ -1,4 +1,4 @@ -use crate::{styled_ext::Sizable, theme::ActiveTheme, Size}; +use crate::{theme::ActiveTheme, Sizable, Size}; use gpui::{ prelude::FluentBuilder as _, svg, AnyElement, Hsla, IntoElement, Render, RenderOnce, SharedString, StyleRefinement, Styled, Svg, View, VisualContext, WindowContext, diff --git a/crates/ui/src/input/input.rs b/crates/ui/src/input/input.rs index 096396e1..6815fed7 100644 --- a/crates/ui/src/input/input.rs +++ b/crates/ui/src/input/input.rs @@ -9,10 +9,10 @@ use super::blink_cursor::BlinkCursor; use super::history::History; use super::ClearButton; use crate::indicator::Indicator; -use crate::styled_ext::{Sizable, StyleSized}; use crate::theme::ActiveTheme; +use crate::StyledExt as _; use crate::{event::InteractiveElementExt as _, Size}; -use crate::{Clickable as _, StyledExt as _}; +use crate::{Sizable, StyleSized}; use gpui::prelude::FluentBuilder as _; use gpui::{ actions, div, fill, point, px, relative, rems, size, AnyElement, AppContext, Bounds, diff --git a/crates/ui/src/label.rs b/crates/ui/src/label.rs index 2603e0ee..b87377ee 100644 --- a/crates/ui/src/label.rs +++ b/crates/ui/src/label.rs @@ -17,7 +17,6 @@ pub enum TextAlign { pub struct Label { base: Div, label: SharedString, - multiple_lines: bool, align: TextAlign, marked: bool, } @@ -27,17 +26,11 @@ impl Label { Self { base: h_flex().line_height(rems(1.25)), label: label.into(), - multiple_lines: true, align: TextAlign::default(), marked: false, } } - pub fn multiple_lines(mut self) -> Self { - self.multiple_lines = true; - self - } - pub fn text_align(mut self, align: TextAlign) -> Self { self.align = align; self @@ -74,11 +67,7 @@ const MASKED: &'static str = "•"; impl RenderOnce for Label { fn render(self, cx: &mut WindowContext) -> impl IntoElement { - let text = if !self.multiple_lines { - SharedString::from(self.label.replace('\n', "␤")) - } else { - self.label - }; + let text = self.label; let text_display = if self.marked { MASKED.repeat(text.chars().count()) diff --git a/crates/ui/src/lib.rs b/crates/ui/src/lib.rs index b01600c4..523aca29 100644 --- a/crates/ui/src/lib.rs +++ b/crates/ui/src/lib.rs @@ -1,13 +1,9 @@ -mod clickable; mod colors; -mod disableable; mod event; mod focusable; mod icon; -mod selectable; -mod stack; -mod styled_ext; +mod styled; mod svg_img; mod time; @@ -43,17 +39,14 @@ use std::ops::Deref; // re-export pub use wry; -pub use clickable::Clickable; -pub use disableable::Disableable; +pub use crate::Disableable; pub use event::InteractiveElementExt; pub use focusable::FocusableCycle; -pub use selectable::{Selectable, Selection}; -pub use styled_ext::{Sizable, Size, StyledExt}; +pub use styled::*; pub use time::*; pub use colors::*; pub use icon::*; -pub use stack::*; pub use svg_img::*; rust_i18n::i18n!("locales", fallback = "en"); diff --git a/crates/ui/src/list/list_item.rs b/crates/ui/src/list/list_item.rs index efdbe4ab..ade220e1 100644 --- a/crates/ui/src/list/list_item.rs +++ b/crates/ui/src/list/list_item.rs @@ -5,9 +5,7 @@ use gpui::{ }; use smallvec::SmallVec; -use crate::{ - h_flex, styled_ext::Sizable as _, theme::ActiveTheme, Disableable, Icon, IconName, Selectable, -}; +use crate::{h_flex, theme::ActiveTheme, Disableable, Icon, IconName, Selectable, Sizable as _}; #[derive(IntoElement)] pub struct ListItem { diff --git a/crates/ui/src/popover.rs b/crates/ui/src/popover.rs index 0b0ada2d..6c5537e4 100644 --- a/crates/ui/src/popover.rs +++ b/crates/ui/src/popover.rs @@ -9,7 +9,7 @@ use gpui::{ }; use std::{cell::RefCell, rc::Rc}; -use crate::{theme::ActiveTheme, Selectable, StyledExt as _}; +use crate::{theme::ActiveTheme, Selectable}; actions!(popover, [Open, Dismiss]); @@ -247,10 +247,11 @@ impl Element for Popover { div() .size_full() .occlude() - .elevation_2(cx) - .bg(bg_color) .border_1() .border_color(cx.theme().border) + .shadow_lg() + .rounded_lg() + .bg(bg_color) .map(|this| match anchor { AnchorCorner::TopLeft | AnchorCorner::TopRight => this.top_2(), AnchorCorner::BottomLeft | AnchorCorner::BottomRight => { @@ -627,7 +628,8 @@ where this.bg(cx.theme().popover) .border_1() .border_color(cx.theme().border) - .elevation_2(cx) + .shadow_lg() + .rounded_lg() }) .bg(cx.theme().popover) .child(self.view.clone()) diff --git a/crates/ui/src/popup_menu.rs b/crates/ui/src/popup_menu.rs index 7a7c2905..77a2bb38 100644 --- a/crates/ui/src/popup_menu.rs +++ b/crates/ui/src/popup_menu.rs @@ -8,8 +8,8 @@ use gpui::{ }; use crate::{ - button::Button, h_flex, list::ListItem, popover::Popover, styled_ext::Sizable as _, - theme::ActiveTheme, v_flex, Icon, IconName, Selectable, + button::Button, h_flex, list::ListItem, popover::Popover, theme::ActiveTheme, v_flex, Icon, + IconName, Selectable, Sizable as _, }; actions!(menu, [Confirm, Dismiss, SelectNext, SelectPrev]); diff --git a/crates/ui/src/radio.rs b/crates/ui/src/radio.rs index d140d6db..9f55c21a 100644 --- a/crates/ui/src/radio.rs +++ b/crates/ui/src/radio.rs @@ -14,7 +14,7 @@ use crate::{ pub struct Radio { id: ElementId, label: Option, - selected: bool, + checked: bool, disabled: bool, on_click: Option>, } @@ -24,7 +24,7 @@ impl Radio { Self { id: id.into(), label: None, - selected: false, + checked: false, disabled: false, on_click: None, } @@ -35,8 +35,8 @@ impl Radio { self } - pub fn selected(mut self, selected: bool) -> Self { - self.selected = selected; + pub fn checked(mut self, checked: bool) -> Self { + self.checked = checked; self } @@ -73,7 +73,7 @@ impl RenderOnce for Radio { .rounded_full() .border_1() .border_color(color) - .when(self.selected, |this| this.bg(color)) + .when(self.checked, |this| this.bg(color)) .child( svg() .absolute() @@ -81,10 +81,10 @@ impl RenderOnce for Radio { .left_px() .size_3() .text_color(color) - .when(self.selected, |this| { + .when(self.checked, |this| { this.text_color(cx.theme().primary_foreground) }) - .map(|this| match self.selected { + .map(|this| match self.checked { true => this.path(IconName::Check.path()), false => this, }), @@ -103,7 +103,7 @@ impl RenderOnce for Radio { self.on_click.filter(|_| !self.disabled), |this, on_click| { this.on_click(move |_event, cx| { - on_click(&!self.selected, cx); + on_click(&!self.checked, cx); }) }, ) diff --git a/crates/ui/src/resizable/panel.rs b/crates/ui/src/resizable/panel.rs index 370a0322..48e75a1d 100644 --- a/crates/ui/src/resizable/panel.rs +++ b/crates/ui/src/resizable/panel.rs @@ -6,7 +6,7 @@ use gpui::{ StatefulInteractiveElement, Styled, View, ViewContext, VisualContext as _, WindowContext, }; -use crate::{h_flex, styled_ext::AxisExt, theme::ActiveTheme, v_flex}; +use crate::{h_flex, theme::ActiveTheme, v_flex, AxisExt}; #[derive(Clone, Render)] pub struct DragPanel(pub (EntityId, usize, Axis)); diff --git a/crates/ui/src/selectable.rs b/crates/ui/src/selectable.rs deleted file mode 100644 index 841363c0..00000000 --- a/crates/ui/src/selectable.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::fmt::Display; - -/// A trait for elements that can be selected. -/// -/// Generally used to enable "toggle" or "active" behavior and styles on an element through the [`Selection`] status. -pub trait Selectable { - /// Sets whether the element is selected. - fn selected(self, selected: bool) -> Self; -} - -/// Represents the selection status of an element. -#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)] -pub enum Selection { - /// The element is not selected. - #[default] - Unselected, - /// The selection state of the element is indeterminate. - Indeterminate, - /// The element is selected. - Selected, -} - -impl From for Selection { - fn from(selected: bool) -> Self { - if selected { - Self::Selected - } else { - Self::Unselected - } - } -} - -impl Display for Selection { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Unselected => write!(f, "Unselected"), - Self::Indeterminate => write!(f, "Indeterminate"), - Self::Selected => write!(f, "Selected"), - } - } -} - -impl Selection { - /// Returns the inverse of the current selection status. - /// - /// Indeterminate states become selected if inverted. - pub fn inverse(&self) -> Self { - match self { - Self::Unselected | Self::Indeterminate => Self::Selected, - Self::Selected => Self::Unselected, - } - } - - pub fn is_selected(&self) -> bool { - matches!(self, Self::Selected) - } -} diff --git a/crates/ui/src/stack.rs b/crates/ui/src/stack.rs deleted file mode 100644 index 5e33a4b6..00000000 --- a/crates/ui/src/stack.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::StyledExt as _; -use gpui::{div, Div, Styled}; - -/// Horizontally stacks elements. Sets `flex()`, `flex_row()`, `items_center()` -#[track_caller] -pub fn h_flex() -> Div { - div().h_flex() -} - -/// Vertically stacks elements. Sets `flex()`, `flex_col()` -#[track_caller] -pub fn v_flex() -> Div { - div().v_flex() -} - -/// A horizontal divider. Sets `h_0.5()`, `bg()`, `bg_gray()` -pub fn span() -> Div { - div().w_auto() -} diff --git a/crates/ui/src/styled_ext.rs b/crates/ui/src/styled.rs similarity index 78% rename from crates/ui/src/styled_ext.rs rename to crates/ui/src/styled.rs index 6706abca..f140d2e5 100644 --- a/crates/ui/src/styled_ext.rs +++ b/crates/ui/src/styled.rs @@ -3,53 +3,17 @@ use crate::{ theme::{ActiveTheme, Colorize}, }; use gpui::{ - hsla, point, px, rems, AnyView, Axis, BoxShadow, Element, Fill, FocusHandle, Pixels, Styled, - WindowContext, + div, px, rems, AnyView, Axis, Div, Element, Fill, FocusHandle, Pixels, Styled, WindowContext, }; -use smallvec::{smallvec, SmallVec}; -pub enum ElevationIndex { - Surface, - PopoverSurface, - ModalSurface, +/// Returns a `Div` as horizontal flex layout. +pub fn h_flex() -> Div { + div().h_flex() } -impl ElevationIndex { - pub fn shadow(self) -> SmallVec<[BoxShadow; 2]> { - match self { - ElevationIndex::Surface => smallvec![], - - ElevationIndex::PopoverSurface => smallvec![BoxShadow { - color: hsla(0., 0., 0., 0.12), - offset: point(px(0.), px(2.)), - blur_radius: px(3.), - spread_radius: px(0.), - }], - - ElevationIndex::ModalSurface => smallvec![ - BoxShadow { - color: hsla(0., 0., 0., 0.1), - offset: point(px(0.), px(4.)), - blur_radius: px(6.), - spread_radius: px(-1.), - }, - BoxShadow { - color: hsla(0., 0., 0., 0.1), - offset: point(px(0.), px(2.)), - blur_radius: px(4.), - spread_radius: px(-2.), - } - ], - } - } -} - -fn elevated(this: E, cx: &WindowContext, index: ElevationIndex) -> E { - this.bg(cx.theme().popover) - .rounded(px(8.)) - .border_1() - .border_color(cx.theme().border) - .shadow(index.shadow()) +/// Returns a `Div` as vertical flex layout. +pub fn v_flex() -> Div { + div().v_flex() } macro_rules! font_weight { @@ -63,35 +27,16 @@ macro_rules! font_weight { /// Extends [`gpui::Styled`] with specific styling methods. pub trait StyledExt: Styled + Sized { - /// Horizontally stacks elements. - /// - /// Sets `flex()`, `flex_row()`, `items_center()` + /// Apply self into a horizontal flex layout. fn h_flex(self) -> Self { self.flex().flex_row().items_center() } - /// Vertically stacks elements. - /// - /// Sets `flex()`, `flex_col()` + /// Apply self into a vertical flex layout. fn v_flex(self) -> Self { self.flex().flex_col() } - /// Located above the app background - fn elevation_1(self, cx: &WindowContext) -> Self { - elevated(self, cx, ElevationIndex::Surface) - } - - /// Appear above most UI elements - fn elevation_2(self, cx: &WindowContext) -> Self { - elevated(self, cx, ElevationIndex::PopoverSurface) - } - - // Above all other UI elements and are located above the wash layer - fn elevation_3(self, cx: &WindowContext) -> Self { - elevated(self, cx, ElevationIndex::ModalSurface) - } - /// Render a border with a width of 1px, color red fn debug_red(self) -> Self { if cfg!(debug_assertions) { @@ -227,6 +172,18 @@ impl From for Size { } } +/// A trait for defining element that can be selected. +pub trait Selectable: Sized { + /// Set the selected state of the element. + fn selected(self, selected: bool) -> Self; +} + +/// A trait for defining element that can be disabled. +pub trait Disableable { + /// Set the disabled state of the element. + fn disabled(self, disabled: bool) -> Self; +} + /// A trait for setting the size of an element. pub trait Sizable: Sized { /// Set the ui::Size of this element. diff --git a/crates/ui/src/switch.rs b/crates/ui/src/switch.rs index e1f3af76..d2190600 100644 --- a/crates/ui/src/switch.rs +++ b/crates/ui/src/switch.rs @@ -1,7 +1,7 @@ use std::time::Duration; use crate::{ - stack::h_flex, + h_flex, theme::{ActiveTheme, Colorize}, Disableable, Sizable, Size, }; diff --git a/crates/ui/src/tab/tab.rs b/crates/ui/src/tab/tab.rs index 13817fa1..3ed191d4 100644 --- a/crates/ui/src/tab/tab.rs +++ b/crates/ui/src/tab/tab.rs @@ -1,5 +1,5 @@ -use crate::selectable::Selectable; use crate::theme::{ActiveTheme, Colorize}; +use crate::Selectable; use gpui::prelude::FluentBuilder as _; use gpui::{ div, AnyElement, Div, ElementId, InteractiveElement, IntoElement, ParentElement as _, diff --git a/crates/ui/src/tab/tab_bar.rs b/crates/ui/src/tab/tab_bar.rs index b8457871..0414e8b7 100644 --- a/crates/ui/src/tab/tab_bar.rs +++ b/crates/ui/src/tab/tab_bar.rs @@ -1,4 +1,4 @@ -use crate::stack::h_flex; +use crate::h_flex; use crate::theme::ActiveTheme; use gpui::prelude::FluentBuilder as _; use gpui::{ diff --git a/crates/ui/src/table.rs b/crates/ui/src/table.rs index 803d4640..d2639a93 100644 --- a/crates/ui/src/table.rs +++ b/crates/ui/src/table.rs @@ -521,7 +521,7 @@ where col_ix: usize, cx: &mut ViewContext, ) -> Option { - let sort = self.col_groups.get(col_ix).and_then(|g| g.sort); + let sort = self.delegate().col_sort(col_ix); if sort.is_none() { return None; } diff --git a/crates/ui/src/time/calendar.rs b/crates/ui/src/time/calendar.rs index 23078def..9955b39e 100644 --- a/crates/ui/src/time/calendar.rs +++ b/crates/ui/src/time/calendar.rs @@ -12,7 +12,7 @@ use crate::{ button::Button, h_flex, theme::{ActiveTheme, Colorize}, - v_flex, Clickable, Disableable, IconName, Selectable, + v_flex, Disableable as _, IconName, Selectable, }; use super::utils::days_in_month; diff --git a/crates/ui/src/time/date_picker.rs b/crates/ui/src/time/date_picker.rs index 16631633..a64332f2 100644 --- a/crates/ui/src/time/date_picker.rs +++ b/crates/ui/src/time/date_picker.rs @@ -7,8 +7,8 @@ use gpui::{ use rust_i18n::t; use crate::{ - dropdown::Escape, h_flex, input::ClearButton, styled_ext::StyleSized as _, - theme::ActiveTheme as _, Clickable, Icon, IconName, Sizable, Size, StyledExt as _, + dropdown::Escape, h_flex, input::ClearButton, theme::ActiveTheme as _, Icon, IconName, Sizable, + Size, StyleSized as _, StyledExt as _, }; use super::calendar::{Calendar, CalendarEvent, Date}; @@ -223,7 +223,10 @@ impl Render for DatePicker { .rounded_lg() .p_3() .w(px(popover_width)) - .elevation_2(cx) + .border_1() + .border_color(cx.theme().border) + .shadow_lg() + .rounded_lg() .on_mouse_up_out( MouseButton::Left, cx.listener(|view, _, cx| view.escape(&Escape, cx)), diff --git a/crates/ui/src/tooltip.rs b/crates/ui/src/tooltip.rs index d3b83077..51241281 100644 --- a/crates/ui/src/tooltip.rs +++ b/crates/ui/src/tooltip.rs @@ -3,7 +3,7 @@ use gpui::{ VisualContext, WindowContext, }; -use crate::{theme::ActiveTheme, StyledExt}; +use crate::theme::ActiveTheme; pub struct Tooltip { text: SharedString, @@ -23,7 +23,10 @@ impl Render for Tooltip { .m_3() .bg(cx.theme().popover) .text_color(cx.theme().popover_foreground) - .elevation_1(cx) + .bg(cx.theme().popover) + .border_1() + .border_color(cx.theme().border) + .shadow_md() .rounded(px(6.)) .pt_1() .pb_0p5() diff --git a/crates/workspace/src/notification.rs b/crates/workspace/src/notification.rs index 08e2338e..8531fcc3 100644 --- a/crates/workspace/src/notification.rs +++ b/crates/workspace/src/notification.rs @@ -8,7 +8,7 @@ use gpui::{ ViewContext, VisualContext, WindowContext, }; -use ui::{h_flex, label::Label, theme::ActiveTheme, v_flex, Icon, IconName, StyledExt}; +use ui::{h_flex, label::Label, theme::ActiveTheme, v_flex, Icon, IconName}; use crate::Workspace; @@ -210,7 +210,11 @@ impl MessageNotification { impl Render for MessageNotification { fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { v_flex() - .elevation_3(cx) + .bg(cx.theme().popover) + .border_1() + .border_color(cx.theme().border) + .shadow_xl() + .rounded_xl() .p_4() .max_w_80() .bg(cx.theme().background)