diff --git a/crates/ui2/src/color.rs b/crates/ui2/src/color.rs index 7e7453dc72cb924e5bddd5c193a64d961c6deabd..03e141831bd4d1a3ab8e68ae9ea3a7970a5e4a82 100644 --- a/crates/ui2/src/color.rs +++ b/crates/ui2/src/color.rs @@ -166,13 +166,13 @@ impl ThemeColor { surface: theme.middle.base.default.background, background: theme.lowest.base.default.background, filled_element: theme.lowest.base.default.background, - filled_element_hover: theme.lowest.base.hovered.background, - filled_element_active: theme.lowest.base.active.background, + filled_element_hover: hsla(0.0, 0.0, 100.0, 0.16), + filled_element_active: hsla(0.0, 0.0, 100.0, 0.32), filled_element_selected: theme.lowest.accent.default.background, filled_element_disabled: transparent, ghost_element: transparent, - ghost_element_hover: theme.lowest.base.default.background, - ghost_element_active: theme.lowest.base.hovered.background, + ghost_element_hover: hsla(0.0, 0.0, 100.0, 0.08), + ghost_element_active: hsla(0.0, 0.0, 100.0, 0.16), ghost_element_selected: theme.lowest.accent.default.background, ghost_element_disabled: transparent, text: theme.lowest.base.default.foreground, diff --git a/crates/ui2/src/elements/button.rs b/crates/ui2/src/elements/button.rs index 9d7897cb24fc4f4ace06ffbb9d926f0914e0cff6..d38905ef572a7da219ab6ab2c233a08581df98bd 100644 --- a/crates/ui2/src/elements/button.rs +++ b/crates/ui2/src/elements/button.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use std::sync::Arc; -use gpui2::{DefiniteLength, Hsla, MouseButton, WindowContext}; +use gpui2::{div, DefiniteLength, Hsla, MouseButton, WindowContext}; use crate::settings::user_settings; use crate::{h_stack, Icon, IconColor, IconElement, Label, LabelColor}; @@ -21,6 +21,35 @@ pub enum ButtonVariant { Filled, } +impl ButtonVariant { + pub fn bg_color(&self, cx: &mut WindowContext) -> Hsla { + let color = ThemeColor::new(cx); + + match self { + ButtonVariant::Ghost => color.ghost_element, + ButtonVariant::Filled => color.filled_element, + } + } + + pub fn bg_color_hover(&self, cx: &mut WindowContext) -> Hsla { + let color = ThemeColor::new(cx); + + match self { + ButtonVariant::Ghost => color.ghost_element_hover, + ButtonVariant::Filled => color.filled_element_hover, + } + } + + pub fn bg_color_active(&self, cx: &mut WindowContext) -> Hsla { + let color = ThemeColor::new(cx); + + match self { + ButtonVariant::Ghost => color.ghost_element_active, + ButtonVariant::Filled => color.filled_element_active, + } + } +} + pub type ClickHandler = Arc) + 'static + Send + Sync>; struct ButtonHandlers { @@ -36,26 +65,26 @@ impl Default for ButtonHandlers { #[derive(Element)] pub struct Button { state_type: PhantomData, - label: SharedString, - variant: ButtonVariant, - state: InteractionState, + disabled: bool, + handlers: ButtonHandlers, icon: Option, icon_position: Option, + label: SharedString, + variant: ButtonVariant, width: Option, - handlers: ButtonHandlers, } impl Button { pub fn new(label: impl Into) -> Self { Self { state_type: PhantomData, - label: label.into(), - variant: Default::default(), - state: Default::default(), + disabled: false, + handlers: ButtonHandlers::default(), icon: None, icon_position: None, + label: label.into(), + variant: Default::default(), width: Default::default(), - handlers: ButtonHandlers::default(), } } @@ -68,11 +97,6 @@ impl Button { self } - pub fn state(mut self, state: InteractionState) -> Self { - self.state = state; - self - } - pub fn icon(mut self, icon: Icon) -> Self { self.icon = Some(icon); self @@ -96,43 +120,24 @@ impl Button { self } - fn background_color(&self, cx: &mut ViewContext) -> Hsla { - let color = ThemeColor::new(cx); - - match (self.variant, self.state) { - (ButtonVariant::Ghost, InteractionState::Enabled) => color.ghost_element, - (ButtonVariant::Ghost, InteractionState::Focused) => color.ghost_element, - (ButtonVariant::Ghost, InteractionState::Hovered) => color.ghost_element_hover, - (ButtonVariant::Ghost, InteractionState::Active) => color.ghost_element_active, - (ButtonVariant::Ghost, InteractionState::Disabled) => color.filled_element_disabled, - (ButtonVariant::Filled, InteractionState::Enabled) => color.filled_element, - (ButtonVariant::Filled, InteractionState::Focused) => color.filled_element, - (ButtonVariant::Filled, InteractionState::Hovered) => color.filled_element_hover, - (ButtonVariant::Filled, InteractionState::Active) => color.filled_element_active, - (ButtonVariant::Filled, InteractionState::Disabled) => color.filled_element_disabled, - } + pub fn disabled(mut self, disabled: bool) -> Self { + self.disabled = disabled; + self } fn label_color(&self) -> LabelColor { - match self.state { - InteractionState::Disabled => LabelColor::Disabled, - _ => Default::default(), + if self.disabled { + LabelColor::Disabled + } else { + self.label_color() } } fn icon_color(&self) -> IconColor { - match self.state { - InteractionState::Disabled => IconColor::Disabled, - _ => Default::default(), - } - } - - fn border_color(&self, cx: &WindowContext) -> Hsla { - let color = ThemeColor::new(cx); - - match self.state { - InteractionState::Focused => color.border_focused, - _ => color.border_transparent, + if self.disabled { + IconColor::Disabled + } else { + self.icon_color() } } @@ -151,53 +156,47 @@ impl Button { _view: &mut S, cx: &mut ViewContext, ) -> impl Element { - let icon_color = self.icon_color(); - let border_color = self.border_color(cx); + let color = ThemeColor::new(cx); let settings = user_settings(cx); + let icon_color = self.icon_color(); - let mut el = h_stack() + let mut button = h_stack() + .relative() + .id(SharedString::from(format!("{}", self.label))) .p_1() .text_size(ui_size(cx, 1.)) .rounded_md() - .border() - .border_color(border_color) - .bg(self.background_color(cx)) - .hover(|style| { - let color = ThemeColor::new(cx); - - style.bg(match self.variant { - ButtonVariant::Ghost => color.ghost_element_hover, - ButtonVariant::Filled => color.filled_element_hover, - }) - }); + .bg(self.variant.bg_color(cx)) + .hover(|style| style.bg(self.variant.bg_color_hover(cx))) + .active(|style| style.bg(self.variant.bg_color_active(cx))); match (self.icon, self.icon_position) { (Some(_), Some(IconPosition::Left)) => { - el = el + button = button .gap_1() .child(self.render_label()) .children(self.render_icon(icon_color)) } (Some(_), Some(IconPosition::Right)) => { - el = el + button = button .gap_1() .children(self.render_icon(icon_color)) .child(self.render_label()) } - (_, _) => el = el.child(self.render_label()), + (_, _) => button = button.child(self.render_label()), } if let Some(width) = self.width { - el = el.w(width).justify_center(); + button = button.w(width).justify_center(); } if let Some(click_handler) = self.handlers.click.clone() { - el = el.on_mouse_down(MouseButton::Left, move |state, event, cx| { + button = button.on_mouse_down(MouseButton::Left, move |state, event, cx| { click_handler(state, cx); }); } - el + button } }