diff --git a/crates/storybook/src/story_selector.rs b/crates/storybook/src/story_selector.rs index efbd605b59..7c875c4d90 100644 --- a/crates/storybook/src/story_selector.rs +++ b/crates/storybook/src/story_selector.rs @@ -32,7 +32,6 @@ pub enum ComponentStory { OverflowScroll, Picker, Scroll, - Setting, Tab, TabBar, Text, @@ -66,7 +65,6 @@ impl ComponentStory { Self::ListItem => cx.new_view(|_| ui::ListItemStory).into(), Self::OverflowScroll => cx.new_view(|_| crate::stories::OverflowScrollStory).into(), Self::Scroll => ScrollStory::view(cx).into(), - Self::Setting => cx.new_view(|cx| ui::SettingStory::init(cx)).into(), Self::Text => TextStory::view(cx).into(), Self::Tab => cx.new_view(|_| ui::TabStory).into(), Self::TabBar => cx.new_view(|_| ui::TabBarStory).into(), diff --git a/crates/ui/src/components.rs b/crates/ui/src/components.rs index 72fe080388..3a56e46eae 100644 --- a/crates/ui/src/components.rs +++ b/crates/ui/src/components.rs @@ -17,7 +17,6 @@ mod popover; mod popover_menu; mod radio; mod right_click_menu; -mod setting; mod settings_container; mod settings_group; mod stack; @@ -48,7 +47,6 @@ pub use popover::*; pub use popover_menu::*; pub use radio::*; pub use right_click_menu::*; -pub use setting::*; pub use settings_container::*; pub use settings_group::*; pub use stack::*; diff --git a/crates/ui/src/components/setting.rs b/crates/ui/src/components/setting.rs deleted file mode 100644 index 7413f174b6..0000000000 --- a/crates/ui/src/components/setting.rs +++ /dev/null @@ -1,358 +0,0 @@ -use crate::{prelude::*, Checkbox, ContextMenu, ListHeader}; - -use super::DropdownMenu; - -#[derive(PartialEq, Clone, Eq, Debug)] -pub enum ToggleType { - Checkbox, - // Switch, -} - -impl From for SettingType { - fn from(toggle_type: ToggleType) -> Self { - SettingType::Toggle(toggle_type) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum InputType { - Text, - Number, -} - -impl From for SettingType { - fn from(input_type: InputType) -> Self { - SettingType::Input(input_type) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum SecondarySettingType { - Dropdown, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum SettingType { - Toggle(ToggleType), - ToggleAnd(SecondarySettingType), - Input(InputType), - Dropdown, - Range, - Unsupported, -} - -#[derive(Debug, Clone, IntoElement)] -pub struct LegacySettingsGroup { - pub name: String, - settings: Vec, -} - -impl LegacySettingsGroup { - pub fn new(name: impl Into) -> Self { - Self { - name: name.into(), - settings: Vec::new(), - } - } - - pub fn add_setting(mut self, setting: SettingsItem) -> Self { - self.settings.push(setting); - self - } -} - -impl RenderOnce for LegacySettingsGroup { - fn render(self, _cx: &mut WindowContext) -> impl IntoElement { - let empty_message = format!("No settings available for {}", self.name); - - let header = ListHeader::new(self.name); - - let settings = self.settings.clone().into_iter(); - - v_flex() - .p_1() - .gap_2() - .child(header) - .when(self.settings.len() == 0, |this| { - this.child(Label::new(empty_message)) - }) - .children(settings) - } -} - -#[derive(Debug, Clone, PartialEq)] -pub enum SettingLayout { - Stacked, - AutoWidth, - FullLine, - FullLineJustified, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct SettingId(pub SharedString); - -impl From for ElementId { - fn from(id: SettingId) -> Self { - ElementId::Name(id.0) - } -} - -impl From<&str> for SettingId { - fn from(id: &str) -> Self { - Self(id.to_string().into()) - } -} - -impl From for SettingId { - fn from(id: SharedString) -> Self { - Self(id) - } -} - -#[derive(Debug, Clone, PartialEq)] -pub struct SettingValue(pub SharedString); - -impl From for SettingValue { - fn from(value: SharedString) -> Self { - Self(value) - } -} - -impl From for SettingValue { - fn from(value: String) -> Self { - Self(value.into()) - } -} - -impl From for SettingValue { - fn from(value: bool) -> Self { - Self(value.to_string().into()) - } -} - -impl From for bool { - fn from(value: SettingValue) -> Self { - value.0 == "true" - } -} - -#[derive(Debug, Clone, IntoElement)] -pub struct SettingsItem { - pub id: SettingId, - current_value: Option, - disabled: bool, - hide_label: bool, - icon: Option, - layout: SettingLayout, - name: SharedString, - // possible_values: Option>, - setting_type: SettingType, - toggled: Option, -} - -impl SettingsItem { - pub fn new( - id: impl Into, - name: SharedString, - setting_type: SettingType, - current_value: Option, - ) -> Self { - let toggled = match setting_type { - SettingType::Toggle(_) | SettingType::ToggleAnd(_) => Some(false), - _ => None, - }; - - Self { - id: id.into(), - current_value, - disabled: false, - hide_label: false, - icon: None, - layout: SettingLayout::FullLine, - name, - // possible_values: None, - setting_type, - toggled, - } - } - - pub fn layout(mut self, layout: SettingLayout) -> Self { - self.layout = layout; - self - } - - pub fn toggled(mut self, toggled: bool) -> Self { - self.toggled = Some(toggled); - self - } - - // pub fn hide_label(mut self, hide_label: bool) -> Self { - // self.hide_label = hide_label; - // self - // } - - pub fn icon(mut self, icon: IconName) -> Self { - self.icon = Some(icon); - self - } - - // pub fn disabled(mut self, disabled: bool) -> Self { - // self.disabled = disabled; - // self - // } -} - -impl RenderOnce for SettingsItem { - fn render(self, cx: &mut WindowContext) -> impl IntoElement { - let id: ElementId = self.id.clone().into(); - - // When the setting is disabled or toggled off, we don't want any secondary elements to be interactable - let _secondary_element_disabled = self.disabled || self.toggled == Some(false); - - let full_width = match self.layout { - SettingLayout::FullLine | SettingLayout::FullLineJustified => true, - _ => false, - }; - - let hide_label = self.hide_label || self.icon.is_some(); - - let justified = match (self.layout.clone(), self.setting_type.clone()) { - (_, SettingType::ToggleAnd(_)) => true, - (SettingLayout::FullLineJustified, _) => true, - _ => false, - }; - - let (setting_type, current_value) = (self.setting_type.clone(), self.current_value.clone()); - let current_string = if let Some(current_value) = current_value.clone() { - Some(current_value.0) - } else { - None - }; - - let toggleable = match setting_type { - SettingType::Toggle(_) => true, - SettingType::ToggleAnd(_) => true, - _ => false, - }; - - let setting_element = match setting_type { - SettingType::Toggle(_) => None, - SettingType::ToggleAnd(secondary_setting_type) => match secondary_setting_type { - SecondarySettingType::Dropdown => Some( - DropdownMenu::new( - id.clone(), - current_string.unwrap_or_default(), - ContextMenu::build(cx, |menu, _cx| menu), - ) - .into_any_element(), - ), - }, - SettingType::Input(input_type) => match input_type { - InputType::Text => Some(div().child("text").into_any_element()), - InputType::Number => Some(div().child("number").into_any_element()), - }, - SettingType::Dropdown => Some( - DropdownMenu::new( - id.clone(), - current_string.unwrap_or_default(), - ContextMenu::build(cx, |menu, _cx| menu), - ) - .full_width(true) - .into_any_element(), - ), - SettingType::Range => Some(div().child("range").into_any_element()), - SettingType::Unsupported => None, - }; - - let checkbox = Checkbox::new( - ElementId::Name(format!("toggle-{}", self.id.0).to_string().into()), - self.toggled.into(), - ) - .disabled(self.disabled); - - let toggle_element = match (toggleable, self.setting_type.clone()) { - (true, SettingType::Toggle(toggle_type)) => match toggle_type { - ToggleType::Checkbox => Some(checkbox.into_any_element()), - }, - (true, SettingType::ToggleAnd(_)) => Some(checkbox.into_any_element()), - (_, _) => None, - }; - - let item = if self.layout == SettingLayout::Stacked { - v_flex() - } else { - h_flex() - }; - - item.id(id) - .gap_2() - .w_full() - .when_some(self.icon, |this, icon| { - this.child(div().px_0p5().child(Icon::new(icon).color(Color::Muted))) - }) - .children(toggle_element) - .children(if hide_label { - None - } else { - Some(Label::new(self.name.clone())) - }) - .when(justified, |this| this.child(div().flex_1().size_full())) - .child( - h_flex() - .when(full_width, |this| this.w_full()) - .when(self.layout == SettingLayout::FullLineJustified, |this| { - this.justify_end() - }) - .children(setting_element), - ) - // help flex along when full width is disabled - // - // this probably isn't needed, but fighting with flex to - // get this right without inspection tools will be a pain - .when(!full_width, |this| this.child(div().size_full().flex_1())) - } -} - -pub struct LegacySettingsMenu { - name: SharedString, - groups: Vec, -} - -impl LegacySettingsMenu { - pub fn new(name: impl Into) -> Self { - Self { - name: name.into(), - groups: Vec::new(), - } - } - - pub fn add_group(mut self, group: LegacySettingsGroup) -> Self { - self.groups.push(group); - self - } -} - -impl Render for LegacySettingsMenu { - fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { - let is_empty = self.groups.is_empty(); - v_flex() - .id(ElementId::Name(self.name.clone())) - .elevation_2(cx) - .min_w_56() - .max_w_96() - .max_h_2_3() - .px_2() - .map(|el| { - if is_empty { - el.py_1() - } else { - el.pt_0().pb_1() - } - }) - .gap_1() - .when(is_empty, |this| { - this.child(Label::new("No settings found").color(Color::Muted)) - }) - .children(self.groups.clone()) - } -} diff --git a/crates/ui/src/components/stories.rs b/crates/ui/src/components/stories.rs index 4007fba998..9014f5a470 100644 --- a/crates/ui/src/components/stories.rs +++ b/crates/ui/src/components/stories.rs @@ -10,7 +10,6 @@ mod label; mod list; mod list_header; mod list_item; -mod setting; mod tab; mod tab_bar; mod toggle_button; @@ -28,7 +27,6 @@ pub use label::*; pub use list::*; pub use list_header::*; pub use list_item::*; -pub use setting::*; pub use tab::*; pub use tab_bar::*; pub use toggle_button::*; diff --git a/crates/ui/src/components/stories/setting.rs b/crates/ui/src/components/stories/setting.rs deleted file mode 100644 index bfdfb6a591..0000000000 --- a/crates/ui/src/components/stories/setting.rs +++ /dev/null @@ -1,225 +0,0 @@ -use gpui::View; - -use crate::prelude::*; - -use crate::{ - LegacySettingsGroup, LegacySettingsMenu, SecondarySettingType, SettingLayout, SettingType, - SettingsItem, ToggleType, -}; - -pub struct SettingStory { - menus: Vec<(SharedString, View)>, -} - -impl SettingStory { - pub fn new() -> Self { - Self { menus: Vec::new() } - } - - pub fn init(cx: &mut ViewContext) -> Self { - let mut story = Self::new(); - story.empty_menu(cx); - story.editor_example(cx); - story.menu_single_group(cx); - story - } -} - -impl SettingStory { - pub fn empty_menu(&mut self, cx: &mut ViewContext) { - let menu = cx.new_view(|_cx| LegacySettingsMenu::new("Empty Menu")); - - self.menus.push(("Empty Menu".into(), menu)); - } - - pub fn menu_single_group(&mut self, cx: &mut ViewContext) { - let theme_setting = SettingsItem::new( - "theme-setting", - "Theme".into(), - SettingType::Dropdown, - Some(cx.theme().name.clone().into()), - ) - .layout(SettingLayout::Stacked); - let high_contrast_setting = SettingsItem::new( - "theme-contrast", - "Use high contrast theme".into(), - SettingType::Toggle(ToggleType::Checkbox), - None, - ) - .toggled(false); - let appearance_setting = SettingsItem::new( - "switch-appearance", - "Match system appearance".into(), - SettingType::ToggleAnd(SecondarySettingType::Dropdown), - Some("When Dark".to_string().into()), - ) - .layout(SettingLayout::FullLineJustified); - - let group = LegacySettingsGroup::new("Appearance") - .add_setting(theme_setting) - .add_setting(appearance_setting) - .add_setting(high_contrast_setting); - - let menu = cx.new_view(|_cx| LegacySettingsMenu::new("Appearance").add_group(group)); - - self.menus.push(("Single Group".into(), menu)); - } - - pub fn editor_example(&mut self, cx: &mut ViewContext) { - let font_group = LegacySettingsGroup::new("Font") - .add_setting( - SettingsItem::new( - "font-family", - "Font".into(), - SettingType::Dropdown, - Some("Berkeley Mono".to_string().into()), - ) - .icon(IconName::Font) - .layout(SettingLayout::AutoWidth), - ) - .add_setting( - SettingsItem::new( - "font-weight", - "Font Weight".into(), - SettingType::Dropdown, - Some("400".to_string().into()), - ) - .icon(IconName::FontWeight) - .layout(SettingLayout::AutoWidth), - ) - .add_setting( - SettingsItem::new( - "font-size", - "Font Size".into(), - SettingType::Dropdown, - Some("14".to_string().into()), - ) - .icon(IconName::FontSize) - .layout(SettingLayout::AutoWidth), - ) - .add_setting( - SettingsItem::new( - "line-height", - "Line Height".into(), - SettingType::Dropdown, - Some("1.35".to_string().into()), - ) - .icon(IconName::LineHeight) - .layout(SettingLayout::AutoWidth), - ) - .add_setting( - SettingsItem::new( - "enable-ligatures", - "Enable Ligatures".into(), - SettingType::Toggle(ToggleType::Checkbox), - None, - ) - .toggled(true), - ); - - let editor_group = LegacySettingsGroup::new("Editor") - .add_setting( - SettingsItem::new( - "show-indent-guides", - "Indent Guides".into(), - SettingType::Toggle(ToggleType::Checkbox), - None, - ) - .toggled(true), - ) - .add_setting( - SettingsItem::new( - "show-git-blame", - "Git Blame".into(), - SettingType::Toggle(ToggleType::Checkbox), - None, - ) - .toggled(false), - ); - - let gutter_group = LegacySettingsGroup::new("Gutter") - .add_setting( - SettingsItem::new( - "enable-git-hunks", - "Show Git Hunks".into(), - SettingType::Toggle(ToggleType::Checkbox), - None, - ) - .toggled(true), - ) - .add_setting( - SettingsItem::new( - "show-line-numbers", - "Line Numbers".into(), - SettingType::ToggleAnd(SecondarySettingType::Dropdown), - Some("Ascending".to_string().into()), - ) - .toggled(true) - .layout(SettingLayout::FullLineJustified), - ); - - let scrollbar_group = LegacySettingsGroup::new("Scrollbar") - .add_setting( - SettingsItem::new( - "scrollbar-visibility", - "Show scrollbar when:".into(), - SettingType::Dropdown, - Some("Always Visible".to_string().into()), - ) - .layout(SettingLayout::AutoWidth) - .icon(IconName::Visible), - ) - .add_setting( - SettingsItem::new( - "show-diagnostic-markers", - "Diagnostic Markers".into(), - SettingType::Toggle(ToggleType::Checkbox), - None, - ) - .toggled(true), - ) - .add_setting( - SettingsItem::new( - "show-git-markers", - "Git Status Markers".into(), - SettingType::Toggle(ToggleType::Checkbox), - None, - ) - .toggled(false), - ) - .add_setting( - SettingsItem::new( - "show-selection-markers", - "Selection & Match Markers".into(), - SettingType::Toggle(ToggleType::Checkbox), - None, - ) - .toggled(true), - ); - - let menu = cx.new_view(|_cx| { - LegacySettingsMenu::new("Editor") - .add_group(font_group) - .add_group(editor_group) - .add_group(gutter_group) - .add_group(scrollbar_group) - }); - - self.menus.push(("Editor Example".into(), menu)); - } -} - -impl Render for SettingStory { - fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { - div() - .bg(cx.theme().colors().background) - .text_color(cx.theme().colors().text) - .children(self.menus.iter().map(|(name, menu)| { - v_flex() - .p_2() - .gap_2() - .child(Headline::new(name.clone()).size(HeadlineSize::Medium)) - .child(menu.clone()) - })) - } -}